How to adjust microphone sensitivity while recording audio in android
Asked Answered
L

4

10

I'm working on a voice recording app. In it, I have a Seekbar to change the input voice gain. I couldn't find any way to adjust the input voice gain.

I am using the AudioRecord class to record voice.

 recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
            RECORDER_SAMPLERATE, RECORDER_CHANNELS,
            RECORDER_AUDIO_ENCODING, bufferSize);

    recorder.startRecording();

I've seen an app in the Google Play Store using this functionality.

Langston answered 22/8, 2014 at 6:52 Comment(0)
Y
22

As I understand you don't want any automatic adjustments, only manual from the UI. There is no built-in functionality for this in Android, instead you have to modify your data manually.

Suppose you use read (short[] audioData, int offsetInShorts, int sizeInShorts) for reading the stream. So you should just do something like this:

float gain = getGain(); // taken from the UI control, perhaps in range from 0.0 to 2.0
int numRead = read(audioData, 0, SIZE);
if (numRead > 0) {
    for (int i = 0; i < numRead; ++i) {
        audioData[i] = (short)Math.min((int)(audioData[i] * gain), (int)Short.MAX_VALUE);
    }
}

Math.min is used to prevent overflow if gain is greater than 1.

Yachting answered 22/8, 2014 at 7:58 Comment(3)
thanks for help. i have done some modifications with your code and my problem is now solved.Langston
you also need to call Math.max(intValue, Short.MIN_VALUE) since Java short is signed, see my answer below.Serval
Only this answer works after searching a lot on the net. I had to set gain to over 7 to see some great effect! Thanks!Sepalous
P
3

Dynamic microphone sensitivity is not a thing that the hardware or operating system is capable of as it requires analysis on the recorded sound. You should implement your own algorithm to analyze the recorded sound and adjust (amplify or decrease) the sound level on your own.

You can start by analyzing last few seconds and find a multiplier that is going to "balance" the average amplitude. The multiplier must be inversely proportional to the average amplitude to balance it.

PS: If you still want to do it, the mic levels are accessible when you have a root access, but I am still not sure -and don't think it is possible- if you can change the settings while recording. Hint: "/system/etc/snd_soc_msm" file.

Prent answered 22/8, 2014 at 7:23 Comment(0)
C
0

Solution by OP.

I have done it using

final int USHORT_MASK = (1 << 16) - 1;

final ByteBuffer buf = ByteBuffer.wrap(data).order(
                        ByteOrder.LITTLE_ENDIAN);
final ByteBuffer newBuf = ByteBuffer.allocate(
                        data.length).order(ByteOrder.LITTLE_ENDIAN);

int sample;
        while (buf.hasRemaining()) {
                sample = (int) buf.getShort() & USHORT_MASK;
                sample *= db_value_global;
                        newBuf.putShort((short) (sample & USHORT_MASK));
                }

                data = newBuf.array();

                os.write(data);
Coinsurance answered 22/8, 2014 at 6:52 Comment(0)
S
-1

This is working implementation based on ByteBuffer for 16bit audio. It's important to clamp the increased value from both sides since short is signed. It's also important to set the native byte order to ByteBuffer since audioRecord.read() returns native endian bytes.

You may also want to perform audioRecord.read() and following code in a loop, calling data.clear() after each iteration.

    double gain = 2.0;

    ByteBuffer data = ByteBuffer.allocateDirect(SAMPLES_PER_FRAME).order(ByteOrder.nativeOrder());

    int audioInputLengthBytes = audioRecord.read(data, SAMPLES_PER_FRAME);
    ShortBuffer shortBuffer = data.asShortBuffer();
    for (int i = 0; i < audioInputLengthBytes / 2; i++) { // /2 because we need the length in shorts
        short s = shortBuffer.get(i);
        int increased = (int) (s * gain);
        s = (short) Math.min(Math.max(increased, Short.MIN_VALUE), Short.MAX_VALUE);
        shortBuffer.put(i, s);
    }
Serval answered 10/7, 2017 at 16:36 Comment(1)
so this didn't work at all... static noise all aroundHunterhunting

© 2022 - 2024 — McMap. All rights reserved.