воспроизведение звука с помощью SlimDX и DirectSound (C#)

(извините, если это дубликат ... я разместил, но не увидел доказательств того, что он действительно попал на форум)

Я пытался заставить работать SlimDX DirectSound. Вот код, который у меня есть. Он заполняет вторичный буфер из wav-файла, а затем в цикле потоков поочередно заполняет нижнюю или верхнюю половины буфера.

Он отлично воспроизводит первую загрузку буфера. AutoResetEvents срабатывает, когда они должны, и заполняется нижняя половина, а затем верхняя половина буфера (проверено с помощью операторов отладки). Но воспроизведение не продолжается после первой загрузки буфера. Так что каким-то образом повторное заполнение буфера не работает должным образом.

Идеи?

(Я использую DirectSound, потому что это единственный способ, которым я нашел, чтобы установить guid аудиоустройства, которое я хочу использовать. Я открыт для других подходов, дружественных к .NET.)

private void PlaySound(Guid soundCardGuid, string audioFile) {
        DirectSound ds = new DirectSound(soundCardGuid);

        ds.SetCooperativeLevel(this.Handle, CooperativeLevel.Priority);

        WaveFormat format = new WaveFormat();
        format.BitsPerSample = 16;
        format.BlockAlignment = 4;
        format.Channels = 2;
        format.FormatTag = WaveFormatTag.Pcm;
        format.SamplesPerSecond = 44100;
        format.AverageBytesPerSecond = format.SamplesPerSecond * format.BlockAlignment;

        SoundBufferDescription desc = new SoundBufferDescription();
        desc.Format = format;
        desc.Flags = BufferFlags.GlobalFocus;
        desc.SizeInBytes = 8 * format.AverageBytesPerSecond; 

        PrimarySoundBuffer pBuffer = new PrimarySoundBuffer(ds, desc);

        SoundBufferDescription desc2 = new SoundBufferDescription();
        desc2.Format = format;
        desc2.Flags = BufferFlags.GlobalFocus | BufferFlags.ControlPositionNotify | BufferFlags.GetCurrentPosition2;
        desc2.SizeInBytes = 8 * format.AverageBytesPerSecond;

        SecondarySoundBuffer sBuffer1 = new SecondarySoundBuffer(ds, desc2);

        NotificationPosition[] notifications = new NotificationPosition[2];
        notifications[0].Offset = desc2.SizeInBytes / 2 + 1;
        notifications[1].Offset = desc2.SizeInBytes - 1; ;

        notifications[0].Event = new AutoResetEvent(false);
        notifications[1].Event = new AutoResetEvent(false);
        sBuffer1.SetNotificationPositions(notifications);

        byte[] bytes1 = new byte[desc2.SizeInBytes / 2];
        byte[] bytes2 = new byte[desc2.SizeInBytes];

        Stream stream = File.Open(audioFile, FileMode.Open);

        Thread fillBuffer = new Thread(() => {
            int readNumber = 1;
            int bytesRead;

            bytesRead = stream.Read(bytes2, 0, desc2.SizeInBytes);
            sBuffer1.Write<byte>(bytes2, 0, LockFlags.None);
            sBuffer1.Play(0, PlayFlags.None); 
            while (true) {
                if (bytesRead == 0) { break; }
                notifications[0].Event.WaitOne();
                bytesRead = stream.Read(bytes1, 0, bytes1.Length);
                sBuffer1.Write<byte>(bytes1, 0, LockFlags.None);

                if (bytesRead == 0) { break; }
                notifications[1].Event.WaitOne();
                bytesRead = stream.Read(bytes1, 0, bytes1.Length);
                sBuffer1.Write<byte>(bytes1, desc2.SizeInBytes / 2, LockFlags.None); 
            }
            stream.Close();
            stream.Dispose();
        });
        fillBuffer.Start();
    }
}

person blearyeye    schedule 06.10.2010    source источник


Ответы (1)


Вы не зациклили его на буфере воспроизведения. Измените свой код на:

sBuffer1.Play(0, PlayFlags.Looping); 
person Goz    schedule 07.10.2010
comment
Спасибо. Вот оно. В отсутствие какого-либо документа SlimDX по этому вопросу я неправильно понял значение флагов. - person blearyeye; 07.10.2010
comment
Сделанный. Забыл сделать это раньше. - person blearyeye; 06.01.2011
comment
Работает и для DirectSound. Была та же проблема, что и у сонного глаза. Спасибо, что указали мне на это... - person Martin Hennings; 15.02.2011