PDA

View Full Version : Stop and Play in DirectSound


Stuw
10-02-2005, 01:01 PM
Hi!
When I often call Stop() method (IDirectSoundBuffer interface) and then Play() method sound plays with distortion (beating). It is because playing recommences from end of last part (repeating small part of sound). I can't correct this.

Plaese, help me!

TheNut
10-04-2005, 07:59 PM
DirectSound does resume playback at the last known position, but it doesn’t distort playback. Here are some tips:

1) Try resetting the position back to 0 via SetCurrentPosition() and see if the problem persists, if so, see steps 2 to 4.
2) Are you using streams? Make sure the forward buffer is filled in properly.
3) Are your buffers configured correctly? Secondary buffers should have the same settings as your primary.
4) Make sure you are using the right playback properties (samples per second, bits per sample, block alignment, etc…)

Stuw
10-07-2005, 02:31 AM
Hello! :)

(Sorry for my bad english!!!)

Thanks for help.

I changeed my algorithm (now I use SetCurrentPosition(0)), but my problem not solved :(

I create only secondary buffer.
Buffer properties are correct (samples per second, bits per sample, block alignment, etc…).

When I fill temp buffer (not DirectSoundBuffer) whith data (put little parts of sound data in buffer in series) and then play this buffer - sound playing normaly. Only when I set notifications (and Stop buffer for it) sound playng badly.

You say - "Make sure the forward buffer is filled in properly." What does it mean? How fill buffer correctly?

Once more BIG THANKS :)

Nema
10-07-2005, 06:04 AM
Some time ago I started to write a totorial about DirectShow (http://www.josua.hoengermedia.ch/download/DirectShowPart1.pdf) ( a mix of found knowledge on the internet and my own experience). Maybe it is useful to answer some questions, or maybe somebody wants to revise it and make a public DirectShow tutorial at DevMaster.net out of it? Feel free to do whatever you like with it!

TheNut
10-07-2005, 09:33 PM
"You say - "Make sure the forward buffer is filled in properly." What does it mean? How fill buffer correctly?"

When streaming audio (which sounds like what you're doing), you should supplement extra data in the sound buffer. This is the “forward buffer” in a sound stream. Since streaming audio uses a cyclic buffer, the forward buffer is always your (total buffer – play buffer). Make sure not to put in more than that otherwise you will overwrite your current play buffer. In most cases, 2 to 2.5x (2.5x play buffer) ahead of your current play position will guarantee smooth playback. Also, don’t stop the audio playback to inject new stream data. Instead, lock the portion of memory that DirectSound is not currently playing and throw the sound data on there. If you stop then play every time you fill up a piece of the buffer then you’ll of course get a lot of distortions and garbled playback.

Example:
Bits per Sample = 8 (= 1 byte)
Samples per Second = 44100
Number of channels = 2
Bytes per second = 1 * 44100 * 2 = 88200
Sound Buffer = 1 meg (quite a generous amount)

0..........88200 (1s) ........................220500 (2.5s).............1 meg (11s)
|______|________________________|_________________ __|
^ Current play position....................^ End of prebuffer

Initially we supply 220500 bytes of audio data. DirectSound will begin audio playback at the 0th position. When the current play position hits 88200 (1 second), fill in another 88200 bytes at the last known prebuffer position, which is 220500 in this case. Again, don’t stop the sound buffer for this. Lock the buffer from 220500 to (220500 + 88200) = 308700 and fill in the audio buffer. By this time, DirectSound will probably have played only a few milliseconds of audio.

Nema
10-08-2005, 12:41 AM
ups, i have mixed "DirectShow" and DirectSound" - sorry.

however, it is easy to playback sound (e.g. mp3) with DirectShow, and you don't have to care about buffers and stuff, and you can easy retrieve the playback position.

btw, some very well thoughts about sound programming in general: http://www.kebby.org/articles.html

Stuw
10-10-2005, 03:15 AM
Hi, all! :)

Thanks for help.

You say - "Also, don’t stop the audio playback to inject new stream data."
I don't stop the audio playback to inject new stream data, but I stop it to use SetNotificationPositions().

I wrote sound module for program which playing video files in specific format.

[video data for 1-st channel][audio data for 1-st channel]...
It's simplest variant

[video data for 1-st channel][video data for 2-nd channel][video data for 3-rd channel][video data for 4-th channel][audio data for 1-st channel][audio data for 2-nd channel]...
This full variant (almost full, in this format also text and system data, but they not need for us)

Video cadr must bee showed when audio data which plced after it playing.
(show video cadr; play sound; when sound finished show new video cadr)

Module for video decoding and playing was written befor me.
I must write audio module which will synchronize video and audio.

I use algorithm (function work with audio and then return control to programm):

1-st function call
{
lpbuf.Stop();
lpbuf.SetCurrentPos(0);
lpbuf.SetNotificationPositions(EndOfBuffer);
lpbuf.Lock();
add_data();
lpbuf.Unlock();
lpbuf.Play();
}

others function calls

{
WaitForMultipleObjects(EndOfBuffer);
lpbuf.Stop();
lpbuf.SetCurrentPos(0);
lpbuf.SetNotificationPositions(EndOfBuffer);
lpbuf.Lock();
add_data();
lpbuf.Unlock();
lpbuf.Play();
}

My be somebody tell me how to do this faster and better? My be I need to use threads?

Big thanks for help :)

wahaha
04-06-2006, 08:17 PM
Hello! Stuw!

Not long ago, I encountered this problem.

But difference is that I was using wavOutXXX() APIs to write a simple AuidoSystem.

I tried many ways to attemp to solve it...T_T
Finally, I solved it!

My solution:
When your playing is end, you can create an additonal buffer and fill 'silence' audio data, then use your currently DS buffer to play it...

I hope this way can help you!


....Are you chinese ?:lol: