Tuesday, July 22, 2008

YM2413 Tuning and Instrumentation

When I think about the strengths of a chip such as the YM2413, two things come to mind. Firstly, it has nine pitched voices for music playback. This is great, because the SN76489 for example only had three. The other strength of the YM2413 is instrument zero, which can be customised in terms of the sound that it produces via FM synthesis. Additionally, tuning is much less an issue than with the SN76489 for example.

Okay, so you might be thinking "Only one customisable instruments, that's not much at all!" and although I see your point, you have to put this into perspective of the era that this sound chip was produced in and the purposes that it was produced for.

So anyway, I made a Max/MSP patch with which the customisable instrument is easily controlled from (via MIDI CC messages). Of course, these parameters can be controlled from any MIDI sequencing program (Ableton live, Logic, etc).

Here is a quick example of controlling only three of these parameters whilst playing a one bar loop. The parameters that are changed throughout this example are the modulation level, the wave selection for the carrier and the wave selection for the modulator. The changes in octave are due to the wave selection for the carrier being changed throughout the example.

The scope for a variety of different sounds is quite large, especially considering that the sound design of such a custom instrument might be based on both a micro scale (for example, a note-by-note basis) and other parameters might play an important role on a structural scale (for example, used to highlight various points of tension and release in a phrase).

Below you can see the unmodulated, unrectified output waveform of the carrier playing an A3.

Due to the way that the YM2413 produces sound and frequency, the spread of data values to musical pitch across its eight octave range is much more even than a generator whose output frequency is determined by a straightforward division of the master clock.

I created a lookup table of sorts, based upon data found within the YM2413 application note. However, I found that the resultant frequencies were off by a relatively large amount when compared to TET-12 tuning, as follows:

C#: -16.113 cents
D: -13.973 cents
D#: -9.017 cents
E: -10.063 cents
F: -8.883 cents
F#: -13.292 cents
G: -9.199 cents
G#: -10.972 cents
A: -12.018 cents
A#: -12.729 cents
B: -13.459 cents
C -9.450 cents

Obviously, a tuning error margin of up to approximately -16 cents is unacceptable. These errors are most likely caused by the fact that the manual assumes a 3.6MHz clock for the YM2413, but the board that I am using in the Sega Master System uses an NTSC colour burst crystal running at 3.579545MHz.

I created a new lookup table that compensates for these errors, resulting in the following tuning anomalies:

C#: +2.912 cents
D: +3.967 cents
D#: -0.552 cents
E: -2.066 cents
F: -1.340 cents
F#: +0.957 cents
G: -2.475 cents
G#: +1.711 cents
A: -0.037 cents
A#: -1.414 cents
B: -2.773 cents
C: +0.615 cents

Yes, the D is still quite out of tune (by approximately + 4 cents) but that is as close as it is going to get.


athleos said...

man Seb, now that the YM2413 is an option for all us non-japanese SMS owners, i am really stoked about all this! i wish i could help out! i ordered an add-on board from Tim so i should get one in a week or two.... this is really awesome! are you going to incorporate support for the YM and the SN separately, i.e. "12 voices" and "stacked voices" etc..?

Sebastian Tomczak said...

Athleos, at the moment I am addressing the voices as separate channels, so SN76389 sits on MIDI channels 1 - 4 and YM2413 sits on 5 - 13. Im making some slow progress with all of this.

Anonymous said...

Hi Seb,

So I guess came across this post, but it really interests me. I recently acquired a Yamaha TX81Z synth module from a friend of mine and I have been experimenting with it. The TX81Z synth has a seemingly similar chip to the one you were using in this example (the TX81Z uses the YM2414). I can't find much information about it online, but I am interested in controlling the parameters like the modulation level, wave selection etc in real time. You wrote that you controlled them with MIDI CC messages. Do you remember what channels those parameters were sitting on? Did you have to map the parameters to those CC channels in order to control them? Any info you have would be really helpful just to push me in the right direction.


Sebastian Tomczak said...

Hi Carl,
I can't really help you (I'm sorry) but because the YM2413 is inside of the Sega Master System, I have actually done all the MIDI mapping myself, so I'm just controlling it with a CC message.

- Seb

Anonymous said...

Hey Seb,

You may or may not be interested, but I figured out a way to control voice parameters like wave selection on my TX81Z in realtime. The solution is a combination of Midi CC messages and System Exclusive (SysEx) messages. For example in SuperCollider you can send SysEx messages directly using Arrays. To create a crude kind of control using CC all I have to do is assign the val of a MIDI CC number to a particular byte of the SysEx message. For Example:

//Change Each Operators' Waveform using MIDI CC and SysEx
MIDIIn.control = { arg src, chan, num, val;
x = case
//Operator 1
{num == 10}
m.sysex(Int8Array[ 16rf0, 16r43, 16r16, 16r13, 18, val, 16rf7])
//Operator 2
{num == 11}
m.sysex(Int8Array[ 16rf0, 16r43, 16r16, 16r13, 8, val, 16rf7])
//Operator 3
{num == 12}
m.sysex(Int8Array[ 16rf0, 16r43, 16r16, 16r13, 13, val, 16rf7])
//Operator 4
{num == 13}
m.sysex(Int8Array[ 16rf0, 16r43, 16r16, 16r13, 3, val, 16rf7])

Anyway, just wanted to let you know that your post still helped me out in terms of inspiration to figure this out :) Hopefully someone will find this useful sometime down the road.