AudioRecord 增益控制获得嘈杂的声音
Posted
技术标签:
【中文标题】AudioRecord 增益控制获得嘈杂的声音【英文标题】:AudioRecord gain control getting noisy sound 【发布时间】:2014-04-08 20:22:18 【问题描述】:我经历了堆栈溢出问题apply gain with variation 与我想知道的相同但是找不到答案我尝试了他们在上面问题链接中提到的答案没有适当或准确的解决方案我仍然得到声音(比如对讲机)。任何做得好的人。
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】:这是音频增益或麦克风音量增益的完整代码
忽略部分与此无关的代码
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));
【讨论】:
以上是关于AudioRecord 增益控制获得嘈杂的声音的主要内容,如果未能解决你的问题,请参考以下文章
Android 4.4中AudioRecord用例 - 录制系统内置声音