Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用AudioICeChoCanceler时,AudioTrack是否需要指定与AudioRecord相同的AudioSessionId?_Android_Xamarin - Fatal编程技术网

Android 使用AudioICeChoCanceler时,AudioTrack是否需要指定与AudioRecord相同的AudioSessionId?

Android 使用AudioICeChoCanceler时,AudioTrack是否需要指定与AudioRecord相同的AudioSessionId?,android,xamarin,Android,Xamarin,在我的Google Pixel 3a和我的设置中,我很难让AcousticEchoCanceler功能正常工作(实际上是减去回声)。我的设置包括一部电话(本例中是我的像素)和一台桌面计算机,它们通过网络连接在一起交换音频数据包。最终目标是一个双向音频应用程序。双向音频发生并工作,但正如我前面提到的,有回声 我已经搜索过了,但是我发现了一些相互矛盾的结果,这些结果是关于需要启用/禁用什么,以及即使在启用/禁用的情况下,实际工作情况如何 通过搜索,我发现我需要启用隔离: AudioManager

在我的Google Pixel 3a和我的设置中,我很难让AcousticEchoCanceler功能正常工作(实际上是减去回声)。我的设置包括一部电话(本例中是我的像素)和一台桌面计算机,它们通过网络连接在一起交换音频数据包。最终目标是一个双向音频应用程序。双向音频发生并工作,但正如我前面提到的,有回声

我已经搜索过了,但是我发现了一些相互矛盾的结果,这些结果是关于需要启用/禁用什么,以及即使在启用/禁用的情况下,实际工作情况如何

通过搜索,我发现我需要启用隔离:

 AudioManager am = (AudioManager)this.GetSystemService(Context.AudioService);
            am.Mode = Mode.InCommunication;
但目前还不完全清楚是否需要通过会话ID将AudioTrack和AudioRecord绑定在一起,尽管在我的情况下,这似乎并不重要,因为我仍然得到echo:

                int bufferSize = AudioRecord.GetMinBufferSize(SampleRate,
                    ChannelIn.Mono,
                    Android.Media.Encoding.Pcm16bit);


                AudioRecord record = new AudioRecord(
                    AudioSource.VoiceCommunication,
                    //44100,
                    SampleRate,
                    ChannelIn.Mono,
                    Android.Media.Encoding.Pcm16bit,
                    bufferSize);

                if (EchoCancellationAvailable)
                {
                    AcousticEchoCanceler aec = AcousticEchoCanceler.Create(record.AudioSessionId);
                    if (!aec.Enabled)
                    {
                        aec.SetEnabled(true);
                    }
                }

                int numBytesToWrite = AudioTrack.GetMinBufferSize(SampleRate,
                    ChannelOut.Mono,
                    Android.Media.Encoding.Pcm16bit);

                AudioTrack play = new AudioTrack(
                    Android.Media.Stream.Music,
                    //44100,
                    SampleRate,
                    ChannelOut.Mono,
                    Android.Media.Encoding.Pcm16bit,
                    numBytesToWrite,
                    AudioTrackMode.Stream, 
                    record.AudioSessionId);
然后我在两个独立的线程中使用AudioRecord和AudioTrack。我是否正确地将这两个对象关联在一起?我需要吗?有没有其他问题可能会突出,为什么回声消除不是真的减去回声


提前感谢。

不,您不需要将Id传递到AudioTrack ctor,请使用另一个ctor(注意:如果您的目标是API21+,请使用
Builder
而不是不推荐使用的ctor)。另外,为什么要使用两个线程?您只需要一个线程(可运行),从AudioRecord读取数据并将缓冲区传递给AudioTrack。另外,AudioICeChoCanceler应该是类级别的变量,这样就不会泄漏C#/Java对等成员上的内存并导致错误。此外,这仅适用于设备本身的回声,即麦克风到扬声器(不确定您是否从手机的麦克风上拾取桌面音频输出)AudioRecord正在从麦克风获取音频数据,并通过网络将其发送到桌面机;AudioTrack通过网络从台式机获取音频数据,并在设备的扬声器上播放。我听到的是另一台设备的扬声器发出的声音。我认为AEC的想法是识别我声音的波形特性,并将其从设备扬声器输出的声音中移除,包括来自另一侧的回声。
。包括来自另一侧的回声。
如果“回声”是由设备的麦克风拾取桌面扬声器输出的音频产生的,然后是否定的,因为该阶段将不匹配原始源与您正在接收并通过AudioTrack播放的内容,即辅助源馈送/混音到录音源将是双(+)回声,即反馈,AEC不会有多大帮助。那么是原始回音,还是二次回音(反馈)?在某些设备上,可以通过同时添加噪声抑制和AEC来抑制反馈/振荡(
NoiseSuppressor
),因为它们位于不同的房间,所以“设备”(本例中的电话,我相信是您的意思)听不到另一台机器的扬声器。发生的情况是,另一个房间的机器扬声器的输出被它自己的麦克风接收(没有回声消除),并通过网络发送回手机。我的印象是AEC意识到它通过麦克风发送的相位,并将其从自己的扬声器中移除。“我的概念是不是颠倒了?”本,你的问题解决了吗?