Xamarin Forms / Android - пользовательский интерфейс вызывает замедление потока рабочих потоков аудио - PullRequest
0 голосов
/ 30 августа 2018

Я работаю над версией 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();
        }
    }
}

Спасибо!

...