AllahinAskeri
AllahinAskeri

Reputation: 31

Audio record glitchy audio

I'm using AudioRecord class to record internal audio. Sometimes this code works and records the audio perfectly but sometimes it is glitchy. I tried different record techniques but none of them worked exactly there is still sometimes glitch in background.

Link of bad recorded audio: https://youtu.be/Ccundu91Kjs

                AudioPlaybackCaptureConfiguration configuration = new AudioPlaybackCaptureConfiguration.Builder(mediaProjection)
                        .addMatchingUsage(AudioAttributes.USAGE_MEDIA)
                        .build();

                audioFormat = new AudioFormat.Builder()
                        .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
                        .setSampleRate(44100)
                        .setChannelMask(AudioFormat.CHANNEL_IN_STEREO)
                        .build();

                audioRecord = new AudioRecord.Builder()
                        .setAudioFormat(audioFormat)
                        .setAudioPlaybackCaptureConfig(konfigurasyon)
                        .build();

                audioRecord.startRecording();
        new Thread(() -> {
            while(recordAudio) {

                try {
                    
                    final ByteBuffer buffer = ByteBuffer.allocateDirect(AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT));

                    try {
                       os = new FileOutputStream(context.getExternalFilesDir(Environment.DIRECTORY_MUSIC) + "/tempAudio.pcm");
                    } catch (Exception e) {
                       e.printStackTrace();
                    }

                                      
                    Log.e("writeAudioDataToFile", "Recording.");

                    Log.e("writeAudioDataToFile", String.valueOf(AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT)));

                    audioRecord.read(buffer.array(), 0, AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT));                    
                  
                    os.write(buffer.array(), 0, AudioRecord.getMinBufferSize(44100, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT));
                    buffer.clear();
                } catch (Exception e) {

                    recordAudio = false;
                    audioRecord.stop();
                    audioRecord.release();
                    audioRecord = null;
                    Data = null;

                    try {
                        os.close();
                    } catch (Exception e1) {
                        e.printStackTrace();
                    }

                    os = null;

                    new File(context.getExternalFilesDir(Environment.DIRECTORY_MUSIC) + "/tempAudioInProcess.pcm").delete();
                    new File(context.getExternalFilesDir(Environment.DIRECTORY_MUSIC) + "/tempAudio.pcm").delete();
                    new File(context.getExternalFilesDir(Environment.DIRECTORY_MUSIC) + "/tempAudio.mp3").delete();

                    showNotification(context);

                    e.printStackTrace();
                }

It should record audio without glitch in background.

Upvotes: 1

Views: 79

Answers (2)

dev.bmax
dev.bmax

Reputation: 10601

If you look at the documentation of ENCODING_PCM_16BIT you will see:

The audio sample is a 16 bit signed integer typically stored as a Java short in a short array, but when the short is stored in a ByteBuffer, it is native endian (as compared to the default Java big endian).

So it's important to use the native byte order when you create the buffer:

ByteBuffer buffer = ByteBuffer.allocateDirect(bufferSize);
buffer.order(ByteOrder.nativeOrder());

When AudioRecord reads samples it tells you the number of bytes that were actually read.

int bytesRead = audioRecord.read(buffer, bufferSize);
if (bytesRead < 0) {
    // todo: handle the error
}

You should use this number instead of assuming that the buffer is always full.

Upvotes: 1

Karolis
Karolis

Reputation: 31

I think it is related to the fact that you are using hard coded buffer size. Documentation states that:

Returns the minimum buffer size required for the successful creation of an AudioRecord object, in byte units. Note that this size doesn't guarantee a smooth recording under load, and higher values should be chosen according to the expected frequency at which the AudioRecord instance will be polled for new data. See AudioRecord(int, int, int, int, int) for more information on valid configuration values.

Ref: getMinBufferSize

Upvotes: 1

Related Questions