views:

200

answers:

1

Hi all,

I am currently trying to create an Android application that loops Audio from the mic to the earpiece, I can do that perfectly but when I do it over and over again in my application I eventually get an Out Of Memory Error.


Here is the code I use to create the Audio Loop:

static final int bufferSize = 200000;
    final short[] buffer = new short[bufferSize];
    short[] readBuffer = new short[bufferSize];

    public void run() {  
      isRecording = true;
      android.os.Process.setThreadPriority
      (android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

      int buffersize = AudioRecord.getMinBufferSize(11025,
      AudioFormat.CHANNEL_CONFIGURATION_MONO,
      AudioFormat.ENCODING_PCM_16BIT);


                     arec = new AudioRecord(MediaRecorder.AudioSource.MIC,
                                     11025,
                                     AudioFormat.CHANNEL_CONFIGURATION_MONO,
                                     MediaRecorder.AudioEncoder.AMR_NB,
                                     buffersize);
                     atrack = new AudioTrack(AudioManager.STREAM_VOICE_CALL,
                                     11025,
                                     AudioFormat.CHANNEL_CONFIGURATION_MONO,
                                     MediaRecorder.AudioEncoder.AMR_NB,
                                     buffersize,
                                     AudioTrack.MODE_STREAM);

                     Log.d("AUDIO", "sample rate = : " + arec.getSampleRate());

                     atrack.setPlaybackRate(11025);

                     byte[] buffer = new byte[buffersize];
                     arec.startRecording();
                     atrack.play();

                     while(isRecording) {
                             arec.read(buffer, 0, buffersize);
                             atrack.write(buffer, 0, buffer.length);
                     }  

    }

And here is the error I get:

ERROR/AndroidRuntime(3442): Uncaught handler: thread main exiting due to uncaught exception
ERROR/AndroidRuntime(3442): java.lang.OutOfMemoryError
ERROR/AndroidRuntime(3442):     at com.phone.engine.CallAudio$Record.<init>(CallAudio.java:114)
ERROR/AndroidRuntime(3442):     at com.phone.engine.CallAudio.onCreate(CallAudio.java:42)
ERROR/AndroidRuntime(3442):     at android.app.ActivityThread.handleCreateService(ActivityThread.java:2465)
ERROR/AndroidRuntime(3442):     at android.app.ActivityThread.access$2800(ActivityThread.java:112)
ERROR/AndroidRuntime(3442):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1744)
ERROR/AndroidRuntime(3442):     at android.os.Handler.dispatchMessage(Handler.java:99)
ERROR/AndroidRuntime(3442):     at android.os.Looper.loop(Looper.java:123)
ERROR/AndroidRuntime(3442):     at android.app.ActivityThread.main(ActivityThread.java:3948)
ERROR/AndroidRuntime(3442):     at java.lang.reflect.Method.invokeNative(Native Method)
ERROR/AndroidRuntime(3442):     at java.lang.reflect.Method.invoke(Method.java:521)
ERROR/AndroidRuntime(3442):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
ERROR/AndroidRuntime(3442):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
ERROR/AndroidRuntime(3442):     at dalvik.system.NativeStart.main(Native Method)

So the Error specifically focuses on this line in the code

short[] readBuffer = new short[bufferSize];

And it happens after I try to do the Loop several times, so say I start the application and after 10 times starting the loop I get the error.

So I think the buffer is simply becomiing full or something?? Is that correct? If so how would I keep clearing out the buffer?

Thanks in advance

+1  A: 

According to the API docs, you must stop the recording and release the instance. Otherwise, it'll hog system resources and you'll eventually run out. So add the necessary cleanup code and it should work.

Aaron Digulla
Cheers Aaron, so its likely to be that is filling up the buffer?
Donal Rafferty
Nope. It just means that the processes never terminate and the old buffers stay around (with all the other objects). Since the memory is never returned to the system, you'll eventually run out of it.
Aaron Digulla