Baldvin Hansson
2005-Jun-07 16:37 UTC
[Speex-dev] What to do when speex_jitter_get(...) has no buffer to return
[The following is perhaps a long question and even off-speex topic,] [but if anyone can at least point me in the right direction for ] [alternate sources of information, I'd really appreciate it. ] When speex_jitter_get(...) is called and there is no buffer/data to return, would I not want to know that there is no true data to play? If I turn around and queue 20ms of silence to play for the sound-card, the sound card will never be able to "catch-up" with the datastream when it starts to feed actual voice data? The above question may be a horrible manifestation of what I'm actually trying to ask (the question is very clear in about 3000 words in my head) but to perhaps explain better, this is what my app is doing now (with fairly good results when no data goes missing in transport: Network thread: 1) Wait until UDP packet available then Read it 2) Call PUT function to save to jitter buffer 3) Trigger sound-card thread 4) goto 1 Sound-card thread: 1) Wait until triggered by Network thread 2) Call GET function to get data from jitter buffer 3) Feed this data to the sound-card for playback 4) goto 1 A typical session would go: READ UDP PUT IN JITTER READ FROM JITTER FEED TO SOUND CARD REPEAT Now, with this implementation, when a network packet goes "missing", the trigger to the sound card thread is not called for one "cycle". This would mean that the sound card would never play the (hopefully) available queued packets in the jitter buffer. If I however let the sound card thread "run free", calling the speex_jitter_get(...) faster than the packets are coming in, I'll just be feeding the sound card with a ton of 20ms silent packets which it needs to finish playing before it can get to playing buffers that contain data decoded from the UDP stream. With my original question (way up at the top of this email), if I knew that there was no data returned from the jitter buffer, I could skip feeding it to the sound card and thus the sound card would be able to "catch up" on the playing of samples from the UDP stream received via the jitter buffer mechanism. Sincerely, Baldvin
Jean-Marc Valin
2005-Jun-08 12:44 UTC
[Speex-dev] What to do when speex_jitter_get(...) has no buffer to return
The thing you're forgetting is that normally, the write to the soundcard is blocking and will block for the same time it will take to receive a new packet. If you're using 20 ms frames, then you'll likely receive 50 packets per second and if you're timed on the soundcard, you'll call speex_jitter_get about 50 times per second too. If there's a slight difference in the sampling rate or the network delay changes, the jitter buffer will compensate for that and maintain a low delay. As for the speex_jitter_get_pointer_timestamp() function, you don't have to use it if you don't need it. The idea is that it allows synchronization of other stuff (e.g. image) with the audio. Jean-Marc Le mardi 07 juin 2005 ? 23:38 +0000, Baldvin Hansson a ?crit :> [The following is perhaps a long question and even off-speex topic,] > [but if anyone can at least point me in the right direction for ] > [alternate sources of information, I'd really appreciate it. ] > > When speex_jitter_get(...) is called and there is no buffer/data to > return, would I not want to know that there is no true data to play? > > If I turn around and queue 20ms of silence to play for the sound-card, > the sound card will never be able to "catch-up" with the datastream when > it starts to feed actual voice data? > > The above question may be a horrible manifestation of what I'm actually > trying to ask (the question is very clear in about 3000 words in my > head) but to perhaps explain better, this is what my app is doing now > (with fairly good results when no data goes missing in transport: > > Network thread: > 1) Wait until UDP packet available then Read it > 2) Call PUT function to save to jitter buffer > 3) Trigger sound-card thread > 4) goto 1 > > Sound-card thread: > 1) Wait until triggered by Network thread > 2) Call GET function to get data from jitter buffer > 3) Feed this data to the sound-card for playback > 4) goto 1 > > A typical session would go: > > READ UDP > PUT IN JITTER > READ FROM JITTER > FEED TO SOUND CARD > REPEAT > > Now, with this implementation, when a network packet goes "missing", the > trigger to the sound card thread is not called for one "cycle". This > would mean that the sound card would never play the (hopefully) > available queued packets in the jitter buffer. > > If I however let the sound card thread "run free", calling the > speex_jitter_get(...) faster than the packets are coming in, I'll just > be feeding the sound card with a ton of 20ms silent packets which it > needs to finish playing before it can get to playing buffers that > contain data decoded from the UDP stream. > > With my original question (way up at the top of this email), if I knew > that there was no data returned from the jitter buffer, I could skip > feeding it to the sound card and thus the sound card would be able to > "catch up" on the playing of samples from the UDP stream received via > the jitter buffer mechanism. > > Sincerely, > Baldvin > > _______________________________________________ > Speex-dev mailing list > Speex-dev@xiph.org > http://lists.xiph.org/mailman/listinfo/speex-dev >-- Jean-Marc Valin <Jean-Marc.Valin@USherbrooke.ca> Universite de Sherbrooke