back to buchty.net Casiorama back to Casiorama

The filters Trying to reach me?
The FZ-1 filters are somewhat legendary. Not only, they were the almost first real DCFs employed in a commercially sold musical instrument, no, it's their very special, sometimes strange sound. Personally I think the FZ-1's DCF is one of the best distortion I've ever heard :) Suggestions, questions, acclamation, or simple curiosity about who that guy is you might want to place here:

rainer@buchty.net


Is it analog or digital?

Casio's DCFs seem to be some special beasts. Some sound designers claim they sound very analog, and, given the fact that they indeed have analog in- and outputs, believe that it is a truly analog filter. An additional point usually is that the filters have true resonance control -- a feature unseen in commercial synthesizers' digital filters until the late 1980s.

However, looking closer (see pinout below) reveals a clock input which is a good indication that something time-discrete is going on and we are definitely not dealing with your average transistor ladder or OTA-based filter.

A quick patent search reveals several interesting Casio patents on digital filters dating back to the early 1980s, also digital filters with resonance control pop up, for instance Patent 4,467,440. What we basically see here is indeed an IIR (Infinite Impulse Response) filter, although by the way described it looks like only the control is truly digital while anything else, i.e. summing, multiplication, and also storing the time-discrete signals is performed in the analog domain using ordinary adders, multipliers, and S&H stages.This would explain why this filter is perceived "analog" and exhibits a saturation behavior like conventional analog filters, while internally being digital (i.e. time-discrete) by nature.

In other words, the FZ-1's filter is a so-called switched-capacitor filter. As such, it is time-discrete, but continuous-valued. Your favorite BBD-based effects box from the late 1970s and early 1980s works similarly, just that there the capacitor / delay line is set up as an allpass filter.

(If you're interested in what makes analog filters sound the way they do and how this can be achieved in software, have a look at Oscillator and Filter Algorithms for Virtual Analog Synthesis by Vesa Välimäki and Antti Huovilainen. The same authors also published some interesting papers on the DAFX conference series.)


Programming the DCF
The Casio DCFs differ a bit from ordinary VCF/VCA combinations, most notably offering two channels instead of just one and featuring a digital interface. The DCF chip is controlled by the following signals:

SignalTask
CHS Channel Select
A high level designates channel 1, a low level channel 0 respectively.
F/A# Filter/Amplifier selection
When this signal is high, data on data bus becomes DCF control data, otherwise amplitude control data.
FC/Q# Cutoff frequency / Resonance selection
This signal is paired with F/A#. At F/A#=1, it selects either cutoff frequency (1) or resonance (0), otherwise gain (1) or volume (0).

This looks somewhat confusing at first, so let's see how it is set up in the FZ-1. With A5=F/A#, A4=FC/Q and A[3:1] for channel selection based on CHS and two additional address signals, we get the following address layout in I/O memory space:

  • 0x80-0x8e: DCA volume
  • 0x90-0x9e: DCA gain
  • 0xa0-0xae: DCF frequency
  • 0xb0-0xbe: DCF resonance
Resulting, each section features eight audio channels available on even addresses. (It's an 8086-based platform after all ...)

Unfortunately, programming information is scarce and has to be extracted from the FZ-1 OS. Right now, the following is known:

  • Filter frequency is applied as an 8-bit quantity D[7:0]. Not great, but it was more or less the standard back then. Also analog machines often enough only used an 8-bit DAC for frequency control. No specific scaling is applied, but from occasional known values it can be deduced that the linear input data is internally transformed into an exponential control value: the init value is 0x9f (159), and for sampling we have either 0x7c (124; 9kHz) or 0x6c (108; 4.5kHz) applied. Judging from the service manual, 0x00 means 20Hz and 159 equals 20kHz.

    After playing around with some regression solvers / function approximators over these points, I'd say it's somewhat safe to assume that piecewise linear approximation is close enough, i.e. the range 0-108 has steps of 41.48Hz, 108-124 281.25Hz steps, and 124-159 finally 314.29Hz.

    If we consider 159 as 18kHz and 255 as 20kHz, it turns out even nicer with a more or less uniform stepping beween 108 and 159, and 160-255 again equalling the step size of 0-108. Assuming, of course, that the range 160-255 is valid at all.

    The programming documentation claims that the filter is "fully open" at 127 -- which would mean about 10kHz by above calculation.

  • Resonance is a 5-bit quantity D[4:0]. It's computed as an 8-bit quantity, but then the lowest 3 bits are thrown away. Considering that resonance control is typically linear, it's probably safe to assume that they linearly map the range of 0.71 to 10.9, as given in the service manual.

  • Volume again is an 8-bit quantity, whereas gain is only 4 steps and hence a 2-bit quantity D[1:0] -- and not D[7:6] as stated in available documentation). The below code gives some insight on calculating the 10-bit gain/volume value from the 8-bit volume generated by synthesis and the (7-bit) master volume.

uint8_t offs, volume, master_volume;
int16_t expo;
uint16_t dca;

// convert linear volume to exponential one
offs=0xff-volume;
expo=0x7fff-tab_exp[offs&0xfe];

// factor in master volume
offs=(~master_volume)&0x7f;
expo-=tab_exp[offs<<1];

// avoid underrun
// expo in [0000:7fff]
if (expo<0) expo=0x00;

// rescale
// expo in [0000:fff8]
expo<<=1;

// convert to 8-bit quantity
// dca in [00:ff]
dca=(expo>>8)&0xff;

// adjust to gain/volume
// low-gain [0xe0:0x17f]
// high-gain [0x180:0x37f] via tab_exp2
// bits 9/8: gain
// bits 7-0: volume
if(dca<=0x9f)
    dca+=0xe0;
else
{
     dca-=0xa0;
     dca=tab_exp2(dca<<1);
}

You find both tables in the FZ-1's OS ROM at the following offsets:

  • tab_exp at offset 0x490, featuring 128 16-bit entries ranging 0x0000 to 0x7fff.
  • tab_exp2 at offset 0x590, featuring 96 16-bit entries ranging 0x180 to 0x37f.

Caveat 1: For whatever reason it seemingly is not advised to go from "high gain" directly to "low gain" settings. With gain/volume settings of 0x180 and above, these need to be reduced step 4 until the "low gain" domain is reached, cf. OS function #52 generator off.

Caveat 2: When initializing the filter, don't just open it, but "sweep" it open, cf. OS function #13 note on. To do this, apply the sequence 0x3f/0x5f/0x7f/0x9f to the frequency setting and for each of the aforementioned values sweep down resonance by applying 0x0f/0x0d/0x0b/0x00 to it.

Caveat 3: A gain/volume value of 0x0df seemingly equals "silence", as this triggers Function 042 "generator off" in the timer IRQ handler which, among other tasks, triggers synthesis.

Fun fact: There's another FZ-1 OS bug, this time in filter modulation: Probably nobody ever noticed, but you can set the DCF modwheel modulation amount to whatever value you want, it'll be disregarded -- because the OS wrongly uses the DCA modwheel modulation amount instead. I think I need to fix that some day, and leave this here as a reminder to myself.


Pinout

Pin Terminal Direction Function
1-8 D0-D7 in Input data
9 WR# in Write enable
10 CE# in Chip enable
11 CHS in Channel selection
12 F/A# in Filter/Amplifier selection
13 FC/Q# in Frequency/Q selection
14 DGND power Digital ground
15-17 unused n.c.  
18 OSC in 3.58MHz clock pulse for internal operation (rising edge)
19 RESET# in Resets the chip, setting default values (FC=20Hz, Q=0.71, Gain=-∞)
20 VSS power -5V source
21 AI2 in Source signal for audio channel 2
22 PD# in Power down control (not used in FZ-1 thus tied to VDD)
23 AO2 out Filtered and amplified sound output of channel 2
24 AGND power Analog ground
25 AO1 out Filtered and amplified sound output of channel 1
26 TC# in Test circuit (not used in FZ-1 thus tied to VDD)
27 AI1 in Source signal for audio channel 1
28 VDD power +5V source