5
\$\begingroup\$

I'm developing an audio recorder app for android using AudioRecord class to have a low level access to audio samples.

mRecordingThread = new Thread(new Runnable() {
    @Override
    public void run() {
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);
        try {
            FileChannel fileChannel = new FileOutputStream("/foo/bar/temp.wav").getChannel();
            ByteBuffer audioBuffer = ByteBuffer.allocateDirect(mBufferSize).order(ByteOrder.nativeOrder());

            mAudioRecord.startRecording();
            mIsRecording = true;
            while (mIsRecording) {
                int readSize = mAudioRecord.read(audioBuffer, audioBuffer.capacity());
                if (readSize == AudioRecord.ERROR_INVALID_OPERATION || readSize == AudioRecord.ERROR_BAD_VALUE) {
                    Logger.getInstance().e("Could not read audio data.");
                    break;
                }
                try {
                    audioBuffer.limit(readSize);
                    fileChannel.write(audioBuffer);

                    audioBuffer.rewind(); // set buffer's position to 0.
                    mAudioDataReceiver.onAudioDataReceived(audioBuffer, mConfig.getSampleWidth());

                    audioBuffer.clear(); // set buffer's limit to its capacity, set position to 0.

                } catch (IOException e) {
                    Logger.getInstance().e(e);
                }
            }
            fileChannel.close();

        } catch (IOException e) {
            Logger.getInstance().e(e);
            // ...
        }
    }
});
mRecordingThread.start();

As shown in the above code, i'm writing the samples to a file as well as passing them to another function mAudioDataReceiver.onAudioDataReceived for visualisation (generate waveform, analyse loudness, etc.). I'm using ByteBuffer as container so i can easily convert it to other type (ShortBuffer or FloatBuffer, depending on the given sample width) before processing the samples

public void onAudioDataReceived(ByteBuffer buffer, int sampleWidth) {
    switch (sampleWidth) {
        case 8: // 8-bit = 1 byte per sample
            onAudioDataReceived(buffer);
            break;
        case 16: // 16-bit = 2 bytes per sample
            onAudioDataReceived(buffer.asShortBuffer());
            break;
        case 32: // 32-bit = 4 bytes per sample
            onAudioDataReceived(buffer.asFloatBuffer());
            break;
    }
} 

Question: This line is kinda worrying to me:

ByteBuffer audioBuffer = ByteBuffer.allocateDirect(mBufferSize).order(ByteOrder.nativeOrder());

Is it right to set the byte ordering to native order? Will this work with every device?

Also, is there anything wrong in my code that would potentially mess up the quality of the audio?

Sorry if my questions sound silly, i'm relatively new to android/java development/audio processing, so please bear with me. Thanks

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.