开发者

playing sound with SlimDX and DirectSound (C#)

(apologies if this is a duplicate ... i posted but saw no evidence that it actually made it to the forum)

I've been trying to get SlimDX DirectSound working. Here's the code I have. It fills the secondary buffer from a wav file and then, in a thread loop, alternately fills the lower or upper halves of the buffer.

It plays the first load of the buffer fine. The AutoResetEvents fire when they should and the lower half then upper half of the buffer are populated (verified with Debug statements). But playing does not continue after the first load of the buffer. So somehow the repopulation of the buffer doesn't work as it should.

Ideas?

(I'm using DirectSound because it's the only way I've found to set the guid of the audio device that I want to use. Am open to other .NET-friendly approaches.)

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;

      开发者_JAVA技巧  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();
    }
}


You haven't set it to loop on the play buffer. Change your code to:

sBuffer1.Play(0, PlayFlags.Looping); 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜