【问题标题】:AcousticEchoCanceler on Samsung devices not working三星设备上的 AcousticEchoCanceler 无法正常工作
【发布时间】:2017-10-04 08:56:31
【问题描述】:

我有 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 在三星设备上工作吗?

【问题讨论】:

  • 我注意到它几乎是随机的——在某些情况下,AEC 可以在三星设备上运行,有时则不能。我仍然没有找到任何原因,相同的代码只是随机工作。

标签: android samsung-mobile echo-cancellation


【解决方案1】:

我最近遇到了同样的问题。对我来说最重要的部分是在创建 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(我想它应该自动完成)。

【讨论】:

    【解决方案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");
        }
    }
    

    【讨论】:

    • 我已经有一个类似的代码,但它随机无法在最新的三星设备上运行。
    【解决方案3】:

    试试以下几行:

    if (AcousticEchoCanceler.isAvailable() && WebRtcAudioUtils.isAcousticEchoCancelerSupported()) {
                    WebRtcAudioUtils.setWebRtcBasedAcousticEchoCanceler(true);
                    WebRtcAudioUtils.useWebRtcBasedAcousticEchoCanceler();
                }
    

    【讨论】:

    • 看来单靠代码做不了多少,整个管道需要改成使用WebRtc音频。而且我不完全确定该怎么做。
    • 实际上,当添加到正确的代码点时,仅这一行似乎就可以解决这个问题 - 我需要更多的测试,但到目前为止看起来很有希望!另请参阅Twilio's doc 了解此内容。
    • 除了现在它再次在三星上崩溃并且没有任何帮助了
    • 由于时间不多了,我将奖励这个答案,这样它就不会丢失,它是最接近问题根源的答案,但问题仍然悬而未决
    猜你喜欢
    • 2017-12-10
    • 2019-12-02
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多