#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 вы решили свою проблему?