... as in, I should have spent more time in Linux rather than iOS and I would have worked this out before Christmas.
Time to fess up - and don't flame me for being an almighty dufus, but - it's only today, 20 minutes ago in fact, that I realized that I need to do a sched_setscheduler(0, SCHED_FIFO, &p); in order to have my thread priorities honoured. No wonder I was struggling with glitches and pops, any old piece of junk could step in and force me to yield for hundreds, nay thousand of microseconds. I feel like whacking my fat old head against a concrete slab for a few minutes. Maybe 30 or 40 minutes, at 160 bpm.
But there we are.
It's a bit too late to turn up the amp and throw hands all over the keyboard, but via the magic of ssh, Macfusion and the intro to 'Fox on the Run' I have now run for a solid 19 minutes, even more than that, 20 minutes minus the time to go
make
sudo ./piana.bin
without a single packet underrunning in ALSA, 8 note polyphony, 900MHz overclock (as in, every Pi out there ever sold should be able to do this).
Brilliant. And clearly, whole new, previously undocumented levels of stupid all at once, but the stupid's now in the past. Well, until the next time my inner idiot rears himself up and imposes himself all over my code.
Awesome :)
ReplyDeleteAnd at the same time awesomely stupid :)
ReplyDeleteHere's an update today, grabbed out of a terminal just now -
ReplyDeleteSynth : time 1974.480469 audio pkts 1345332 busy pkts 672666 pkts/s = 688.995728 samples/s = 44095.726562 MIDI backoffs 1 aAddWaits 1639577 aRmvWaits 7 alsaSml 144 alsaBig 384 wfails 7 dfails 0
What's this all mean? Well, time 1974 means it's been running for over half an hour, wfails is the number of ALSA write underruns, which becomes 7 within a few hundred ms of the app starting due to the synth loop fopening a few dozen sample files and failing to push any samples to the consumer thread, then 32 minutes later, not a single underrun. Which is a big step up from a couple of days back. Notice also that 'aRmvwaits' is also 7 - this is the number of times the ALSA thread tried to grab samples and they were not yet there from the synth, forcing it to sleep for a few hundred microseconds at a time - again, these 7 all happen within a few hundred ms of startup. AlsaSml is the smallest number of items it ever saw in the FIFO, AlsaBig is the biggest.
Definitely a working synth, that is managing latency reasonably well.
And the news from the morning is still positive, but it was close -
ReplyDeleteSynth : time 43205.687500 audio pkts 29753452 busy pkts 14876726 pkts/s = 688.995605 samples/s = 44095.718750 MIDI backoffs 1 aAddWaits 35925552 aRmvWaits 9 alsaSml 51 alsaBig 384 wfails 7 dfails 0
After 43205 seconds (when I finally hit ctrl-c - a rather uncanny 12 hours and 5 seconds of running!) still the same 7 write fails, but the 'smallest FIFO depth' shrank during the night to a pretty tight 51 samples. Here's the 'lateness of sleep' histogram from just less than 12 hours of running - see the next post to make more sense of this. I find it interesting that there are giant clumps at the 1ms, 2ms and 3ms slots - as though something kernely, being scheduled at 1ms (and multiple of 1ms) intervals is getting in and blocking me consistently, with 2ms as the worst offender - it looks like about 50% (55%?) of the usleeps being done in the ALSA thread are waking up 2ms late, and maybe 40% are waking up sort of on time.
late[00 = 0000]=10509889
late[01 = 0256]=0004455
late[02 = 0512]=0000485
late[03 = 0768]=0761410
late[04 = 1024]=0085170
late[05 = 1280]=0000088
late[06 = 1536]=0000225
late[07 = 1792]=9766901
late[08 = 2048]=4355967
late[09 = 2304]=0718357
late[10 = 2560]=0003501
late[11 = 2816]=0000279
late[12 = 3072]=0004343
late[13 = 3328]=0003289
late[14 = 3584]=0000032
late[15 = 3840]=0000000
late[16 = 4096]=0000000
late[17 = 4352]=0000001
late[18 = 4608]=0000000
late[19 = 4864]=0000000
late[20 = 5120]=0000000
late[21 = 5376]=0000000
late[22 = 5632]=0000000
late[23 = 5888]=0000001
late[24 = 6144]=0000000
late[25 = 6400]=0000000
late[26 = 6656]=0000000
late[27 = 6912]=0000000
late[28 = 7168]=0000000
late[29 = 7424]=0000001
late[30 = 7680]=0000000
late[31 = 7936]=0000006
p.s. 28M 64-sample packets delivered overnight with no fails!
ReplyDeletewow, does that mean you are getting close to the end of latency/crashing issues?
ReplyDeleteIt's probability game at this point.
DeleteIt would appear that I've reached a combination of efficient enough coding coupled with buffer settings where ALSA underruns are statistically very unlikely (as in, not observed over a couple of 12 hour runs), but it may be that if (for example) I pull out the SD card while it's playing it all goes to hell, or if the SD card goes bad, or if somebody plugs in a USB device, or if somebody logs in over SSH or copies files using SSH via Fusion ... you know, unusual stuff for a working synthesizer.
But it would seem that under 'normal' conditions, I have settings that never overrun after the first couple of seconds of booting and warming up.