0

I'm trying to record from the MIC direcly to a short array.

The goal is not to write a file with the audio track, just save it within a short array.

If've tried several methods and the best I've found is recording with AudioRecord and to play it with AudioTrack. I've found a good class here:

Android: Need to record mic input

This class makes all I need, I just have to modify it to achieve my desired result, but...I don't get it well, I'm missing something...

Here's is my modification (not working at all):

private class Audio extends Thread {
        private boolean stopped = false;
        /**
         * Give the thread high priority so that it's not canceled unexpectedly, and start it
         */
        private Audio()
        { 
            android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
            start();
        }

        @Override
        public void run()
        { 
            Log.i("Audio", "Running Audio Thread");
            AudioRecord recorder = null;
            AudioTrack track = null;
            //short[][]   buffers  = new short[256][160];
            int ix = 0;

            /*
             * Initialize buffer to hold continuously recorded audio data, start recording, and start
             * playback.
             */
            try
            {
                int N = AudioRecord.getMinBufferSize(8000,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT);
                recorder = new AudioRecord(AudioSource.MIC, 8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10);
                short[] buff = new short[N];
                recorder.startRecording();
                /*
                 * Loops until something outside of this thread stops it.
                 * Reads the data from the recorder and writes it to the audio track for playback.
                 */
                while(!stopped) {  
                    //Log.i("Map", "Writing new data to buffer");
                    //short[] buffer = buffer[ix++ % buffer.length];
                    N = recorder.read(buff, 0, buff.length);
                }

                recorder.stop();
                recorder.release();

                track = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, 
                        AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10, AudioTrack.MODE_STREAM);
                track.play();

                for (int i =0; i< buff.length;i++) {
                    track.write(buff, i, buff.length);
                }


            } catch(Exception x)    { 
                //Log.e("Audio", x.getMessage());
                x.printStackTrace();
            } finally { 

                track.stop();
                track.release();
            }
        }

        /**
         * Called from outside of the thread in order to stop the recording/playback loop
         */
        private void close()
        { 
            stopped = true;
        }

    }

What I need is to record the sound in the short array buffer and when the user push a button, play it...But right now, I'm trying to record the sound and, when user push a button, recording stop and the sound start playing...

Anyone can help me?

Thanks.

Community
  • 1
  • 1
josecash
  • 339
  • 4
  • 19
  • Are you getting anything in the 'recorder.read()' function call? How many bytes is it returning in 'N'? Do you know that when you are reading the buffer like this you are getting a very small slice of audio? It's like 20ms of data, so if you are trying to verify by listening you won't hear it. Your loop continues to read into the single buffer until 'stopped' is set to true. So you will only ever play the last chunk of audio. – spartygw May 14 '13 at 15:30
  • N return (at the moment I pressed stop button) 4096. To be honest, I don't really understand this code, maybe because I haven't use input streams so much...Thanks for your explanation, now I understand why only sounds the same bip lots of times...So how could I make this to save all bytes in the short array? – josecash May 14 '13 at 16:07

1 Answers1

0

You need to restructure the code to do what you want it to do. If I understand correctly you want to read sound until the 'stopped' is set true, then play the data.

Just so you understand that is potentially a lot of buffered data depending on how long that recording time is. You could write it to a file or store a series of buffers into some abstract data type.

Just to get something to work create a Vector of short [] and allocate a new short [] buffer in your 'while(!stopped)' loop and then stuff it into the vector.

After the while loop stops you can iterate through the vector and write the buffers to the AudioTrack.

As you now understand, the blip you were hearing is just the last 20ms or so of audio since your buffer only kept that last little bit.

spartygw
  • 3,289
  • 2
  • 27
  • 51