Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f91a272 authored by luca020400's avatar luca020400
Browse files

Improve high quality recorder

Record in stereo.

This also makes the pcm converter
configurable to allow easily playing
with the options

Change-Id: I33bcd5a8b2a925a06bc2e1a2693c62cdfcd872e5
parent a9c599f9
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -36,12 +36,13 @@ public class HighQualityRecorder implements SoundRecording {
    private static final String FILE_NAME_EXTENSION_WAV = "wav";
    private static final String FILE_MIME_TYPE_WAV = "audio/wav";
    private static final int SAMPLING_RATE = 44100;
    private static final int CHANNEL_IN = AudioFormat.CHANNEL_IN_DEFAULT;
    private static final int CHANNEL_IN = AudioFormat.CHANNEL_IN_STEREO;
    private static final int FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    private static final int BUFFER_SIZE_IN_BYTES = 2 * AudioRecord.getMinBufferSize(SAMPLING_RATE,
            CHANNEL_IN, FORMAT);

    private AudioRecord mRecord;
    private PcmConverter mPcmConverter;
    private Path mPath;
    private int mMaxAmplitude;

@@ -53,8 +54,19 @@ public class HighQualityRecorder implements SoundRecording {
    @RequiresPermission(Manifest.permission.RECORD_AUDIO)
    public void startRecording(Path path) {
        mPath = path;
        mRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT,
                SAMPLING_RATE, CHANNEL_IN, FORMAT, BUFFER_SIZE_IN_BYTES);

        AudioFormat audioFormat = new AudioFormat.Builder()
                .setSampleRate(SAMPLING_RATE)
                .setChannelMask(CHANNEL_IN)
                .setEncoding(FORMAT)
                .build();

        mPcmConverter = new PcmConverter(audioFormat.getSampleRate(),
                audioFormat.getChannelCount(),
                audioFormat.getFrameSizeInBytes() * 8 / audioFormat.getChannelCount());

        mRecord = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, audioFormat.getSampleRate(),
                audioFormat.getChannelMask(), audioFormat.getEncoding(), BUFFER_SIZE_IN_BYTES);
        mRecord.startRecording();

        mIsRecording.set(true);
@@ -76,7 +88,7 @@ public class HighQualityRecorder implements SoundRecording {
        } catch (InterruptedException e) {
            // Wait at most 1 second, if we fail save the current data
        } finally {
            PcmConverter.convertToWave(mPath, BUFFER_SIZE_IN_BYTES);
            mPcmConverter.convertToWave(mPath, BUFFER_SIZE_IN_BYTES);
        }

        return true;
+27 −28
Original line number Diff line number Diff line
@@ -25,11 +25,13 @@ import java.nio.file.Path;
import java.util.Arrays;

public final class PcmConverter {
    private static final long SAMPLE_RATE = 44100;
    private static final byte RECORDER_BPP = 16;
    private static final byte CHANNELS = 1;
    private static final long BYTE_RATE = CHANNELS * SAMPLE_RATE * RECORDER_BPP / 8;
    private static final byte[] WAV_HEADER = {
    private final byte[] WAV_HEADER;
    private static final String TAG = "PcmConverter";

    public PcmConverter(long sampleRate, int channels, int bitsPerSample) {
        long byteRate = channels * sampleRate * bitsPerSample / 8;

        WAV_HEADER = new byte[]{
                'R', 'I', 'F', 'F',
                0, 0, 0, 0, // data length placeholder
                'W', 'A', 'V', 'E',
@@ -37,24 +39,21 @@ public final class PcmConverter {
                16, // 4 bytes: size of 'fmt ' chunk
                0, 0, 0, 1, // format = 1
                0,
            CHANNELS,
                (byte) channels,
                0,
            (byte) (SAMPLE_RATE & 0xff), (byte) ((SAMPLE_RATE >> 8) & 0xff), 0, 0, // sample rate
            (byte) (BYTE_RATE & 0xff), (byte) ((BYTE_RATE >> 8) & 0xff),
            (byte) ((BYTE_RATE >> 16) & 0xff), 0, // byte rate
            (byte) (CHANNELS * RECORDER_BPP / 8),  // block align
                (byte) (sampleRate & 0xff), (byte) ((sampleRate >> 8) & 0xff), 0, 0, // sample rate
                (byte) (byteRate & 0xff), (byte) ((byteRate >> 8) & 0xff),
                (byte) ((byteRate >> 16) & 0xff), 0, // byte rate
                (byte) (channels * bitsPerSample / 8),  // block align
                0,
            RECORDER_BPP, // bits per sample
                (byte) bitsPerSample, // bits per sample
                0,
                'd', 'a', 't', 'a',
                0, 0, 0, 0, // audio length placeholder
        };
    private static final String TAG = "PcmConverter";

    private PcmConverter() {
    }

    public static void convertToWave(Path path, int bufferSize) {
    public void convertToWave(Path path, int bufferSize) {
        InputStream input = null;
        OutputStream output = null;

@@ -96,7 +95,7 @@ public final class PcmConverter {
    }

    // http://stackoverflow.com/questions/4440015/java-pcm-to-wav
    private static void writeWaveHeader(OutputStream out, long audioLength,
    private void writeWaveHeader(OutputStream out, long audioLength,
                                 long dataLength) throws IOException {
        byte[] header = Arrays.copyOf(WAV_HEADER, WAV_HEADER.length);