【问题标题】:How To Record Sound in Android with Better Quality and Reduce Noise如何在 Android 中以更好的质量录制声音并降低噪音
【发布时间】:2014-04-12 12:06:48
【问题描述】:

我正在尝试为安卓平台构建一个音乐分析应用程序。

该应用正在使用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);

提前致谢

【问题讨论】:

标签: android filter audio-recording android-audiorecord noise-reduction


【解决方案1】:

上面的解决方案对我不起作用。

所以,我四处寻找,发现this article

长话短说,我使用了MediaRecorder.AudioSource.VOICE_RECOGNITION 而不是AudioSource.MIC,这给了我非常好的结果,并且背景中的噪音确实减少了很多。

这个解决方案的伟大之处在于,它可以与 AudioRecord 和 MediaRecorder 类一起使用。

【讨论】:

    【解决方案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, (String)bufferSizeField.get(am)));
                int sampleRate = Integer.valueOf((String)getProperty.invoke(am, (String)sampleRateField.get(am)));
                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,则设备中的采样率不可用的逻辑。您应该针对您的特定用例试验这些值。

    【讨论】:

    • 嗨@Bartol,请帮助提供 selectBestValue() 方法。谢谢
    【解决方案3】:

    虽然这是一个老问题,但以下解决方案会有所帮助。 我们可以使用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
    • AudioEncodingBitRate 应根据需要使用 96000 或 128000 以确保声音清晰。

    【讨论】:

      猜你喜欢
      • 2011-05-03
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      • 1970-01-01
      • 1970-01-01
      • 2022-08-06
      • 2020-12-05
      • 1970-01-01
      相关资源
      最近更新 更多