* volume levels

I finally got to do some 'real' YM2413 reverse engineering. Though I
started simple: I looked at the 4-bit volume register of the YM2413
channels (located in bits 3-0 of registers 0x30-0x38).

I wrote a program that plays a sine wave (the exact shape is less
important here) for all 16 volume settings. I captured those signals
(see analyze/volume/volume{0-15}.raw) converted them to YM2413 levels
(see analyze/volume/volume{0-15}.out) and looked at the maximum
amplitude of the signal.

That gives 16 pictures that look like this (this picture shows vol=0):
  [image: ym-vol-0.png]
As expected for volume=0 (the maximum volume setting), the signal spans
the full 9-bit range going from 0-511.
   ... I should start using signed YM2413 signal values, in that
   case the signal goes from -255 to +255 (including both -0 and +0, more
   on these two zeros below).

Mostly because it looks nice, I (manually) copy-pasted one sine-period of
each volume setting into a single picture:
 [image: all-volumes.png]

Here's a table showing volume-setting versus maximum-amplitude:
	volume / amplitude
	   0       255
	   1       181
	   2       127
	   3        90
	   4        63
	   5        45
	   6        31
	   7        22
	   8        15
	   9        11
	  10         7
	  11         5
	  12         3
	  13         2
	  14         1
	  15         1

As already mentioned for vol=0 we get a maximum amplitude of 255. The
YM2413 datasheet states that each volume step changes the volume by -3dB
(thus multiplying the amplitude by a factor sqrt(0.5) ~= 0.707). And
that's also what we see in this table.

The table shows the same maximum amplitude for volumes 14 and 15. Let's
take a closer look:
  [image: ym-vol-14.png]
  [image: ym-vol-15.png]
In both cases the signal (only) takes on 4 distinct values: -1, -0, +0 and
+1 (more on -0 and +0 below). But for vol=14 (the louder of the two) the
signal is more often +/-1 than for vol=15, so on average it's further away
from zero. Or in other words after quantization both signals use the same
set of (only 4) values, but the signal for vol=14 has higher energy than
the one for vol=15.

This shows that only looking at the maximum amplitude doesn't tell the
whole story. I'll have to investigate this in more detail later.
Probably after I've figured out the exact shape of the sine wave (it's
not a perfect sine wave, instead it's a discretized version stored in
ROM).

It's also interesting to know that setting vol=15 does not fully mute
the channel (although -45dB is already very quite).


The pictures above show YM2413 levels, it's also interesting to look at
the raw signal (I mean the ADC values not yet converted to YM2413
levels). The following image shows the raw signal for vol=12.
  [image raw-vol-12.png]

As explained in earlier posts there's relatively little noise near the
center levels, so we can very clearly see the distinct YM2413 levels. But
what is strange in this image is the non-uniform distance between the
different levels (y-axis). For most levels this distance is (very roughly)
about 100 ADC units, but for the center levels the distance is only about
50 units.

The two levels encircled in red are what I've been calling -0 and +0. If
we make these two levels coincide (so move -0 a bit up and +0 a bit down),
we get a much nicer image (though this transformation doesn't yet make the
inter-level-distance completely uniform). And this confirms my guess that
-0 and +0 should (ideally) be the same level.


One thing I already noticed a while ago but didn't mention yet in these
posts is that the rising side of the sine wave (but not the falling
side) shows some anomalies. These are shown in the next image:
  [image rising-side.png]
So instead of monotonically rising, at regular intervals, the signal
jumps up for one sample, then jumps two levels down for a while and then
goes back to the original level. My current best explanation is that
this is caused by the modulator part of the YM2413 instrument settings.
These are the settings used in this image:
  mod={AM=0 PM=0 EG=1 KR=0 ML=00 KL=0 TL=63 WF=0 FB=0 AR=15 DR=15 SL=00 RR=15}
  car={AM=0 PM=0 EG=1 KR=0 ML=00 KL=0       WF=0      AR=15 DR=15 SL=00 RR=15}
So apparently, even though mod.TL=63, the frequency modulation is not
fully suppressed. I tried setting mod.AR=0, but that didn't make any
difference.

What did help was setting mod.WF=1 (use a clipped sine wave for the
modulator, so for half a period the signal is zero) and setting car.ML=1
(make the carrier move twice as fast as the modulator). The combined
effect is that we now have alternating 'clean' periods and periods
with anomalies.



* sine-table resolution

Above I mentioned we need to know the exact shape of the sine wave to be
able to exactly calculate the volume levels (because we could only
measure amplitudes up to integer YM2413 levels). So let's make a start
in investigating that sine wave table. One (easy) aspect is to determine
the number of entries in the table.

For all the earlier measurements I used an arbitrary YM2413 channel
frequency setting:
  R#0x10 = 0x61
  R#0x20 = 0x12
this sets fnum=97 and block=1 (that results in a frequency of 37Hz
assuming the YM2413 is clocked at 3.5MHz, but the actual value doesn't
matter here). In the following experiments I've set the frequency to
nice round powers-of-2 (IIRC I used fnum=32,64 and block=0,1 but again
the exact values don't matter much).

Because we're using such low channel frequencies the YM2413 output
remains constant for a number of consecutive samples before it moves to
the next entry in the internal sine wave table. We could already see
this in the earlier experiments: there the output remained constant for
either 5 or 6 samples. Now when using powers-of-2 each 'flat' segment in
the output also lasts for an exact power-of-2 number of samples (e.g.
exactly 4, 8 or 16 samples).

Next I looked at the duration of one full sine period. When dividing
that period-length by the segment-length, I found that this ratio is
always exactly 1024. This means the YM2413 has 1024 entries in its sine
wave table (and as expected this is also a power-of-2).

Actually a sine wave has some symmetry properties that allow to only
store 1/4 of the wave in the table (the other parts can be reconstructed
by flipping the x- and/or y-axis). So the ROM only needs 256 entries.

This result matches with other reverse engineering results of OPL2 and
OPL3 chips. Those chips also divide the sine wave in 1024 steps. See
this article for more details:
    https://docs.google.com/document/d/18IGx18NQY_Q1PJVZ-bHywao9bhsDoAqoIn1rIm42nwo/edit

The YM2413 (OPLL) is derived from the YM3812 (OPL2), OPLL is a cheaper
variant of OPL2 ('L' for light-weight??). So it's possible that, next to
the number of entries, also the actual values in the tables match. But
it's also possible the values are stored with less precision. That's
something I should investigate later.
