13

我有 AcousticEchoCanceler 为我尝试过的所有其他设备类型的 VoIP 呼叫工作,但在任何三星设备上都没有。设备报告 AcousticEchoCanceler 可用,但它什么也不做。

我有什么:

  • acousticEchoCanceler.setEnabled(true);
  • audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
  • 音频会话 ID 传递给AudioTrack
  • 采样率:16k
  • 尝试了单声道和立体声录音
  • <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  • <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

有没有人让 AcousticEchoCanceler 在三星设备上工作?

4

3 回答 3

9

我最近有同样的问题。对我来说最重要的部分是在创建 AudioRecord 之前使用 audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION)。

接下来创建 AudioRecord:

mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, mSamplingRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, audioRecordBufferSize);

最后创建并启用 NS 和 AEC :

mNoiseSuppressor = NoiseSuppressor.create(mAudioRecord.getAudioSessionId());
if (mNoiseSuppressor != null) {
    int res = mNoiseSuppressor.setEnabled(true);
}

mAcousticEchoCanceler = AcousticEchoCanceler.create(mAudioRecord.getAudioSessionId());
if (mAcousticEchoCanceler != null) {
    int res = mAcousticEchoCanceler.setEnabled(true);
}

AudioTrack 不需要关联到与 AudioTrack 相同的音频会话 ID(我想它应该自动完成)。

于 2017-12-08T08:22:28.117 回答
2

几年前我曾尝试过这段代码,并记得它确实有效。不能说最新设备的表现如何。

int audioSource = MediaRecorder.AudioSource.VOICE_COMMUNICATION;
int sampleFreq = 16000;
int numChannels = 1;
int numBytesPerSample = 2;
int channelConfig = numChannels == 1 ? AudioFormat.CHANNEL_IN_MONO : AudioFormat.CHANNEL_IN_STEREO;
int audioFormat = numBytesPerSample == 2 ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
int bufSize = AudioRecord.getMinBufferSize(sampleFreq, channelConfig, audioFormat);
if (bufSize == AudioRecord.ERROR_BAD_VALUE || bufSize == AudioRecord.ERROR) {
        return;
}

AudioRecord audioInRecord   = new AudioRecord(audioSource, sampleFreq, 
                channelConfig, audioFormat, bufSize);
if (audioInRecord.getState() != AudioRecord.STATE_INITIALIZED) {
    return;
}

boolean aecAvailable = AcousticEchoCanceler.isAvailable();
if (aecAvailable) {
    AcousticEchoCanceler instance;
    if((instance = AcousticEchoCanceler.create(audioInRecord.getAudioSessionId())) != null) {
        instance.setEnabled(true);
        Log.d(TAG, "AEC enabled");
    } else {
        Log.d(TAG, "AEC disabled");
    }
}
于 2017-10-12T04:51:13.543 回答
1

试试这些行:

if (AcousticEchoCanceler.isAvailable() && WebRtcAudioUtils.isAcousticEchoCancelerSupported()) {
                WebRtcAudioUtils.setWebRtcBasedAcousticEchoCanceler(true);
                WebRtcAudioUtils.useWebRtcBasedAcousticEchoCanceler();
            }
于 2017-10-09T04:41:54.277 回答