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

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -