SoundPlayer.PlaySync останавливается преждевременно - PullRequest
0 голосов
/ 15 января 2011

Я хочу воспроизвести файл wav синхронно в потоке графического интерфейса, но мой вызов PlaySync возвращается рано (и преждевременно останавливает воспроизведение). WAV-файл 2-3 минуты.

Вот как выглядит мой код:

        //in gui code (event handler)
        //play first audio file
        JE_SP.playSound("example1.wav");

        //do a few other statements
        doSomethingUnrelated();

        //play another audio file
        JE_SP.playSound("example2.wav");

    //library method written by me, called in gui code, but located in another assembly
    public static int playSound(string wavFile, bool synchronous = true,
        bool debug = true, string logFile = "", int loadTimeout = FIVE_MINUTES_IN_MS)
    {
        SoundPlayer sp = new SoundPlayer();
        sp.LoadTimeout = loadTimeout;
        sp.SoundLocation = wavFile;
        sp.Load();

        switch (synchronous)
        {
            case true:
                sp.PlaySync();
                break;
            case false:
                sp.Play();
                break;
        }

        if (debug)
        {
            string writeMe = "JE_SP: \r\n\tSoundLocation = " + sp.SoundLocation
                + "\r\n\t" + "Synchronous = " + synchronous.ToString();
            JE_Log.logMessage(writeMe);
        }

        sp.Dispose();
        sp = null;

        return 0;
    }

Некоторые вещи, о которых я подумал, это тайм-аут загрузки и воспроизведение аудио в другом потоке, а затем ручное «замораживание» графического интерфейса, заставляя поток графического интерфейса ожидать продолжительность звукового файла. Я попытался увеличить время ожидания загрузки, но это ничего не дало.

Я не совсем уверен, что лучший способ получить длительность wav-файла без использования кода, написанного кем-то, кто не я / Microsoft. Я предполагаю, что это можно рассчитать, так как я знаю размер файла, и все свойства кодирования (битрейт, частота дискретизации, размер выборки и т. Д.) Одинаковы для всех файлов, которые я собираюсь воспроизвести. Может кто-нибудь уточнить, как рассчитать продолжительность файла WAV, используя эту информацию? То есть, если никто не знает, почему PlaySync возвращается рано.

редактирует:

Примечание: я столкнулся с подобной проблемой в VB 6 некоторое время назад, но это было вызвано таймаутом, который, я не подозреваю, является проблемой здесь. Короткие (<1 мин) файлы, кажется, воспроизводятся нормально, поэтому я мог бы решить вручную отредактировать более длинные файлы, а затем воспроизвести их отдельно с несколькими вызовами. </p>

Дополнительная информация: я заметил, что один и тот же файл останавливается последовательно в одно и то же время. Файлы были созданы с использованием Audacity. Возможно ли, что PlaySync ожидает определенную кодировку файлов, которая отличается от той, которую я создал в Audacity?

1 Ответ

0 голосов
/ 31 января 2011

На случай, если у кого-то еще возникнут проблемы с синхронным воспроизведением большого файла wav, вот метод, который я написал и который использует WMP в качестве альтернативы:

public static int playSoundWMP(string soundFile, bool synchronous = true)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();

        wmp.URL = soundFile;
        wmp.controls.play();

        Thread.Yield();

        while (wmp.playState == WMPLib.WMPPlayState.wmppsTransitioning)
        {
            Application.DoEvents();
            Thread.Yield();
        }

        int duration = Convert.ToInt32(wmp.currentMedia.duration * 1000);
        double waitTime = wmp.currentMedia.duration;

        if (synchronous)
        {
            Thread.Sleep(duration);
        }

        long elapsed = sw.ElapsedMilliseconds;
        sw.Stop();
        sw = null;

        return (int) wmp.currentMedia.duration * 1000;
    }

Этот метод использует WMP для воспроизведения аудиофайла вместо класса SoundPlayer, поэтому он может более надежно воспроизводить большие файлы wav ...

...