Possible buffer overrun in WaveSynth module
Jon Abbott (1421) 2651 posts |
I’m seeing a random crash within WaveSynth, in the Finished code (line 739):
Registers at the time of the crash are: Could it be overrunning the sound buffer under certain conditions? |
Jeffrey Lee (213) 6048 posts |
Yeah, it looks like it will overflow the buffer if the sound finishes right at the end of the buffer. I’ve just checked in a fix, so everything should be OK come tomorrow’s ROMs. |
Jon Abbott (1421) 2651 posts |
Thanks Jeffrey, I’ve been trying to create a repro all week, to no avail! I’ll check the new ROM build tonight and confirm if it’s resolved the issue. EDIT: Looks like 4.11 didn’t make it into the build, so I’ll test tomorrow. |
Jon Abbott (1421) 2651 posts |
The code changes are now in the ROM, however it crashes in the same place:
Registers at the time of the crash are:
EDIT: At the time it crashes, R12=FAFF7E78 / FAFF7E9C on entry so the problem may be outside of WaveSynth and possibly in SoundDMA or SoundChannels? EDIT2: Repro steps from BASIC SYS “Sound_Configure”,0,0,0,0,0 TO A%,B%,C%,D%,E% Hold END to repeatedly generate a beep. |
Jeffrey Lee (213) 6048 posts |
On entry to where – Finished, or WaveSynth’s buffer fill code? If that’s the value on entry to Finished then it’s fine (apart from the obvious crash).
Yes, the location of the buffer will shift around a bit depending on how many channels are in use (1 or 2 = start of page, 4 or 8 = end of page). Anyway, after taking a second look at the code I’ve spotted what the problem is. WaveSynth normally outputs samples 4 at a time (which is fine, all current versions of SoundDMA ensure the per-channel buffer size is a multiple of 4). But Finished can get called from any point, including when halfway through a 4 sample block. So I’ve now checked in a new version which simply checks for the end of the buffer before each write within Finished. I would have spotted that sooner, but thought your ‘crashes here’ marker hadn’t taken into account the 8 byte PC offset. D’oh! |
Jeffrey Lee (213) 6048 posts |
EDIT2: Repro steps from BASIC Yep, I can confirm that the new version fixes that. |
Jon Abbott (1421) 2651 posts |
We got there in the end :) I noticed SoundChannels has the same 4 byte fill loop in Level1FlushLoop (line 1672), it may suffer the same issue so you may want to check it.
Someone needs to change the Debugger so it shows the correct instruction to save this constantly being a source of confusion! |
Jeffrey Lee (213) 6048 posts |
I believe that code only runs when the entire buffer needs flushing, so it should be safe. |
Rick Murray (539) 13850 posts |
What confusion? The Debugger is telling the truth – at the point of the failure, the PC was at that location, two instructions ahead of the instruction actually being executed. We perhaps ought to be glad that the ARM is simplifying its world view and that, generally, PC is two words ahead even though modern ARMs are horrendously more complicated than the ARM2! The Pi’s pipeline is eight stages. The Cortex-A8 is 13 stage and can execute two things at once if there are no interdependencies. Don’t ask about the Cortex-A15. Complex much. |
Jon Abbott (1421) 2651 posts |
The PC isn’t the source of confusion, it’s the arrow that indicates which instruction crashed that’s confusing. |