back to buchty.net Yamaha District up


How to get 16 Operator Waveforms from just one sine segment

With the second generation of 4op machines, Yamaha introduced additional waveforms for the operators. All of them were derived from a creative, yet simple read-out of the sine wave ROM.

The SY77 offers a whopping 16 waveforms, some of them look ... interesting. But, like before, Yamaha just creatively used what was there already.

Sine memory

Back in the days, memory was expensive. Where wave symmetry was needed, this was typically achieved by external circuitry instead of fully laying out the wave in memory. A most prominent example is the PPG Wave that only stored half the waveform in memory, the second half was just the first half read out reversely and value-inverted.

Yamaha did something similar with the sine wave ROM. As it is easy to see, only a quarter, the first quadrant, of the sine wave needs to be stored. The remaining parts can be reconstructed by reversely reading and inverting as shown in the following table.

QuadrantDirectionPolarity
1+
2+
3-
4-

Direction reversal is just inverting the index pointer, polarity reversal inverts the read-out data. Both are easy enough to achieve in hardware, only requiring XOR gates for inversion.

This read-out process can be controlled easily by the phase index, which is dissected into the quadrant indicator (topmost two bits) and the index pointer (remaining bits). The quadrant indicator then drives direction and polarity control. In this very example, the topmost bit controls polarity, the following bit direction.

Achieving additional waves

Now the fun begins: The aformentioned configuration will, for instance, give a "spiked sine" by just flipping the playback directions compared to the sine-wave setup:

QuadrantDirectionPolarity
1+
2+
3-
4-

With the above scenario, we can also achieve something that almost resembles a saw wave:

QuadrantDirectionPolarity
1+
2-
3+
4-

Spotted the difference? While keeping the same playback setting as for the sine wave, now polarity control is different. This gives a full-swing almost-saw, just that the saw's slope is not straight.

With the following setting, we can achieve something similar, but now with only positive values:

QuadrantDirectionPolarity
1+
2+
3+
4+

As you probably noticed, the "saw wave" however is tuned one octave up, creating two full waves with each full playback cycle. Similarly, the "unipolar saw" example is even tuned up two octaves for outputting four full waves per cycle.

Luckily, this is easy enough to fix via the index pointer. To make it run slower by a factor of two, just disregard the lowest bit by right-shifting it. Similarly, for a factor of four, right-shift it twice, killing the lowest two bits.

This of course also works the other way round: If you want to make it faster, left-shift it and pad it with a right-most zero. That way you will lose resolution, but this does not matter as you need to skip every second sample anyway to play the sample twice in a time slot that was made for just one period. (This is, btw. how your favorite fixed-frequency sampler or sampling-based synth does octave switching.)

What we now have covered are waves like "half-sine", "double-half sine", "double-half positive followed by double-half negative" and the likes, just by messing around with read direction, polarity, and read-out speed.

What else can be done cheaply? You could either output or not depending on the quadrant control, like knocking off the wave's second half, replacing it by either -max, zero, or +max. This can be easily done on electrical level by gated drivers, not contributing much to the chip layout.

The SY77/99 operator waves

With the above tricks, we're set for waves 1,3,5, and 7. Also wave 13 can be achieved by creative segment playback and applying -max.

But what is it with wave 2 and derived ones?

If this waveform reminds you of sin2(x), you are absolutely right. Recreating this very waveform, i.e. sin2(x) from [0:π] and -sin2(x) from [π:2π], shows the desired spectrum.

But how do we get sin2(x)?

If you check the FM generator's internal structure (see here, for instance), you will notice that it operates in the log domain. Remember the

log operator * amplitude = log operator + log amplitude

from there? The same math of course works for the sine wave:

log sin2(x) = log sin(x) + log sin(x) = 2*log sin(x).

Selecting either the pure or squared sine wave is hence performing a simple left-shift on the result (or not). This could be done by a true shifter (which I doubt for this case) or selected by a simple XOR gate per result bit (or even easier by gating transistors).

Little extra effort, maximum effect.

Checking the waveforms' spectra (or the description thereof) makes it clear that they were selected for even/odd harmonic content and fall-off. They hence can help with crafting the desired spectrum by already providing some harmonic base set that otherwise would have required two or more operators plus feedback.

Following the wave numbering, there's a mild grouping visible that indicates an original coding which was seemingly altered in the course of selecting suitable waves:

  • Waves 1-8: the normal ones
    • With these, there is an (almost) uniform encoding: bit 0 activates squaring, bit 1 triggers half-wave operation, bit 2 the double mode.
      (Technically, wave 4 (0xb0011) should've been a positive half-wave squared zero-padded, but that probably was changed for not giving much extra with regard to the required harmonics.)
    • Waves 1,3,5,7 are alterations of the pure sine wave.
    • Waves 2,4,6,8 are — almost — the same, but based on the squared sine wave.
      Wave 4 obviously doesn't follow the encoding rule.

  • Waves 9-16: getting funky
    • Wave 10: like wave 11, but double-speed / zero-padded
    • Wave 11: Segments 1/4 are squared, 2/3 pure.
    • Wave 12: Segments 1/2 are pure, 3/4 squared
    • Wave 13: A double-speed sine, presumably reversed for the entire [π:2π] half, not just the last part, and clamped to -max for [3π/4:6π/4]
    • Wave 14: like wave 13, but for squared sine
    • Wave 15: like wave 13, but only segment 1 is pure, all the others squared
    • Wave 16: like wave 15, but the reversed part is switched back to pure sine