Reputation: 31
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
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
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