Problems with YM sound effects on real hardware (works in emulators)

All aspects of programming on the Commander X16.
doslogo
Posts: 24
Joined: Fri Dec 20, 2024 4:26 pm

Problems with YM sound effects on real hardware (works in emulators)

Post by doslogo »

A little bit controversial here, but I am using the zsound library (which hasn't been updated in 3 years), but wow it is good! I mean it, don't discard something that is so fast it allows for gameplay and other things to actually be "complex" and run at 60 Hz.

As the descriptions in the readme file specifies, the scripts for making zfx files are broken, and only the first implementation of the sound effects engine has been completed. Still, that is enough for me to spit out almost 100% replicas of the sounds I need, and on both emulators (official and box16), everything works flawlessly.

But I have the real hardware now. And ears starts bleeding once a sound effect starts playing, with random notes, pitches, and sometimes noise filling up the background song, or even without a background song at all (initialization removed, update removed, just to not interfere with the testing). The PSG sound effects work without problems even with YM background music.

I am not a music hardware person, and even with some hacking of the script file, I was able to export the register and pauses needed to play the YM sound effects perfectly in the emulators. So when the hardware says "no", the only thing I can do is randomly hack the library to try to do something differently, which will take way too long. I have tried everything from exporting more registers in the sound effect data, which takes much more cycles because loading YM voices takes more than my own-16 bit division routine? So again, controversial topic:
I tried the other sound library, and for every new voice loaded (like at the start or loop point), it doesn't take just ~150 cycles or so, but actually half a frame. I can't have lag like that, unacceptable for 60 Hz precision platform game.

I have tried to contact ZeroByte... But in the meantime, is there anyone out there who has the real hardware who would like to do some testing on the example found in zsound-main\examples\zfxdemo? The first PSG sound should play fine, but then the YM should work in x16emu-r48 but not on real hardware? Or maybe some hints what to change in the zfxplayer.asm code from the library?
User avatar
darvidanoar
Posts: 25
Joined: Wed Mar 22, 2023 7:53 pm
Location: Australia

Re: Problems with YM sound effects on real hardware (works in emulators)

Post by darvidanoar »

Hi doslogo

I ran this on my official emulator (r48) and it played both sounds: The sort of synthy buzz and then a two tone ding ding.
However, on the actual hardware (also r48) it only played the first synthy buzz.

My X16 is running VERA version 47.0.2, SMC version 48.0.0, and has the YM2164 variant, if that makes a difference.
David aka BKD (Bee Keeper Dave)
GitHub: https://github.com/Darvidanoar/
doslogo
Posts: 24
Joined: Fri Dec 20, 2024 4:26 pm

Re: Problems with YM sound effects on real hardware (works in emulators)

Post by doslogo »

darvidanoar wrote: Mon Mar 10, 2025 8:50 pm has the YM2164 variant, if that makes a difference.
Thanks for the info and testing! I checked mine as well, and I have the YM2151.

So we have the same problems. I've better clarify that background music (ZSM files) play perfectly on the real hardware with this library, so it is the YM sound effects implementation that is missing something.
User avatar
darvidanoar
Posts: 25
Joined: Wed Mar 22, 2023 7:53 pm
Location: Australia

Re: Problems with YM sound effects on real hardware (works in emulators)

Post by darvidanoar »

The code on the repo looks pretty old and I wonder of it's targeting a much older version of the mainboard, maybe even a pre-release board.
David aka BKD (Bee Keeper Dave)
GitHub: https://github.com/Darvidanoar/
ZeroByte
Posts: 718
Joined: Wed Feb 10, 2021 2:40 pm

Re: Problems with YM sound effects on real hardware (works in emulators)

Post by ZeroByte »

Hi, folks. First of all, thanks for the kind words about Zsound, Doslogo!

Questions:
Do the FM sounds play okay if you're not also playing music?
Are the SFX using channels that aren't being used by the music?

There is no channel contention code in the ZSM/ZFX players, so if your music uses YM channel 0 and the sound effect is being played on YM channel 0, then you're going to get bad results. There are 26 registers that all need to be set in order to completely define an instrument patch, and if you only set some of them but leave others untouched, then things are going to start getting corrupted. I ran into this back when I was adding sound to PETSCII Robots. Essentially, there was some register somewhere that I wasn't clearing properly.

The large CPU spikes in ZSMkit come from the fact that the YM is a very slow chip to communicate with. It requires roughly 1 raster line per write, and if you suspend a channel, that's going to require several writes, and then patch the new instrument in (another 26 writes), etc., it's an expensive proposition.

Speed is a top priority in Zsound, so whenever I get back into developing Zsound further, I am going to take a few different approaches than ZSMkit.

I would say reserve 1 FM channel for SFX and ensure that your ZSM does not touch it at all - zero writes to it. Then only play your SFX on that channel, and create an "init" sound that cleanly initializes whatever channel it's played on.

A full init would do this:
set RR to the fastest (zero? - I don't have my code or docs open and it's been a while)
release the channel (write the channel number into register $08)
write zeros into all patch registers: $20 and $38, then $40, $48, $50, $58 .. $F0, $F8.
doslogo
Posts: 24
Joined: Fri Dec 20, 2024 4:26 pm

Re: Problems with YM sound effects on real hardware (works in emulators)

Post by doslogo »

Happy to see you back ZeroByte! You are an inspiration to all of us!
ZeroByte wrote: Tue Mar 11, 2025 2:28 pm Questions:
Do the FM sounds play okay if you're not also playing music?
Are the SFX using channels that aren't being used by the music?
Yes and yes. I tried absolutely everything before even making this thread.
ZeroByte wrote: Tue Mar 11, 2025 2:28 pm The large CPU spikes in ZSMkit come from the fact that the YM is a very slow chip to communicate with. It requires roughly 1 raster line per write, and if you suspend a channel, that's going to require several writes, and then patch the new instrument in (another 26 writes), etc., it's an expensive proposition.
It's probably also because of PCM support. I am willing to skip that just to get the cycles. It was just very sad to see how much cycles were lost for the potentially same sounds. Also I am willing to program my own priority system for sound effects and keep it low level to keep it just a little faster.
ZeroByte wrote: Tue Mar 11, 2025 2:28 pm Speed is a top priority in Zsound, so whenever I get back into developing Zsound further, I am going to take a few different approaches than ZSMkit.
It was also simplicity (except for the php scripts, but they are kinda easy to get used to, and Furnace does a lot nowadays).
ZeroByte wrote: Tue Mar 11, 2025 2:28 pm A full init would do this:
set RR to the fastest (zero? - I don't have my code or docs open and it's been a while)
release the channel (write the channel number into register $08)
write zeros into all patch registers: $20 and $38, then $40, $48, $50, $58 .. $F0, $F8.
I am placing note-offs in the sound effect, but even your own sound effect is broken on real hardware.
Zeroing $20 on any play will just make everything silent. I am sure your init clears everything. So I also tried to call init, patchym, and play each time I play the sound effect, but real hardware has the same random bahaviour. See my PM for the captures videos, which does just this. All those calls, and it is still faster than starting a ZSM in ZSMkit, which just shows how fast Zsound is.
ZeroByte
Posts: 718
Joined: Wed Feb 10, 2021 2:40 pm

Re: Problems with YM sound effects on real hardware (works in emulators)

Post by ZeroByte »

After some reflection, I'm pretty sure I know what the problem is:

There probably needs to be more delay added in the ZFX player between writing the address select and the value. The ZSM player got all of the attention back when I was working with Wavicle during the pre-release HW days. We found that the code was not quite patient enough, and added some NOPs to the write routine. I never adjusted the ZFX player.

(this is zfxplayer.asm, starting at line 289)

Code: Select all

write_ym:
	bit YM_data
	bmi write_ym
	stx YM_reg
	nop  ; <------ there needs to be about 9 of these
	sta YM_data
I don't have my dev environment available to me for the time being, so feel free to patch this in your copy and submit a PR to fix it if you wish.

Extra thoughts re: the rest of the discussion:

0. The fast RR value is $0F (instant silence upon release)

1. The init routine in the ZFX player only initializes the player's state RAM, and does not talk to the YM at all. You could make an "init" sound and play that on a channel to initialize it.

2. You mentioned that your test sound resets all channels. You cannot specify channels in a ZXF because the player modifies register addresses to reference whichever channel the sound is being played on. Suppose your data has reg:0x42, val:0x30. This would normally affect the DT1/MUL value for operator M1 on channel 2. However, if you play this on channel zero, the reg is modified to 0x40 (DT1/MUL for M1 on channel 0). To reset all channels, you just need a sequence that resets a single channel, and then play it on all 8 channels.

A proper reset sequence might look like this: (all values hex, REG:VAL)
E0:0F, E8:0F, F0:0F, F8:0F, 08:00, 20:00, 38:00, 40:00, 48:00, 50:00, 58:00, ... F8:00

3. When I last touched ZFX, I hadn't yet met Wavicle and started getting feedback about behavior on real HW. Not only that, the audio bank had not yet been implemented. Now the YM is initialized by the Kernal to have working patches on all 8 voices by default, so it's important to not assume registers have zeros in them like my demo might have.
(note, this is when I realized the YM write timing is the culprit)
ZeroByte
Posts: 718
Joined: Wed Feb 10, 2021 2:40 pm

Re: Problems with YM sound effects on real hardware (works in emulators)

Post by ZeroByte »

The reason it works in emu but not in HW is because the emulation doesn't strictly enforce the physical limitations of talking to the YM, especially in the delay requirements between setting the address register and doing a data write.

The actual real required delay is variable, depending upon where in the chip's internal loop cycle it happens to be whenever you talk to it. On HW, it just happens that sometimes, the chip is happy even with the fast write, and sometimes it wasn't ready so some values are just randomly being dropped.
doslogo
Posts: 24
Joined: Fri Dec 20, 2024 4:26 pm

Re: Problems with YM sound effects on real hardware (works in emulators)

Post by doslogo »

ZeroByte wrote: Tue Mar 11, 2025 7:10 pm I'm pretty sure I know what the problem is
Yep, that was the problem. Here are the updates needed to fix the issue on real hardware:
Replace

Code: Select all

	nop
with

Code: Select all

.repeat 9
	nop
.endrepeat
at line 293 in zfxplayer.asm

and at lines 22 and 43 in patchym.asm
I am not qualified to do any edits on github so I leave that for someone else.

All the other suggestions were not needed as long as the YM channel of the sound effect doesn't conflict with a playing channel of the current playing background music.

Thank you ZeroByte for finding this and helping me (and others) to develop hopefully optimized games without too much problems!



Here is my approach for playing ZSM without any lag at 60 Hz with ZSound:
Allocate the instruments used throughout the background music to be initialized once by letting one initial pattern play one channel (by itself) with zero volume for one frame, then the next, and so on until all have been loaded, then jump to the real pattern where the music starts (with the volume set to default), and at the loop point, jump back to a pattern that doesn't reload any instruments. The loop point will take a little bit longer, but it will not lag the frame.
Disadvantage is that the music starts a few frames after it was started with ZSound, but can be compensated in the game by also waiting there (like syncing video and audio when possible).

Both YM sound effects and PSG sound effects can be played at the same time, also at the same time as the background music is playing! I have tested this. No lag even with very little cycles left per frame.

Preparing YM sound effects to dedicated channels must also be done. I tried loading the instruments into the ZSM file to see if I could skip this manual hardcoding, but it doesn't play. It is not a big deal.

I can live without fade-ins and fade-outs, so I am not screaming for any more functionality. A tool to create ZFX from a ZSM would be grateful though!

That's my approach to music and sound effects.
ZeroByte
Posts: 718
Joined: Wed Feb 10, 2021 2:40 pm

General - CX16 Re: Problems with YM sound effects on real hardware (works in emulators)

Post by ZeroByte »

Glad that fixed it. Once I got thinking about it, I realized how familiar that "works on emu, but not hw" problem was. :D

I do want to update Zsound to use the Kernal API call for writing YM and setting attenuation levels. It makes YM writes a bit more expensive, but if you have even 2 writes to do, it really doesn't matter because you're going to have to spend ~150 clocks waiting around for the YM to finish processing each write before the next one can happen.

I'd also like to implement tell/seek by ticks
Post Reply