我正在尝试为Android平台构建音乐分析应用程序。
该应用正在使用MediaRecorder.AudioSource.MIC
记录MIC的音乐,他们用11025频率编码PCM 16BIT,但录制的音频样本质量很低有没有办法让它更好,降低噪音?
mRecordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC,FREQUENCY, CHANNEL,ENCODING, minBufferSize);
mRecordInstance.startRecording();
do
{
samplesIn += mRecordInstance.read(audioData, samplesIn, bufferSize - samplesIn);
if(mRecordInstance.getRecordingState() == AudioRecord.RECORDSTATE_STOPPED)
break;
}
while (samplesIn < bufferSize);
先谢谢
答案 0 :(得分:3)
上述解决方案对我没有用。
所以,我四处搜寻,发现this article。
长话短说,我使用MediaRecorder.AudioSource.VOICE_RECOGNITION代替AudioSource.MIC,这给了我非常好的结果,背景中的噪音确实减少了很多。
这个解决方案的优点是,它可以与AudioRecord和MediaRecorder类一起使用。
答案 1 :(得分:2)
SR和缓冲区大小的最佳组合取决于设备,因此您的结果将根据硬件而有所不同。我使用此实用程序来确定运行Android 4.2及更高版本的设备的最佳组合;
public static DeviceValues getDeviceValues(Context context) {
try {
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
try {
Method getProperty = AudioManager.class.getMethod("getProperty", String.class);
Field bufferSizeField = AudioManager.class.getField("PROPERTY_OUTPUT_FRAMES_PER_BUFFER");
Field sampleRateField = AudioManager.class.getField("PROPERTY_OUTPUT_SAMPLE_RATE");
int bufferSize = Integer.valueOf((String)getProperty.invoke(am, bufferSizeField));
int sampleRate = Integer.valueOf((String)getProperty.invoke(am, sampleRateField));
return new DeviceValues(sampleRate, bufferSize);
} catch(NoSuchMethodException e) {
return selectBestValue(getValidSampleRates(context));
}
} catch(Exception e) {
return new DeviceValues(DEFAULT_SAMPLE_RATE, DEFAULT_BUFFER_SIZE);
}
}
这使用反射来检查getProperty方法是否可用,因为此方法是在API级别17中引入的。如果您正在针对特定设备类型进行开发,则可能需要尝试各种缓冲区大小和采样率。我用作后备的默认值是;
private static final int DEFAULT_SAMPLE_RATE = 22050;
private static final int DEFAULT_BUFFER_SIZE = 1024;
另外,我通过查看getMinBufferSize是否返回合理的值来检查各种SR;
private static List<DeviceValues> getValidSampleRates(Context context) {
List<DeviceValues> available = new ArrayList<DeviceValues>();
for (int rate : new int[] {8000, 11025, 16000, 22050, 32000, 44100, 48000, 96000}) { // add the rates you wish to check against
int bufferSize = AudioRecord.getMinBufferSize(rate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
if (bufferSize > 0 && bufferSize < 2048) {
available.add(new DeviceValues(rate, bufferSize * 2));
}
}
return available;
}
这取决于如果getMinBufferSize返回0的逻辑,则设备中的采样率不可用。您应该针对特定用例试验这些值。
答案 2 :(得分:1)
尽管这是一个古老的问题,但遵循以下解决方案将有所帮助。 我们可以使用MediaRecorder轻松录制音频。
private void startRecording() {
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setAudioEncodingBitRate(96000)
recorder.setAudioSamplingRate(44100)
recorder.setOutputFile(".../audioName.m4a");
try {
recorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
recorder.start();
}
注意:
MediaRecorder.AudioEncoder.AAC
被用作MediaRecorder.AudioEncoder.AMR_NB
编码,在iOS中不再受支持。 Reference