streaming - C++ - DirectSoundBuffer stop playing at specific location - no notifications -
i'm using directsound's directsoundbuffer play voice data streaming on network. nature of voice/speech doesn't stream (it starts , stops) , can come in varying packet sizes (which makes difficult predict buffer should stop). keep stoppingpoint
variable keeps track of in buffer have written (it takes account circular nature of buffer). if stoppingpoint
reached, stop playing buffer. also, stoppingpoint
signify point @ i'd start writing from.
my buffer |==============================|--------------------------| ^ ^ ^ | | | voice data stopping point old/garbage data
also, can't use notifications, because in order use notification buffer must stopped. in case, more data come in buffer playing, pushing 'stoppingpoint` value.
what have function called every frame. function, amongst other things, checking play cursor is. if play cursor passed stoppingpoint
location, stops buffer, , moves play cursor stoppingpoint
location. seems work ok far, you'd expect, play cursor quite overshoots stoppingpoint
. means little bit of old/garbage data played every time end of streamed data reached.
i'm curious if there way stop playing directsoundbuffer @ specific offset? write data buffer, play, have stop precisely @ location described stoppingpoint
variable without overshooting it.
note: haven't included code because more of high-level solution need. implementation incredibly straight forward, typical , part work. need nudge in right direction remove overshooting of stoppingpoint
. perhaps there function can use? or other algorithm commonly used achieve this?
i've come solution, i'm still interested in feedback or alternative solutions. i'm not sure if way i've done ok, seems producing desired results. although, solution feels little convoluted...
1) whenever write data, write @ either buffer's write cursor
or stoppingpoint
- whichever later. avoid stopping, later writing in "untouchable" space between play cursor , write cursor, data has been dedicated playback.
dword writecursoroffset = 0; buffer->getcurrentposition(null, &writecursoroffset); //if write cursor has passed stopping point, need write there. //so update m_stoppingpoint reflect new writing position. m_stoppingpoint = m_stoppingpoint > writecursoroffset ? m_stoppingpoint : writecursoroffset;
2) added silence after every single write, left stoppingpoint
point @ end of actual voice data. eg.
|==============================|*********|---------------------| ^ ^ ^ ^ | | | | voice data stopping silence old/garbage point data
3) if buffer's play cursor
passed stoppingpoint
, stop playing buffer. if play cursor overshoots here, play silence.
//error checking removed demonstration purposes buffer->stop();
4) after stopping update stoppingpoint
equal end of silence. ensure when more speech data comes in, buffer not play silence first.
//don't forget modulo @ end - circular buffer! m_stoppingpoint = (m_stoppingpoint + silence_buffer_size) % buffersize; |==============================|*********|-------------------| ^ | move stopping point here
again, if i've done glaringly evil here, please let me know!
Comments
Post a Comment