Нужно ли назначать AudioTrack тот же audioSessionId, что и AudioRecord, при использовании AcousticEchoCanceler?

#android #xamarin

#Android #xamarin

Вопрос:

У меня возникли проблемы с тем, чтобы функция AcousticEchoCanceler работала хорошо (например, фактически вычитала эхо) на моем Google Pixel 3a и в моей настройке. Моя настройка состоит из телефона (в данном случае моего Pixel) и настольного компьютера, которые объединены в сеть и обмениваются аудиопакетами. Конечная цель — это двустороннее аудиоприложение. Двустороннее аудио происходит и работает, но, как я упоминал ранее, есть эхо.

Я искал SO, но я нашел противоречивые результаты о том, что именно нужно включить / отключить, и о том, насколько хорошо все на самом деле работает, даже когда они работают.

Путем поиска я обнаружил, что мне нужно включить отключение связи:

  AudioManager am = (AudioManager)this.GetSystemService(Context.AudioService);
            am.Mode = Mode.InCommunication;
  

Но не совсем ясно, нужно ли связывать 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 в двух отдельных потоках. Правильно ли я связал два объекта вместе? Нужно ли это? Есть ли какие-либо другие проблемы, которые, возможно, касаются того, почему подавление эха на самом деле не вычитает эхо?

Заранее спасибо.

Комментарии:

1. Нет, вам не нужно передавать идентификатор в ctor AudioTrack, используйте другой ctor (примечание: если вы ориентируетесь на API21 , используйте Builder вместо устаревших ctors.) Кроме того, почему вы используете два потока? Все, что вам нужно, — это один поток (выполняемый), в котором вы считываете из AudioRecord и передаете буфер в AudioTrack. Также AcousticEchoCanceler должен быть переменной уровня класса, чтобы вы не пропускали память на одноранговом члене C # / Java и не вызывали ошибку. Кроме того, это работает только для echo на самом устройстве, то есть с микрофона на динамик (не уверен, что вы возвращаете аудиовыход на рабочий стол обратно на микрофон телефона)

2. AudioRecord берет аудиоданные с микрофона и отправляет их на настольный компьютер по сети; AudioTrack берет аудиоданные с настольного компьютера по сети и воспроизводит их на динамике устройства. Я слышу свой голос из динамика другого устройства. Я думал, что идея AEC заключалась в том, чтобы определить волновые свойства моего голоса и удалить его из того, что выходит из динамика на устройстве, включая эхо с другой стороны.

3. ..including the echo from the other side. Если «эхо» генерируется микрофоном устройства, улавливающим звук с выхода динамика вашего рабочего стола, то нет, поскольку фаза этого не будет соответствовать исходному источнику тому, что вы получаете обратно и воспроизводите через AudioTrack, т.Е. Вторичный источник, подающий / микширующий в источник аудиозаписибыло бы двойное ( ) эхо, т. Е. Обратная связь, AEC не сильно помогло бы. Так это исходное эхо или вторичное эхо (обратная связь)? На некоторых устройствах обратная связь / колебания могут быть подавлены путем одновременного добавления подавления шума с AEC ( NoiseSuppressor )

4. Они находятся в разных комнатах, поэтому «устройство» (телефон в чехле, я полагаю, это то, что вы имеете в виду) не может слышать динамик другого устройства. Что происходит, так это то, что сигнал с динамика устройства в другой комнате улавливается его собственным микрофоном (на нем нет эхоподавления) и отправляется обратно на телефон по сети. У меня сложилось впечатление, что AEC знал о фазе, которую он отправлял через микрофон, и удалил ее из того, что выходило из его собственных динамиков. У меня есть концепция назад или что-то в этом роде?

5. @Ben вы решили свою проблему?