Бесшумное (зацикленное) воспроизведение звука с DirectX в C # - PullRequest
4 голосов
/ 17 марта 2010

Я сейчас использую следующий код (C #):

    private static void PlayLoop(string filename)
    {
        Audio player = new Audio(filename);
        player.Play();
        while (player.Playing)
        {
            if (player.CurrentPosition >= player.Duration)
            {
                player.SeekCurrentPosition(0, SeekPositionFlags.AbsolutePositioning);
            }
            System.Threading.Thread.Sleep(100);
        }
    }

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

  • Я попытался уменьшить поток. Сплю до 10 или 5, но разрыв остается.
  • Я также попытался удалить его полностью, но затем загрузка процессора возрастает до 100%, и все еще остается небольшой разрыв.

Есть ли какой-нибудь (простой) способ сделать воспроизведение в DirectX без разрывов? Это не имеет большого значения, поскольку это всего лишь личный проект, но если я делаю что-то глупое или иным образом совершенно неправильно, я ' я хотел бы знать.

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

Ответы [ 2 ]

2 голосов
/ 17 марта 2010

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

Я не вижу в документах ничего, что можно было бы сказать, чтобы клип зациклился. Единственное, что я могу предложить, - это использовать событие Audio.Ending, чтобы возобновить воспроизведение клипа. Это устранит необходимость в вашей отдельной ветке мониторинга, но я не уверен, будет ли это достаточно быстро, чтобы устранить пробел.

Вы также должны убедиться, что ваш аудиоклип не начинается или не заканчивается периодом молчания.

0 голосов
/ 17 марта 2010

Поскольку вы знаете продолжительность песни, просто используйте таймер, чтобы регулярно вызывать вас методом «перемотки», и дайте таймеру интервал, немного меньший, чем реальная продолжительность песни.

private static void PlayLoop(string filename)
{
    Audio player = new Audio(filename);
    player.Play();

    //System.Timers.Timer (i reduce the length by 100 ms to try to avoid blank)
    var timer = new Timer((player.Duration - TimeSpan.FromMilliseconds(100)).TotalMilliseconds());
    timer.Elapsed += (sender, arg) =>
    {
        player.SeekCurrentPosition(0, SeekPositionFlags.AbsolutePositioning);
    };
    timer.Start();
}

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

Надеюсь, это поможет вам. Manitra

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