> (PS, if you do use threads, protect speex_jitter_put/get with a mutex > (CRITICAL_SECTION I believe they're called in Win32Speak) -- calling put > and get at the exact same time from different threads leads to "features")I've never tested this, but I designed the jitter buffer to work from two threads even without using a mutex. This would work as long as there is one thread doing the "put" and one thread doing the "get".> As for detecting outages, a hack I use is to check jitter->valid_bits. If > it's set, we decoded "something", if it's not, we're interpolating > something which may not sound that good so feed the soundcard 20ms of > silence instead.Why would you do that. The idea of interpolating a frame is exactly to get better quality than just putting zeros. Jean-Marc -- Jean-Marc Valin <Jean-Marc.Valin@USherbrooke.ca> Universit? de Sherbrooke
>> (PS, if you do use threads, protect speex_jitter_put/get with a mutex >> (CRITICAL_SECTION I believe they're called in Win32Speak) -- calling put >> and get at the exact same time from different threads leads to "features") > > I've never tested this, but I designed the jitter buffer to work from > two threads even without using a mutex. This would work as long as there > is one thread doing the "put" and one thread doing the "get".Err, unless I'm totally wrong, there are a few race conditions. Assume the buffer is full of packets newer than the current pointer, and one that is at the current pointer. get and put start at the same time. get will find the correct buffer index. Now, just after it finds it's index, assume we switch to the put thread. Put needs to put a new packet in, so discards the oldest, which is the current packet, and replaces it with the new one (let's call it newest). get now starts decoding, but the index it found now points to the newest packet, which it will decode and remove from the buffer. Granted, it's not terribly likely to happen, and the jitter-buffer as a whole has no crashbugs regarding two-thread access, but it will sound a bit odd if this should ever happen :)>> As for detecting outages, a hack I use is to check jitter->valid_bits. If >> it's set, we decoded "something", if it's not, we're interpolating >> something which may not sound that good so feed the soundcard 20ms of >> silence instead. > > Why would you do that. The idea of interpolating a frame is exactly to > get better quality than just putting zeros.Actually, I oversimplified a bit. I check if valid_bits has been zero for the last 4 frames or more, because once you interpolate more than 100ms from the last known state, you end up with some weird blipp-blopp-blooiiing sound. Actually it reminds me of the ambient sound of weird aliens in bad 50s scifi movies. At that point, silence is much better :)
> Err, unless I'm totally wrong, there are a few race conditions. > > Assume the buffer is full of packets newer than the current pointer, and > one that is at the current pointer. > > get and put start at the same time. > > get will find the correct buffer index. Now, just after it finds it's > index, assume we switch to the put thread. > > Put needs to put a new packet in, so discards the oldest, which is the > current packet, and replaces it with the new one (let's call it newest).[...] True. It was originally race-safe when I was discarding the incoming packet in case of buffer full. I changed that behaviour exactly because of burst issues and the like. Other than that, I don't think there should be any other possible race (assuming CPU cache coherence).> > Why would you do that. The idea of interpolating a frame is exactly to > > get better quality than just putting zeros. > > Actually, I oversimplified a bit. I check if valid_bits has been zero for > the last 4 frames or more, because once you interpolate more than 100ms > from the last known state, you end up with some weird > blipp-blopp-blooiiing sound. Actually it reminds me of the ambient sound > of weird aliens in bad 50s scifi movies. At that point, silence is much > better :)Then it would be a problem with the packet loss concealment. It's actually decreasing the level of the interpolated audio with time. Maybe it's not decreasing quickly enough? Jean-Marc -- Jean-Marc Valin <Jean-Marc.Valin@USherbrooke.ca> Universit? de Sherbrooke