UWP AudioGraph: сборщик мусора вызывает щелчки в аудиовыходе - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть приложение C # UWP, которое использует AudioGraph API.

Я использую пользовательский эффект для MediaSourceAudioInputNode.

Я следовал примеру на этой странице: https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/custom-audio-effects

Это работает, но я слышу несколько щелчков в секунду в динамиках, когда работает пользовательский эффект.

Вот код для моего ProcessFrame метода:

    public unsafe void ProcessFrame(ProcessAudioFrameContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        AudioFrame frame = context.InputFrame;

        using (AudioBuffer inputBuffer = frame.LockBuffer(AudioBufferAccessMode.Read))
        using (IMemoryBufferReference inputReference = inputBuffer.CreateReference())
        {
            ((IMemoryBufferByteAccess)inputReference).GetBuffer(out byte* inputDataInBytes, out uint inputCapacity);
            Span<float> samples = new Span<float>(inputDataInBytes, (int)inputCapacity / sizeof(float));

            for (int i = 0; i < samples.Length; i++)
            {
                float sample = samples[i];

                // sample processing...

                samples[i] = sample;
            }
        }
    }

Я использовал профилировщик Visual Studio, чтобы определить причину проблемы.Понятно, что есть проблема с памятью.Сборка мусора выполняется несколько раз в секунду.При каждой сборке мусора я слышу щелчок.

Профилировщик Visual Studio показывает, что объекты для сбора мусора имеют тип ProcessAudioFrameContext.

Эти объекты создаются API AudioGraph перед вводомметод ProcessFrame и переданный в качестве параметра этому методу.

Можно ли что-то сделать, чтобы избежать этих частых сборок мусора?

Ответы [ 2 ]

0 голосов
/ 05 марта 2019

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

0 голосов
/ 20 февраля 2019

Проблема не относится к пользовательским эффектам, но это общая проблема с AudioGraph (текущий SDK 1809).Сборщики мусора могут приостанавливать поток AudioGraph на слишком долгое время (более 10 мс, это размер аудио-буферов по умолчанию).В результате на аудиовыходе слышны щелчки.Использование пользовательских эффектов оказывает большое давление на сборщик мусора.

Я нашел хороший обходной путь.Используется метод GC.TryStartNoGCRegion.

После вызова этого метода щелчки полностью исчезают.Но приложение продолжает расти в памяти, пока не будет вызван метод GC.EndNoGCRegion.

// at the beginning of playback...
// 240 Mb is the amount of memory that can be allocated before a GC occurs
GC.TryStartNoGCRegion(240 * 1024 * 1024, true);

// ... at the end of playback
GC.EndNoGCRegion();

MSDN doc: https://docs.microsoft.com/fr-fr/dotnet/api/system.gc.trystartnogcregion?view=netframework-4.7.2

И хорошая статья: https://mattwarren.org/2016/08/16/Preventing-dotNET-Garbage-Collections-with-the-TryStartNoGCRegion-API/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...