录制音频,然后使用 AudioRecord、AudioTrack.trouble 播放

Posted

技术标签:

【中文标题】录制音频,然后使用 AudioRecord、AudioTrack.trouble 播放【英文标题】:to record audio and then to playback with AudioRecord, AudioTrack.trouble 【发布时间】:2015-04-18 11:37:57 【问题描述】:

我实时录制了一段录音然后播放,但是当我开始时 这听起来很嘈杂的声音和我的声音。所以我只想用干净的音调来表达我的声音

我正在使用混响、低音增强、均衡器和可视化效果实现此应用

我只想清理没有这些效果的声音

至于此应用目标版本至少适用于android 2.3.3(api 10)

问:我必须如何修改这个重要的代码部分? (对于 audioRecord.startRecording、audioTrack.record、audioTrack.write)

这是我的代码 sn-p 如下:

//////////////////////////////

private void main() 

        for (;;) 

            Log.d("AFX", "Starting audio thread");
            this.audioRecord.startRecording();
            this.audioTrack.play();

            int i;

            if (!this.running) 
                this.audioRecord.stop();
                this.audioTrack.stop();
                this.audioRecord.release();
                return;
            

            i = this.audioRecord.read(this.buffer, 0, this.chunkSize);
            Log.v("AudioRecord", "read " + this.chunkSize + "bytes");

            try 

                // Log.d("AFX", "Starting audio thread");
                this.audioRecord.startRecording();
                this.audioTrack.play();
                Log.d("AFX", "Starting audio thread");

                boolean flag = this.running; // df value : false

                if (!flag) 
                    this.audioRecord.stop();
                    this.audioTrack.stop();
                    // this.audioRecord.release(); // added
                    // this.audioTrack.release(); // added
                    Log.d("AFX", "Exiting audio thread");
                    return;
                

                i = this.audioRecord.read(this.buffer, 0, this.chunkSize);
                Log.v("AudioRecord", "read " + this.chunkSize + "bytes");

                if (i < 0) 
                    Log.e("AFX", "Record error: " + i);
                    this.running = false;
                    continue;
                    // break;
                
                if (!this.running) 
                    continue;
                    // break;
                

             finally 
                this.audioRecord.stop();
                // this.audioRecord.release(); // added
                this.audioTrack.stop();
                // this.audioTrack.release(); // added
            

            this.audioTrack.write(this.buffer, 0, i);
            // Log.d("AFX", "Starting audio thread");
            // this.audioRecord.startRecording();
            // this.audioTrack.play();
        
    

任何想法都会受到赞赏

非常感谢

【问题讨论】:

【参考方案1】:

试试AudioEffects。

ar = new AudioRecord(MediaRecorder.Audiosource.VOICE_RECOGNITION, SAMPLE_RATE_IN_HZ, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bs * 10);

        if(AutomaticGainControl.isAvailable())
        
            AutomaticGainControl agc =AutomaticGainControl.create(ar.getAudioSessionId());
            //agc.g
            Log.d("AudioRecord", "AGC is " + (agc.getEnabled()?"enabled":"disabled"));
            agc.setEnabled(true);
            Log.d("AudioRecord", "AGC is " + (agc.getEnabled()?"enabled":"disabled" +" after trying to enable"));
        else
        
            Log.d("AudioRecord", "AGC is unavailable");
        

        if(NoiseSuppressor.isAvailable())
            NoiseSuppressor ns = NoiseSuppressor.create(ar.getAudioSessionId());
            Log.d("AudioRecord", "NS is " + (ns.getEnabled()?"enabled":"disabled"));
            ns.setEnabled(true);
            Log.d("AudioRecord", "NS is " + (ns.getEnabled()?"enabled":"disabled" +" after trying to disable"));
        else
        
            Log.d("AudioRecord", "NS is unavailable");
        
        if(AcousticEchoCanceler.isAvailable())

            AcousticEchoCanceler aec = AcousticEchoCanceler.create(ar.getAudioSessionId());
            Log.d("AudioRecord", "AEC is " + (aec.getEnabled()?"enabled":"disabled"));
            aec.setEnabled(true);
            Log.d("AudioRecord", "AEC is " + (aec.getEnabled()?"enabled":"disabled" +" after trying to disable"));

        else
        
            Log.d("AudioRecord", "aec is unavailable");
        

他们在 api 16+ 上工作,但他们也有均衡器、低音增强和你提到的其他东西。在开始录制之前设置它们。

【讨论】:

我的应用至少面向 android 2.3.3(API 10)。 @Raiv【参考方案2】:

在您的问题中,您对您遇到的噪音类型有点不确定。 但是,如果您录制和播放相同的声音,您可能会遇到严重的反馈或回声。通常是非常响亮的高音。

Android 已内置回声消除功能来解决此问题。如果您使用 AudioSource.VOICE_COMMUNICATION,则默认启用它,如下所示:

recorder = new AudioRecord( AudioSource.VOICE_COMMUNICATION, 
                            44100,
                            AudioFormat.CHANNEL_IN_MONO,
                            AudioFormat.ENCODING_PCM_16BIT,
                            n );

此外,44100 是唯一保证适用于所有 Android 设备的采样率。不要使用其他任何东西,否则您可能会得到奇怪的结果。

【讨论】:

这个噪音很不稳定,检查一下,如果可能的话,我希望你直接玩我的应用程序。嗯@TimmyBrolin VOICE_COMMUNICATION 自 API 级别 11 起可用。您可以使用 VOICE_CALL 作为后备。它通常应该具有回声消除功能,但不能保证具有它。它从 API 级别 4 开始可用。VOICE_COMMUNICATION 的定义更好,因此它在设备之间以更统一的方式运行。 developer.android.com/reference/android/media/… 这个应用程序的目标版本至少是 api 10+(android 2.3.3 以上).. :(,但我很感激你的想法! 如果噪音不稳定、响亮并且与您的声音相呼应,那么您正在体验反馈。试试“VOICE_COMMUNICATION”看看会发生什么。如果它解决了问题,那么您只需要找出 API 10 的解决方法。 反馈问题的硬件解决方案是将外部麦克风或扬声器连接到手机,并将扬声器和麦克风放置在远离的地方。耳机也可以。对于使用 Android 2.3 的用户来说,这可能是一个可以接受的解决方法?

以上是关于录制音频,然后使用 AudioRecord、AudioTrack.trouble 播放的主要内容,如果未能解决你的问题,请参考以下文章

使用 AudioRecord 录制音频

使用 AudioRecord 以 .mp3 格式录制音频

Android 音频录制-AudioRecord

Android:使用 audiorecord 类录制音频播放快进

音频的录制方式-AudioRecord,MediaRecorder的使用及播放

无法在 Android 中使用 AudioRecord 进行录制