Jump to content
  • 0

FM Synthesis on the CX16


svenvandevelde
 Share

Question

8 answers to this question

Recommended Posts

  • 0
On 11/28/2021 at 8:42 PM, Ender said:

It may not be compiled for R38.

I think I got that program working with R38.

I used the YM2151 in my recent music demo, alongside the VERA PSG.

The bass, hihats, kick drum and melody are done with the YM2151. The supersaw and the noise effects are done with the PSG.

Concerto can be tried out in the Web Emulator:

Concerto lets you program sounds that combine the VERA PSG and the YM2151, but of course you can simply deactivate the PSG by reducign the number of (PSG) oscillators to zero. This is done under "Global" -> "N. OSCS". After that, the YM2151 is the only sound source. You can program the different parameters on the right side of the Concerto UI. Use your keyboard to play notes to hear what it sounds like.
Some parameters are not available though, e.g. the LFO. The YM2151 SYNTH UI program mentioned by Ender can be used to learn about those.

Edited by kliepatsch
  • Like 1
Link to comment
Share on other sites

  • 0

My Flappy Bird game uses the YM exclusively for sound, and my Sonic The Hedgehog tech demo uses both FM and PSG (since that's what Sega Genesis used).

SlithyMatt's game Chasevault uses the YM exclusively for sound as well.

Some things to note about the YM2151 support in emulator versions: x16emu r38 contains several inaccuracies regarding the FM emulation:

  • The base IO address of the YM is $9FE0 in R38 whereas the real hardware has it at $9F40. R39 and Box16 emulators use the correct address. Be sure to take this into account in your programs if you want to support both R38 and R39.
  • The YM2151's clock speed is 4MHz in R38 whereas the physical X16 uses a 3.5MHz clock (the speed recommended by Yamaha). R39 and Box16 use 3.5MHz.
    • This has the effect that the output pitch generated by R38's FM synthesis is 1 step too high - i.e. if you put in the keycode for concert A (A4, 440hz) you will instead get a B4.
    • It has other subtle effects that aren't as noticeable, such as ADSR envelopes process slightly faster on 4MHz-clocked chips than they do on 3.5MHz-clocked chips. @kliepatsch- I don't know how low-level your synth gets with the FM component of the sounds it makes - since your program relies on phases and mixing to get specific sounds, you may want to check your results in R39 to make sure nothing changes here.
  • The YM2151's busy state is not emulated in either R38 or R39, but is available on Box16
    • The YM2151 becomes busy after any data writes for 64 YM clock cycles (not CPU clock cycles) and will drop any writes to it while busy. The chip's busy state may be checked by reading from the data port ($9FE1 / $9F41) and checking the most significant bit. If clear, the chip is ready to receive a byte of data. If set, the chip is busy and writes will have no effect. What this means is that in emulator versions R38 and R39, you can write to the chip as fast as you like and nothing will be dropped, whereas on the real hardware, your music will be corrupted because many writes will be missed by the YM2151 chip.
    • The busy behavior is not emulated at all in x16emu - meaning that the chip neither mimics the busy behavior, nor does it ever show a busy state in the status byte if you read from it. Box16 does support the busy behavior as an option: -ymstrict causes the chip to drop writes if busy. Even without ymstrict, the busy flag is properly emulated so your program will see the high bit of the status byte set if the YM2151 is busy. The emulator simply queues up writes during busy state and applies them later. This was done to keep emulator behavior parity between Box16 and the official emulator.
  • The physical X16 has the YM2151's IRQ line connected to the CPU, so it can generate IRQs but this is not emulated in x16emu. Box16 emulates this properly if you run it with -ymirq command line option.
  • Mixing output levels are only "best guess" for now:
    • FM, PSG, and PCM outputs are mixed in the emulators (all versions) by averaging of the three sources. Box16 uses a newer MIT licensed FM library, YMFM whereas x16emu uses the GPL-licensed MAME source. YMFM seems to produce louder FM than the GPL MAME library did - so FM tends to overpower PSG tracks a bit more on Box16 than on x16emu. It is unknown exactly what levels should be used to mix the outputs, as the real hardware does analog mixing between the VERA and YM2151 audio outputs.
    • Until output levels from the emulators can be compared with physical hardware, any results are simply a "best guess" for now.
  • Box16's FM output has distortions - Box16 is fantastic for debugging audio-related programs, as it has very useful debug overlays for the sound sources, but the resampling methods in Box16 seem to cause distortions in the generated sound, which are especially noticeable at higher frequencies. Stephen Horn put in lots of effort into this front, but is currently busy with the day job, but still does accept PRs on the repo, so if anyone were to supply a fix for this, he'd most likely incorporate it fairly quickly.

 

Link to comment
Share on other sites

  • 0
On 11/29/2021 at 4:43 PM, ZeroByte said:

My Flappy Bird game uses the YM exclusively for sound, and my Sonic The Hedgehog tech demo uses both FM and PSG (since that's what Sega Genesis used).

SlithyMatt's game Chasevault uses the YM exclusively for sound as well.

Some things to note about the YM2151 support in emulator versions: x16emu r38 contains several inaccuracies regarding the FM emulation:

  • The base IO address of the YM is $9FE0 in R38 whereas the real hardware has it at $9F40. R39 and Box16 emulators use the correct address. Be sure to take this into account in your programs if you want to support both R38 and R39.
  • The YM2151's clock speed is 4MHz in R38 whereas the physical X16 uses a 3.5MHz clock (the speed recommended by Yamaha). R39 and Box16 use 3.5MHz.
    • This has the effect that the output pitch generated by R38's FM synthesis is 1 step too high - i.e. if you put in the keycode for concert A (A4, 440hz) you will instead get a B4.
    • It has other subtle effects that aren't as noticeable, such as ADSR envelopes process slightly faster on 4MHz-clocked chips than they do on 3.5MHz-clocked chips. @kliepatsch- I don't know how low-level your synth gets with the FM component of the sounds it makes - since your program relies on phases and mixing to get specific sounds, you may want to check your results in R39 to make sure nothing changes here.
  • The YM2151's busy state is not emulated in either R38 or R39, but is available on Box16
    • The YM2151 becomes busy after any data writes for 64 YM clock cycles (not CPU clock cycles) and will drop any writes to it while busy. The chip's busy state may be checked by reading from the data port ($9FE1 / $9F41) and checking the most significant bit. If clear, the chip is ready to receive a byte of data. If set, the chip is busy and writes will have no effect. What this means is that in emulator versions R38 and R39, you can write to the chip as fast as you like and nothing will be dropped, whereas on the real hardware, your music will be corrupted because many writes will be missed by the YM2151 chip.
    • The busy behavior is not emulated at all in x16emu - meaning that the chip neither mimics the busy behavior, nor does it ever show a busy state in the status byte if you read from it. Box16 does support the busy behavior as an option: -ymstrict causes the chip to drop writes if busy. Even without ymstrict, the busy flag is properly emulated so your program will see the high bit of the status byte set if the YM2151 is busy. The emulator simply queues up writes during busy state and applies them later. This was done to keep emulator behavior parity between Box16 and the official emulator.
  • The physical X16 has the YM2151's IRQ line connected to the CPU, so it can generate IRQs but this is not emulated in x16emu. Box16 emulates this properly if you run it with -ymirq command line option.
  • Mixing output levels are only "best guess" for now:
    • FM, PSG, and PCM outputs are mixed in the emulators (all versions) by averaging of the three sources. Box16 uses a newer MIT licensed FM library, YMFM whereas x16emu uses the GPL-licensed MAME source. YMFM seems to produce louder FM than the GPL MAME library did - so FM tends to overpower PSG tracks a bit more on Box16 than on x16emu. It is unknown exactly what levels should be used to mix the outputs, as the real hardware does analog mixing between the VERA and YM2151 audio outputs.
    • Until output levels from the emulators can be compared with physical hardware, any results are simply a "best guess" for now.
  • Box16's FM output has distortions - Box16 is fantastic for debugging audio-related programs, as it has very useful debug overlays for the sound sources, but the resampling methods in Box16 seem to cause distortions in the generated sound, which are especially noticeable at higher frequencies. Stephen Horn put in lots of effort into this front, but is currently busy with the day job, but still does accept PRs on the repo, so if anyone were to supply a fix for this, he'd most likely incorporate it fairly quickly.

 

I read your feedback with great interest. You have a lot of experience in this. I will do baby steps soon but hope to get some success out if it. As you know I'm building this heap manager in banked ram (BRAM) and VERA RAM (VRAM). Once this is finished I'll start with the ym2151. Also developing a game but taking it slower also due to lack of time. In the meanwhile I'm reading the web on ym2151 manuals. I'm specifically interested in how to create instruments and how the fm synthesis works. I remember the manual if the C64, which explained how to simulate a flute, trumpet, piano... Today I'm a but older so a good theoretical reference on fm synthesis and how to patch the sound would be very useful.

Link to comment
Share on other sites

  • 0
On 11/29/2021 at 8:28 PM, svenvandevelde said:

a good theoretical reference on fm synthesis and how to patch the sound would be very useful

The FM synthesis on the YM2151 works pretty much the same way it works in the Yamaha DX7. The biggest difference is that the DX7 has 6 operators whereas the YM2151 has only 4. But 4 operators is still plenty of material to work with. Both modulators and carriers are "operators", and both can either modulate or output sound. In "connection" 7, all operators output sound directly, in "connection" 0, only the operator 4 outputs sound, whereas the other three are modulators. I disagree with how the YM2151's manual calls the operators modulator or carrier regardless of what they are actually doing (which depends on the "connection", or "algorithm" in terms of DX7 language).

I learned FM synthesis by simply seeing examples of what can be done with FM synths and how it is done, and then trying them out by myself. And a lot of messing around and trying stuff out (making educated guesses).

You could start with these two tutorials, and then search other DX7 tutorials. The YM2151 does not have all the features of a DX7, but most things can be applied to the YM2151 as well.

I should mention one pitfall that has confused me when I started working with the YM2151: the total level (TL) in the YM2151 is attenuation! TL=0 means max level. TL=127 means no output. The same goes for the decay level IIRC (D1L).

If you want to hear something, the attack rate (AR) should be non-zero. Maybe set it to 10 or so. Higher values make it faster, low values slower.

 

 

On 11/29/2021 at 4:43 PM, ZeroByte said:

I don't know how low-level your synth gets with the FM component of the sounds it makes - since your program relies on phases and mixing to get specific sounds, you may want to check your results in R39 to make sure nothing changes here.

I am sure things will change slightly. The envelopes are indeed slightly slower with 3.5 MHz clock. But I am not worrying about that right now. Any patches can be adapted as soon as the official emulator moves on.

  • Thanks 2
Link to comment
Share on other sites

  • 0

@svenvandevelde: If you want to play with patches, I recommend using the instrument editor in Deflemask (I'm pretty sure they still offer the freeware version). FM instrument design is definitely something that's better done by getting an intuition and feel for it more than a left-brained understanding. The technical part can definitely guide your hand, but to me, it's one of those things that you're better off just playing with knobs and seeing what comes out.

You can save instruments in Deflemask to its custom FM instrument format DMP.
I've made a script to convert DMP into raw register byte writes for X16. All you have to do to use them is poke them into the YM in the proper order using a very simple algorithm: (pseudocode)

ym_write(addr,data) {
  // ensure YM is not busy, then:
  poke $9FE0,addr  // $9F40 for R39
  poke $9FE1,data  // $9F41 for R39
}

patch_data[26] = x,x,x,x,x,x,x,x,x,x,.... // (the 26 bytes of patch data)
addr = 0x20 + voiceID // voiceID = 0-7 i.e. which voice you're patching
ym_write(addr,patch_data[0])
addr = 0x30 + voiceID
for (i=1..25) {
  addr += 8
  ym_write(addr,patch_data[i])
}

Assuming voice 0, the bytes of the patch should be written to YM registers:
0x20, 0x38, 0x40, 0x48, 0x50, 0x58 ... 0xF0, 0xF8

I call this format "YMP" for YM Patch.

One thing I've omitted from YMP that may or may not be an issue is the operator mask to use when keying notes for a patch. OPM format also records this information (DMP files do not) - not sure how often one may come across patches in the wild that don't use all 4 operators....

Let me know if you'd like me to post that conversion script - it's a tool in the suite I'm working on called zsound, which currently has a defined music data file format (ZSM), and includes an assembly-based playback library, and an import script to convert from VGM into ZSM. (It can convert OPN chip tunes as well as AY-3 and TI SN7xxxx PSG chips as well as YM2151). Once I get more of the intended core functionality done, I'm going to release the whole thing for the community's use, but for now, I'll post the patch conversion tool if you're interested.

I believe that instrument creation represents the bulk of the complexity of the YM2151. If you start with patches that sound like what you want, then playing music on the YM can be much simpler than even on the PSG, as it's really nothing more than just spooling a sequence of note pitch values and keyUP/keyDN events.

  • Like 1
Link to comment
Share on other sites

  • 0
On 11/29/2021 at 10:17 PM, ZeroByte said:

it's one of those things that you're better off just playing with knobs and seeing what comes out.

Definitely. If you're new to FM synthesis, I too would recommend getting access to some FM synthesizer other than using assembly or C on the CX16. I haven't tried Deflemask, but from what I have seen in Matt's video, it seems to be a good fit for that.

Edited by kliepatsch
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

Please review our Terms of Use