Created
October 31, 2014 13:19
-
-
Save usysrc/796fb490776e2d6d95b3 to your computer and use it in GitHub Desktop.
The Ad Lib Music Synthesizer Card, P R O G R A M M I N G G U I D E, Written by Tero Töttö
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
┌──────────────────────────────────────────────────────────────────────────────┐ | |
│ │ | |
│ The Ad Lib Music Synthesizer Card │ | |
│ │ | |
│ P R O G R A M M I N G G U I D E │ | |
│ │ | |
│ │ | |
│ Written by Tero Töttö │ | |
│ │ | |
└──────────────────────────────────────────────────────────────────────────────┘ | |
CHAPTER 1: DESCRIPTION OF THE SYNTHESIZER 1 | |
Operators 1 | |
Operating Modes 1 | |
Melodic and Percussive Mode 2 | |
CHAPTER 2: PROGRAMMING THE SYNTHESIZER 3 | |
Card location in I/O channel 3 | |
Card addresses 3 | |
CHAPTER 3: ALMSC REGISTER MAP 4 | |
Status Register 4 | |
Write registers 4 | |
Operator offsets 4 | |
Channel formation 5 | |
CHAPTER 4: ALMSC REGISTER REFERENCE 6 | |
Status Register 6 | |
Registers 01h - 04h 6 | |
Registers 08h - 55h 7 | |
Registers 60h - BDh 8 | |
Registers C0h - F5h 9 | |
APPENDIX A: INSTRUMENT BANK (.BNK) FILE STRUCTURE 10 | |
APPENDIX B: NOTE FREQUENCIES 11 | |
DISCLAIMER: IN NO EVENT WILL I BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING | |
ANY LOST OF PROFITS, LOST SAVINGS OR OTHER INCIDENTIAL OR | |
CONSEQUENTIAL DAMAGES ARISING OUT OF YOUR USE OR INABILITY TO | |
USE THIS MANUAL, OR FOR ANY OTHER CLAIM BY ANY OTHER PARTY. | |
TRADEMARKS: Ad Lib is registered trademark of Ad Lib Inc. | |
COPYRIGHT: This manual can be distributed freely if not modified. | |
DESCRIPTION OF THE SYNTHESIZER (1) | |
────────────────────────────── | |
Ad Lib Synthesizer is made up of oscillators and envelope generators. An | |
oscillator, an envelope generator, and a level controller are linked together | |
to form an "operator": | |
┌────────────┐ ┌────────────────────┐ ┌──────────────────┐ | |
│ Oscillator ├─>│ Envelope Generator ├─>│ Level Controller ├──> OUTPUT | |
└────────────┘ └────────────────────┘ └──────────────────┘ | |
The Ad Lib Music Synthesizer card (ALMSC) contains 18 operators which are | |
generally grouped into pairs in order to produce instrumental sounds. The | |
operators can be combined in three different ways: | |
* FM synthesis uses two operators in series. The first operator, | |
the modulator, modulates the second operator, the carrier, via | |
its modulation data input. | |
┌─────────────┐ ┌─────────────┐ | |
Frequency │ Operator │ │ Operator │ | |
Modulation │ 1. ├─>│ 2. ├─> SPEAKER | |
synthesis │ (Modulator) │ │ (Carrier) │ | |
└─────────────┘ └─────────────┘ | |
* Additive synthesis uses two operators in parallel, adding both | |
outputs together. This method of synthesis is not as interesting | |
as FM synthesis, but it can generate good organ-type sounds. | |
┌─────────────┐ | |
│ Operator │ | |
│ 1. ├──┐ | |
│ │ │ | |
Additive └─────────────┘ │ | |
synthesis ├─> SPEAKER | |
┌─────────────┐ │ | |
│ Operator │ │ | |
│ 2. ├──┘ | |
│ │ | |
└─────────────┘ | |
* Composite sine wave synthesis (CSW) may be used to generate speech | |
or other related sounds by playing all 9 voices simultaneously. When | |
using this method, the card cannot generate any other sounds. This | |
mode is not explained here, because other methods have proved to | |
provide better quality speech. | |
The ALMSC produces either 9 melodic sounds or 6 melodic sounds and 5 (2) | |
percussion instruments. For the 9 melodic sounds, the operators are | |
grouped in pairs. For the percussion mode, the opearators are arranged | |
as follows: | |
* 6 melodic instruments (12 operators) | |
* 1 Bass Drum (2 operators) | |
* 1 Snare Drum (1 operator) | |
* 1 Tom-Tom (1 operator) | |
* 1 Cymbal (1 operator) | |
* 1 Hi-Hat (1 operator) | |
Because ALMSC has only 9 registers for frequency information (one for | |
each melodic channel), Cymbal and Hi-Hat pitches are fixed. | |
In percussion mode, a white noise generator is used to create rhythm sounds. | |
This white noise generator uses voices 7 and 8 (Snare Drum and Tom-Tom) | |
frequency information (Block, Frequency Number, Multiplication), and the proper | |
phase output. Various rhythm sounds are produced by combining this output signal | |
with white noise. The result is then sent to the operators. Best ratio for the | |
two frequencies is 3:1 (Snare Drum frequency = 3 * Tom-Tom frequency). Finally, | |
envelope information is multiplied with the wave table output. As the envelope | |
is set for one operator which corresponds to a single rhythm instrument, the | |
values are set in the parameter registers in the same manner as for melodic | |
instruments. | |
PROGRAMMING THE SYNTHESIZER (3) | |
─────────────────────────── | |
The ALMSC may be located at four different addresses: | |
218h , 288h , 318h , 388h | |
The port address is currently hard-wired to 388h, but jumpers may be added in | |
the future, so you should take into account the possibility of using different | |
addresses when programming. Later on this manual, I will refer only to the | |
address 388h. | |
The card decodes two addresses: | |
388h - Index register (write), Status register (read) | |
389h - Data register (write only) | |
The index register is used to select the register address, and then data is | |
written to data register. Status register returns the state of two timers on | |
the card. | |
Because of the nature of the card, you must wait 3.3 μsec after a register | |
select write, and 23 μsec after a data write. Best way to handle this is to read | |
ALMSC status register in loop, because bus speed is always the same regardless | |
of processor speed. 6 reads after register select write and 36 reads after data | |
write should do the job. | |
ALMSC REGISTER MAP: (4) | |
─────────────────── | |
Status Register (388h): | |
┌───────────────────────────────────────────────────────────────────────┐ | |
│ D7 D6 D5 D4 D3 D2 D1 D0 │ | |
├────────┼────────┼────────┼────────┴────────┴────────┴────────┴────────┤ | |
│IRQFlag │ T1Flag │ T2Flag │ │ | |
└────────┴────────┴────────┴────────────────────────────────────────────┘ | |
Write Registers (389h): | |
┌─────┬───────────────────────────────────────────────────────────────────────┐ | |
│ REG │ D7 D6 D5 D4 D3 D2 D1 D0 │ | |
├─────┼────────┴────────┼────────┼────────┴────────┴────────┴────────┴────────┤ | |
│ 01 │ │WSEnable│ Test Register │ | |
├─────┼─────────────────┴────────┴────────────────────────────────────────────┤ | |
│ 02 │ Timer 1 Count (80 μsec resolution) │ | |
├─────┼───────────────────────────────────────────────────────────────────────┤ | |
│ 03 │ Timer 2 Count (320 μsec resolution) │ | |
├─────┼────────┬────────┬────────┬──────────────────────────┬────────┬────────┤ | |
│ 04 │IRQReset│ T1Mask │ T2Mask │ │T2 Start│T1 Start│ | |
├─────┼────────┼────────┼────────┴──────────────────────────┴────────┴────────┤ | |
│ 08 │ CSW │NOTE-SEL│ │ | |
├─────┼────────┼────────┼────────┬────────┬───────────────────────────────────┤ | |
│20-35│Tremolo │Vibrato │Sustain │ KSR │ Frequency Multiplication Factor │ | |
├─────┼────────┴────────┼────────┴────────┴───────────────────────────────────┤ | |
│40-55│ Key Scale Level │ Output Level │ | |
├─────┼─────────────────┴─────────────────┬───────────────────────────────────┤ | |
│60-75│ Attack Rate │ Decay Rate │ | |
├─────┼───────────────────────────────────┼───────────────────────────────────┤ | |
│80-95│ Sustain Level │ Release Rate │ | |
├─────┼───────────────────────────────────┴───────────────────────────────────┤ | |
│A0-A8│ Frequency Number ( Lower 8 bits ) │ | |
├─────┼─────────────────┬────────┬──────────────────────────┬─────────────────┤ | |
│B0-B8│ │ KEY-ON │ Block Number │ F-Num (hi bits) │ | |
├─────┼────────┬────────┼────────┼────────┬────────┬────────┼────────┬────────┤ | |
│ BD │Trem Dep│Vibr Dep│PercMode│ BD On │ SD On │ TT On │ CY On │ HH On │ | |
├─────┼────────┴────────┴────────┴────────┼────────┴────────┴────────┼────────┤ | |
│C0-C8│ │FeedBack Modulation Factor│Additive│ | |
├─────┼───────────────────────────────────┴─────────────────┬────────┴────────┤ | |
│E0-F5│ │ Waveform Select │ | |
└─────┴─────────────────────────────────────────────────────┴─────────────────┘ | |
For some of the parameters, there is one register per output channel. For those | |
parameters, channel number can be used as an offset into the map. For many | |
parameters, there is one register per operator. However, there are holes in the | |
address map so that in this case, the operator number CANNOT be used as an | |
offset. The operator offsets for those registers are (in hex form): | |
┌─────┬────────────────────────────────────────────────────────────────────────┐ | |
│ OPR │ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 │ | |
├─────┼────────────────────────────────────────────────────────────────────────┤ | |
│ OFS │ 00 01 02 03 04 05 08 09 0A 0B 0C 0D 10 11 12 13 14 15 │ | |
└─────┴────────────────────────────────────────────────────────────────────────┘ | |
The next two tables illustrates which operators together form a channel: (5) | |
┌───────────────────────────────────────────────────┐ | |
│ M E L O D I C M O D E │ | |
├──────┬────┬────┬────┬────┬────┬────┬────┬────┬────┤ | |
│ CHAN │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ | |
├──────┼────┼────┼────┼────┼────┼────┼────┼────┼────┤ | |
│ OPR1 │ 1 │ 2 │ 3 │ 7 │ 8 │ 9 │ 13 │ 14 │ 15 │ | |
│ OPR2 │ 4 │ 5 │ 6 │ 10 │ 11 │ 12 │ 16 │ 17 │ 18 │ | |
└──────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ | |
┌─────────────────────────────────────────────────────────────┐ | |
│ P E R C U S S I O N M O D E │ | |
├──────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┤ | |
│ CHAN │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ BD │ SD │ TT │ CY │ HH │ | |
├──────┼────┼────┼────┼────┼────┼────┼────┼────┼────┼────┼────┤ | |
│ OPR1 │ 1 │ 2 │ 3 │ 7 │ 8 │ 9 │ 13 │ 17 │ 15 │ 18 │ 14 │ | |
│ OPR2 │ 4 │ 5 │ 6 │ 10 │ 11 │ 12 │ 16 │ │ │ │ │ | |
└──────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘ | |
ALMSC REGISTER REFERENCE: (6) | |
───────────────────────── | |
Status Register: | |
D7 IRQ Flag. Set if D5 and/or D6 are/is set. | |
D6 Timer 1 Flag. Set when the preset time in Timer 1 has elapsed. | |
D5 Timer 2 Flag. Set when the preset time in Timer 2 has elapsed. | |
Timer interrupts are not wired, but the timers can be used to detect | |
the presence of the card as follows: | |
1. Reset T1 and T2: write 60h to register 4. | |
2. Reset the IRQ: write 80h to register 4. | |
3. Read status register: read at 388h. Save the result. | |
4. Set timer 1 to FFh: write FFh to register 2. | |
5. Unmask and start timer 1: write 21h to register 4. | |
6. Wait in a delay loop for at least 80 μsec. | |
7. Read status register: read at 388h. Save the result. | |
8. Reset T1,T2 and IRQ as in steps 1 and 2. | |
9. Test the results of the two reads: the first should | |
be 0, the second should be C0h. If either is incorrect, | |
then the ALMSC is not presents. | |
NOTE1: You should AND the result bytes with E0h because | |
the unused bits are undefined. | |
NOTE2: This testing method doesn't work in SoundBlaster. | |
01: Test Register / WSE: | |
D5 Waveform Select Enable. If clear, all channels will use normal | |
sine wave. If set, register E0-F5 (WS) contents will be used. | |
D4-D0 Test Register, must be reset to zero before any operation. | |
02: Timer 1 Count: | |
Upward 8 bit counter with a resolution of 80 μsec. If an overflow | |
occurs, the status register bit is set, and the preset value is | |
loaded into the timer again. | |
03: Timer 2 Count: | |
Same as Timer 1, but with a resolution of 320 μsec. | |
04: IRQ-Reset / Mask / Start: | |
D7 IRQ-Reset. Resets timer and IRQ flags in status register. | |
All other bits are ignored when this bit is set. | |
D6 Timer 1 Mask. If 1, status register is not affected in overflow. | |
D5 Timer 2 Mask. Same as above. | |
D1 Timer 2 Start. Timer on/off. | |
D0 Timer 1 Start. Same as above. | |
08: CSW / NOTE-SEL: (7) | |
D7 Composite sine wave mode on/off. | |
D6 NOTE-SEL. Controls the split point of the keyboard. When 0, the | |
keyboard split is the second bit from the bit 8 of the F-Number. | |
When 1, the MSb of the F-Number is used. | |
20-35: Tremolo / Vibrato / Sustain / KSR / Frequency Multiplication Factor: | |
D7 Tremolo (Amplitude vibrato) on/off. | |
D6 Frequency vibrato on/off. | |
D5 Sound Sustaining. When 1, operator's frequency will be held at | |
its sustain level until a KEY-OFF is done. | |
D4 Envelope scaling (KSR) on/off. When 1, higher notes are shorter | |
than lower notes. | |
D3-D0 Frequency Multiplication Factor (MULTI): | |
┌───────┬────────┐ | |
│ MULTI │ Factor │ | |
├───────┼────────┤ | |
│ 0 │ ½ │ | |
│ 1 │ 1 │ | |
│ 2 │ 2 │ | |
│ 3 │ 3 │ | |
│ 4 │ 4 │ | |
│ 5 │ 5 │ | |
│ 6 │ 6 │ | |
│ 7 │ 7 │ | |
│ 8 │ 8 │ | |
│ 9 │ 9 │ | |
│ 10 │ 10 │ | |
│ 11 │ 10 │ | |
│ 12 │ 12 │ | |
│ 13 │ 12 │ | |
│ 14 │ 15 │ | |
│ 15 │ 15 │ | |
└───────┴────────┘ | |
40-55: Key Scale Level / Output Level: | |
D7-D6 Key Scale Level. Attenuates output level towards higher pitch: | |
┌─────┬─────────────┐ | |
│ KSL │ Attenuation │ | |
├─────┼─────────────┤ | |
│ 0 │ - │ | |
│ 1 │ 1.5 dB/oct │ | |
│ 2 │ 3.0 dB/oct │ | |
│ 3 │ 6.0 dB/oct │ | |
└─────┴─────────────┘ | |
D5-D0 Output Level. Attenuates the operators output level. In additive | |
synthesis, varying the output level of any operator varies the | |
volume of its corresponding channel. In FM synthesis, varying | |
the output level of the carrier varies the volume of the channel. | |
Varying the output of then modulator will change the frequency | |
spectrum produced by the carrier. | |
60-75: Attack Rate / Decay Rate: (8) | |
D7-D4 Attack Rate. Determines the rising time for the sound. The | |
higher the value, the faster the attack. | |
D3-D0 Decay Rate. Determines the diminishing time for the sound. | |
The higher the value, the shorter the decay. | |
80-95: Sustain Level / Release Rate: | |
D7-D4 Sustain Level. Determines the point at which the sound ceases | |
to decay and chages to a sound having a constant level. The | |
sustain level is expressed as a fraction of the maximum level. | |
Note that the Sustain-bit in the register 20-35 must be set for | |
this to have an effect. | |
D3-D0 Release Rate. Determines the rate at which the sound disappears | |
after KEY-OFF. The higher the value, the shorter the release. | |
A0-A8: Frequency Number: | |
Determines the pitch of the note. Highest bits of F-Number are stored | |
in the register below. | |
B0-B8: Key On / Block Number / F-Num(hi bits): | |
D5 KEY-ON. When 1, channels output is enabled. | |
D4-D2 Block Number. Roughly determines the octave. | |
D1-D0 Frequency Number. 2 highest bits of the above register. | |
The following formula is used to determine F-Number and Block: | |
F-Num = Music Frequency * 2^(20-Block) / 49716 Hz | |
BD: Trem Dep / Vibr Dep / PercMode / BD/SD/TT/CY/HH On: | |
D7 Tremolo (Amplitude Vibrato) Depth. 0 = 1.0dB, 1 = 4.8dB. | |
D6 Frequency Vibrato Depth. 0 = 7 cents, 1 = 14 cents. | |
A "cent" is 1/100 of a semi-tone. | |
D5 Percussion Mode. 0 = Melodic Mode, 1 = Percussion Mode. | |
D4 BD On. KEY-ON of the Bass Drum channel. | |
D3 SD On. KEY-ON of the Snare Drum channel. | |
D2 TT On. KEY-ON of the Tom-Tom channel. | |
D1 CY On. KEY-ON of the Cymbal channel. | |
D0 HH On. KEY-ON of the Hi-Hat channel. | |
C0-C8: FeedBack Modulation Factor / Additive: (9) | |
D3-D1 FeedBack Modulation Factor: | |
┌───────┬────────┐ | |
│ MULTI │ Factor │ | |
├───────┼────────┤ | |
│ 0 │ 0 │ | |
│ 1 │ π/16 │ | |
│ 2 │ π/8 │ | |
│ 3 │ π/4 │ | |
│ 4 │ π/2 │ | |
│ 5 │ π │ | |
│ 6 │ 2∙π │ | |
│ 7 │ 4∙π │ | |
└───────┴────────┘ | |
D0 Additive. 1 = Additive synthesis, 0 = Frequency Modulation | |
E0-F5: Waveform Select: | |
D7-D2 Not used | |
D1-D0 WaveForm Select (WS): | |
┌────┬────────────┐ | |
│ WS │ WaveForm │ | |
├────┼────────────┤ | |
│ 00 │ Sine │ | |
│ 01 │ Half-Sine │ | |
│ 10 │ Abs-Sine │ | |
│ 11 │ Pulse-Sine │ | |
└────┴────────────┘ | |
APPENDIX A: INSTRUMENT BANK (.BNK) FILE STRUCTURE (10) | |
───────────────────────────────────────────────── | |
Field Size Type Description | |
─────────────────────────────────────────────────────────────────────────────── | |
HEADER SECTION | |
1 1 byte file version, major | |
2 1 byte file version, minor | |
3 6 byte signature: "ADLIB-" | |
4 2 integer number of list entries used | |
5 2 integer total number of list entries in file | |
6 4 longint absolute offset in file of start of name list | |
7 4 longint absolute offset in file of start of data | |
8 8 byte pad (set to zero) | |
INSTRUMENT NAME SECTION RECORD | |
1 2 integer index into data section | |
2 1 byte flag: 0 if record used, else 1 | |
3 9 byte instrument name (max 8 chars + NULL) | |
DATA SECTION RECORD | |
1 1 byte mode (0=melodic,1=percussion) | |
2 1 byte voice number (if percussion mode) | |
modulator (operator 0) parameters: | |
3 1 byte key scale level | |
4 1 byte frequency multiplier | |
5 1 byte feedback modulation factor | |
6 1 byte attack rate | |
7 1 byte sustain level | |
8 1 byte sound sustaining | |
9 1 byte dacay rate | |
10 1 byte release rate | |
11 1 byte output level | |
12 1 byte amplitude vibrato (tremolo) | |
13 1 byte frequency vibrato | |
14 1 byte envelope scaling | |
15 1 byte 0=FM synthesis, 1=additive synthesis | |
carrier (operator 1) parameters (for melodic channels and bassdrum only): | |
3 1 byte key scale level | |
4 1 byte frequency multiplier | |
5 1 byte feedback modulation factor | |
6 1 byte attack rate | |
7 1 byte sustain level | |
8 1 byte sound sustaining | |
9 1 byte dacay rate | |
10 1 byte release rate | |
11 1 byte output level | |
12 1 byte amplitude vibrato (tremolo) | |
13 1 byte frequency vibrato | |
14 1 byte envelope scaling | |
15 1 byte unused | |
29 1 byte waveform for modulator | |
30 1 byte waveform for carrier | |
APPENDIX B: NOTE FREQUENCIES (11) | |
──────────────────────────── | |
The following table contains frequencies in Hertz for the notes in octaves | |
1 to 8. Middle C is in octave 5. | |
┌──────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐ | |
│ NOTE │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ | |
├──────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤ | |
│ C │ 16.352 │ 32.703 │ 65.406 │ 130.81 │*261.63*│ 523.25 │ 1046.5 │ 2093.0 │ | |
│ C# │ 17.324 │ 34.648 │ 69.295 │ 138.59 │ 277.18 │ 554.37 │ 1108.7 │ 2217.5 │ | |
│ D │ 18.354 │ 36.708 │ 73.416 │ 146.83 │ 293.66 │ 587.33 │ 1174.7 │ 2349.3 │ | |
│ D# │ 19.445 │ 38.890 │ 77.781 │ 155.56 │ 311.13 │ 622.25 │ 1244.5 │ 2489.0 │ | |
│ E │ 20.601 │ 41.203 │ 82.406 │ 164.81 │ 329.63 │ 659.26 │ 1318.5 │ 2637.0 │ | |
│ F │ 21.826 │ 43.653 │ 87.307 │ 174.61 │ 349.23 │ 698.46 │ 1396.9 │ 2793.8 │ | |
│ F# │ 23.124 │ 46.249 │ 92.499 │ 184.99 │ 369.99 │ 739.99 │ 1480.0 │ 2960.0 │ | |
│ G │ 24.499 │ 48.999 │ 97.998 │ 195.99 │ 391.99 │ 783.99 │ 1568.0 │ 3136.0 │ | |
│ G# │ 25.956 │ 51.913 │ 103.82 │ 207.65 │ 415.31 │ 830.61 │ 1661.2 │ 3322.4 │ | |
│ A │ 27.500 │ 55.000 │ 110.00 │ 220.00 │ 440.00 │ 880.00 │ 1760.0 │ 3520.0 │ | |
│ A# │ 29.135 │ 58.270 │ 116.54 │ 233.08 │ 466.16 │ 932.32 │ 1864.7 │ 3729.3 │ | |
│ B │ 30.867 │ 61.735 │ 123.47 │ 246.94 │ 493.88 │ 987.77 │ 1975.5 │ 3951.1 │ | |
└──────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment