Акустическое эхоподавление (AEC) в Xamarin.iOS

В настоящее время я работаю над кросс-платформенной разработкой приложений Voip на платформе Xamarin.iOS. Я искал реализацию AEC на iOS, но большинство тем связаны с Objective-C. Чего я уже добился сейчас, так это того, что я мог бы использовать Audiotoolbox (аудио-очередь) для получения входных необработанных звуковых данных с микрофона и отправки их с помощью сокета. Но во время тестирования с другим устройством я слышу очень четкое эхо на телефоне. Вот код:

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 в OSX с использованием AudioQueue, Я усвоил подсказку, что я должен передавать необработанные звуковые данные в блок ввода-вывода (аудиоблок?). Но из-за отсутствия примеров в Xamarin.iOS(c#) я не могу понять, как реализовать этот процесс в деталях. Может ли кто-нибудь, кто знаком с разработкой приложений Voip на платформе Xamarin, привести пример для изучения? Очень ценю любую помощь или намек на это.

(21 ноября 2018 г.) Некоторые связанные сообщения, которые я нашел: Запись звука с аудиоблоком Обратные вызовы аудиоблока Пример аудиоустройства


person Akatsuki821    schedule 20.11.2018    source источник


Ответы (2)


Я предлагаю проанализировать характер эха в вашей системе (например, test эхо-путь). Возможно, это выходит за рамки возможностей вашего встроенного эхоподавления.

person Tim    schedule 22.11.2018
comment
Спасибо за предложения. Мы выяснили, как включить встроенный в систему AEC, и он работает так, как ожидалось. Статью, которой вы делитесь, очень интересно читать. Спасибо - person Akatsuki821; 28.11.2018

Наконец-то мы выяснили, как включить встроенный в iOS AEC на платформе Xamarin.iOS. Документация здесь очень помог лучше понять детали Audio Unit (несмотря на то, что этот документ предназначен для собственной среды разработки iOS) и рабочего механизма. Если вы хотите точно управлять каждым аудиоблоком и разбираться в параметрах функций, обязательно прочитайте этот документ.

Работа здесь предоставить очень хорошую отправную точку для экспериментов с Audio Unit. Я сделал некоторые изменения в шаге 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();
    }
person Akatsuki821    schedule 28.11.2018