Closed dansanderson closed 8 months ago
I suppose, the problem can be somewhere here in targets/mega65/audio65.c
:
if (XEMU_UNLIKELY((addr & 0xFFFF) == limit)) {
// if top address is reached: either stop, or loop (on looped samples only!)
[...]
I guess, changing ==
to >=
may help. The problem here, that I haven't thought on this too much, and the code was mostly tested on 8 bit samples, when this is not a problem.
Also it would worth to test on other edge cases:
>=
can be problematic.Surely I need to test this, if it's really the case, and this simple fix is enough or not.
@dansanderson Thanks for the report!
Proposal (I have to test this, I had no time for it yet ...):
if (XEMU_UNLIKELY(
((addr & 0xFFFFU) == limit) // limit reached
|| ( // OR ...
(chio[0] & 3) == 3 && // ... 16 bit sample
((addr - 1) & 0xFFFFU) == limit // ... and the limit was the previous byte (as with 16 bit samples we would miss the limit if not aligned!)
)
)) {
[...]
But, as far as I see so far, there is another problem here, that even if playback is not stopped correctly, it shouldn't "break free" to infinity. That's the question that audio DMA is "wrapped" within a 64K range always or not. Ie, if so, in theory some can set up a sample from - let's say - $48000 and setting the limit (that's a 64K setting) to $1000, thus then playback should go from $48000 to $48FFF and then continue at $40000 till hitting $41000. Well, if that's true it is wrapped. If not, it will continue to $50000 and stopping at $51000, I guess. But actually I can easily test this by looking the output of your test program (after modifying the limit for that test) on a real MEGA65 for sure.
The proposed fix has been pushed to next
. I've tested this on real MEGA65 too and with Xemu, looks like identical now in behaviour. I've also tested the wrapping (or warping? I am never sure ...) around, and indeed MEGA65 doesn't do that either (ie, it continues on the next 64K "bank").
So, I guess, the only real problem here was the "alignment" of start/limit addresses in case of 16 bit samples. Which has been - hopefully - cured by this commit above.
I'm about to close this issue now, please free to re-open if there is some problem with this fix, or the problem remained in certain circumstances.
Describe the bug Audio DMA does not stop playback at TADDR when TADDR is odd and the bit depth is 16. This affects both non-looping and looping playback: in both cases, it continues playback beyond the top address, and does not loop.
Used version of the project Xemu/MEGA65 20240228183812, macOS
To Reproduce
You can either provide an 8 kHz 16-bit signed sound sample in the "sample" file, or just remove line 10 and play whatever is in memory. If it's zeroes it won't sound; if it's garbage you might want to turn down the volume. :)
wpoke $d727,65534
(the lower 16 bits of the end address) and it'll stop correctly.poke $d720,128+2
(8-bit sample) and it'll stop correctly for either TADDR.100 poke $d720,128+64+3
Expected behavior On real hardware, when $d727-8 is 65535, ch0curaddr stops at $60000. With the looping flag on, it loops at that point.
Computer/Device (please complete the following information):