Neil Jerram <n...@ossau.homelinux.net> writes: > I had an unsuccessful call this evening; it was an incoming one. The > gsm-voice-routing log for it is below; I plan to analyse this more > myself to see if there's a repeating pattern of overruns and underruns, > but thought it worth posting in case someone else sees and understands > the pattern first.
Well the pattern is clear enough, and persists in exactly the same form throughout the whole call. r_mod (capture from the modem) gets an overrun every 4 loop iterations. p_ear and p_mod (playback to the earpiece and to the modem) get an underrun every 8 iterations. r_mic (capture from the microphone) doesn't get any overruns at all. For context, here's a representation of the gsm-voice-routing main loop. +-------+ +-------+ +-------+ +-------+ .->| Read |--+->| Read |--+->| Write |---->| Write |--. / | r_mic | | | r_mod | | | p_ear | | p_mod | \ / +-------+ | +-------+ | +-------+ +-------+ \ \ (if overrun) (if overrun) / \ / / / '-----<-----'-------<-----'-------<-------------<-------' I had two ideas for explaining the observed over/underruns, but neither of them makes complete sense when we look at the full detail. #1 was that the modem sound card was running slightly faster than the main sound card. (In theory they should both be at 8kHz.) However I think that is disproved by the fact that I got _exactly_ the same underrun pattern for p_ear and p_mod. I think that means that the rates of the two sound cards must differ by less than 1 period over the 16s duration of the call that I logged, i.e. by less than 0.2%. (The period - i.e. how much audio data is read or written in each block shown above - is 32ms.) #2 was that gsm-voice-routing might not be getting enough CPU. The period time is 32ms; let's call that P. Also note that gsm-voice-routing uses hardware buffers that have room for 4P. Now suppose that the average time for gsm-voice-routing to iterate round its main loop is more than P, say 1.9P. After 4 iterations, the capture devices have captured 7.6P, but gsm-voice-routing has only read 4P from them - so they have 3.6P still available and are close to overrunning. The loop always reads r_mic first, so manages to do that before r_mic overruns, reducing its remaining data to 2.6P. But that took a bit of time, and that was long enough for r_mod to fill from 3.6P to 4P, so that 'Read r_mod' reports an overrun. r_mod's buffer is now reset to empty and the main loop does a 'continue', which means that it skips the 'Write's and loops back to reading r_mic again. For p_ear and p_mod, the underrun every 8 iterations is roughly explained by the fact that they have a start threshold of 4 periods. Hence, after an underrun, it takes some iterations for the playback buffers to fill up to their start threshold, then 4 and a bit iterations at 1.9P each for them to be emptied (faster than the loop can keep them filled) and eventually see another underrun. But there are several problems with this explanation. - It doesn't actually explain why we never see r_mic overruns. After an r_mod overrun, r_mod's buffer is reset to 0 but r_mic's buffer is left unchanged. So now r_mic is ahead of r_mod, and we ought to see an r_mic overrun before the next r_mod overrun... - If the loop time was nearly 2P, it should take only 2 and a bit iterations for p_ear and p_mod to fill to their start threshold. Plus 4 iterations to empty again, and that only makes 6 (and a bit), not 8. - The log shows 519 loop iterations, and QtMoko recorded the call duration as 17s, so the average loop iteration time was 32.8ms, i.e. almost exactly P as it should be, and nowhere near 2P. So the head scratching continues. Any ideas? Neil _______________________________________________ Openmoko community mailing list community@lists.openmoko.org http://lists.openmoko.org/mailman/listinfo/community