AudioRecord增益控制获得嘈杂的声音

时间:2014-04-08 20:22:18

标签: java android audio audio-recording amplitude

我经历了堆栈溢出问题apply gain with variation和我想知道的相同但无法找到答案我试过他们在上面的问题链接中提到的回答没有正确或确切的解决方案仍然我得到了声音(比如Walkie-Talkie)。任何正确完成它的人。

 public class Mediarec extends Activity {

public static final int SAMPLE_RATE = 16000;

private AudioRecord mRecorder;
private File mRecording;
private short[] mBuffer;
private final String startRecordingLabel = "Start recording";
private final String stopRecordingLabel = "Stop recording";
private boolean mIsRecording = false;
private ProgressBar mProgressBar;
short iGain= (short)1.0f;
CheckBox gain;

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_mediarec);

    initRecorder();

    gain = (CheckBox) findViewById(R.id.checkBox1);
    mProgressBar = (ProgressBar) findViewById(R.id.progressBar);

    final Button button = (Button) findViewById(R.id.start);
    button.setText(startRecordingLabel);

    gain.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

           @Override
           public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {

               if(gain.isChecked())
               {

                   iGain = (short) Math.pow(10, 9.0 / 20.0 ) ;
                  // iGain = (short)2.0f;
               }
               else
               {
                   iGain = (short) Math.pow(10, 3 / 20.0 ) ;
               }
           }
        });

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
            if (!mIsRecording) {
                button.setText(stopRecordingLabel);
                mIsRecording = true;
                mRecorder.startRecording();
                mRecording = getFile("raw");
                startBufferedWrite(mRecording);
            }
            else {
                button.setText(startRecordingLabel);
                mIsRecording = false;
                mRecorder.stop();
                File waveFile = getFile("wav");
                try {
                    rawToWave(mRecording, waveFile);
                } catch (IOException e) {
                    Toast.makeText(Mediarec.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                }
                Toast.makeText(Mediarec.this, "Recorded to " + waveFile.getName(),
                        Toast.LENGTH_SHORT).show();
            }
        }
    });
}

@Override
public void onDestroy() {
    mRecorder.release();
    super.onDestroy();
}

private void initRecorder() {
    int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT);
    mBuffer = new short[bufferSize];
    mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT, bufferSize);
}

private void startBufferedWrite(final File file) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            DataOutputStream output = null;
            try {
                output = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
                while (mIsRecording) {
                    double sum = 0;
                    int readSize = mRecorder.read(mBuffer, 0, mBuffer.length);
                    for (int i = 0; i < readSize; i++) {
                        output.writeShort(mBuffer[i]);
                        sum += mBuffer[i] * mBuffer[i];
                    }
                    if (readSize > 0) {
                        final double amplitude = sum / readSize;
                        mProgressBar.setProgress((int) Math.sqrt(amplitude));
                    }
                }
            } catch (IOException e) {
                Toast.makeText(Mediarec.this, e.getMessage(), Toast.LENGTH_SHORT).show();
            } finally {
                mProgressBar.setProgress(0);
                if (output != null) {
                    try {
                        output.flush();
                    } catch (IOException e) {
                        Toast.makeText(Mediarec.this, e.getMessage(), Toast.LENGTH_SHORT)
                                .show();
                    } finally {
                        try {
                            output.close();
                        } catch (IOException e) {
                            Toast.makeText(Mediarec.this, e.getMessage(), Toast.LENGTH_SHORT)
                                    .show();
                        }
                    }
                }
            }
        }
    }).start();
}

private void rawToWave(final File rawFile, final File waveFile) throws IOException {

    byte[] rawData = new byte[(int) rawFile.length()];
    DataInputStream input = null;
    try {
        input = new DataInputStream(new FileInputStream(rawFile));
        input.read(rawData);
    } finally {
        if (input != null) {
            input.close();
        }
    }

    DataOutputStream output = null;
    try {
        output = new DataOutputStream(new FileOutputStream(waveFile));
        // WAVE header
        // see http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
        writeString(output, "RIFF"); // chunk id
        writeInt(output, 36 + rawData.length); // chunk size
        writeString(output, "WAVE"); // format
        writeString(output, "fmt "); // subchunk 1 id
        writeInt(output, 16); // subchunk 1 size
        writeShort(output, (short) 1); // audio format (1 = PCM)
        writeShort(output, (short) 1); // number of channels
        writeInt(output, SAMPLE_RATE); // sample rate
        writeInt(output, SAMPLE_RATE * 2); // byte rate
        writeShort(output, (short) 2); // block align
        writeShort(output, (short) 16); // bits per sample
        writeString(output, "data"); // subchunk 2 id
        writeInt(output, rawData.length); // subchunk 2 size
        // Audio data (conversion big endian -> little endian)
        short[] shorts = new short[rawData.length / 2];
        ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
        ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2);


        for (short s : shorts) {

            //Apply Gain
            s *= iGain;

                             if(s>32767)
            {
                s=32767;
            }
            else if(s<-32768)
            {
                s=-32768;
            }
            bytes.putShort(s);
        }
        output.write(bytes.array());
    } finally {
        if (output != null) {
            output.close();
        }
    }
}

private File getFile(final String suffix) {
    Time time = new Time();
    time.setToNow();
    return new File(Environment.getExternalStorageDirectory(), time.format("%Y%m%d%H%M%S") + "." + suffix);
}

private void writeInt(final DataOutputStream output, final int value) throws IOException {
    output.write(value >> 0);
    output.write(value >> 8);
    output.write(value >> 16);
    output.write(value >> 24);
}

private void writeShort(final DataOutputStream output, final short value) throws IOException {
    output.write(value >> 0);
    output.write(value >> 8);
}

private void writeString(final DataOutputStream output, final String value) throws IOException {
    for (int i = 0; i < value.length(); i++) {
        output.write(value.charAt(i));
    }
}

}

声音非常低 寻找解决方案如何应用带变化的增益

1 个答案:

答案 0 :(得分:0)

这是音频增益或麦克风音量增益的完整代码

忽略与此

无关的代码的某些部分
public class MainActivity extends Activity {

public static final int SAMPLE_RATE = 16000;

private AudioRecord mRecorder;
private File mRecording;
private short[] mBuffer;
private final String startRecordingLabel = "Start recording";
private final String stopRecordingLabel = "Stop recording";
private boolean mIsRecording = false;
private ProgressBar mProgressBar;
float iGain = 1.0f;
CheckBox gain;

protected int bitsPerSamples = 16;

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_main);

    initRecorder();

    Button bluetooth = (Button)findViewById(R.id.blue);
    gain = (CheckBox) findViewById(R.id.checkBox1);
    mProgressBar = (ProgressBar) findViewById(R.id.progressBar);

    final Button button = (Button) findViewById(R.id.start);
    button.setText(startRecordingLabel);

    bluetooth.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent i = new Intent("");
        }
    });
    gain.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {

            if (gain.isChecked()) {
                iGain = 5.0f;

            } else {
                iGain = 2.0f;
            }
        }
    });

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
            if (!mIsRecording) {
                button.setText(stopRecordingLabel);
                mIsRecording = true;
                mRecorder.startRecording();
                mRecording = getFile("raw");
                startBufferedWrite(mRecording);
            } else {
                button.setText(startRecordingLabel);
                mIsRecording = false;
                mRecorder.stop();
                File waveFile = getFile("wav");
                try {
                    rawToWave(mRecording, waveFile);
                } catch (IOException e) {
                    Toast.makeText(MainActivity.this, e.getMessage(),
                            Toast.LENGTH_SHORT).show();
                }
                Toast.makeText(MainActivity.this,
                        "Recorded to " + waveFile.getName(),
                        Toast.LENGTH_SHORT).show();
            }
        }
    });
}

@Override
public void onDestroy() {
    mRecorder.release();
    super.onDestroy();
}

private void initRecorder() {
    int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
            AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
    mBuffer = new short[bufferSize];
    mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE,
            AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,
            bufferSize);
}

private void startBufferedWrite(final File file) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            DataOutputStream output = null;
            try {
                output = new DataOutputStream(new BufferedOutputStream(
                        new FileOutputStream(file)));
                while (mIsRecording) {
                    double sum = 0;

                    int readSize = mRecorder.read(mBuffer, 0,
                            mBuffer.length);

                    final int bytesPerSample = bitsPerSamples / 8;
                    final int emptySpace = 64 - bitsPerSamples;
                    int byteIndex = 0;
                    int byteIndex2 = 0;
                    int temp = 0;
                    int mLeftTemp = 0;
                    int mRightTemp = 0;
                    int a = 0;
                    int x = 0;

                    for (int frameIndex = 0; frameIndex < readSize; frameIndex++) {

                        for (int c = 0; c < 1; c++) {

                            if (iGain != 1) {

                                long accumulator = 0;
                                for (int b = 0; b < bytesPerSample; b++) {

                                    accumulator += ((long) (mBuffer[byteIndex++] & 0xFF)) << (b * 8 + emptySpace);
                                }

                                double sample = ((double) accumulator / (double) Long.MAX_VALUE);
                                sample *= iGain;
                                int intValue = (int) ((double) sample * (double) Integer.MAX_VALUE);

                                for (int i = 0; i < bytesPerSample; i++) {
                                    mBuffer[i + byteIndex2] = (byte) (intValue >>> ((i + 2) * 8) & 0xff);
                                }
                                byteIndex2 += bytesPerSample;

                            }
                        }// end for(channel)

                        // mBuffer[frameIndex] *=iGain;
                        if (mBuffer[frameIndex] > 32765) {
                            mBuffer[frameIndex] = 32767;

                        } else if (mBuffer[frameIndex] < -32767) {
                            mBuffer[frameIndex] = -32767;
                        }
                        output.writeShort(mBuffer[frameIndex]);
                        sum += mBuffer[frameIndex] * mBuffer[frameIndex];

                    }

                    if (readSize > 0) {
                        final double amplitude = sum / readSize;
                        mProgressBar.setProgress((int) Math.sqrt(amplitude));
                    }
                }
            } catch (IOException e) {
                Toast.makeText(MainActivity.this, e.getMessage(),
                        Toast.LENGTH_SHORT).show();
            } finally {
                mProgressBar.setProgress(0);
                if (output != null) {
                    try {
                        output.flush();
                    } catch (IOException e) {
                        Toast.makeText(MainActivity.this, e.getMessage(),
                                Toast.LENGTH_SHORT).show();
                    } finally {
                        try {
                            output.close();
                        } catch (IOException e) {
                            Toast.makeText(MainActivity.this, e.getMessage(),
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            }
        }
    }).start();
}

private void rawToWave(final File rawFile, final File waveFile)
        throws IOException {

    byte[] rawData = new byte[(int) rawFile.length()];
    DataInputStream input = null;
    try {

        input = new DataInputStream(new FileInputStream(rawFile));
        input.read(rawData);
    } finally {
        if (input != null) {
            input.close();
        }
    }

    DataOutputStream output = null;
    try {
        output = new DataOutputStream(new FileOutputStream(waveFile));
        // WAVE header
        // see http://ccrma.stanford.edu/courses/422/projects/WaveFormat/
        writeString(output, "RIFF"); // chunk id
        writeInt(output, 36 + rawData.length); // chunk size
        writeString(output, "WAVE"); // format
        writeString(output, "fmt "); // subchunk 1 id
        writeInt(output, 16); // subchunk 1 size
        writeShort(output, (short) 1); // audio format (1 = PCM)
        writeShort(output, (short) 1); // number of channels
        writeInt(output, SAMPLE_RATE); // sample rate
        writeInt(output, SAMPLE_RATE * 2); // byte rate
        writeShort(output, (short) 2); // block align
        writeShort(output, (short) 16); // bits per sample
        writeString(output, "data"); // subchunk 2 id
        writeInt(output, rawData.length); // subchunk 2 size
        // Audio data (conversion big endian -> little endian)
        short[] shorts = new short[rawData.length / 2];
        ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN)
                .asShortBuffer().get(shorts);
        ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2);

        for (short s : shorts) {

            // Apply Gain
            /*
             * s *= iGain; if(s>32767) { s=32767; } else if(s<-32768) {
             * s=-32768; }
             */
            bytes.putShort(s);
        }
        output.write(bytes.array());
    } finally {
        if (output != null) {
            output.close();
        }
    }
}

private File getFile(final String suffix) {
    Time time = new Time();
    time.setToNow();
    return new File(Environment.getExternalStorageDirectory(),
            time.format("%Y%m%d%H%M%S") + "." + suffix);
}





private void writeInt(final DataOutputStream output, final int value)
        throws IOException {
    output.write(value >> 0);
    output.write(value >> 8);
    output.write(value >> 16);
    output.write(value >> 24);
}

private void writeShort(final DataOutputStream output, final short value)
        throws IOException {
    output.write(value >> 0);
    output.write(value >> 8);
}

private void writeString(final DataOutputStream output, final String value)
        throws IOException {
    for (int i = 0; i < value.length(); i++) {
        output.write(value.charAt(i));
    }
}
}