Xamarin.iOS 上的声学回声消除 (AEC)
Posted
技术标签:
【中文标题】Xamarin.iOS 上的声学回声消除 (AEC)【英文标题】:Acoustic Echo Cancellation (AEC) on Xamarin.iOS 【发布时间】:2018-11-20 21:42:04 【问题描述】:我目前正在开发基于 Xamarin.ios 平台的跨平台 Voip 应用程序。我确实搜索了 iOS 上的 AEC 实现,但大多数主题都与 Objective-C 相关。 我现在已经实现的是:我可以使用 Audiotoolbox(音频队列)从 mic 获取输入的原始声音数据并通过套接字将其发送出去。但是在使用其他设备进行测试时,我在手机上遇到了非常清晰的回声。这是代码:
private void SetupInputQueue()
inputQueue = new InputAudioQueue(audioStreamBasicDescription);
//sendbuffer initialization
heading = Encoding.ASCII.GetBytes("msg ");
sendBuffer = new byte[CountAudioBuffers][];
for (int i = 0; i < CountAudioBuffers; i++)
sendBuffer[i] = new byte[516];
for (int j = 0; j < heading.Length; j++)
sendBuffer[i][j] = heading[j];
for (int count = 0; count < CountAudioBuffers; count++)
IntPtr bufferpointer;
inputQueue.AllocateBuffer(AudioBufferLength, out bufferpointer);
inputQueue.EnqueueBuffer(bufferpointer, AudioBufferLength, null);
inputQueue.InputCompleted += HandleInputCompleted;
private void HandleInputCompleted(object sender, InputCompletedEventArgs e)
unsafe
byte* shortPtr = (byte*)e.UnsafeBuffer->AudioData;
for (int count = heading.Length; count < sendBuffer[sendOutIndex].Length; count++)
sendBuffer[sendOutIndex][count] = *shortPtr;
shortPtr++;
socket.SendTo(sendBuffer[sendOutIndex], master);
this.inputQueue.EnqueueBuffer(e.IntPtrBuffer, AudioBufferLength, null);
sendOutIndex = (sendOutIndex + 1) % CountAudioBuffers;
根据AEC on OSX using AudioQueue,我了解到我应该将原始声音数据传递给 I/O 单元(音频单元?)的提示。但是由于 Xamarin.iOS(c#) 中缺少示例,我无法弄清楚如何详细实现这个过程。任何熟悉 Xamarin 平台上的 Voip 应用程序开发的人可以给我一些学习的例子吗?非常感谢任何帮助或提示。
(2018年11月21日)我找到的一些相关帖子:Record audio with audio unitAudio unit CallbacksAn audio unit example
【问题讨论】:
【参考方案1】:我建议分析您系统中回声的性质(例如test the echo path)。也许它超出了您的内置回声消除功能。
【讨论】:
感谢您的建议。我们找到了打开系统内置 AEC 的方法,它按预期工作。你分享的文章读起来很有趣。谢谢【参考方案2】:最后我们弄清楚了如何在 Xamarin.iOS 平台上打开 iOS 内置 AEC。 文档here 有助于更好地理解Audio Unit 的细节(尽管这个文档是针对iOS 原生开发环境的)和工作机制。如果你想精确控制每一个音频单元,了解功能中的参数,这篇文档是必读的。
here 的工作为在音频单元上进行实验提供了一个非常好的起点。我在这篇文章的第 2 步做了一些修改。关键部分是我们必须使用 AudioTypeOutput.VoiceProcessingIO,这会开启 AEC。
public void prepareAudioUnit()
var _audioComponent = AudioComponent.FindComponent(AudioTypeOutput.VoiceProcessingIO);
audioUnit = new AudioUnit.AudioUnit(_audioComponent);
audioUnit.SetEnableIO(true,
AudioUnitScopeType.Input,
1 // Remote Input
);
// setting audio format
audioUnit.SetAudioFormat(audioStreamBasicDesc,
AudioUnitScopeType.Output,
1
);
audioUnit.SetInputCallback(input_CallBack, AudioUnitScopeType.Input, 1);
audioUnit.SetRenderCallback(render_CallBack, AudioUnitScopeType.Global, 0);
audioUnit.Initialize();
audioUnit.Start();
【讨论】:
以上是关于Xamarin.iOS 上的声学回声消除 (AEC)的主要内容,如果未能解决你的问题,请参考以下文章