Я работаю над версией Android своего приложения для синтеза аудио в реальном времени и столкнулся с некоторыми проблемами с производительностью, которые не были проблемой на стороне iOS. Трудно поделиться кодом, потому что разные куски разбросаны по разным файлам, но я сделаю все возможное. Вот основная проблема:
- Xamarin Forms, использующие службу зависимостей для обработки звука.
- Я использую парадигму AudioTrack / write (). Синтез и генерация звука работают нормально.
Потоковый код выполняется в простом рабочем потоке:
protected void StartAndroid()
{
if (PlaybackWorker == null) PlaybackWorker = new Thread(() => {
while (true)
{
_SetSampleCountToNextBeat();
AudioManager.FillAudioBuffer(GeneratorFactory, this);
}
} );
PlaybackWorker.Priority = ThreadPriority.Highest;
PlaybackWorker.Start();
}
Проблема: Каждый раз, когда с пользовательским интерфейсом происходит что-либо, будь то вызов, который я делаю явно через код, или это происходит через прямое взаимодействие с пользователем, аудио-киоски / заминки / дрожания / и т.д. Это обычно не серьезно, но это очень заметно, и, поскольку аудио приложение основано на ритме, оно вызывает проблемы.
Вопрос: Я настраиваю рабочий поток наиболее эффективным способом для долгосрочной задачи потокового аудио? Я знаю, что существует низкоуровневый приоритет потока, который позволяет выполнять задачу «Экстремально высокий / Аудио / Срочно», но с тем потоком, который я использую, все, к чему у меня есть доступ, - это несколько вариантов с ThreadPriority.Highest. ... самый высокий ... Кажется, что пользовательский интерфейс выигрывает каждый раз.
Дайте мне знать, если понадобится больше кода. Опять же, на стороне iOS у меня нет проблем ... но я также не использую фоновый рабочий для заполнения аудио-буфера (я использую механизм обратного вызова буфера AudioQueue в iOS, поэтому я не нужно создать отдельный поток ...) Я чувствую, что на стороне Android у меня битва потоков (UI vs. Worker @ ThreadPriority.Highest), которую я не до конца понимаю.
Еще несколько кодовых подсказок для правильной меры:
public void InitAudioSystem()
{
int minSize = AudioTrack.GetMinBufferSize((int)Globals.SampleRate, ChannelOut.Mono, Encoding.PcmFloat);
audioTrack = new AudioTrack.Builder().SetAudioAttributes(new AudioAttributes.Builder()
.SetUsage(AudioUsageKind.Media)
.SetContentType(AudioContentType.Music)
.Build())
.SetAudioFormat(new AudioFormat.Builder()
.SetEncoding(Encoding.Pcm16bit)
.SetSampleRate((int)Globals.SampleRate)
.SetChannelMask(ChannelOut.Mono)
.Build()).SetBufferSizeInBytes(minSize)
.Build();
}
public void WriteAudio()
{
if (audioTrack != null && EnabledDAC)
{
audioTrack.Write(_Buffer, 0, _Buffer.Length, WriteMode.Blocking);
if (audioTrack.PlayState != PlayState.Playing)
{
audioTrack.Play();
}
}
}
Спасибо!