@UltraSound HPC-HelpKit v0.85áeta :GUS HelpKit:HPC-Kit About ^Gravis UltraSound HPC-HelpKit version 0.85áeta ^by Condor/Accession,BloodBrothers! %About This HelpKit is made for only those, who program Gravis Ultrasound at the lowest possible level. So I haven't included any C or Pascal codes, only assembler and pseudo code is used in exampled. Also, I haven't included any function descriptions from GUS SDK Lowlevel programmer's kit. If you want them, I don't give a shit. %NOTE This HelpKit is combined from various sources(see below). So any misinformation is NOT my fault. For more information about programming GUS, read these documents. %Credits I can't take much credits from this HelpKit, because I have only converted texts to HelpPC format. Also additional editing was required. (see above) But here are the persons, whose texts I have included to this HelpKit: Kurt Kennett and Mike Travers (GUS SDK 2.10) Tran/Renaissance and Joshua Jensen (UltraDOX 1.0) Tran and Cyberstrike of Renaissance (UltraDOX 2.0) ? (GUS SDK 2.20) Thunder (MODFIL v1.0) Lars "ZAP" Hamre/Amiga Freelancers (Protracker 1.1B Mod Format) Freejack of Elven Nation (ULT File Format) ? (S3M and STM File Format) %History % Version 0.85áeta - ULT, S3M and STM File format added to HelpKit - i'm tired of these minor fixes to indexes, but if you notice bugs on them, please let me know. % Version 0.80 - MODFIL10.TXT added to HelpKit - Protracker 1.1b Module Format added to HelpKit - and more minor fixes to indexes % Version 0.70 - Information from GUS SDK 2.20 added to HelpKit - more minor fixes to indexes % Version 0.60 - UltraDOX added to HelpKit - some minor fixes to indexes % Version 0.50 - GUS SDK 2.10 added to HelpKit % How to contact me Well, from these boards you can contact me: Metropoli +358-(9)0-615 00029 (you can also connect via internet to here) The DarkSide +358-(9)0-294 0467 or +358-(9)0-294 1594 Xception 13 (not opened yet) Mika Mannermaa alias Condor/Accession, BloodBrothers! :1_HPC_MAIN_ ^Gravis UltraSound HPC-HelpKit version 0.85áeta ^by Condor/Accession,BloodBrothers! ^MAIN MENU ~HPC-Kit About~ - Information about GUS HPC-HelpKit % Port Information ~GUS Port Map~ - All ports of Gravis Ultrasound card ~Global registers~ - Voice independent registers ~Voice registers~ - Voice specific registers ~Revision Level~ - Port where to check GUS Revision level ~UltraMAX Control~ - Control port of UltraMAX % General Information ~GF1~ - Information about GF1 ~Mixer~ - Info about mixer (Rev. 3.7+) ~Codec~ - Info about codec functions (Rev 3.7+) ~MIDI Interface~ - Information about GUS MIDI Interface ~Freq calculation~ - How to calculate output frequency ~U_Freq calculation~ - Same as above,but more programming info ~U_DRAM Addressing~ - Info about GUS DRAM addressing ~U_Poke DRAM~ - How to poke/peek data to/from GUS DRAM? ~U_Probe~ - How to autodetect GUS? ~U_Memory amount~ - How to autodetect memory amount of GUS? ~U_UltraReset~ - Example code to reset GUS ~Volume ramping~ - How GUS Volume ramping works? ~Ultra clicks~ - Tips for removing ultraclicks(tm) ~Rollover~ - Tips for using the rollover feature of samples ~Patch file format~ - File format of Ultrasound Patches ~Modulation tables~ - Tables for GUS Patch file format % Module Player Information ~Module Player~ - Main menu of Module Player section ~M_FileFormat~ - MOD File format ~M_ProFile~ - Protracker 1.1b MOD Format ~M_S3M File Format~ - S3M and STM File Format ~M_ULT File Format~ - ULT File Format ~M_EffectList~ - List of standard effects :Freq calculation:GF1:Frequency ^Calculating the Frequency - GF1 %Information about GF1 The GF1 is basically a pipeline processor. It constantly loops from voice #0 to the end of the active voices (how to define the number of active voices is shown later). Every 1.6 microseconds, the GF1 performs a series of operations on a particular voice. The more active voices there are, the longer it takes between each time a particular voice is serviced. This puts a limit on the rate at which playback can occur. 14 active voices will allow a maximum of 44.1 kHz playback. 28 voices will allow 22 kHz. %The formula for calculating the playback rate is: % Frequency Active Voices Frequency Active Voices 44100 14 25725 24 41160 15 24696 25 38587 16 23746 26 36317 17 22866 27 34300 18 22050 28 32494 19 21289 29 30870 20 20580 30 29400 21 19916 31 28063 22 19293 32 26843 23 This table is calculated by knowing that 14 active voices will give exactly 44.1 kHz playback. Therefore, the voice servicing rate 'X' can be calculated from: 1,000,000 / (X * 14) = 44100 Hz X = 1.619695497 microseconds Once X is known, the frequency 'divisor' is calculated by: divisor = 1,000,000 / (1.619695497 * # of active voices) A frequency 'counter' is used to calculate how often a voice is updated by the GF1. To calculate an FC (frequency counter) for any given frequency with a particular # of active voices, run it through this formula: %C: fc = (unsigned int)(((speed_khz<<9L)+(divisor>>1L)) / divisor); fc = fc << 1; The left shift is needed since the FC is in bits 15-1. This value is then put in the frequency control register for that particular voice. Remember that the GF1 works on a voice every 1.6 microseconds. This means that the fewer voices, the faster each voice gets updated. The frequency control register setting for the voice MUST take this into account. The FC must get smaller if the number of active voices gets smaller. This will increase the number of points created between the actual data points so the perceived playback speed remains the same. See also: ~Sampling Control~,~U_Freq calculation~ :MIDI Interface ^MIDI Interface The MIDI 101 interface consists of standard UART functionality - Motorola MC68C50. An interrupt to the PC can be generated for each byte of MIDI data received or transmitted. This hardware is independent of any of the other hardware. The main MIDI circuitry is included in the GF1 processor, but external to the chip is an optical isolator that is used on the serial input data and an open collector driver that is used for the serial output. In addition, external logic is included on board to loop back transmit data to the receive data under software control. The serial interface has a fixed configuration with no programmable options, as in the MC6850. A control register is used to enable and disable the interrupt generation logic. A status register is used to determine if the transmit or receive register is interrupting. A read or write to the data register clears the interrupt status. %The specifications for the interface are: 31.25 kHz +- 1% asynchronous 1 start bit 8 data bits 1 stop bit The MIDI signals are available on the 15 pin D connector used for the joystick. An external cable assembly containing the optical isolator and driver is required to use the MIDI interface. :GUS Port Map ^GUS I/O Port Map The following describes I/O address map used on the board. The 'X' is defined by the jumper settings on the UltraSound and should match that specified in the ULTRASND environment variable. % INTERFACE I/O,MEM, R,W ADDRESS % INT,DMA HEX ------------------------------------------------------------ UltraSound Base Port: --- -- 2X0 % MIDI Interface: ~MIDI Control~ I/O W 3X0 ~MIDI Status~ I/O R 3X0 Transmit Data I/O W 3X1 Receive Data I/O R 3X1 Joystick Interface: Trigger Timer I/O W 201 Read Data I/O R 201 % GF1 Synthesizer: GF1 ~Page Register~ I/O R/W 3X2 GF1/Global ~Select Register~ I/O R/W 3X3 GF1/~Global Data~ Low Byte I/O R,W 3X4 GF1/Global Data High Byte I/O R/W 3X5 ~IRQ Status~ Register 1=ACTIVE I/O R 2X6 ~Timer Control port~ I/O R/W 2X8 ~Timer Data~ I/O W 2X9 ~DRAM I/O~ I/O R,W 3X7 DRAM DMA R,W 1,3,5,6,7 Record Digital Audio DMA R 1,3,5,6,7 BOARD ONLY ~Mix Control~ register I/O W 2X0 ~IRQ Control~ register I/O W 2XB (2X0- bit 6 = 1) ~DMA Control~ register I/O W 2XB (2X0- bit 6 = 0) ~Register Control~ I/O R/W 2XF (Rev 3.4+) ~Board Version~ I/O R 7X6 (Rev 3.7+) ~Mixer~ Control Control Port I/O W 7X6 (Rev 3.7+) Data Port I/O W 3X6 (Rev 3.7+) ~Codec~ Daughter Card I/O R/W 530-533 or 604-607 or E80-E83 or F40-F43 UltraMax I/O R/W 3XC-3XF Codec Addr Select I/O R/W Base+0 Codec Data I/O R/W Base+1 Codec Status I/O R/W Base+2 Codec PIO I/O R/W Base+3 ~UltraMax Control~ Port (MAX ONLY) I/O W 3X6 See also: ~Global registers~,~Voice registers~ %MIDI Data Port - port 3x1h The transmit and receive registers are at 3X1 hex and are 8 bits wide. :MIDI Control ^MIDI Control Port - port 3x0h Here are the bit definitions for the MIDI control byte. It is located at address 3X0 hex and is write only. ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- 1 \ Master reset (when set) | | | | | | +-------- 1 / | | | | | +------------ Reserved | | | | +---------------- Reserved | | | +-------------------- Reserved | | +------------------------ 1 \ xmit IRQ enabled | +---------------------------- 0 / +-------------------------------- 1 = Receive IRQ enabled Bit 0 & 1 will cause a master reset when toggled high and then low. They must be left low when using port. This will normally cause a transmit buffer empty IRQ. See Also: ~MIDI Status Port~ :MIDI Status ^MIDI Status Port - port 3x0h Here are the bit definitions for the MIDI status byte. It is located at address 3X0 hex and is read-only. ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- Receive reg. full | | | | | | +-------- Transmit reg. empty | | | | | +------------ Reserved | | | | +---------------- Reserved | | | +-------------------- Framing Error | | +------------------------ Overrun error | +---------------------------- Reserved +-------------------------------- Interrupt pending The MIDI control interface behaves identically to a 6850 UART. See also: ~MIDI Control Port~ :Page register:Voice select ^Page Register - port 3x2h This could also be called the voice select register. This register is used to specify which voice's registers you want to read/write. This value can range from 0 to the number of active voices specified (13-31). Once this has been specified, you may select the specific register within that voice. Be careful that IRQs are off during the time that the page and select registers are being modified. This will prevent the foreground from selecting a voice and having the background change it in the background. :Select Register:Global Registers ^Select Register - port 3x3h ^Global Registers These are the global registers. They are not voice-specific. % Address Mode Width Description 41 R/W 8 ~DRAM DMA Control~ 42 W 16 ~DMA Start Address~ 43 W 16 ~DRAM I/O Address~ (LOW) 44 W 8 DRAM I/O Address (HIGH) 45 R/W 8 ~Timer Control reg~ 46 W 8 #1 ~Timer Count~ 47 W 8 #2 Timer Count 48 W 8 Sampling Frequency 49 R/W 8 ~Sampling Control~ 4B W 8 ~Joystick DAC~ 4C R/W 8 ~RESET Register~ % Sampling Frequency - (48) The formula for calculating this value is: rate = 9878400/(16*(FREQ+2)) For Voice specific registers see ~Voice Registers~ For Other I/O ports see ~GUS Port Map~ :DRAM DMA Control ^DRAM DMA Control Register - Global Registers(41) ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- Enable DMA (1=go) | | | | | | +-------- DMA direction (1=read) | | | | | +------------ DMA channel width | | | | +---------------- \ | | | +-------------------- / DMA Rate divider | | +------------------------ DMA IRQ Enable | +---------------------------- (R) DMA IRQ Pending | (W) DATA SIZE (0=8bit,1=16bit) +-------------------------------- Invert MSB (write only) Bit 0 - Enable the DMA channel. The GF1 will begin sending DMA ACK protocol. If PC DMA controller is programmed, data will begin being transferred. If not, data will move as soon as it is programmed. Bit 1 - DMA transfer direction. Read is taking data OUT of the UltraSound, Write sends data to it. Bit 2 - 0 = if DMA channel is an 8 bit channel (0-3). 1 = If it is a 16 bit channel (4-7) Note: This is INDEPENDENT of the data size. Bit 3,4 -DMA Rate divisor. The Maximum rate is approx 650 khz. 00 = divide by 1 01 = divide by 2 10 = divide by 3 11 = divide by 4 Bit 5 - DMA terminal count interrupt enable Bit 6 - Read - DMA terminal count IRQ pending Write - Data size 0 = 8 Bit data 1 = 16 bit data Note: Data size is independent of channel size Bit 7 - 1 = Invert High bit to flip data to twos complement form. Note: This flips bit 7 for 8 bit data and bit 15 for 16 bit data. See Also: ~Global Registers~ :DMA Start Address ^DMA Start Address - Global Registers(42) Bits 15-0 are Address lines 19-4. This register defines where the DMA will transfer data to or from. Since only the upper 16 address bits are used and the lower 4 bits are set to 0, a DMA transfer MUST begin on an 16 byte boundary for an 8 bit DMA channel (0-3). If a 16 bit DMA channel is being used, the transfer MUST being on a 32 byte boundary. An additional address translation is necessary if a 16 bit DMA channel is used. For simple example code on how to do this translation, see the C function convert_to_16(). See Also: ~Global Registers~ :DRAM I/O Address ^DRAM I/O Address - Global Registers(43,44) These 2 registers allow you to specify an address to peek and poke directly into UltraSound DRAM. Register 43 is the lower 16 address lines. Register 44 is the upper 4 address lines. (bits 0-3). Read or write to register 3X7 to get at the address location. See Also: ~Global Registers~ :Timer Control reg ^Timer Control - Global Registers(45) ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- Reserved (Set to 0) | | | | | | +-------- Reserved (Set to 0) | | | | | +------------ Enable Timer 1 IRQ | | | | +---------------- Enable Timer 2 IRQ | | | +-------------------- Reserved (Set to 0) | | +------------------------ Reserved (Set to 0) | +---------------------------- Reserved (Set to 0) +-------------------------------- Reserved (Set to 0) See Also: ~Global Registers~ :Timer count ^Timer 1 and Timer 2 Count - Global Registers(46,47) These counts are loaded by the application and then they will count up to $FF and generate and IRQ. Timer 1 has a granularity of 80 microseconds (0.00008 sec) and Timer 2 has a granularity of 320 microseconds (0.00032 sec). See Also: ~Global Registers~ :Sampling Control ^Sampling Control Register - Global Registers(49) ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- Start sampling | | | | | | +-------- Mode (0=mono, 1=stereo) | | | | | +------------ DMA width (0=8bit,1=16bit) | | | | +---------------- Reserved (Set to 0) | | | +-------------------- Reserved (Set to 0) | | +------------------------ DMA IRQ enable | +---------------------------- (Read) DMA IRQ pending +-------------------------------- Invert MSB Bit 0 -If PC DMA controller is programmed, it will begin sampling as soon as this is enabled. Bit 1 -0 = mono 1 = stereo In stereo mode, the order of the data bytes is left is first, and right is second. If a 16 bit data channel is used, the left is in the lower byte. Bit 2 -DMA Channel width (0 = 8 bit, 1 = 16 bit) Bit 5 -Enable DMA terminal count IRQ Bit 6 -DMA terminal count IRQ pending Bit 7 -Flip bit 7 to get non-twos compliment data See Also: ~Global Registers~ :Joystick DAC ^Joystick Trim DAC - Global Registers(4B) This register is initialized to 4.3 volts (value = 29). It only needs to be modified to account for faster/slower machines. A utility is provided (ULTRAJOY.EXE) that sets this up. There should be no reason for your application to modify this register. See Also: ~Global Registers~ :RESET Register ^Reset Register - Global Registers(4C) ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- Master Reset | | | | | | +-------- DAC Enable | | | | | +------------ GF1 Master IRQ Enable | | | | +---------------- Reserved (Set to 0) | | | +-------------------- Reserved (Set to 0) | | +------------------------ Reserved (Set to 0) | +---------------------------- Reserved (Set to 0) +-------------------------------- Reserved (Set to 0) Bit 0 -GF1 Master Reset. 0 = reset, 1 = run. As long as this is a 0, it will be held in a reset state. Bit 1 -Enable DAC output. DAC's will not run unless this bit is set. Bit 2 -Master IRQ enable. This bit MUST be set to get ANY of the GF1- generated IRQs (wavetable, volume, etc). This register will normally contain the value $07 while your application is running. See Also: ~Global Registers~ :Voice registers ^Voice-specific Registers - Select Register port 3x3h The following are the voice-specific registers. Each voice has its own bank of read and write registers that alter its behavior. The write registers range from 0 to F and the corresponding read registers range from 80 to 8F. To convert from the write to the read, just add 80 hex. % Write Read Width Description 0 80 8 ~Voice Control~ 1 81 16 ~Freq Control~ 2 82 16 ~Starting Address~ (HIGH) 3 83 16 Starting Address (LOW) 4 84 16 ~Ending Address~ (HIGH) 5 85 16 Ending Address (LOW) 6 86 8 ~Volume Ramp Rate~ 7 87 8 ~Volume Ramp Start~ 8 88 8 ~Volume Ramp End~ 9 89 16 ~Current Volume~ A 8A 16 ~Current Address~ (HIGH) B 8B 16 Current Address (LOW) C 8C 8 ~Pan Position~ D 8D 8 ~Volume Ramp Control~ E 8E 8 ~Active Voices~ (Voice independent) - 8F 8 ~IRQ Status~ (Voice independent) ^NOTE There are several 'self-modifying' bits defined for these registers. This means that the GF1 may change them at anytime on its own. Due to the fact that the software must accommodate this phenomena, it is possible that the GF1 may change something immediately after your application has set/reset one of the bits. This is due to the GF1's pipeline processor type of architecture: it does a read-modify-write cycle, and if your application modifies one of these bits AFTER it has done the read portion and BEFORE it does the write portion, it's possible for the chip to perform incorrectly. To overcome this, you need to do a double write (with a delay in between) when those particular bits are involved. This delay must be at least 3 times the length of time necessary to process a voice. (3*1.6 microsecs). In the lowlevel code, this is done with a function called GF1_Delay. The self-modifying bits are designated with an (*) after the particular bit definition. Changing the start and end points of a voice while its playing can have some strange side effects. For example, if you change end poistion to a lower location than it is currently playing, you will get and IRQ (if they are enabled). Also, since the high and low bytes are set individually and asynchronously to when the GF1 is working on a voice, it is possible to get an unexpected IRQ if the current position and the new end position cross. For global registers see ~Global Registers~ For Other I/O ports see ~GUS Port Map~ :Voice Control ^Voice Control Register - Voice Registers(0,80) ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- Voice Stopped | | | | | | +-------- Stop Voice | | | | | +------------ 16 bit data | | | | +---------------- Loop enable | | | +-------------------- Bi-directional loop enable | | +------------------------ Wave table IRQ | +---------------------------- Direction of movement +-------------------------------- IRQ pending * Bit 0- 1 = Voice is stopped. This gets set by hitting the end address (not looping) or by setting bit 1 in this reg. Bit 1- 1 = Stop Voice. Manually force voice to stop. Bit 2- 1 = 16 bit wave data, 0 = 8 bit data Bit 3- 1 = Loop to begin address when it hits the end address. Bit 4- 1 = Bi-directional looping enabled Bit 5- 1 = Enable wavetable IRQ. Generate an IRQ when the voice hits the end address. Will generate IRQ even if looping is enabled. * Bit 6- 1 = Decreasing addresses, 0 = increasing addresses. It is self- modifying because it might shift directions when it hits one of the loop boundaries and looping is enabled. * Bit 7- 1 = Wavetable IRQ pending. If IRQ's are enabled and looping is NOT enabled, an IRQ will be constantly generated until the voice is stopped. This means that you may get more than 1 IRQ if it isn't handled properly. See also: ~Voice Registers~ :Freq Control ^Frequency Control Register - Voice Registers(1,81) Bits 15-10 - Integer Portion Bits 9-1 - Fractional Portion Bit 0 - Not used. This register determines the amount added to (or subtracted from) the current position of the voice to determine where the next position will be. This is how the interpolated data points are determined. If the FC register is less than 0, the GF1 will interpolate the data point in between the two actual data points. Note that the FC can be greater than 1. This allows for skipping over data bytes. The actual frequency that it will play back is directly related to the number of active voice specified (register 8E). See also: ~Voice Registers~,~Freq calculation~,~U_Freq calculation~ :Starting address ^Starting location HIGH - Voice Registers(2,82) Bits 12-0 are the HIGH 13 bits of the address of the starting location of the waveform (Addr lines 19-7). Bits 15-13 are not used. ^Starting location LOW - Voice Registers(3,83) Bits 15-9 are the low 7 bits of the address of the starting location of the waveform. (Addr lines 6-0). Bits 8-5 are the fractional part of the starting address. Bits 4-0 are not used. See also: ~Voice Registers~,~U_DRAM Addressing~ :Ending address ^End Address HIGH - Voice Registers(4,84) Bits 12-0 are the high 13 bits of the address of the ending location of the waveform. (Addr lines 19-7) Bits 15-13 are not used. ^End Address LOW - Voice Registers(5,85) Bits 15-9 are the low 7 bits of the address of the ending location of the waveform. (Addr lines 6-0). Bits 8-5 are the fractional part of the ending address. Bits 4-0 are not used. See also: ~Voice Registers~,~U_DRAM Addressing~ :Volume Ramp Reg:Volume Ramp Rate:Volume Ramp Start:Volume Ramp End ^Volume Ramp Rate - Voice Registers(6,86) Bits 5-0 is the amount added to (or subtracted from) the current volume to get the next volume. The range is from 1 to 63. The larger the number, the greater the volume step. Bits 7-6 defines the rate at which the increment is applied. ^Volume Ramp Start - Voice Registers(7,87) Bits 7-4 Exponent Bits 3-0 Mantissa This register specifies the starting position of a volume ramp. See the special section on volume ramping for a more complete explanation of how this register works. ^Volume Ramp End - Voice Registers(8,88) Bits 7-4 Exponent Bits 3-0 Mantissa This register specifies the ending position of a volume ramp. See the special section on volume ramping for a more complete explanation of how this register works. Note: The starting volume must always be less than the ending volume. If you want the volume to ramp down, turn on the decreasing volume bit in the Volume Control Register. For more information about volume ramping, please read ~Volume Ramping~ See also: ~Voice Registers~ :Current Volume ^Current Volume - Voice Registers(9,89) * Bits 15-12 Exponent * Bits 11-4 Mantissa Bits 3-0 Reserved (Set to 0) Note: This register has 4 extra bits of precision that is necessary for finer granularity of volume placement. The extra bits are used during a volume ramp. Note: This is a self-modifying value. The GF1 will update this register as it ramps. Note: You should always set this register equal to the value of the beginning of the volume ramp (start OR end). For more information about volume ramping, please read ~Volume Ramping~ See also: ~Voice Registers~ :Current address ^Current Location HIGH - Voice Registers(A,8A) Bits 15-13 Reserved (Set to 0) Bits 12-0 High 13 bits of address (address lines 19-7) ^Current Location LOW - Voice Registers(B,8B) Bits 15-9 Low 7 bits of address. (address lines 6-0) Bits 8-0 9 bit fractional position. See also: ~Voice Registers~ :Pan Position ^Pan Position - Voice Registers(C,8C) Bits 8-4 Reserved (Set to 0) Bits 3-0 Pan position. (0=full left, 15=full right) See also: ~Voice Registers~ :Volume Ramp Control ^Volume Ramp Control Register - Voice Registers(D,8D) ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- Ramp Stopped | | | | | | +-------- Stop Ramp | | | | | +------------ Rollover condition | | | | +---------------- Loop Enable | | | +-------------------- Bi-directional loop enable | | +------------------------ Volume ramp IRQ enable | +---------------------------- Direction +-------------------------------- IRQ pending * Bit 0- Show the ramp has stopped Bit 1- Manually stop the ramp. Bit 2- Roll over condition. This bit pertains more towards the location of the voice rather than its volume. Its purpose is to generate an IRQ and NOT stop (or loop). It will generate an IRQ and the voice's address will continue to move thru DRAM in the same direction. This can be a very powerful feature. It allows the application to get an interrupt without having the sound stop. This can be easily used to implement a ping-pong buffer algorithm so an application can keep feeding it data and there will be no pops. Even if looping is enabled, it will not loop. Bit 3- Enable looping. Loop from end to start (or start to end). Bit 4- Enable bi-directional looping. When it hits end (or start) it will change directions and proceed toward the other limit. Bit 5- Enable getting an IRQ when ramp hits end. * Bit 6- Ramp direction. 0=increasing, 1=decreasing. * Bit 7- (READ) Volume ramp IRQ pending. For more information about volume ramping, please read ~Volume Ramping~ See also: ~Voice Registers~ :Active Voices ^Active Voices - Voice Registers(E,8E) Bits 7-6 Must be set to a 1 Bits 5-0 # of voices to enable - 1. The range is from 14 - 32. Any value less than 14 will be forced to 14. See also: ~Voice Registers~ :IRQ Source Register ^IRQ Source Register - Voice Registers(F,8F) ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +----\ | | | | | | +-------- \ | | | | | +------------ - Interrupting voice # | | | | +---------------- / | | | +--------------------/ | | +------------------------ 1 | +---------------------------- Volume Ramp IRQ pending +-------------------------------- WaveTable IRQ pending Bit 4-1-Voice # (0-31) of interrupting voice Bit 5- ALWAYS a 1 Bit 6- 0 = Volume Ramp IRQ occurred Bit 7- 0 = Wavetable IRQ occurred Note: This is a global read only register. There is only 1 for ALL voices. You MUST service any indicated IRQ's since a read of this port will clear the associated IRQ bits in the particular voice's control and/or volume control registers. Note: It is possible that multiple voices could interrupt at virtually the same time. In this case, this register will behave like a fifo. When in your IRQ handler, keep reading (and servicing) this register until you do a read with both IRQ bits set to a 1. This means there are no voice IRQs left to deal with. Note: Since it is possible to get ANOTHER IRQ from the same voice for the SAME reason, you must ignore any subsequent IRQ from that voice while in the IRQ handler. For example, when a voice hits its end position and generates an IRQ back to your application, it will continue to generate IRQ's until either the voice is stopped, the IRQ enable is turned off, or the end location is moved. See also: ~Voice Registers~ :Global Data ^Global Data Low - port 3x4h This register can be used to do either a 16 bit transfer for one of the 16 bit wide GF1 registers (Start addr high etc) when using a 16 bit I/O instruction or the low part of a 16 bit wide register when using an 8 bit I/O instruction. ^Global Data High - port 3x5h This register is used to do either an 8 bit transfer for one of the GF1 8 bit registers or to do the high part of a 16 bit wide register. :IRQ Status ^IRQ Status - port 2x6h CAUTION: Note that this is at 2X6 *** NOT 3X6 ***. ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- MIDI Transmit IRQ | | | | | | +-------- MIDI Receive IRQ | | | | | +------------ Timer 1 IRQ | | | | +---------------- Timer 2 IRQ | | | +-------------------- Reserved (Set to 0) | | +------------------------ WaveTable IRQ (any voice) | +---------------------------- Volume Ramp IRQ (any voice) +-------------------------------- DMA TC IRQ (DRAM or Sample) :Timer Control port ^Timer Control Register - port 2x8h This register maps to the same location as the ADLIB board's control register. Writing a 4 here selects the timer stuff. Bit 6 will be set if timer #1 has expired. Bit 5 will be set it timer #2 has expired. :Timer Data ^Timer Data Register - port 2x9h ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- Timer 1 Start | | | | | | +-------- Timer 2 Start | | | | | +------------ Reserved (Set to 0) | | | | +---------------- Reserved (Set to 0) | | | +-------------------- Reserved (Set to 0) | | +------------------------ Mask Timer 2 | +---------------------------- Mask Timer 1 +-------------------------------- Reset Timer IRQ Bit 0 - Start up timer #1 Bit 1 - Start up timer #2 Bit 5 - Mask off timer 2 Bit 6 - Mask off timer 1 Bit 7 - Clear Timer IRQ :DRAM I/O ^DRAM I/O - port 3x7h This register is used to read or write data at the location pointed at by registers 43 and 44. This is used to peek and poke directly to DRAM. :Mix Control ^Mix Control Register - port 2X0 ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- 0=Enable Line IN | | | | | | +-------- 0=Enable Line OUT | | | | | +------------ 1=Enable MIC IN | | | | +---------------- Enable latches | | | +-------------------- Combine chan1 IRQ with Chan2 | | +------------------------ Enable MIDI loopback TxD to RxD | +---------------------------- Control Reg Select +-------------------------------- Reserved (Set to 0) Bit 0 -Enable UltraSound line Input Bit 1 -Enable UltraSound Line output Bit 2 -Enable Stereo Mic Input Bit 3 -Enable latches.This provides power to the DMA/IRQ latches. Once these are enabled, NEVER disable them. Disabling them will cause random IRQ's in the PC since the DMA and IRQ lines are not being driven any more. Bit 4 -Combine Channel 1 (GF1) IRQ's with Channel 2 (MIDI) Bit 5 -Enable MIDI loopback. Any data sent out Transmit port will be looped back into the input port. Bit 6 -Control Register Select. When this is set to a 1, the next IO write to 2XB will be to the IRQ control latches. When this is set to a 0, the next IO write to 2XB will be to the DMA channel latches. The write to 2XB for either of these MUST occur as the NEXT IOW or else the write to 2XB will be locked out and not occur. This is to prevent an application that is probing for cards to accidentaly corrupt the latches. :IRQ Control ^IRQ Control Register - port 2xBh % IRQ control register I/O W 2XB (2X0- bit 6 = 1) Bits 2-0 Channel 1 (GF1) IRQ Selector 0=No Interrupt 1=IRQ2 2=IRQ5 3=IRQ3 4=IRQ7 5=IRQ11 6=IRQ12 7=IRQ15 Bits 5-3 Channel 2 (MIDI) IRQ selector 0=No Interrupt 1=IRQ2 2=IRQ5 3=IRQ3 4=IRQ7 5=IRQ11 6=IRQ12 7=IRQ15 Bit 6 1 = Combine Both IRQS using Channel 1's IRQ Bit 7 Reserved (Set to 0) Note: If the channels are sharing an IRQ, channel 2's IRQ must be set to 0 and turn on bit 6. A bus conflict will occur if both latches are programmed with the same IRQ #. :DMA Control ~DMA Control - port 2xBh % DMA control register I/O W 2XB (2X0- bit 6 = 0) Bits 2-0 DMA Select Register 1 0=NO DMA 1=DMA1 2=DMA3 3=DMA5 4=DMA6 5=DMA7 Bits 5-3 DMA Select Register 2 0=NO DMA 1=DMA1 2=DMA3 3=DMA5 4=DMA6 5=DMA7 Bit 6 - Combine Both on the same DMA channel. Bit 7 - Reserved (Set to 0). Note: If the channels are sharing an DMA, channel 2's DMA must be set to 0 and turn on bit 6. A bus conflict will occur if both latches are programmed with the same DMA #. :Register Control ^Register Control - port 2xFh This register is only valid for UltraSound boards that are at or above revision 3.4. It is not valid for boards which have a prior revision number. On 3.4 and above boards, there is a bank of 6 registers that exist at location 2XB. Register 2XF is used to select which one is being talked to. Register # Use 0 Same as pre-3.4 boards 1-4 Unused - Reserved 5 Write a 0 to clear IRQs on power-up 6 'Jumper register' Jumper register definition: ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- Reserved (Set to 0) | | | | | | +-------- 1=Enable MIDI port addr decode | | | | | +------------ 1=Enable joystick port decode | | | | +---------------- Reserved (Set to 0) | | | +-------------------- Reserved (Set to 0) | | +------------------------ Reserved (Set to 0) | +---------------------------- Reserved (Set to 0) +-------------------------------- Reserved (Set to 0) :Revision Level:Board Version ^Revision Level - port 7x6h This register is only valid for UltraSound boards that are 3.7 or greater. Any reads from this port on boards prior to 3.7 will return 0xff. This is a way for software to detect whether or not the ICS-2101 mixer is present. Here is a table of what is currently defined for each revision. Revision ID Board Revision 0xff Pre 3.7 boards. ICS mixer NOT present 5 Rev 3.7 with ICS Mixer. Some R/L: flip problems. 6-9 Revision 3.7 and above. ICS Mixer present 0x0A-NN UltraMax. CS4231 present, no ICS mixer :UltraMAX Control ^UltraMax Control Register - port 3x6h This is a write only register that is only valid for the UltraMax. Note that it is on the same port location as the data port for the ICS-2101 mixer. This implies that your software MUST know what device is there before it starts writing to them. ================================= | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ================================= | | | | | | | | | | | | | | | +---- Codec Addr Decode Bit 4 | | | | | | +-------- Codec Addr Decode Bit 5 | | | | | +------------ Codec Addr Decode Bit 6 | | | | +---------------- Codec Addr Decode Bit 7 | | | +-------------------- Capture Channel type (0=8 bit, 1=16 bit) | | +------------------------ Playback Channel type (0=8 bit, 1=16 bit) | +---------------------------- Codec Enable (0=disable, 1=enable) +-------------------------------- Reserved (Set to 0) Bits 0-3 - Define the 'X' in 3XC to define the base port location. By convention, the 'X' is usually set to the same as the base port of the UltraSound, but it doesn't need to be. This value can range from 0 - F. Bit 4 - Defines the type of DMA channel used for recording. Set this bit to 0 for an 8 bit channel and a 1 for a 16 bit channel. Bit 5 - Defines the type of DMA channel used for playback. Set this bit to 0 for an 8 bit channel and a 1 for a 16 bit channel. Bits 4 and 5 need to be set up because the CS4231 is only capable of using and 8 bit DMA channel. To allow it to take advantage of the UltraSounds capability of using a 16-bit channel, extra hardware was added to buffer the data and send it out a 16 bit channel. An UltraMax CS4231 shares the DMA channels with base UltraSounds channels. See chapter ~Codec~ for more info on the interactions between the two. Bit 6 is to enable the CS4231. Until this bit is set, the CS4231 is inactive and will not appear in the address space. :Mixer ^Mixer - Revision 3.7+ %Introduction Revision 3.7 and above UltraSounds have had a new mixer added to them. This document will not attempt to describe how the internals of the mixer works. If you want more detailed information that is provided by this document or the example code in mixer.c, you can get a data sheet from ICS or an ICS data book. The part number is ICS-2101. You can contact ICS directly at: Integrated Circuit Systems, Inc 2435 Boulevard of the Generals P.O. Box 968 Valley Forge, Pa. 19482-0968 Phone # (215)-630-5300 or Phone # (215)-630-5399 %Notes To determine if one of these mixers is present, you MUST look at the revision of the board. This can be determined by reading port location 7X6. If the value read back is FF, then no revision ID is present and means that the version is pre-3.4 and therefore no mixer is present. If the revision is between 5 and 9, then the version number of the base UltraSound is 3.7 or above. All those versions will have this mixer. See ~Revision Level~ for more information. If the version is 10 or above, then it is an UltraMax. This mixer is NOT used on an UltraMax. The codec on the UltraMax has a mixer built into it. See ~Codec~ for more information on that. If your software determines that the board revision is 5, then you must do some special stuff. That specific revision of the UltraSound had a couple of the right\left input lines reversed. The ICS-2101 has the ability to flip them around inside the chip to correct for this problem. Subsequent versions of the board corrected this. The lines that were flipped were the synth input to the mixer and the master output. Look at the mixer.c code in the SDK sources to see and example of how to do this. Any application that uses the mixer MUST reset back to its transparent values when it exits so the any application that isn't aware of the mixer will operate properly. The only exception to this may be some app that wants to adjust the volumes outside any running apps (TSR). Just be aware that any other programs that use the mixer will probably overwrite any values you may have set up. Since the mixer is a write only device, that app would have no idea that its values were changed. :Codec Functions:Codec:Daughter card:UltraMAX Codec ^16 Bit Codec Functions (Rev 3.7+) %Introduction Both the 16-bit daughter card and the UltraMax use the same chip to perform the extra recording and mixing functions. It is built by Crystal Semiconductors CS4231 Audio Codec. This section will describe how it fits into each of those boards. It will NOT describe much about how the internals of the CS4231 work. To get a data sheet on the part, contact Crystal Semiconductor at: Crystal Semiconductor Corporation P.O. Box 17847 Austin, TX 78760 Phone # (512) 445-7222 Fax # (512) 445-7581 Tish SDK is not meant to be a complete toolkit for programming the CS4231. The CS4231 is a very versitile part that can be used in many different ways. This SDK give some simple simple example routines that can be very useful to get the part running. It is quite likely that you may find it necessary to modify or re-write some of the SDK code for use in your app. Please don't be afraid of doing just that. %Features: - 8 or 16 bit playback and recording - Up to 48kHz - 2 DMA channels for simultaneous playback and record - 8 or 16 bit DMA channel selection (software selectable) - Multiple data formats - Linear PCM data - u-law compression (2-1) - a-law compression (2-1) - ADPCM (4-1) - 10 microsecond granularity timer - Extensive mixer - Line in level adjust - Line out level adjust - AUX1 and AUX2 input level adjust - Mic input level adjust %Notes The L/M blocks are level adjustments and mutes. Some can perform gain and attenuation. Some can do gain only. Refer to the CS4231 data sheet to see the use and range of each of these blocks. The microphone is mono only. The left side is connected to both right and left. This allows the same the recording to be the same whether the recording is being done thru MONO IN or MIC IN. MONO IN was connected to the MIC so that some user selectable gain could be used. This block diagram is the same for both the UltraMax and the 16-bit daughter card. Due to the need for backward compatibility, the mute settings for the base Ultrasound still apply. If the either codec mutes or the mute switches on the base Ultrasound are set, the corresponding input WILL be muted. To use only the codec mixer, use UltraEnableLineIn, UltraEnableMicIn, and UltraEnableOutput to ensure that the inputs are not being muted before they reach the CS4231. %Daughter card Specific Info The daughter card has its own jumper selectable DMA channel and IRQ. These MUST be different than the software programmable ones on the base UltraSound. If not, conflicts will occur and will result in unpredictable behavior. Only 1,2 and 3 are valid DMA channels. No 16 bit channels are available. Since only 1 DMA channel is provided, simultaneous playback and record thru the codec is not possible. The base address for the codec on a daughter card can be at one of 4 locations (530,604,E80 and F40) %UltraMax Codec Specific Info Even though the same part is used for both the 16-bit daughter card and the Max, the Max has quite a bit more functionality. First of all, it can use a 16-bit DMA channel. It also has 2 DMA channels available so that it can do simultaneous playback and record. The Windows drivers demonstrate this feature. To support these added features, some extra hardware was added to an UltraMax. Since the CS4231 is an 8-bit DMA device, some hardware buffers were added that takes the output of the CS4231 and sends it out a 16 bit DMA channel. These buffers essentially collect 2 8-bit DMA transfers and then does 1 16-bit transfer. This is why there are 2 control bits in register 3X6. The UltraMax hardware has to know if the destination DMA channels is 8 or 16 so it knows to do this buffering. The Max shares its DMA channels and IRQ with the base UltraSound. This limits the amount of resources that your Max will need from your system. The CS4231 will generate irqs on the same irq as the GF1. Your software will need to look at the codec (along with the GF1) when that particular level irq is generated to see if it need to be serviced. %UltraMax DMA Channel block diagram Note that the DMA channels appear flipped between the GF1 and the codec. This is to allow us to DMA to dram to load patches while the codec is busy playing back .WAV data. We can also record the output of the GF1 (MIDI) by making sure that the patches have been loaded prior to starting the record. Since those two functions share the same DMA channel, you cannot be loading DRAM via DMA while you are recording with the codec. The codec is capable of combining its record channel with its play channel inside the codec. (That is what the 'C' is means inside the diagram above) However, because the Max does the 8-16 bit DMA channel conversion OUTSIDE the codec, this will only work on an 8 bit channel. If you try and combine the channels inside the codec and you are using 16-bit channels, the recording will fail. See also: ~UltraMAX Control~ :Modulation Tables:TREMOLO Rate:VIBRATO Rate ^Modulation Tables - RATE table for TREMOLO* and VIBRATO** %rate frequency rate frequency rate frequency %--------------------------------------------------------- 000: 0.050 Hz 085: 2.034 Hz 170: 4.018 Hz 001: 0.073 Hz 086: 2.057 Hz 171: 4.041 Hz 002: 0.097 Hz 087: 2.081 Hz 172: 4.064 Hz 003: 0.120 Hz 088: 2.104 Hz 173: 4.088 Hz 004: 0.143 Hz 089: 2.127 Hz 174: 4.111 Hz 005: 0.167 Hz 090: 2.151 Hz 175: 4.135 Hz 006: 0.190 Hz 091: 2.174 Hz 176: 4.158 Hz 007: 0.213 Hz 092: 2.197 Hz 177: 4.181 Hz 008: 0.237 Hz 093: 2.221 Hz 178: 4.205 Hz 009: 0.260 Hz 094: 2.244 Hz 179: 4.228 Hz 010: 0.283 Hz 095: 2.267 Hz 180: 4.251 Hz 011: 0.307 Hz 096: 2.291 Hz 181: 4.275 Hz 012: 0.330 Hz 097: 2.314 Hz 182: 4.298 Hz 013: 0.353 Hz 098: 2.337 Hz 183: 4.321 Hz 014: 0.377 Hz 099: 2.361 Hz 184: 4.345 Hz 015: 0.400 Hz 100: 2.384 Hz 185: 4.368 Hz 016: 0.423 Hz 101: 2.407 Hz 186: 4.391 Hz 017: 0.447 Hz 102: 2.431 Hz 187: 4.415 Hz 018: 0.470 Hz 103: 2.454 Hz 188: 4.438 Hz 019: 0.493 Hz 104: 2.477 Hz 189: 4.461 Hz 020: 0.517 Hz 105: 2.501 Hz 190: 4.485 Hz 021: 0.540 Hz 106: 2.524 Hz 191: 4.508 Hz 022: 0.563 Hz 107: 2.547 Hz 192: 4.531 Hz 023: 0.587 Hz 108: 2.571 Hz 193: 4.555 Hz 024: 0.610 Hz 109: 2.594 Hz 194: 4.578 Hz 025: 0.633 Hz 110: 2.617 Hz 195: 4.601 Hz 026: 0.657 Hz 111: 2.641 Hz 196: 4.625 Hz 027: 0.680 Hz 112: 2.664 Hz 197: 4.648 Hz 028: 0.704 Hz 113: 2.687 Hz 198: 4.671 Hz 029: 0.727 Hz 114: 2.711 Hz 199: 4.695 Hz 030: 0.750 Hz 115: 2.734 Hz 200: 4.718 Hz 031: 0.774 Hz 116: 2.757 Hz 201: 4.741 Hz 032: 0.797 Hz 117: 2.781 Hz 202: 4.765 Hz 033: 0.820 Hz 118: 2.804 Hz 203: 4.788 Hz 034: 0.844 Hz 119: 2.827 Hz 204: 4.811 Hz 035: 0.867 Hz 120: 2.851 Hz 205: 4.835 Hz 036: 0.890 Hz 121: 2.874 Hz 206: 4.858 Hz 037: 0.914 Hz 122: 2.897 Hz 207: 4.881 Hz 038: 0.937 Hz 123: 2.921 Hz 208: 4.905 Hz 039: 0.960 Hz 124: 2.944 Hz 209: 4.928 Hz 040: 0.984 Hz 125: 2.967 Hz 210: 4.951 Hz 041: 1.007 Hz 126: 2.991 Hz 211: 4.975 Hz 042: 1.030 Hz 127: 3.014 Hz 212: 4.998 Hz 043: 1.054 Hz 128: 3.038 Hz 213: 5.021 Hz 044: 1.077 Hz 129: 3.061 Hz 214: 5.045 Hz 045: 1.100 Hz 130: 3.084 Hz 215: 5.068 Hz 046: 1.124 Hz 131: 3.108 Hz 216: 5.091 Hz 047: 1.147 Hz 132: 3.131 Hz 217: 5.115 Hz 048: 1.170 Hz 133: 3.154 Hz 218: 5.138 Hz 049: 1.194 Hz 134: 3.178 Hz 219: 5.161 Hz 050: 1.217 Hz 135: 3.201 Hz 220: 5.185 Hz 051: 1.240 Hz 136: 3.224 Hz 221: 5.208 Hz 052: 1.264 Hz 137: 3.248 Hz 222: 5.231 Hz 053: 1.287 Hz 138: 3.271 Hz 223: 5.255 Hz 054: 1.310 Hz 139: 3.294 Hz 224: 5.278 Hz 055: 1.334 Hz 140: 3.318 Hz 225: 5.301 Hz 056: 1.357 Hz 141: 3.341 Hz 226: 5.325 Hz 057: 1.380 Hz 142: 3.364 Hz 227: 5.348 Hz 058: 1.404 Hz 143: 3.388 Hz 228: 5.372 Hz 059: 1.427 Hz 144: 3.411 Hz 229: 5.395 Hz 060: 1.450 Hz 145: 3.434 Hz 230: 5.418 Hz 061: 1.474 Hz 146: 3.458 Hz 231: 5.442 Hz 062: 1.497 Hz 147: 3.481 Hz 232: 5.465 Hz 063: 1.520 Hz 148: 3.504 Hz 233: 5.488 Hz 064: 1.544 Hz 149: 3.528 Hz 234: 5.512 Hz 065: 1.567 Hz 150: 3.551 Hz 235: 5.535 Hz 066: 1.590 Hz 151: 3.574 Hz 236: 5.558 Hz 067: 1.614 Hz 152: 3.598 Hz 237: 5.582 Hz 068: 1.637 Hz 153: 3.621 Hz 238: 5.605 Hz 069: 1.660 Hz 154: 3.644 Hz 239: 5.628 Hz 070: 1.684 Hz 155: 3.668 Hz 240: 5.652 Hz 071: 1.707 Hz 156: 3.691 Hz 241: 5.675 Hz 072: 1.730 Hz 157: 3.714 Hz 242: 5.698 Hz 073: 1.754 Hz 158: 3.738 Hz 243: 5.722 Hz 074: 1.777 Hz 159: 3.761 Hz 244: 5.745 Hz 075: 1.800 Hz 160: 3.784 Hz 245: 5.768 Hz 076: 1.824 Hz 161: 3.808 Hz 246: 5.792 Hz 077: 1.847 Hz 162: 3.831 Hz 247: 5.815 Hz 078: 1.871 Hz 163: 3.854 Hz 248: 5.838 Hz 079: 1.894 Hz 164: 3.878 Hz 249: 5.862 Hz 080: 1.917 Hz 165: 3.901 Hz 250: 5.885 Hz 081: 1.941 Hz 166: 3.924 Hz 251: 5.908 Hz 082: 1.964 Hz 167: 3.948 Hz 252: 5.932 Hz 083: 1.987 Hz 168: 3.971 Hz 253: 5.955 Hz 084: 2.011 Hz 169: 3.994 Hz 254: 5.978 Hz 255: 6.002 Hz * Tremolo rates for the GF1 UltraSound vary a small amount by depth. The larger the depth the more accurate the rate. ** Vibrato rates for the GF1 UltraSound lose resolution as the rate increases. In other words, you will hear a rate difference between 0 and 1, but not between 169 and 179. See also: ~TREMOLO Depth~, ~VIBRATO Depth~ :Tremolo Depth ^Modulation Tables - DEPTH table for TREMOLO %depth decibels depth decibels depth decibels %-------------------------------------------------------- 000: OFF 085: 4.031 dB 170: 8.016 dB 001: 0.094 dB 086: 4.078 dB 171: 8.062 dB 002: 0.141 dB 087: 4.125 dB 172: 8.109 dB 003: 0.188 dB 088: 4.172 dB 173: 8.156 dB 004: 0.234 dB 089: 4.219 dB 174: 8.203 dB 005: 0.281 dB 090: 4.266 dB 175: 8.250 dB 006: 0.328 dB 091: 4.312 dB 176: 8.297 dB 007: 0.375 dB 092: 4.359 dB 177: 8.344 dB 008: 0.422 dB 093: 4.406 dB 178: 8.391 dB 009: 0.469 dB 094: 4.453 dB 179: 8.438 dB 010: 0.516 dB 095: 4.500 dB 180: 8.484 dB 011: 0.562 dB 096: 4.547 dB 181: 8.531 dB 012: 0.609 dB 097: 4.594 dB 182: 8.578 dB 013: 0.656 dB 098: 4.641 dB 183: 8.625 dB 014: 0.703 dB 099: 4.688 dB 184: 8.672 dB 015: 0.750 dB 100: 4.734 dB 185: 8.719 dB 016: 0.797 dB 101: 4.781 dB 186: 8.766 dB 017: 0.844 dB 102: 4.828 dB 187: 8.812 dB 018: 0.891 dB 103: 4.875 dB 188: 8.859 dB 019: 0.938 dB 104: 4.922 dB 189: 8.906 dB 020: 0.984 dB 105: 4.969 dB 190: 8.953 dB 021: 1.031 dB 106: 5.016 dB 191: 9.000 dB 022: 1.078 dB 107: 5.062 dB 192: 9.047 dB 023: 1.125 dB 108: 5.109 dB 193: 9.094 dB 024: 1.172 dB 109: 5.156 dB 194: 9.141 dB 025: 1.219 dB 110: 5.203 dB 195: 9.188 dB 026: 1.266 dB 111: 5.250 dB 196: 9.234 dB 027: 1.312 dB 112: 5.297 dB 197: 9.281 dB 028: 1.359 dB 113: 5.344 dB 198: 9.328 dB 029: 1.406 dB 114: 5.391 dB 199: 9.375 dB 030: 1.453 dB 115: 5.438 dB 200: 9.422 dB 031: 1.500 dB 116: 5.484 dB 201: 9.469 dB 032: 1.547 dB 117: 5.531 dB 202: 9.516 dB 033: 1.594 dB 118: 5.578 dB 203: 9.562 dB 034: 1.641 dB 119: 5.625 dB 204: 9.609 dB 035: 1.688 dB 120: 5.672 dB 205: 9.656 dB 036: 1.734 dB 121: 5.719 dB 206: 9.703 dB 037: 1.781 dB 122: 5.766 dB 207: 9.750 dB 038: 1.828 dB 123: 5.812 dB 208: 9.797 dB 039: 1.875 dB 124: 5.859 dB 209: 9.844 dB 040: 1.922 dB 125: 5.906 dB 210: 9.891 dB 041: 1.969 dB 126: 5.953 dB 211: 9.938 dB 042: 2.016 dB 127: 6.000 dB 212: 9.984 dB 043: 2.062 dB 128: 6.047 dB 213: 10.031 dB 044: 2.109 dB 129: 6.094 dB 214: 10.078 dB 045: 2.156 dB 130: 6.141 dB 215: 10.125 dB 046: 2.203 dB 131: 6.188 dB 216: 10.172 dB 047: 2.250 dB 132: 6.234 dB 217: 10.219 dB 048: 2.297 dB 133: 6.281 dB 218: 10.266 dB 049: 2.344 dB 134: 6.328 dB 219: 10.312 dB 050: 2.391 dB 135: 6.375 dB 220: 10.359 dB 051: 2.438 dB 136: 6.422 dB 221: 10.406 dB 052: 2.484 dB 137: 6.469 dB 222: 10.453 dB 053: 2.531 dB 138: 6.516 dB 223: 10.500 dB 054: 2.578 dB 139: 6.562 dB 224: 10.547 dB 055: 2.625 dB 140: 6.609 dB 225: 10.594 dB 056: 2.672 dB 141: 6.656 dB 226: 10.641 dB 057: 2.719 dB 142: 6.703 dB 227: 10.688 dB 058: 2.766 dB 143: 6.750 dB 228: 10.734 dB 059: 2.812 dB 144: 6.797 dB 229: 10.781 dB 060: 2.859 dB 145: 6.844 dB 230: 10.828 dB 061: 2.906 dB 146: 6.891 dB 231: 10.875 dB 062: 2.953 dB 147: 6.938 dB 232: 10.922 dB 063: 3.000 dB 148: 6.984 dB 233: 10.969 dB 064: 3.047 dB 149: 7.031 dB 234: 11.016 dB 065: 3.094 dB 150: 7.078 dB 235: 11.062 dB 066: 3.141 dB 151: 7.125 dB 236: 11.109 dB 067: 3.188 dB 152: 7.172 dB 237: 11.156 dB 068: 3.234 dB 153: 7.219 dB 238: 11.203 dB 069: 3.281 dB 154: 7.266 dB 239: 11.250 dB 070: 3.328 dB 155: 7.312 dB 240: 11.297 dB 071: 3.375 dB 156: 7.359 dB 241: 11.344 dB 072: 3.422 dB 157: 7.406 dB 242: 11.391 dB 073: 3.469 dB 158: 7.453 dB 243: 11.438 dB 074: 3.516 dB 159: 7.500 dB 244: 11.484 dB 075: 3.562 dB 160: 7.547 dB 245: 11.531 dB 076: 3.609 dB 161: 7.594 dB 246: 11.578 dB 077: 3.656 dB 162: 7.641 dB 247: 11.625 dB 078: 3.703 dB 163: 7.688 dB 248: 11.672 dB 079: 3.750 dB 164: 7.734 dB 249: 11.719 dB 080: 3.797 dB 165: 7.781 dB 250: 11.766 dB 081: 3.844 dB 166: 7.828 dB 251: 11.812 dB 082: 3.891 dB 167: 7.875 dB 252: 11.859 dB 083: 3.938 dB 168: 7.922 dB 253: 11.906 dB 084: 3.984 dB 169: 7.969 dB 254: 11.953 dB 255: 12.000 dB :VIBRATO Depth ^Modulator Tables - DEPTH table for VIBRATO %depth centibels depth centibels depth centibels %-------------------------------------------------------------------- 000: OFF 085: 0403.1 cents 170: 0801.6 cents 001: 0009.4 cents 086: 0407.8 cents 171: 0806.2 cents 002: 0014.1 cents 087: 0412.5 cents 172: 0810.9 cents 003: 0018.8 cents 088: 0417.2 cents 173: 0815.6 cents 004: 0023.4 cents 089: 0421.9 cents 174: 0820.3 cents 005: 0028.1 cents 090: 0426.6 cents 175: 0825.0 cents 006: 0032.8 cents 091: 0431.2 cents 176: 0829.7 cents 007: 0037.5 cents 092: 0435.9 cents 177: 0834.4 cents 008: 0042.2 cents 093: 0440.6 cents 178: 0839.1 cents 009: 0046.9 cents 094: 0445.3 cents 179: 0843.8 cents 010: 0051.6 cents 095: 0450.0 cents 180: 0848.4 cents 011: 0056.2 cents 096: 0454.7 cents 181: 0853.1 cents 012: 0060.9 cents 097: 0459.4 cents 182: 0857.8 cents 013: 0065.6 cents 098: 0464.1 cents 183: 0862.5 cents 014: 0070.3 cents 099: 0468.8 cents 184: 0867.2 cents 015: 0075.0 cents 100: 0473.4 cents 185: 0871.9 cents 016: 0079.7 cents 101: 0478.1 cents 186: 0876.6 cents 017: 0084.4 cents 102: 0482.8 cents 187: 0881.2 cents 018: 0089.1 cents 103: 0487.5 cents 188: 0885.9 cents 019: 0093.8 cents 104: 0492.2 cents 189: 0890.6 cents 020: 0098.4 cents 105: 0496.9 cents 190: 0895.3 cents 021: 0103.1 cents 106: 0501.6 cents 191: 0900.0 cents 022: 0107.8 cents 107: 0506.2 cents 192: 0904.7 cents 023: 0112.5 cents 108: 0510.9 cents 193: 0909.4 cents 024: 0117.2 cents 109: 0515.6 cents 194: 0914.1 cents 025: 0121.9 cents 110: 0520.3 cents 195: 0918.8 cents 026: 0126.6 cents 111: 0525.0 cents 196: 0923.4 cents 027: 0131.2 cents 112: 0529.7 cents 197: 0928.1 cents 028: 0135.9 cents 113: 0534.4 cents 198: 0932.8 cents 029: 0140.6 cents 114: 0539.1 cents 199: 0937.5 cents 030: 0145.3 cents 115: 0543.8 cents 200: 0942.2 cents 031: 0150.0 cents 116: 0548.4 cents 201: 0946.9 cents 032: 0154.7 cents 117: 0553.1 cents 202: 0951.6 cents 033: 0159.4 cents 118: 0557.8 cents 203: 0956.2 cents 034: 0164.1 cents 119: 0562.5 cents 204: 0960.9 cents 035: 0168.8 cents 120: 0567.2 cents 205: 0965.6 cents 036: 0173.4 cents 121: 0571.9 cents 206: 0970.3 cents 037: 0178.1 cents 122: 0576.6 cents 207: 0975.0 cents 038: 0182.8 cents 123: 0581.2 cents 208: 0979.7 cents 039: 0187.5 cents 124: 0585.9 cents 209: 0984.4 cents 040: 0192.2 cents 125: 0590.6 cents 210: 0989.1 cents 041: 0196.9 cents 126: 0595.3 cents 211: 0993.8 cents 042: 0201.6 cents 127: 0600.0 cents 212: 0998.4 cents 043: 0206.2 cents 128: 0604.7 cents 213: 1003.1 cents 044: 0210.9 cents 129: 0609.4 cents 214: 1007.8 cents 045: 0215.6 cents 130: 0614.1 cents 215: 1012.5 cents 046: 0220.3 cents 131: 0618.8 cents 216: 1017.2 cents 047: 0225.0 cents 132: 0623.4 cents 217: 1021.9 cents 048: 0229.7 cents 133: 0628.1 cents 218: 1026.6 cents 049: 0234.4 cents 134: 0632.8 cents 219: 1031.2 cents 050: 0239.1 cents 135: 0637.5 cents 220: 1035.9 cents 051: 0243.8 cents 136: 0642.2 cents 221: 1040.6 cents 052: 0248.4 cents 137: 0646.9 cents 222: 1045.3 cents 053: 0253.1 cents 138: 0651.6 cents 223: 1050.0 cents 054: 0257.8 cents 139: 0656.2 cents 224: 1054.7 cents 055: 0262.5 cents 140: 0660.9 cents 225: 1059.4 cents 056: 0267.2 cents 141: 0665.6 cents 226: 1064.1 cents 057: 0271.9 cents 142: 0670.3 cents 227: 1068.8 cents 058: 0276.6 cents 143: 0675.0 cents 228: 1073.4 cents 059: 0281.2 cents 144: 0679.7 cents 229: 1078.1 cents 060: 0285.9 cents 145: 0684.4 cents 230: 1082.8 cents 061: 0290.6 cents 146: 0689.1 cents 231: 1087.5 cents 062: 0295.3 cents 147: 0693.8 cents 232: 1092.2 cents 063: 0300.0 cents 148: 0698.4 cents 233: 1096.9 cents 064: 0304.7 cents 149: 0703.1 cents 234: 1101.6 cents 065: 0309.4 cents 150: 0707.8 cents 235: 1106.2 cents 066: 0314.1 cents 151: 0712.5 cents 236: 1110.9 cents 067: 0318.8 cents 152: 0717.2 cents 237: 1115.6 cents 068: 0323.4 cents 153: 0721.9 cents 238: 1120.3 cents 069: 0328.1 cents 154: 0726.6 cents 239: 1125.0 cents 070: 0332.8 cents 155: 0731.2 cents 240: 1129.7 cents 071: 0337.5 cents 156: 0735.9 cents 241: 1134.4 cents 072: 0342.2 cents 157: 0740.6 cents 242: 1139.1 cents 073: 0346.9 cents 158: 0745.3 cents 243: 1143.8 cents 074: 0351.6 cents 159: 0750.0 cents 244: 1148.4 cents 075: 0356.2 cents 160: 0754.7 cents 245: 1153.1 cents 076: 0360.9 cents 161: 0759.4 cents 246: 1157.8 cents 077: 0365.6 cents 162: 0764.1 cents 247: 1162.5 cents 078: 0370.3 cents 163: 0768.8 cents 248: 1167.2 cents 079: 0375.0 cents 164: 0773.4 cents 249: 1171.9 cents 080: 0379.7 cents 165: 0778.1 cents 250: 1176.6 cents 081: 0384.4 cents 166: 0782.8 cents 251: 1181.2 cents 082: 0389.1 cents 167: 0787.5 cents 252: 1185.9 cents 083: 0393.8 cents 168: 0792.2 cents 253: 1190.6 cents 084: 0398.4 cents 169: 0796.9 cents 254: 1195.3 cents 255: 1200.0 cents %1 cent = 1/100 of a semitone %1 semitone = 1 half step ^Patch editor rate table for envelopes. %Best values good values Overlaps %--------------------------------------------- 055 - 063 047 - 063 111 - 118 overlaps 061 - 063 119 - 127 111 - 127 175 - 182 overlaps 125 - 127 183 - 191 175 - 191 239 - 246 overlaps 189 - 191 247 - 255 239 - 255 :Volume ramping ^Volume ramping description The UltraSound has built-in volume ramping to facilitate the implementation of the attack decay sustain release envelopes. This ramping uses the same principle as the voices for updating the volume values. A section of the envelope can be programmed such that the PC does not need to be burdened with the task of changing each volume at specified intervals. At the end of that particular section, an IRQ can be generated so that the next section can be programmed in. This continues until the entire envelope has been completed. The start and end points as well as the increment rate are fully programmable. %The hardware volume registers and bit definitions are: Current Volume (9,89) EEEEMMMMMMMM (Bits 15-4) Volume Start (7,87) EEEEMMMM (Bits 7-0) Volume End (8,88) EEEEMMMM (Bits 7-0) Volume Incr (6,86) RRMMMMMM (Bits 7-0) Once the current volume, start and end volumes are programmed, the only thing left is to set up the volume increment register. This register determines how fast the ramp takes place and with what granularity. The finer the granularity, the smoother (but slower) the ramp. The increment register has 2 fields. The first is the amount added to (or subtracted from) the current volume to get to the next one. These are the low 6 bits and can range from 1 to 63. A 1 is a long, slow ramp compared to a 63. The upper 2 bits determine how often the increment is applied to the current volume. The rate bits are defined as: % Rate Bits Volume Update Rate 00 FUR (FUR = 1/(1.6*#active voices)) 01 FUR/8 10 FUR/64 11 FUR/512 Each rate increment is 8 times longer than the preceding one. This means that the value to store for the fastest possible ramp is 1Fh (63), and the value for the slowest possible ramp is 1Ch (193). The approximate times for a full scale volume ramp (0-4095) are: % Rate Vol Inc 14 Voices 32 Voices ---- ------- --------- --------- 0 63 1.4 ms 3.3 ms 0 1 91.7 ms 209.7 ms 1 63 11.5 ms 26.2 ms 1 1 733.8 ms 1.7 sec 2 63 91.8 ms 209.7 ms 3 1 5.9 sec 13.4 sec 3 63 734.0 ms 1.7 sec 3 1 47.0 sec 107.3 sec Note that these times are for full sweep ramping. Since a volume ramp usually goes between points in between the limits, the actual ramp times will be much smaller. Allowing to let the volume ramps to go to the extremes can cause a random oscillation of the volume when it reaches the limits. This is caused by an overshoot past the limit due to a large step size. The SDK routines protect against this by limiting how close to the rails you can get. :Ultra clicks ^Clicks and click removal As was mentioned in a few of the preceding sections, 'clicks' and 'pops' can occur when the output of the DAC changes suddenly. This is the most frequent type of click, since there may not be a way to control the data values the voices are trying to play. In general, it is necessary to remember that all voices are being summed in to the final output, even if they are not running. This means that whatever data value that the voice is pointing at is contributing to the summation. It is important that a voice be pointed to a known value at a known location after it is stopped so that some control is kept over it. For instance, if a voice were left at whereever the end position was for the last time it played, a pop could occur if new data were either DMA'ed or poked over the top of it. For this reason, it is recommended that a voice be pointed to a location containing a 0 and that its volume be set to 0. At that point, the voice will have no contribution to the output. There are some particular cases where clicks most frequently occur: %During Reset - Because of the way the card is reset, a pop can occur through the speakers when a reset occurs. The way to remove this pop is to disable the output, reset the card, and then enable the output again. %During a balance sweep - Since there are only 16 pan positions and there is such a large jump between individual positions, a relatively fast balance sweep from one side to another may produce clicks. You can get a very smooth balance sweep using 2 voices and volume ramping. Set one voice up to one side and one to the other, and ramp one down from volume X to zero at the same rate as you ramp the other from 0 up to volume X. The result is a very smooth balance sweep. %When starting and stopping a voice - By setting up fairly fast rates when a sample start or ends and ramping up or down appropriately, any pop created by a sudden change in the DAC value will be summed in at such a low volume, it will never be heard. %End points not set properly - Make sure your end points are at the ends of your samples. It is a very common mistake to set an end point to 1 sample beyond the end. For example, if a sample is 100 bytes long an starts at location 100, the end point is at position 199, NOT position 200. Also, it is possible that the GF1 will interpolate data at points beyond the end point. To ensure that this does not cause 'clicks', use a few extra bytes after the end point of the sample to maintain it. %Loop points not set properly - The same problem as stated above (end points) is common for loop start and end points. Be sure that the data at the end of the loop and the beginning of the loop are practically identical, since if there is a large step between them a click will result because the DAC value will change suddenly. :Rollover ^Rollover feature Each voice has a 'rollover' feature that allows an application to be notified when a voice's playback position passes over a particular place in DRAM. This is very useful for getting seamless digital audio playback. Basically, the GF1 will generate an IRQ when a voice's current position is equal to the end position. However, instead of stopping or looping back to the start position, the voice will continue playing in the same direction. This means that there will be no pause (or gap) in the playback. Note that this feature is enabled/disabled thru the voice's VOLUME control register (since there are no more bits available in the voice control registers). A voice's loop enable bit takes precedence over the rollover. This means that if a voice's loop enable is on, it will loop when it hits the end position, regardless of the state of the rollover enable. %A simple example of this technique is: 1) Allocate a chunk of DRAM: 20K, for example. 2) Load the entire 20K with wave data. 3) Start up a voice with looping disabled and rollover enabled. Set its end position to the MIDDLE of the buffer. 4) When the voice hits the middle, you will get an IRQ, but the voice will continue to play. 5) At this point, enable looping and disable the rollover. Also, set the end position to the end of the buffer. This will make the voice loop back to the beginning without stopping. 6) Now load the FIRST 10K with more wave data. This will make sure that there is correct data to play when the voice loops. 7) When the voice loops, you will get and IRQ. 8) At this point, disable looping, enable rollover and set the end position back to the middle of the buffer. 9) Now load the SECOND 10K with more wave data. This will make sure that there is corect data to play when the rollover occurs. 10) Continue in a loop, starting at step #4. Note:This algorithm does not take care of an initial condition where not enough data exists to fill one complete buffer. It also doesn't address how to finish playing the last incomplete buffer. These points are left up to your implementation to resolve. :Patch file format %Patch Files Format This appendix contains information about the the patch file format. It assumes the reader is familiar with wave table synthesis, music, sound, and the GF1 ASIC chip that is the heart of the UltraSound audio card. The UltraSound patch file is a collection of data structures and sound data in the following format: patch header (# instruments) instrument header 1 (#layers) layer 1 header (# waves) wave 1 header wave 1 data wave 2 header wave 2 data ... wave n header wave n data layer 2 header (# waves) wave 1 header wave 1 data wave 2 header wave 2 data ... wave n header wave n data instrument header 2 (#layers) etc. All of the Advanced Gravis UltraSound patches contain one instrument at the current time. Except for the main patch header, each of the headers has a size field which can be used to seek past unwanted data. For example, if a patch has two instruments and you want to skip the first instrument, you would read the first instrument header, and then skip INSTRUMENT_SIZE bytes. What follows is the patch header definitions given in C and Pascal. After the definitions, a field-by-field breakdown of the headers is given. %====== % C: %====== #define ENVELOPES 6 #define HEADER_SIZE 12 #define ID_SIZE 10 #define DESC_SIZE 60 #define RESERVED_SIZE 40 #define PATCH_HEADER_RESERVED_SIZE 36 #define LAYER_RESERVED_SIZE 40 #define PATCH_DATA_RESERVED_SIZE 36 #define GF1_HEADER_TEXT "GF1PATCH110" #define MAX_LAYERS 4 #define INST_NAME_SIZE 16 %typedef struct { char header[ HEADER_SIZE ]; char gravis_id[ ID_SIZE ]; /* Id = "ID#000002" */ char description[ DESC_SIZE ]; unsigned char instruments; char voices; char channels; unsigned int wave_forms; unsigned int master_volume; unsigned long data_size; char reserved[ PATCH_HEADER_RESERVED_SIZE ]; } PATCHHEADER; %typedef struct { unsigned int instrument; char instrument_name[ 16 ]; long instrument_size; char layers; char reserved[ RESERVED_SIZE ]; } INSTRUMENTDATA; %typedef struct { char layer_duplicate; char layer; long layer_size; char samples; char reserved[ LAYER_RESERVED_SIZE ]; } LAYERDATA; %typedef struct { char wave_name[7]; unsigned char fractions; long wave_size; long start_loop; long end_loop; unsigned int sample_rate; long low_frequency; long high_frequency; long root_frequency; int tune; unsigned char balance; unsigned char envelope_rate[ ENVELOPES ]; unsigned char envelope_offset[ ENVELOPES ]; unsigned char tremolo_sweep; unsigned char tremolo_rate; unsigned char tremolo_depth; unsigned char vibrato_sweep; unsigned char vibrato_rate; unsigned char vibrato_depth; /* bit 0 = 8 or 16 bit wave data. */ /* bit 1 = Signed - Unsigned data. */ /* bit 2 = looping enabled-1. */ /* bit 3 = Set is bidirectional looping. */ /* bit 4 = Set is looping backward. */ /* bit 5 = Turn sustaining on. (Env. pts. 3)*/ /* bit 6 = Enable envelopes - 1 */ char modes; int scale_frequency; unsigned int scale_factor; /* from 0 to 2048 or 0 to 2 */ char reserved[ PATCH_DATA_RESERVED_SIZE ]; } PATCHDATA; ^File Header %'Header' The header field should contain the text "GF1PATCH110." The first 8 bytes will always be GF1PATCH. The next three bytes are the version number of the patch format. As fields are added to the patch, the number will be incremented. All of the UltraSound patches are currently at version 110. The older 100 patches are obsolete and should no longer be in use. %'Description' This description field is usually for copyright information. %'Instruments' The number of instruments in the patch. All of the gravis patches contain only one instrument. %'Voices' The GF1 synth can update 14 voices at 44.1Khz. As the number of voices increases, the actual output rate of each voice drops. This field should contain the number of voices that were used when creating the patch. This field could be used by a MIDI engine to try and make the patch sound the same regardless of the number of active voices. Currently this feature is not implemented in the gravis MIDI engine. %'Channels' This field is unused. Only mono data can be played out a voice with the GF1. %'Wave_Forms' The total number of waveforms in the patch. This field is used by programs which need to preallocate space for wave form headers before the patch is loaded. %'Master_Volume' This field is currently unused. %'Data_Size' The size of the patch data after it is loaded into GF1 dram. This number includes the space needed to align each of the waveforms on 32 byte boundaries. If you patch loader maintains linked list of waveforms in dram, and you need to use an extra 32 bytes per waveform, then you can use the wave_forms field to figure out how much memory you will need to load the patch. i.e. data_size + (32 * wave_forms). ^Instrument Header %'Instrument' This field is currently unused. %'Instrument_Name' This field is currently unused. %'Instrument_Size' The size of the instrument. The number of bytes to skip in order to read the next instrument header. %'Layers' The number of layers in this instrument. Multiple layers are usually used in patches where more than one sound is required with a single MIDI event (note on). For example, a piano would could have two layers. The first would be the actual tone from the hammer hitting the strings, and the second would be the (thunk) of the key being struck and all of the mechanisms moving inside the piano. The mechanisms would probably be frequency independant, and also independant of the length of the tone. ^Layer Header %'Layer_Duplicate' Currently unused. If the layer duplicate is nonzero, then this layer should use the data from the previous layer. Only the headers will follow. %'Layer' The current layer number for this instrument %'Layer_Size' The size of this layer. Can be used to seek past this layer in the file. %'Samples' The number of waveforms in this layer. This field is ignored if layer_duplicate is true. ^Wave Header %'Wave_Name' This field is currently unused %'Fractions' The start_loop and end_loop are the integer portions of the wavetable address. The GF1 can interpolate between sample points and therefore meore resolution than just the integer address is needed. The most significant four bits are the fractional address for the start_loop, and the least significant four bits are the fractional address for the end_loop. %'Wave_Size' The number of bytes of wave table data that follows -- not # of samples. %'Start_Loop' The integer portion of the starting loop address relative to the beginning of the wave. This address is the relative number of bytes, and not the number of samples. %'End_Loop' The integer portion of the ending loop address relative to the beginning of the wave. This address is the relative number of bytes, and not the number of samples. %'Sample_Rate' This is the sample rate of the recorded data. This number is not related to the actual pitch of the recorded tone. %'Low_Frequency' Each wave covers a specific frequency range. This is the lowest frequency that this wave can be used to play. This field is scaled be 1000 for accuracy. %'High_Frequency' Each wave covers a specific frequency range. This is the highest frequency that this wave can be used to play. This field is scaled by 1000 for accuracy. If there is another wave adjacent to this one and its range overlaps this range, then the next waveform will always be chosen. %'Root_Frequency' If this wave is played back at the original sample_rate, then this number should be the pitch of the original tone. This field is modified to tune the wave to a particular pitch. This field is scaled by 1000 for accuracy. %'Tune' This field is unused. Tuning is accomplished by modifying the root frequency. %'Balance' 0 is 100% to the right, and 15 is 100% to the left. As the balance is shifted from left to right, the total output power of both channels is constant. %'Envelope_Rate' An array of 6 rates to implement a 6-point envelope. The first three rates can be used for attack and decay. If the sustain flag is set, than the third envelope point will be the sustain point. The last three envelope points are for the release, and an optional "echo" effect. If the last envelope point is left at an audible level, then a sampled release can heard after the last envelope point. The rate values are sent directly to the GF1 hardware, and are described in the volume ramping section. %'Envelope_Offset' An array of 6 offsets to implement a 6-point envelope. The first three offsets can be used for attack and decay. If the sustain flag is set, than the third envelope point will be the sustain point. The last three envelope points are for the release, and an optional "echo" effect. If the last envelope point is left at an audible level, then a sampled release can heard after the last envelope point. The offset values are sent directly to the GF1 hardware, and are described in the volume ramping section. %'Tremolo_Sweep' Not implemented. Tremolo starts automatically when the note sustains. This will be changed in future software to gradually sweep in the tremolo depth from 0 at the rate of tremolo_sweep / 45 seconds. %'Tremolo_Rate' The rate of amplitude modulation. 0 is 0.05 Hz, and 255 is 6 Hz. A complete table is listed in ~TREMOLO Rate~. %'Tremolo_Depth' 0 means turn tremolo off. 255 provides a 16 dB modulation. A complete table is listed in ~TREMOLO Depth~. %'Vibrato_Sweep' Gradually sweep in the vibrato depth from 0 at the rate of vibrato_sweep / 45 seconds. %'Vibrato_Rate' The rate of frequency modulation. 0 is 0.05 Hz, and 255 is 6 Hz. A complete table is listed in ~VIBRATO Rate~. %'Vibrato_Depth' 0 means turn vibrato off. 255 is a one octave modulation. A complete table is listed in ~VIBRATO Depth~. %'Modes' A set of bit fields describing modes and data type: BIT 0- 16 bit data BIT 1- unsigned data BIT 2- looping enabled BIT 3- bidirectional loop BIT 4- play patch backwards. start at end address, loop backwards, and then end at beginning address. BIT 5- sustain - enveloping stops at third envelope point. a note off will continue enveloping. BIT 6- currently means enveloping enabled. All gravis patches have this bit set. This field will be modified in the near future to implement a sampled release at note off instead of at the last envelope point. If this bit is on, the sample release occurs after the last envelope point. If this bit is off, the sampled release occurs at the note off. BIT 7- fast release. The last three envelope points are ignored. %'Scale_Frequency' Keyboard frequency scaling. Normally, MIDI note 64 plays a middle C. A 65 plays a C#. frequency scaling changes the distance in pitch of each MIDI note. The scale_frequency is the MIDI note number which is the pivot point for scaling. If scale_frequency is 64, then MIDI note 64 will sound like a C4 regardless of scale factor. %'Scale_Factor' 1024 means normal scaling. Each MIDI note is one semitone away from its neighbor. 512 would be 1/2 semitone apart. 2048 is two semitones apart. :U_Freq calculation ^Voice Frequency Calculation (UltraDox 2.0) Based on the number of voices set through register 0Eh (Number of active voices), the divisor changes. The frequency outputted to the Ultrasound is not a frequency such as 22000hz, but rather the hertz divided by a modifier. See ~GF1~ for additional information We've traced the divisors down to 8 active voices. Apparently, there are a minimum of 14. % # Voices Divisor # Voices Divisor # Voices Divisor % ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ 24 25 8 74 16 37 25 24 9 66 17 35 26 23 10 60 18 33 27 22 11 54 19 31 28 21 12 50 20 30 29 20 13 46 21 28 30 20 14 43 22 27 31 19 15 40 23 26 32 18 It is recommended that you don't use values below 14 voices (even though it appears to work). See also: ~Freq calculation~ % Example: mov dx,BASE+103h ; ~Select Register~ port mov al,0Eh ; Set active voices. out dx,al mov dx,BASE+105h ; ~Global Data~ hi port mov al,13 or 0C0h ; Set number of active voices to 14. out dx,al mov dx,BASE+102h ; ~Page Register~ port mov al,2 ; Use voice #2. out dx,al mov dx,BASE+103h ; Select Register port mov al,1 ; Set Voice Frequency. out dx,al mov dx,BASE+105h ; Global Data hi port mov ax,511 ; 22000/43 out dx,al Do yourself a favor and make a table for your notes. :U_DRAM Addressing ^DRAM Addressing (UltraDox 2.0) Through the use of these two registers, the starting location for the active voice can be set. For an unknown reason, any memory addresses for the BEGIN, START, and END sample locations in DRAM must be divided by 128 and written to u_DataLo, then multiplied by 512 and written to u_DataLo. Set Sample Begin Location (0ah,0bh) and Set Sample End Location (4,5) will refer to this example. They are both done the same way with the exception of the Select register outs. @@Lo should be replaced with 2, 4, or 0ah (based on what you are doing), and @@Hi should be replaced with 3, 5, 0bh. @@AddrLo is the lower word of the 32-bit DRAM location. @@AddrHi is the upper word of the 32-bit DRAM location. % Example: mov dx,BASE+102h ; ~Page register~ port mov al,3 ; Use voice #3. out dx,al mov dx,BASE+103h ; ~Select register~ port mov al,@@Lo ; Request new position. out dx,al mov dx,BASE+104h ; ~Global Data~ low port mov ax,@@AddrLo mov cx,@@AddrHi call RShift out dx,ax mov dx,BASE+103h ; Select register port mov al,@@Hi out dx,al mov dx,BASE+104h ; Global Data low port mov ax,@@AddrLo shl ax,9 out dx,ax :U_Poke DRAM:U_Peek DRAM ^Poking/Peeking a byte to DRAM directly (UltraDox 2.0) DRAM addresses can range from 00000h to fffffh. By outputting the DRAM address and then accessing u_DRAMIO, direct peeks and pokes from the DRAM memory can be accomplished. % Example: mov dx,BASE+103h ; ~Select register~ port mov al,43h out dx,al mov dx,BASE+104h ; ~Global Data~ low port mov ax,@@LoDRAMAddress out dx,ax mov dx,BASE+103h ; Select register port mov al,44h out dx,al mov dx,BASE+105h ; Global Data hi port mov al,@@HiDRAMAddress out dx,al mov dx,BASE+107h ; ~DRAM I/O~ port ; At this point, you can either: in al,dx ; Peek a byte from the address just output ; or: out dx,al ; Poke a byte to the address just output. :U_Probe:Probing Ultra Sound ^Example code to probe Gravis Ultrasound card out BASE+103h, 4Ch out BASE+105h, 0 @DELAY @DELAY out BASE+103h, 4Ch out BASE+105h, 1 Poke Data Byte Loc: 0h, Byte: AA ; Don't think this HAS to be an AA. Poke Data Byte Loc: 100h, Byte: 55 ; Don't think this is needed. Peek Data Byte Loc: 0h Store Byte out BASE+103h, 4Ch out BASE+105h, 0 Restore Byte Is it AA? If so, then we have found a GUS. :U_Memory amount ^Example code to test for amount of memory installed on UltraSound card Poke Data Byte Loc: 40000h, Byte: AA Peek Data Byte Loc: 40000h Is it an AA? If not, then there is 256k of DRAM. Exit. Poke Data Byte Loc: 80000h, Byte: AA Peek Data Byte Loc: 80000h Is it an AA? If not, then there is 512k of DRAM. Exit. Poke Data Byte Loc: C0000h, Byte: AA Peek Data Byte Loc: C0000h Is it an AA? If not, then there is 768k of DRAM. Exit. Poke Data Byte Loc: 0FFFFFh, Byte: AA Peek Data Byte Loc: 0FFFFFh Is it an AA? If not, then there is 1024k of DRAM. Exit. Description: Poke these bytes on the boundaries of 256k, 512k, 768k, and 1024k. If the memory isn't there, then it won't return what is poked. :U_UltraReset:Resetting Ultrasound ^Ultrasound Reset (UltraDox 2.0) code: mov bx,BASE+103h mov cx,BASE+105h mov dx,bx mov al,4Ch out dx,al mov dx,cx mov al,0 out dx,al @DELAY @DELAY mov dx,bx mov al,4Ch out dx,al mov dx,cx mov al,1 out dx,al @DELAY @DELAY mov dx,bx mov al,41h out dx,al mov dx,cx mov al,0 out dx,al mov dx,bx mov al,45h out dx,al mov dx,cx mov al,0 out dx,al mov dx,bx mov al,49h out dx,al mov dx,cx mov al,0 out dx,al mov dx,bx mov al,0Eh out dx,al add dx,2 mov al,MaxVoices or al,0C0h out dx,al mov dx,BASE+6h in al,dx mov dx,bx mov al,41h out dx,al mov dx,cx in al,dx mov dx,bx mov al,49h out dx,al mov dx,cx in al,dx mov dx,bx mov al,8Fh out dx,al mov dx,cx in al,dx push bx cx mov cx,0 @@VoiceClearLoop: mov dx,BASE+102h mov al,cl out dx,al inc dx mov al,0 out dx,al add dx,2 mov al,3 ; Turn voice off out dx,al sub dx,2 mov al,0Dh ; Turn ramp off. out dx,al add dx,2 mov al,3 out dx,al inc cx cmp cx,32 jnz @@VoiceClearLoop pop cx bx mov dx,bx mov al,41h out dx,al mov dx,cx in al,dx mov dx,bx mov al,49h out dx,al mov dx,cx in al,dx mov dx,bx mov al,8Fh out dx,al mov dx,cx in al,dx mov dx,bx mov al,4Ch out dx,al mov dx,cx mov al,7 out dx,al ret :Module player:2_M_MAIN_ ^Module player information %Contents ~M_General~ - General information about .MOD files ~M_Fileformat~ - MOD File format by Thunder ~M_Timing~ - How fast should we play ~M_Periods~ - What frequency should we use to play a note ~M_FineTuning~ - What is finetuning and how to do it ~M_VolDb Table~ - Volume to Decibel conversion table ~M_GUSVol Table~- Volume table for Gravis UltraSound ~M_Effects~ - How to make the effects ~M_EffectList~ - List of standard effects ~M_ExtEffects~ - List of extended effects ~M_OtherInfo~ - Other information about effects ~M_ProFileFormat~ - Protracker 1.1B Module format ~M_S3M File Format~ - S3M and STM File Format ~M_ULT File Format~ - ULT File Format :M_General ^General information about .MOD files Files with the extension '.MOD' are sequenced music files. The file format has it's roots in the Commodore Amiga computer (ugh!). These files use different digital 'samples' played at various frequencies to create three octaves of 'notes' for that sample. In addition to different 'notes', there are a large number of 'effects' which can be done to produce variations on the different notes. There are many variations on the MOD format. Since the format originated on the Commodore Amiga computer, the files were geared towards a machine with 4 voices. These days, with a GUS (Gravis UltraSound), you have 32 independent voices. If you are programming for a sound board or device that has only 1 or 2 digital voices, you will have to mix together the 4 to 8 output channels into those voices. I will not go into this process here, since I do not have experience with it (you don't need to mix on the GUS). The earliest versions of the MOD format used a maximum of 15 instruments and had 4 channels. Through some modifications in format, a 'newer' standard emerged, with a maximum of 31 instruments and up to 8 channels. You can tell what format of file you are working with by a four-character tag field. The programs that are used to play these files on the Amiga are called 'Noisetracker', 'Soundtracker', and 'Protracker'. :M_Fileformat ^.MOD File Format 'Big-End Word' refers to the word format on the Amiga. A 2-byte integer value is a word. On the Amiga, this value has the internal representation HHLL, where HH means the high-order byte and LL means the low-order byte. The Intel chips (inside PCs) use a LLHH format for their words. This means that if you are writing routines for the PC, you have to flip the high and low order bytes to retrieve meaningful values. % Offset Length Format Description %======== ======== ========= ============= 0 20 Chars Title of the song. If the title is not a full 20 chars in length, it will be null- terminated. ~M_F_Song name~ 20 22 Chars Sample 1 name. If the name is not a full 22 chars in length, it will be null terminated. ~M_F_Sample Info~ 42 2 Big-End Sample 1 length in 2-byte words. Multiply Word this value by 2 to get the length of the sample in bytes. 44 1 SNibble Sample 1 finetune. 45 1 Byte Sample 1 linear volume. 46 2 Big-End Sample 1 repeat offset in 2-byte words. Word Multiply this value by 2 to get the position in bytes. 48 2 Big-End Sample 1 repeat length in 2-byte words. Word Multiply this value by 2 to get the length in bytes. 50 30 Sample 2 information. Same format. 80 30 Sample 3 information Same format. . There will either be 15 or 31 sample information blocks. . See the format tag field below for a description of how . to find out how many instruments there are. We'll go on . the assumption that there are 31 instruments in the file. 920 30 Sample 31 information. 950 1 Byte Number of patterns in SONG as played. ~M_F_NPatterns~ 951 1 Byte Song end jump position.~M_F_EndJumpPos~ 952 128 Bytes Pattern Table. These list up to 128 pattern numbers and the order they should be played in. ~M_F_PatternTbl~ 1080 4 Chars File format tag. ~M_F_FileTag~ 1084 ... Pattern and Sample data. Please see pattern section and sample section for more information. :M_F_Song Name ^Song Name This data is pretty self-representative. This is a C 'string' that is null-terminated (i.e. ASCII character 0 is put at the end of the text is the text does not fill up the entire field). Some module writers use this field and the instrument name fields to write 'hello' messages to their friends or dedications instead of giving names to the song or it's samples. I in no way discourage this. :M_F_Sample Info ^Sample Information Based on the format tag field, there can be 15 or 31 sampled instruments for the song. These days it is rare to run into an 'older' format song with only 15 instruments. Please see the ~M_F_Filetag~ field for more information on how to determine how many samples there are in a file. %Sample Name The first field in a sample information block is the sample's name. As was mentioned above, these names are frequently used by the composer to say hello to his or her friends. Again, I in no way discourage this. If the sample name begins with a '#' character (ASCII $23 (35)) then this is assumed not to be an instrument name, and is probably a message. %Sample Length The second field is the sample length in words. Once again, since this is a 680x0 word, the bytes have the order HHLL, and you have to swap them to use the word on PCs. The first 2 bytes of the sample are used by the Amiga players for repeat information, and therefore are NOT part of the playable data. Therefore, if this field is evaluated to a length of less than 3 bytes, there is NO sample. %Sample finetune value The third field is the sample's initial finetune value. The lower four bits represent a signed nibble (-8..7). Each finetune step changes the note 1/8th of a semitone. This is implemented by switching to a different table of period-values for each finetune value. See ~M_Periods~ for a discussion of fine-tuning. %Sample volume The fourth field is the sample's playback volume. These are LINEAR values that range from 0 to 64, with 64 being maximum volume. If you are implementing a MOD player, remember to check if you need to use logarithmic volumes. 'Decibel' is a logrithmical unit, which represents how we feel sound intensity. The volume and decibel value table for conversions is in ~M_VolDb Table~. If you have a GUS, read ~M_GUSVol~. %Sample repeat start The fifth field in the sample information block is the sample repeat start offset. Once this sample has been played completely from beginning to end, if the repeat length (next field) is greater than two bytes it will loop back to this position in the sample and continue playing. Once it has played for the repeat length, it continues to loop back to the repeat start offset. This means the sample continues playing until it is told to stop. %Sample repeat length The last, or sixth field in the sample information is the repeat length. A sample is only looped if this value is greater than 2 bytes. :M_VolDb Table ^Volume - Decibel conversion table Volume Decibel Value Volume Decibel Value ------------------------- ------------------------ 64 0.0 32 -6.0 63 -0.1 31 -6.3 62 -0.3 30 -6.6 61 -0.4 29 -6.9 60 -0.6 28 -7.2 59 -0.7 27 -7.5 58 -0.9 26 -7.8 57 -1.0 25 -8.2 56 -1.2 24 -8.5 55 -1.3 23 -8.9 54 -1.5 22 -9.3 53 -1.6 21 -9.7 52 -1.8 20 -10.1 51 -2.0 19 -10.5 50 -2.1 18 -11.0 49 -2.3 17 -11.5 48 -2.5 16 -12.0 47 -2.7 15 -12.6 46 -2.9 14 -13.2 45 -3.1 13 -13.8 44 -3.3 12 -14.5 43 -3.5 11 -15.3 42 -3.7 10 -16.1 41 -3.9 9 -17.0 40 -4.1 8 -18.1 39 -4.3 7 -19.2 38 -4.5 6 -20.6 37 -4.8 5 -22.1 36 -5.0 4 -24.1 35 -5.2 3 -26.6 34 -5.5 2 -30.1 33 -5.8 1 -36.1 0 Minus infinity The reason for the table starting at 0 dB as the convention from taperecorders of having 0 dB as the optimal recording condition, and displaying anything worse as a negative number. See ~M_GUSVol~ for a complete linear volume format for Gravis UltraSound. :M_F_NPatterns ^Number of patterns in song This byte represents the number of patterns which are played in the entire SONG. This is NOT the number of patterns in the FILE. The file may contain (theoretically) up to 256 patterns, whereas the song is just a selection of those patterns. If I have 30 patterns in my file, and I just want to play patterns 6, 12, 3, 7, and 8 in that order, this byte will have the value 5. :M_F_EndJumpPos ^Song end jump position Historically, this byte has been used for many purposes. Most commonly in the newer format it has been used to signify if a song is to be repeated indefinitely. Some game programs have background music which never ends. If this byte is less than 127, then it specifies the position in the pattern table to jump to when the last pattern has been played. If this byte is greater than or equal to 127, the song ends. :M_F_PatternTbl ^Pattern table This 128 byte block lists the order that patterns in the file should be played in. Only the number of bytes specified by the number of patterns in the song (see ~M_F_NPatterns~) can be considered valid. If the song is to play patterns 6, 0, 12, 11, 21, and 10 in that order, then the table will have those 6 values as the first 6 bytes: Pattern Table Position ---> 0 1 2 3 4 5 6 ---------> 127 |---|---|---|---|---|---|---|---...---|---| |006|000|012|011|021|010| ????????? | |---|---|---|---|---|---|---|---...---|---| One of the effects which is possible (see ~M_Effects~) is a position jump. The argument to this effect is where to jump to in the PATTERN TABLE. This does NOT specify which PATTERN to jump to. In a particular pattern there are 64 lines. These lines are played in order from 0 to 63. When the end of a pattern is reached, playing continues with the next pattern in the pattern table, unless the current pattern is the last one. If the current pattern IS the last one, check the song end jump position (see ~M_F_EndJumpPos~) to see if the song loops to a certain position in the pattern table. Another one of the effects which is possible (see ~M_Effects~) is a pattern break. If this effect is encountered, playing immediately jumps to the first line of the next pattern. :M_F_Filetag ^File format tag This is the most controversial field in the file. This field has been the most 'ravaged', with many people using it in non-standard ways for their own purposes. There are a few standard tags which you can find here which tell you DEFINITELY what file format the file is, but there are many more non-standard tags. This makes the job of deciding what format a MOD is a difficult one. I will attempt to describe the known formats below. If you know of one I miss, please let me know. 'M.K.', 'FLT4', 'M!K!', '4CHN' : 4 channels, 31 instruments '6CHN' : 6 channels, 31 instruments '8CHN', 'OCTA' : 8 channels, 31 instruments Other information that is found in this field can be assumed to be somebody's attempt at protection, or some other information that was used in the 'older' file format. If you can't find any of the above information, it is best to assume that it's a 4 channel file. As for how many instruments there are, check the bytes at location 471 in the file. If there is text there (ASCII $20-$7E (32-126)), then you can probably assume it's a 31-instrument file. Otherwise, it's an older 15 instrument file. :M_F_Patterns ^Patterns There can be any number of patterns in the file. They are stored after the file header and before the sample data. There are USUALLY less than 64, but the maximum is not limited - if the file tag is 'M!K!' there are definitely more than 64 patterns. The patterns are stored sequentially (i.e. the first pattern is #0, the second pattern is #1, etc.). An individual pattern is made up of 64 'lines', stored sequentially (i.e. line 0 to line 63). Each 'line' is comprised of a note for each channel. Each 'note' is made up of 4 bytes, so depending on the number of channels in the file, there are 16, 24, or 32 bytes per line. For a four-channel file there are (4 bytes * 4 channels * 64 lines) =1024 bytes of information per pattern. To find out the number of patterns in a particular file, calculate the length of 'header' information and add to it the lengths of all samples that are mentioned in the sample information blocks. Subtract this number from the file's total size and divide by the number just computed (1024) to get the number of patterns in the file. As mentioned above, each note is stored as 4 bytes. The information held by these bytes has format shown below. How you display the contents of the 4 bytes in a player is up to you. There is NO standard way to do this. % Byte 1 Byte 2 Byte 3 Byte 4 % --------- --------- --------- --------- 7654-3210 7654-3210 7654-3210 7654-3210 wwww XXXX xxxxxxxxx yyyy ZZZZ zzzzzzzzz wwwwyyyy ( 8 bits) : sample number XXXXxxxxxxxx (12 bits) : sample 'period' ZZZZzzzzzzzz (12 bits) : effect and argument The sample number refers to a sample specified in the sample information block. Please see ~M_F_SampleInfo~ for more information on the samples. The sample 'period' corresponds to a delay value on an Amiga computer. Note that on an Intel processor, you have to order these 12 bits as 'xxxxxxxx0000XXXX' to read the value as a word. Please see ~M_Periods~ and ~M_Finetuning~ for more information on how to use these values. The effect is an effect number and an argument for the effect. Please see ~M_F_Effects~ for a discussion of the effects and how to implement them. :M_F_Smp data ^Sample data The sample data follows all of the patterns. After you have finished reading the pattern data, there will be just enough data left in the file for all of the instruments specified in the sample information section. The samples are stored sequentially from sample 1 to sample 31. The sample's data is in 8-bit two's compliment format, so if it needs to be in another format for your sound device to play it, don't forget to convert (UltraSound users: you don't need to convert the data when downloading). Remember that first two bytes are used only by the Amiga MOD players for repeat information, and therefore are NOT part of the playable data. :M_Timing ^Timing If lines are played sequentially, then how long should the player wait between successive lines? On the Amiga, the amount of time a note spends on a channel before the next note is started is calculated by using some complex formulas based on the PAL color carrier frequency. I will not try to bore you with the details of these calculations here, and if you wan't them, email me. A song can be played at a speed ranging from 1 to 127, where the speed specifies how many 'ticks' before playing the next sample. A tick is supposed to happen every .02 seconds, which gives 50 ticks per second. At the start of a line all samples specified on that line are started, samples playing are modified, speed is changed, etc. Some effects require that changes be made to a sample playing on a channel during the course of a line. For example, the retrigger effect re-starts a sample at a certain tick within a line. If the song is playing at speed 6 and the effect specifies a retrigger on the 4th tick: % Time Tick 0.00 1 - start all samples and effects 0.02 2 0.04 3 0.06 4 - retrigger sample here 0.08 5 0.10 6 ------------ 0.00 1 - start next line . . Unless a speed is specified on the first line of the first pattern, the song should start playing at speed 6.Please see ~M_SetSpeed~, for more information on changes in speed. :M_Periods ^Periods MOD players use a technique called frequency shifting to produce different 'notes' of the same sample. If I play a sample at 10 KHz, it will sound one octave higher if I double the frequency to 20 KHz, and one octave lower if I halve the frequency to 5 KHz. Since there are 12 notes per octave on a keyboard (these are called half-steps), each frequency corresponds to one twelfth root of two (1.05946) times the frequency of it's predecessor (to the left). Therefore, if the C-1 frequency (the note of C in octave 1) is 4144 Hz then: Note: C-1 C#1 D-1 ... C-2 ... Freq: 4144 4390 4651 ... 8288 ... The Amiga playing routines were written to run off different interrupts for different Amiga computers, based on whether the machine was a PAL or NTSC machine. The 'period' values are measures which are used in calculating how much data to send to each of the 4 Amiga channels per second (thereby specifying the frequency or pitch of the output). For PC programmers, you don't have to worry about this that much. The thing to remember is that a 'magic number' divided by twice the period value will give the rate (frequency) to play the sample at. Here are the magic numbers and the corresponding formulae. I don't know which number is better to use - It doesn't make a huge difference. % PAL Value NTSC Value % =========== ============ 7093789.2 7159090.5 SampleRate = -------------- SampleRate = -------------- Period * 2 Period * 2 To determine what frequency to play a sample at, look up the specified period value in a table based on the finetune setting (see ~M_Finetuning~ for more information on fine-tuning). If the period is 0, then the previous period used on that channel is used. As an example, let's look at the period table for finetune 0. The notes that are possible in each octave are: % C C# D D# E F F# G G# A A# B Octave 1: 856, 808, 762, 720, 678, 640, 604, 570, 538, 508, 480, 453 Octave 2: 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226 Octave 3: 214, 202, 190, 180, 170, 160, 151, 143, 135, 127, 120, 113 Octave 0:1712,1616,1525,1440,1357,1281,1209,1141,1077,1017, 961, 907 Octave 4: 107, 101, 95, 90, 85, 80, 76, 71, 67, 64, 60, 57 If I was requested to play a sample at period 302, I would scan through the period table until I hit that value. At that point, I know that the note is called 'F#2', F-sharp in octave 2. I calculate the playback frequency by doing the calculations on the next page. % PAL Value NTSC Value % =========== ============ 7093789.2 7159090.5 ----------- = 11745 Hz ----------- = 11853 Hz 302 * 2 302 * 2 There are normally only three octaves (1 to 3) used in playing songs. Octaves 0 and 4 are NOT standard. Some songs may use the values though, and it's nice if your player can handle them. Full period tables for all finetunes are listed in ~M_PeriodTbl~. If you wish to sample sounds to include in MOD files, remember that the data must be stored in 8-bit 2's complement format. There is NO standard sample rate when creating the samples. Most often the samples are done on the rate corresponding to period C-3 (around 16.5 KHz), and sometimes drums are sampled at A-3 (around 28 KHz). If sample number is specified on a channel (sample #0), then the last sample used on that channel will be remembered if new notes come along. Only one sample may play on a channel at a time, so playing a new sample will cancel an old one - even if there is no actual sample data for the new sample (a 'silent' sample). However, if you are constructing a MOD file of your own and you use a "silent" sample it is polite to set its default volume to 0. If you have some memory (around 2k or so) to spare, you could make up a table of words indexed by period value. The value of the word at the index of a period is the corresponding frequency that the sample should be played at. This saves you from having to calculate the frequencies over and over again. If you still don't get what I'm talking about here: I have a array of words, one for each period from the lowest (around 50) to the highest (around 1712). I precalculate the contents of this table so that at index 302 (the period for note F#2), there is the value 11853, the frequency to use to get the note F#2. Therefore, when my player runs accross this value and needs to know what frequency to play the sample at, I simply look up the value in the table directly - no calculations. If you still don't get what I'm talking about, you're screwed. :M_Finetuning ^Fine-Tuning Fine-tuning is a minor adjustment on how an instrument sounds. This is implemented by small changes in the period values. The finetune value for a sample specifies the adjustment on the period values for that instrument. A fine-tune can also be specified for a specific instrument by an effect, at which point the value in the effect will override the one in the sample information block. The value in the sample information block is a signed nibble (4 bits, signed 2's complement). Therefore, the values that can be found have the following corresponding finetunes: Value: 0 1 2 3 4 5 6 7 8 9 A B C D E F Finetune: 0 +1 +2 +3 +4 +5 +6 +7 -8 -7 -6 -5 -4 -3 -2 -1 ~M_PeriodTbl~ specifies period values for all finetunes for octaves 1 to 3. You could use these values in creating your array of frequency words (see ~M_Periods~). :M_Effects ^Effects As was mentioned ~M_F_Patterns~, the 4 bytes for a note have the following format: % Byte 1 Byte 2 Byte 3 Byte 4 % --------- --------- --------- --------- 7654-3210 7654-3210 7654-3210 7654-3210 wwww XXXX xxxxxxxxx yyyy ZZZZ zzzzzzzzz wwwwyyyy ( 8 bits) : sample number XXXXxxxxxxxx (12 bits) : sample 'period' ZZZZzzzzzzzz (12 bits) : effect and argument Again, how you display this information in a player is up to you. I have seen a zillion different formats. I have described what the sample number and period refer to. Here, we will look at the effects that are possible. At this point in time, the Amiga Protracker MOD player (version 2.3A/ 3.01) has 28 effects. Some of these effects are redundant or not possible on some PC sound cards. I will describe the effects and how they are implemented on the Amiga. PC programmers will have to adapt the effects they wish to implement on their own. All numbers are stated in hexadecimal. For the discussion of the effects, we will look at the 'effect and argument' part of the 4 bytes in the following way: Bit number: $CBA987654321 Mentioned above as: ZZZZzzzzzzzz We will use: ZZZZxxxxyyyy There are two types of effects, standard and extended. All effects use the ZZZZ portion to declare the effect number. Standard effects use the xxxx and yyyy portions as one or two arguments, either as an 8-bit value when taken together in the form xxxxyyyy or as 2 nibbles xxxx and yyyy. Extended effects have the ZZZZ effect number $E. They use the xxxx portion to declare the extended effect number and the only the yyyy portion as an argument. See ~M_EffectList~ for list of standard effects. :M_EffectList ^Standard Effects Here are the possible standard effects: ----------------------------------------------------------------------- %# Effect name Uses Arguments as ----------------------------------------------------------------------- 0 Arpeggio xxxx yyyy ;~M_Arpeggio~ 1 Slide Up (Portamento Up) xxxxyyyy ;~M_Slide Up~ 2 Slide Down (Portamento Down) xxxxyyyy ;~M_Slide Dn~ 3 Tone Portamento xxxxyyyy ;~M_TonePor~ 4 Vibrato xxxx yyyy ;~M_Vibrato~ 5 Tone Portamento + Volume Slide xxxx yyyy ;~M_ToneSlide~ 6 Vibrato + Volume Slide xxxx yyyy ;~M_VibrSlide~ 7 Tremolo xxxx yyyy ;~M_Tremolo~ 8 NOT USED n/a 9 Set SampleOffset xxxxyyyy ;~M_SetSmpOffs~ A VolumeSlide xxxx yyyy ;~M_VolumeSlide~ B Position Jump xxxxyyyy ;~M_PosJump~ C Set Volume xxxxyyyy ;~M_SetVolume~ D Pattern Break xxxxyyyy ;~M_PattrnBreak~ E *Extended Effects varies ;~M_ExtEffects~ F Set Speed xxxxyyyy ;~M_SetSpeed~ :M_ExtEffects ^Extended Effect list And here are the possible extended effects: --------------------------------- % # Effect name --------------------------------- E0 Set Filter ;~M_E_SetFilter~ E1 FineSlide Up ;~M_E_FineSlide Up~ E2 FineSlide Down ;~M_E_FineSlide Dn~ E3 Glissando Control ;~M_E_Glissando~ E4 Set Vibrato Waveform ;~M_E_Set VibratoWave~ E5 Set FineTune ;~M_E_Set FineTune~ E6 PatternLoop ;~M_E_LoopPattrn~ E7 Set Tremolo Waveform ;~M_E_Set TremoloWave~ E8 NOT USED E9 Retrig Note ;~M_E_Retrig Note~ EA Fine VolumeSlide Up ;~M_E_FineVolSlide Up~ EB Fine VolumeSlide Down ;~M_E_FineVolSlide Dn~ EC NoteCut ;~M_E_NoteCut~ ED NoteDelay ;~M_E_NoteDelay~ EE PatternDelay ;~M_E_PatternDelay~ EF Invert Loop ;~M_E_Invert Loop~ A description of each effect and how it is implemented is given on the following pages. Once again, all values are given in hexadecimal unless otherwise stated. :M_Arpeggio ^0: Arpeggio If a note as an effect number of 0, it is only an arpeggio if there is at least one non-zero argument. When there is at least one valid argument, this effect means to play the note specified, then the note+xxxx half- steps, then the note+yyyy half-steps, and then return to the original note. These changes are evenly spaced within the time for a line to be played at the current speed. This effect is usually used to simulate chords (where a major chord is the note+4 half steps and the note+7 half-steps). This does not work very well on most samples. This can also be used to produce a heavy vibrato. Here is an example of this effect: Note C-3, xxxx=4, yyyy=7 this will attempt to produce a C-major chord. At the beginning of a line the C-3 note is played, then at 1/3 of the way through the line the note is retriggered at E-3, 2/3 of the way through it is retriggered at G-3, and at the beginning of the next line (if there are no new notes to be played on the channel), it is retriggered at C-3 again. This presents a minor problem for timing, since you have to keep track of the arpeggio during the course of playing a line. What you could do is use a timer differently, or set up another timer that independently tracks the timing of the arpeggio. % Cmd 0. Arpeggio [Range:$0-$F/$0-$F] % ----------------------------------- Usage: $0 + 1st halfnote add + 2nd halfnote add Arpeggio is used to simulate chords. This is done by rapidly changing the pitch between 3(or 2) different notes. It sounds very noisy and grainy on most samples, but ok on monotone ones. Example: C-300047 C-major chord: (C+E+G or C+4+7 halfnotes) C-300037 C-minor chord: (C+D#+G or C+3+7 halfnotes) :M_Slide Up:M_Porta Up ^1: Slide up (Portamento Up) This effect will slide up the frequency (decrease the period) of the sample being played on the channel by xxxxyyyy notes for every tick that occurs during the line. You usually cannot slide past note B-3 unless you have implemented octave 4 (NON-STANDARD!). The number of ticks that occur per line is set with effect $F, the set speed command. Since the slide rate depends on the speed, be careful if you set are composing a MOD when you change the speed. An example of this effect is: Note C-3, xxxxyyyy = 2, playing at speed 3. At the beginning of the line the sample is started at period C-3. At the first tick, the period is decremented by 2 (the frequency is increased). At the second tick, the period is again decremented by 2. At the beginning of the next line, if there is not a new note to be played the period is again decremented by 2. % Cmd 1. Portamento up [Speed:$00-$FF] % ------------------------------------ Usage: $1 + portamento speed Portamento up will simply slide the sample pitch up. You can NOT slide higher than B-3! (Period 113) Example: C-300103 1 is the command, 3 is the portamentospeed. NOTE: The portamento will be called as many times as the speed of the song. This means that you'll sometimes have trouble sliding accuratly. If you change the speed without changing the sliderates, it will sound bad... :M_Slide Dn;M_Porta Dn ^2: Slide down (Portamento Down) This effect will slide down the frequency (increase the period) of the sample being played on the channel by xxxxyyyy tones for every tick that occurs during the line. You usually cannot slide below note C-1 unless you have implemented octave 0 (NON-STANDARD!). The number of ticks that occur per line is set with effect $F, the set speed command. Since the slide rate depends on the speed, be careful if you set are composing a MOD when you change the speed. An example of this effect is: Note C-3, xxxxyyyy = 2, playing at speed 3. At the beginning of the line the sample is started at period C-3. At the first tick, the period is incremented by 2 (the frequency is decreased). At the second tick, the period is again incremented by 2. At the beginning of the next line, if there is not a new note to be played the period is again incremented by 2. % Cmd 2. Portamento down [Speed:$00-FF] % ------------------------------------- Usage: $2 + portamento speed Just like command 1, except that this one slides the pitch down instead. (Adds to the period). You can NOT slide lower than C-1! (Period 856) Example: C-300203 2 is the command, 3 is the portamentospeed. :M_SlidetoNote:M_TonePortamento ^3: Slide to note (Tone Portamento) This effect will slide a note being played on a channel to a specified note. The parameter xxxxyyyy will states the speed at which a slide will occur. For each tick that occurs during the line, the period currently being played is altered by the number of notes specified. The number of ticks that occur per line is set with effect $F, the set speed command. Since the slide rate depends on the speed, be careful if you set are composing a MOD when you change the speed. An example of this effect is: Slide to note C-2, xxxxyyyy = 2, playing at speed 3. At the beginning of the line the current frequency for the sample is altered to be 2 notes closer to C-2. At the first tick, the same alteration occurs, changing the period to form a note even closer to C-2. The same occurs for each tick after that. This effect continues until another effect is started or the specified frequency is reached. If a slide rate is not specified (xxxxyyyy is zero) then the last slide rate used on the channel is used again. % Cmd 3. Tone-portamento [Speed:$00-$FF] % -------------------------------------- Usage: Dest-note + $3 + slidespeed This command will automatically slide from the old note to the new. You don't have to worry about which direction to slide, you need only set the slide speed. To keep on sliding, just select the command $3 + 00. Example: A-200000 First play a note. C-300305 C-3 is the note to slide to, 3 the command, and 5 the speed. :M_Vibrato ^4: Vibrato Vibrato means to "oscillate the sample pitch using a particular waveform with amplitude yyyy notes, such that (xxxx * speed)/64 full oscillations occur in the line". The waveform to use in vibrating is set using effect E4 (see below). By placing vibrato effects on consecutive lines, the vibrato effect can be sustained for any length of time. If either xxxx or yyyy are 0, then values from the most recent prior vibrato will be used. An example is: Note C-3, with xxxx=8 and yyyy=1 when speed=6. This will play tones around C-3, vibrating through D-3 and B-2 to C-3 again (amplitude - yyyy - is 1), with (8*6)/64 = 3/4 of a full oscillation per line. Please see effect E4 for the waveform to use for vibrating. % Cmd 4. Vibrato [Rate:$0-$F,Dpth:$0-$F] % -------------------------------------- Usage: $4 + vibratorate + vibratodepth Example: C-300481 4 is the command, 8 is the speed of the vibrato, and 1 is the depth of the vibrato. To keep on vibrating, just select the command $4 + 00. To change the vibrato, you can alter the rate, depth or both. Use command E4- to change the vibrato-waveform. :M_ToneSlide ^5: Tone Portamento with Volume slide This effect will change the volume of a channel while a tone portamento (~M_TonePor~) is taking place. The values xxxx or yyyy specify the speed of the volume change. If xxxx is nonzero the volume is increased, and if yyyy is nonzero the volume is decreased. It is illegal for both xxxx and yyyy to be non-zero. You cannot slide past 64 or below 0. As an example, take the xxxx to be set to 3. This means that at the beginning of the line, the current volume of the channel is increased by 3. The volume is increased again for every tick on this line and the lines following (until there is a new effect). Once again, the volume cannot slide up past 64. % Cmd 5. ToneP + Volsl [Spd:$0-$F/$0-$F] % -------------------------------------- Usage: $5 + upspeed + downspeed This command will continue the current toneportamento and slide the volume at the same time. Stolen from NT2.0. Example: C-300503 3 is the speed to turn the volume down. C-300540 4 is the speed to slide it up. :M_VibrSlide ^6: Vibrato with Volume slide This effect will change the volume of a channel while a vibrato (~M_Vibrato~) is taking place. The values xxxx or yyyy specify the speed of the volume change. If xxxx is nonzero the volume is increased, and if yyyy is nonzero the volume is decreased. It is illegal for both xxxx and yyyy to be non-zero. You cannot slide past 64 or below 0. As an example, take the yyyy to be set to 2. This means that at the beginning of the line, the current volume of the channel is decreased by 2. The volume is decreased again for every tick on this line and the lines following (until there is a new effect). Once again, the volume cannot slide down below 0. % Cmd 6. Vibra + Volsl [Spd:$0-$F/$0-$F] % -------------------------------------- Usage: $6 + upspeed + downspeed This command will continue the current vibrato and slide the volume at the same time. Stolen from NT2.0. Example: C-300605 5 is the speed to turn the volume down. C-300640 4 is the speed to slide it up. :M_Tremolo ^7: Tremolo Tremolo means to "oscillate the sample volume using a particular waveform with amplitude yyyy*(speed-1), such that (xxxx*speed)/64 full oscillations occur in the line". The waveform to use to oscillate is set using the effect E7 (see ~M_E_Set TremoloWave~). By placing tremolo effects on consecutive lines, the tremolo effect can be sustained for any length of time. If either xxxx or yyyy are 0, then values from the most recent prior tremolo will be used. The usage of this effect is similar to that of effect ~M_Vibrato~. % Cmd 7. Tremolo [Rate:$0-$F,Dpth:$0-$F] % -------------------------------------- Usage: $7 + tremolorate + tremolodepth Tremolo vibrates the volume. Example: C-300794 7 is the command, 9 is the speed of the tremolo, and 4 is the depth of the tremolo. To keep on tremoling, just select the command $7 + 00. To change the tremolo, you can alter the rate, depth or both. Use command E7- to change the tremolo-waveform. :M_SetSmpOffs ^9: Set sample offset This effect allows you to start a sample from a specified position rather than the normal beginning position. Multiply the value xxxxyyyy by 512 to get the position in bytes from the beginning of the sample where playback should start. If no sample is specified with the effect, but one is currently playing on the channel, then the sample currently playing is retriggered to offset specified. An example is instrument 2 being played at note C-3, with xxxxyyyy=$23. This would make playback of the sample start at offset $23*$200 = $4600. This effect gives a rough range to play the sample from. % Cmd 9. Set SampleOffset [Offs:$00-$FF] % -------------------------------------- Usage: $9 + Sampleoffset This command will play from a chosen position in the sample, and not from the beginning. The two numbers equal the two first numbers in the length of the sample. Handy for speech- samples. Example: C-300923 Play sample from offset $2300. :M_VolumeSlide ^A: Volume slide This effect will change the volume of all samples being played on a channel. The values xxxx or yyyy specify the speed of the volume change. If xxxx is nonzero the volume is increased, and if yyyy is nonzero the volume is decreased. It is illegal for both xxxx and yyyy to be non- zero. You cannot slide past 64 or below 0. As an example, take the yyyy to be set to 3. This means that at the beginning of the line, the current volume of the channel is decreased by 3. The volume is decreased by 3 again for every tick on this line and the lines following (until there is a new effect). Once again, the volume cannot slide down below 0. % Cmd A. Volumeslide [Speed:$0-$F/$0-$F] % -------------------------------------- Usage: $A + upspeed + downspeed Example: C-300A05 5 is the speed to turn the volume down. C-300A40 4 is the speed to slide it up. NOTE: The slide will be called as many times as the speed of the song. The slower the song, the more the volume will be changed on each note. :M_PosJump ^B: Position Jump This effect xxxxyyyy parameter specifies a position in the pattern table that playback should jump to after this line. Legal values are in the range of the number of patters that are supposed to be in the song (see ~M_F_NPatterns~). Values outside this range should be ignored. % Cmd B. Position-jump [Pos:$00-$7F] % ---------------------------------- Usage: $B + position to continue at Example: C-300B01 B is the command, 1 is the position to restart the song at. This command will also perform a pattern-break. You can use this command instead of restart as on noisetracker, but you must enter the position in hex! :M_SetVolume ^C: Set volume Effect C will set the volume on a channel to the setting specified by the xxxxyyyy value. Legal volumes are in the range of 0 to 64. An attempt to set the volume to a higher value than 64 will just set it to 64. % Cmd C. Set volume [Volume:$00-$40] % ---------------------------------- Usage: $C + new volume Well, this old familiar command will set the current volume to your own selected. The highest volume is $40. All volumes are represented in hex. (Programmers do it in hex, you know!) Example: C-300C10 C is the command, 10 is the volume (16 decimal). :M_PattrnBreak ^D: Pattern Break This effect is equivalent to a position jump to the next pattern in the pattern table, with the arguments xxxx*10+yyyy specifying the line within that pattern to start playing at. Note that this is NOT xxxx*16+yyyy. For example, the effect with arguments xxxx=0, yyyy=0 would simply jump to the first line in the next pattern in the pattern table after playing the current line. With arguments xxxx=1 and yyyy=6 would jump to the 16th line of the next pattern in the pattern table after playing the current line. % Cmd D. Pattern-break % [Pattern-pos:00-63, decimal] % ---------------------------- Usage: $D + pattern-position This command just jumps to the next song-position, and continues play from the patternposition you specify. Example: C-300D00 Jump to the next song-position and continue play from patternposition 00. Or: C-300D32 Jump to the next song-position and continue play from patternposition 32 instead. :M_E_SetFilter ^E0: Set filter on/off This sets a hardware sound filter to ON (if yyyy is 0) or OFF (if xxxx is nonzero). If your sound device has built-in filters, you should ignore this effect command. This effect is primarily used on Amiga 500 and 2000 computers to dick around with the hardware filter. % Cmd E0. Set filter [Range:$0-$1] % -------------------------------- Usage: $E0 + filter-status This command jerks around with the sound-filter on some A500 + A2000. All other Amiga-users should keep out of playing around with it. Example: C-300E01 disconnects filter (turns power LED off) C-300E00 connects filter (turns power LED on) :M_E_FineSlide Up ^E1: Fineslide up This effect functions just like ~M_Porta Up~, except that the frequency of the sample is only modified once. At the beginning of a line, whatever frequency is being played on a channel is incremented by yyyy notes. This effect does NOT continue on the lines following. You cannot slide the frequency above the note B-3 (unless you implement octave 4 : NON- STANDARD!). An example here would be effect E, xxxx=1 (the extended effect number), yyyy=3. This would slide the current frequency up three notes at the beginning of the line. % Cmd E1. Fineslide up [Range:$0-$F] % ---------------------------------- Usage: $E1 + value This command works just like the normal portamento up, except that it only slides up once. It does not continue sliding during the length of the note. Example: C-300E11 Slide up 1 at the beginning of the note. (Great for creating chorus effects) :M_E_FineSlide Dn ^E2: Fineslide down This effect functions just like ~M_Porta Dn~, except that the frequency of the sample is only modified once. At the beginning of a line, whatever frequency is being played on a channel is decremented by yyyy notes. This effect does NOT continue on the lines following. You cannot slide the frequency below the note C-1 (unless you implement octave 0 : NON- STANDARD!). An example here would be effect E, xxxx=1 (the extended effect number), yyyy=2. This would slide the current frequency down two notes at the beginning of the line. % Cmd E2. Fineslide down [Range:$0-$F] % ------------------------------------ Usage: $E2 + value This command works just like the normal portamento down, except that it only slides down once. It does not continue sliding during the length of the note. Example: C-300E26 Slide up 6 at the beginning of the note. :M_E_Glissando ^E3: Set glissando on/off The argument yyyy to this effect specifies whether the glissando effect is ON (yyyy is 1) or OFF (yyyy is 0). If glissando is on, then the 'Slide to note' will slide a half note at a time. Otherwise, it will perform the default smooth slide. % Cmd E3. Glissando Ctrl [Range:$0-$1] % ------------------------------------ Usage: $E3 + Glissando-Status Glissando must be used with the tone- portamento command. When glissando is activated, toneportamento will slide a halfnote at a time, instead of a straight slide. Example: C-300E31 Turn Glissando on. C-300E30 Turn Glissando off. :M_E_Set VibratoWave ^E4: Set vibrato waveform This effect means to set the waveform appearance for succeeding 'vibrato' effects. There are currently four possible appearances for the wave, each with a possible 'retrigger'. Two cycles are shown below for each type of waveform: yyyy Waveform Name Retriggered No Retrigger ---------- ------------------- ----------- ------------ /\ /\ Sine (default) 0 4 \/ \/ |\ |\ Ramp down 1 5 \| \| ,-, ,-, Square 2 6 '-' '-' ????????? Random 3 7 A "retriggered" waveform will be reset to the start of a cycle at the beginning of each new note. If a wave is selected "without retrigger", the previous waveform will be continued. Waveforms are usually retriggered. % Cmd E4. Set vibrato waveform % [Range:$0-$3] % ---------------------------- Usage: $E4 + vibrato-waveform Example: C-300E40 Set sine(default) E44 Don't retrig WF C-300E41 Set Ramp Down E45 Don't retrig WF C-300E42 Set Squarewave E46 Don't retrig WF C-300E43 Set Random E47 Don't retrig WF :M_E_Set FineTune ^E5: Set finetune value This effect command sets the finetune value for the current instrument to the signed nibble value yyyy. This value overrides the value found in the sample information block at the beginning of the MOD file. The new finetune remains until changed by another E5 effect. Value: 7 6 5 4 3 2 1 0 F E D C B A 9 8 Finetune to set: +7 +6 +5 +4 +3 +2 +1 0 -1 -2 -3 -4 -5 -6 -7 -8 This effect is implemented by storing period values for all possible finetunes, and simply switching to a different table of periods when this effect is encountered. See ~M_FineTuning~ for more information. ~M_PeriodTbl~ lists the period tables for finetunes for octaves 1 to 3. % Cmd E5. Set finetune [Range:$0-$F] % ---------------------------------- Usage: $E5 + finetune-value Example: C-300E51 Set finetune to 1. Use these tables to figure out the finetune-value. Finetune: +7 +6 +5 +4 +3 +2 +1 0 Value: 7 6 5 4 3 2 1 0 Finetune: -1 -2 -3 -4 -5 -6 -7 -8 Value: F E D C B A 9 8 :M_E_LoopPattrn ^E6: Loop pattern This effect allows a section of a pattern to be 'looped', or played through, a certain number of times in succession. If the effect argument yyyy is zero, the effect specifies the loop's start point. Otherwise, it specifies the number of times to play this line and the preceeding lines from the start point. If no start point was specified in the current pattern being played, the loop start defaults to the first line in the pattern. Therefore, you cannot loop through multiple patterns. An example: On line 3, the effect E6 is encountered, with yyyy=0. This specifies that line 3 is the beginning of a loop in this pattern. Down on line 52, the effect E6 is encountered again, with yyyy=2. This means to jump back and play the lines from line 3 to line 52 again twice more before continuing with the rest of the pattern. % Cmd E6. PatternLoop [Loops:$0-$F] % ---------------------------------- Usage: $E6 + number of loops This command will loop a part of a pattern. Example: C-300E60 Set loopstart. C-300E63 Jump to loop 3 times before playing on. :M_E_Set TremoloWave ^E7: Set tremolo waveform Line command E4, this sets the waveform appearance for succeeding 'tremolo' (volume) effects. There are currently four possible appearances for the wave, each with a possible 'retrigger'. Two cycles are shown below for each type of waveform: yyyy Waveform Name Retriggered No Retrigger ---------- ------------------- ----------- ------------ /\ /\ Sine (default) 0 4 \/ \/ |\ |\ Ramp down 1 5 \| \| ,-, ,-, Square 2 6 '-' '-' ????????? Random 3 7 A "retriggered" waveform will be reset to the start of a cycle at the beginning of each new note. If a wave is selected "without retrigger", the previous waveform will be continued. Waveforms are usually retriggered. % Cmd E7. Set tremolo waveform % [Range:$0-$3] % ---------------------------- Usage: $E7 + tremolo-waveform Example: C-300E70 Set sine(default) E74 Don't retrig WF C-300E71 Set Ramp Down E75 Don't retrig WF C-300E72 Set Squarewave E76 Don't retrig WF C-300E73 Set Random E77 Don't retrig WF :M_E_Retrig Note ^E9: Retrigger sample Effect E9 allows you to re-trigger a specified sample at a particular note after yyyy ticks during the line. For example, say note C-3 is specified, with yyyy=2 when the speed is currently 6. This would mean that at the beginning of the line the specified sample is started, and after two ticks it is restarted. This continues until the beginning of the next line. This effect is used mostly with samples of hi-hats. % Cmd E9. Retrig note [Value:$0-$F] % --------------------------------- Usage: $E9 + Tick to Retrig note at. This command will retrig the same note before playing the next. Where to retrig depends on the speed of the song. If you retrig with 1 in speed 6 that note will be trigged 6 times in one note slot. Retrig on hi-hats! Example: C-300F06 Set speed to 6. C-300E93 Retrig at tick 3 out of 6. :M_E_FineVolSlide Up ^EA: Fine volume slide up This effect increments the volume of a particular channel once at the beginning of the line by yyyy points. There is no continuation of the slide on successive lines or for other notes. You cannot slide above volume 64. % Cmd EA. FineVolsl up [Range:$0-$F] % ---------------------------------- Usage: $EA + value This command works just like the normal volumeslide up, except that it only slides up once. It does not continue sliding during the length of the note. Example: C-300EA3 Slide volume up 1 at the beginning of the note. :M_E_FineVolSlide Dn ^EB: Fine volume slide down This effect is just like effect ~M_E_FineVolSlide Up~, except the volume is decremented rather than incremented by the value yyyy. There is no continuation of the slide on successive lines or for other notes. You cannot slide below volume 0. % Cmd EB. FineVolsl down [Range:$0-$F] % ------------------------------------ Usage: $EB + value This command works just like the normal volumeslide down, except that it only slides down once. It does not continue sliding during the length of the note. Example: C-300EB6 Slide volume down 6 at the beginning of the note. :M_E_NoteCut ^EC: Cut sample This effect sets the volume of the sample which is playing to 0 after yyyy ticks in the current line. This has the effect of stopping a sample abruptly. An example here is to play the note C-2, with effect EC and argument yyyy=3, when the speed is 6. The sample is started at note C-2 at the beginning of the line, and after the third tick of 6 in that line, the volume on the channel is set to 0 (cutting it off). Note that if yyyy is 0, nothing will be heard. % Cmd EC. Cut note [Value:$0-$F] % ------------------------------ Usage: $EC + Tick to Cut note at. This command will cut the note at the selected tick, creating extremely short notes. Example: C-300F06 Set speed to 6. C-300EC3 Cut at tick 3 out of 6. Note that the note is not really cut, the volume is just turned down. :M_E_NoteDelay ^ED: Delay sample This effect delays the start of a sample until tick yyyy in the current line. For example, if note C-2 is played, with effect ED and argument yyyy=3 when the speed is 6. The note C-2 will be triggered at the 3rd tick after the start of the line. The purpose of this effect is to delay the start of a sample for a VERY short amount of time. % Cmd ED. NoteDelay [Value:$0-$F] % ------------------------------- Usage: $ED + ticks to delay note. This command will delay the note to the selected tick. Example: C-300F06 Set speed to 6. C-300ED3 Play note at tick 3 out of 6. :M_E_PatternDelay ^EE: Delay pattern This effect forces a small delay in a pattern in between successive lines. All notes and effects continue during this delay. The argument yyyy specified the number of line-equivalent time slices to wait before resuming playback. For example, if effect EE is encountered with speed being 6 and argument yyyy=4, then the next line will be delayed 24 ticks before it is executed. % Cmd EE. PatternDelay [Notes:$0-$F] % ---------------------------------- Usage: $EE + notes to delay pattern. This command will delay the pattern the selected numbers of notes. Example: C-300EE8 Delay pattern 8 notes before playing on. All other effects are still active when the pattern is being delayed. :M_E_Invert Loop ^EF: Invert loop This effect is used on the Amiga to play samples backward at a specified speed. It is not really feasible to implement on other architechtures, and it is not used that often. % Cmd EF. Invert Loop [Speed:$0-$F] % --------------------------------- Usage: $EF + Invertspeed This command will need a short loop ($10,20,40,80 etc. bytes) to work. It will invert the loop byte by byte. Sounds better than funkrepeat... Example: C-300EF8 Set invspeed to 8. To turn off the inverting, set invspeed to 0, or press ctrl + Z. :M_SetSpeed ^F: Set speed This effect changes the speed of playback so that xxxxyyyy ticks occur during every line, starting on the NEXT line. The initial speed (before any 'set speed' effects are encountered) should be set to 6. A value of xxxxyyyy=0 should technically cause playback to stop, but this value is commonly ignored as garbage. Valid values for speed setting in this manner are 1 to 31. If a value is read that is above 31, it means to set a modified speed based on beats per minute, where 4 lines are 1 beat. This means that if I try to set the speed to 42, I am specifying 42 beats per minute, or 42*4=168 lines per minute. You then have to figure out how long to spend on a particular line. If multiple set speed effects are performed on a single line, then the effects on the higher-numbered channels have precedence over the effects on the lower-numbered channels. This effect has the largest number of implementations and is particular to the number of effects that a particular file player supports. % Cmd F. Set speed [Speed:$00-$FF] % -------------------------------- Usage: $F + speed This command will set the speed of the song. :M_OtherInfo ^Other information about the Effects If you're sound device is able to provide stereo output (like the UltraSound), then you need to know what the balance for each channel should be. Channels 1 and 4 are left, and 2 and 3 are right. If you are programming for the UltraSound, it is best not to shove the balances all the way over to the left or to the right. Try a value of 2 for channels 1 and 4 and a value of 13 for channels 2 and 3. If you don't like it - change it. :M_PeriodTbl ^Period tables Here are the period tables for the different fine-tune values: 856,808,762,720,678,640,604,570,538,508,480,453 : C-1 to B-1 Finetune 0 428,404,381,360,339,320,302,285,269,254,240,226 : C-2 to B-2 Finetune 0 214,202,190,180,170,160,151,143,135,127,120,113 : C-3 to B-3 Finetune 0 850,802,757,715,674,637,601,567,535,505,477,450 : C-1 to B-1 Finetune +1 425,401,379,357,337,318,300,284,268,253,239,225 : C-2 to B-2 Finetune +1 213,201,189,179,169,159,150,142,134,126,119,113 : C-3 to B-3 Finetune +1 844,796,752,709,670,632,597,563,532,502,474,447 : C-1 to B-1 Finetune +2 422,398,376,355,335,316,298,282,266,251,237,224 : C-2 to B-2 Finetune +2 211,199,188,177,167,158,149,141,133,125,118,112 : C-3 to B-3 Finetune +2 838,791,746,704,665,628,592,559,528,498,470,444 : C-1 to B-1 Finetune +3 419,395,373,352,332,314,296,280,264,249,235,222 : C-2 to B-2 Finetune +3 209,198,187,176,166,157,148,140,132,125,118,111 : C-3 to B-3 Finetune +3 832,785,741,699,660,623,588,555,524,495,467,441 : C-1 to B-1 Finetune +4 416,392,370,350,330,312,294,278,262,247,233,220 : C-2 to B-2 Finetune +4 208,196,185,175,165,156,147,139,131,124,117,110 : C-3 to B-3 Finetune +4 826,779,736,694,655,619,584,551,520,491,463,437 : C-1 to B-1 Finetune +5 413,390,368,347,328,309,292,276,260,245,232,219 : C-2 to B-2 Finetune +5 206,195,184,174,164,155,146,138,130,123,116,109 : C-3 to B-3 Finetune +5 820,774,730,689,651,614,580,547,516,487,460,434 : C-1 to B-1 Finetune +6 410,387,365,345,325,307,290,274,258,244,230,217 : C-2 to B-2 Finetune +6 205,193,183,172,163,154,145,137,129,122,115,109 : C-3 to B-3 Finetune +6 814,768,725,684,646,610,575,543,513,484,457,431 : C-1 to B-1 Finetune +7 407,384,363,342,323,305,288,272,256,242,228,216 : C-2 to B-2 Finetune +7 204,192,181,171,161,152,144,136,128,121,114,108 : C-3 to B-3 Finetune +7 907,856,808,762,720,678,640,604,570,538,504,480 : C-1 to B-1 Finetune -8 453,428,404,381,360,339,320,302,285,269,254,240 : C-2 to B-2 Finetune -8 226,214,202,190,180,170,160,151,143,135,127,120 : C-3 to B-3 Finetune -8 900,850,802,757,715,675,636,601,567,535,505,477 : C-1 to B-1 Finetune -7 450,425,401,379,357,337,318,300,284,268,253,238 : C-2 to B-2 Finetune -7 225,212,200,189,179,169,159,150,142,134,126,119 : C-3 to B-3 Finetune -7 894,844,796,752,709,670,632,597,563,532,502,474 : C-1 to B-1 Finetune -6 447,422,398,376,355,335,316,298,282,266,251,237 : C-2 to B-2 Finetune -6 223,211,199,188,177,167,158,149,141,133,125,118 : C-3 to B-3 Finetune -6 887,838,791,746,704,665,628,592,559,528,498,470 : C-1 to B-1 Finetune -5 444,419,395,373,352,332,314,296,280,264,249,235 : C-2 to B-2 Finetune -5 222,209,198,187,176,166,157,148,140,132,125,118 : C-3 to B-3 Finetune -5 881,832,785,741,699,660,623,588,555,524,494,467 : C-1 to B-1 Finetune -4 441,416,392,370,350,330,312,294,278,262,247,233 : C-2 to B-2 Finetune -4 220,208,196,185,175,165,156,147,139,131,123,117 : C-3 to B-3 Finetune -4 875,826,779,736,694,655,619,584,551,520,491,463 : C-1 to B-1 Finetune -3 437,413,390,368,347,338,309,292,276,260,245,232 : C-2 to B-2 Finetune -3 219,206,195,184,174,164,155,146,138,130,123,116 : C-3 to B-3 Finetune -3 868,820,774,730,689,651,614,580,547,516,487,460 : C-1 to B-1 Finetune -2 434,410,387,365,345,325,307,290,274,258,244,230 : C-2 to B-2 Finetune -2 217,205,193,183,172,163,154,145,137,129,122,115 : C-3 to B-3 Finetune -2 862,814,768,725,684,646,610,575,543,513,484,457 : C-1 to B-1 Finetune -1 431,407,384,363,342,323,305,288,272,256,242,228 : C-2 to B-2 Finetune -1 216,203,192,181,171,161,152,144,136,128,121,114 : C-3 to B-3 Finetune -1 :M_GusVol Table ^Volume table for GUS The Amiga uses linear volumes from 0 to 64. The volume table specified below lists the logarithmic volume to use on the UltraSound for each of the 65 settings in order to get a linear spread. If you need volumes for another sound device, you will have to find them elsewhere. 0 | 0 1 | 1750 17 | 2332 33 | 3469 49 | 3528 2 | 2503 18 | 3240 34 | 3473 50 | 3532 3 | 2701 19 | 3248 35 | 3478 51 | 3534 4 | 2741 20 | 3256 36 | 3481 52 | 3538 5 | 2781 21 | 3263 37 | 3484 53 | 3543 6 | 2944 22 | 3271 38 | 3489 54 | 3545 7 | 2964 23 | 3279 39 | 3492 55 | 3549 8 | 2981 24 | 3287 40 | 3495 56 | 3552 9 | 3000 25 | 3294 41 | 3499 57 | 3556 10 | 3017 26 | 3303 42 | 3502 58 | 3558 11 | 3034 27 | 3310 43 | 3506 59 | 3563 12 | 3052 28 | 3317 44 | 3509 60 | 3565 13 | 3070 29 | 3325 45 | 3513 61 | 3570 14 | 3207 30 | 3458 46 | 3517 62 | 3573 15 | 3215 31 | 3462 47 | 3520 63 | 3577 16 | 3224 32 | 3466 48 | 3524 64 | 3580 :M_ProFileFormat ^Protracker 1.1B Song/Module Format ^by Lars "ZAP" Hamre/Amiga Freelancers %Offset Bytes Description 0 20 Songname. Remember to put trailing null bytes at the end... %Information for sample 1-31: %Offset Bytes Description 20 22 Samplename for sample 1. Pad with null bytes. 42 2 Samplelength for sample 1. Stored as number of words. Multiply by two to get real sample length in bytes. 44 1 Lower four bits are the finetune value, stored as a signed four bit number. The upper four bits are not used, and should be set to zero. % Value Finetune Value Finetune Value Finetune 0 0 5 +5 A -6 1 +1 6 +6 B -5 2 +2 7 +7 C -4 3 +3 8 -8 D -3 4 +4 9 -7 E -2 F -1 45 1 Volume for sample 1. Range is $00-$40, or 0-64 decimal. 46 2 Repeat point for sample 1. Stored as number of words offset from start of sample. Multiply by two to get offset in bytes. 48 2 Repeat Length for sample 1. Stored as number of words in loop. Multiply by two to get replen in bytes. Information for the next 30 samples starts here. It's just like the info for sample 1. %Offset Bytes Description 50 30 Sample 2... 80 30 Sample 3... . . . 890 30 Sample 30... 920 30 Sample 31... %Offset Bytes Description 950 1 Songlength. Range is 1-128. 951 1 Well... this little byte here is set to 127, so that old trackers will search through all patterns when loading. Noisetracker uses this byte for restart, but we don't. 952 128 Song positions 0-127. Each hold a number from 0-63 that tells the tracker what pattern to play at that position. 1080 4 The four letters "M.K." - This is something Mahoney & Kaktus inserted when they increased the number of samples from 15 to 31. If it's not there, the module/song uses 15 samples or the text has been removed to make the module harder to rip. Startrekker puts "FLT4" or "FLT8" there instead. %Offset Bytes Description 1084 1024 Data for pattern 00. . . . xxxx Number of patterns stored is equal to the highest patternnumber in the song position table (at offset 952-1079). Each note is stored as 4 bytes, and all four notes at each position in the pattern are stored after each other. 00 - chan1 chan2 chan3 chan4 01 - chan1 chan2 chan3 chan4 02 - chan1 chan2 chan3 chan4 etc. Info for each note: _____byte 1_____ byte2_ _____byte 3_____ byte4_ / / / / 0000 0000-00000000 0000 0000-00000000 Upper four 12 bits for Lower four Effect command. bits of sam- note period. bits of sam- ple number. ple number. %Periodtable for Tuning 0, Normal C-1 to B-1 : 856,808,762,720,678,640,604,570,538,508,480,453 C-2 to B-2 : 428,404,381,360,339,320,302,285,269,254,240,226 C-3 to B-3 : 214,202,190,180,170,160,151,143,135,127,120,113 To determine what note to show, scan through the table until you find the same period as the one stored in byte 1-2. Use the index to look up in a notenames table. This is the data stored in a normal song. A packed song starts with the four letters "PACK", but i don't know how the song is packed: You can get the source code for the cruncher/decruncher from us if you need it, but I don't understand it; I've just ripped it from another tracker... In a module, all the samples are stored right after the patterndata. To determine where a sample starts and stops, you use the sampleinfo structures in the beginning of the file (from offset 20). Take a look at the mt_init routine in the playroutine, and you'll see just how it is done. :M_ULT File Format ^Mysterious's ULTRA TRACKER File Format ^by FreeJack of The Elven Nation I've done my best to document the file format of Ultra Tracker (UT). If you find any errors please contact me. The file format has stayed consistent through the first four public releases. At the time of this writting, UltraTracker is up to version 1.3 Thanks go to : SoJa of YLYSY for help translating stuff. Marc Andre Schallehn Thanks for putting out this GREAT program. Also thanks for the info on 16bit samples. With all this crap out of the way lets get to the format. %Sample Structure : ______________________________________________________________________________ Samplename : 32 bytes (Sample name) DosName : 12 bytes (when you load a sample into UT, it records the file name here) LoopStart : dbl word (loop start point) LoopEnd : dbl word (loop end point) SizeStart : dbl word (see below) SizeEnd : dbl word (see below) volume : byte (UT uses a logarithmic volume setting, ranging from 0-255) Bidi Loop : byte (see below) FineTune : word (Fine tune setting, uses full word value) ______________________________________________________________________________ ^8 Bit Samples %SizeStart : The SizeStart is the starting offset of the sample. This seems to tell UT how to load the sample into the Gus's onboard memory. All the files I have worked with start with a value of 32 for the first sample, and the previous SizeEnd value for all sample after that. (See Example below) If the previous sample was 16bit, then SizeStart = (Last SizeEnd * 2) SizeEnd : Like the SizeStart, SizeEnd seems to tell UT where to load the sample into the Gus's onboard memory. SizeEnd equal SizeStart + the length of the sample. %Example : If a UT file had 3 samples, 1st 12000 bytes, 2nd 5600 bytes, 3rd 8000 byte. The SizeStart and SizeEnd would look like this: %Sample SizeStart SizeEnd 1st 32 12032 2nd 12032 17632 3rd 17632 25632 %***Note*** Samples may NOT cross 256k boundaries. If a sample is too large to fit into the remaining space, its Sizestart will equal the start of the next 256k boundary. UT does keep track of the free space at the top of the 256k boundaries, and will load a sample in there if it will fit. Example : EndSize = 252144 If the next sample was 12000 bytes, its SizeStart would be 262144, not 252144. Note that this leaves 10000 bytes unused. If any of the following sample could fit between 252144 and 262144, its Sizestart would be 252144. Say that 2 samples after the 12000 byte sample we had a sample that was only 5000 bytes long. Its SizeStart would be 252144 and its SizeEnd would be 257144. This also applies to 16 Bit Samples. ^16 Bit Samples 16 bit samples are handled a little different then 8 bit samples. The SizeStart variable is calculated by dividing offset (last SizeEnd) by 2. The SizeEnd variable equals SizeStart + (SampleLength / 2). If the first sample is 16bit, then SizeStart = 16. %Example : sample1 = 8bit, 1000 bytes sample2 = 16bit, 5000 bytes sample1 SizeStart = 32 SizeEnd = 1032 (32 + 1000) sample2 SizeStart = 516 (offset (1032) / 2) SizeEnd = 3016 (516 + (5000/2)) %***Note*** If a 16bit sample is loaded into banks 2,3, or 4 the SizeStart variable will be (offset / 2) + 262144 (bank 2) (offset / 2) + 524288 (bank 3) (offset / 2) + 786432 (bank 4) The SizeEnd variable will be SizeStart + (SampleLength / 2) + 262144 (bank 2) SizeStart + (SampleLength / 2) + 524288 (bank 3) SizeStart + (SampleLength / 2) + 786432 (bank 4) %BiDi Loop : (Bidirectional Loop) UT takes advantage of the Gus's ability to loop a sample in several different ways. By setting the Bidi Loop, the sample can be played forward or backwards, looped or not looped. The Bidi variable also tracks the sample resolution (8 or 16 bit). %The following table shows the possible values of the Bidi Loop. Bidi = 0 : No looping, forward playback, 8bit sample Bidi = 4 : No Looping, forward playback, 16bit sample Bidi = 8 : Loop Sample, forward playback, 8bit sample Bidi = 12 : Loop Sample, forward playback, 16bit sample Bidi = 24 : Loop Sample, reverse playback 8bit sample Bidi = 28 : Loop Sample, reverse playback, 16bit sample %Event Structure ------------------------------------------------------------------------------ Note : byte (See note table below) SampleNumber : byte (Sample Number) Effect1 : nib (Effect1) Effect2 : nib (Effect2) EffectVar : word (Effect variables) The High order byte of EffectVar is the Effect variable for Effect1. The Low order byte of EffectVar is the Effect variable for Effect2. %***(Note)*** UT uses a form of compression on repetitive events. Say we read in the first byte, if it = $FC then this signifies a repeat block. The next byte is the repeat count. followed by the event structure to repeat. If the first byte read does NOT = $FC then this is the note of the event. So repeat blocks will be 7 bytes long : RepFlag : byte ($FC) RepCount : byte note : byte samplenumber : byte effect1 : nib effect2 : nib effectVar : word Repeat blocks do NOT bridge patterns. %Note Table: ______________________________________________________________________________ note value of 0 = pause C-0 to B-0 1 to 12 C-1 to B-1 13 to 24 C-2 to B-2 26 to 36 C-3 to B-3 39 to 48 C-4 to B-4 52 to 60 %Offset Bytes Type Description ------------------------------------------------------------------------------ 0 15 byte ID block : should contain 'MAS_UTrack_V001' 15 32 AsciiZ Song Title 47 1 reserved This byte is reserved and always contain 0; 48 1 byte Number of Samples (NOS) 49 NOS * 64 SampleStruct Sample Struct (see Sample Structure) Patt_Seq = 48 + (NOS * 64) Patt_Seq 256 byte Pattern Sequence Patt_Seq+256 1 byte Number Of Channels (NOC) Base 0 Patt_Seq+257 1 byte Number Of patterns (NOP) Base 0 Patt_Seq+258 varies EventStruct Pattern Data (See Event Structure) The remainder of the file is the raw sample data. That should about cover it. If you have any questions , feel free to e-mail me at freejack@shell.portal.com I can also be contacted on The UltraSound Connection (813) 787-8644 The UltraSound Connection is a BBS dedicated to the Gravis Ultrasound Card. Also I'm the author of Ripper and Gvoc. If anyone has any questions or problems, please contact me. :M_S3M File Format:M_STM File Format ^Scream Tracker 3.0 file formats ^Song/Module header % 0 1 2 3 4 5 6 7 8 9 A B C D E F ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ 0000: ³ Song name, max 28 chars (incl. NUL) ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ´ 0010: ³ ³1Ah³Typ³ x ³ x ³ ÃÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ 0020: ³OrdNum ³InsNum ³PatNum ³ Flags ³ Cwt/v ³ Ffv ³'S'³'C'³'R'³'M'³ ÃÄÄÄÂÄÄÄÅÄÄÄÂÄÄÄÅÄÄÄÂÄÄÄÅÄÄÄÂÄÄÄÅÄÄÄÂÄÄÄÅÄÄÄÂÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ 0030: ³m.v³i.s³i.t³m.m³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ ÃÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄ´ 0040: ³Channel settings for 32 channels, 255=unused,+128=disabled ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ 0050: ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ 0060: ³Orders; length=OrdNum (must be even) ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ xxxx: ³Parapointers to instruments; length=InsNum*2 ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ xxxx: ³Parapointers to patterns; length=PatNum*2 ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Typ = File type: 16=module,17=song Ordnum = Number of orders in file Insnum = Number of instruments in file Patnum = Number of patterns in file Cwt/v = Created with tracker / version: &0xfff=version, >>12=tracker ST30:0x1300 Ffv = File format version; 1=original 2=original BUT samples unsigned Parapointers are OFFSET/16 relative to the beginning of the header. % PLAYING AFFECTORS / INITIALIZERS: Flags = +1:st2vibrato +2:st2tempo +4:amigaslides +8:0vol optimizations +16:amiga limits +32:enable filter/sfx m.v = master volume m.m = master multiplier (&15) + stereo(=+16) i.s = initial speed (command A) i.t = initial tempo (command T) % Channel types: &128=on, &127=type: (127=unused) 8 - L-Adlib-Melody 1 (A1) 0 - L-Sample 1 (S1) 9 - L-Adlib-Melody 2 (A2) 1 - L-Sample 2 (S2) 10 - L-Adlib-Melody 3 (A3) 2 - L-Sample 3 (S3) 11 - L-Adlib-Melody 4 (A4) 3 - L-Sample 4 (S4) 12 - L-Adlib-Melody 5 (A5) 4 - R-Sample 5 (S5) 13 - L-Adlib-Melody 6 (A6) 5 - R-Sample 6 (S6) 14 - L-Adlib-Melody 7 (A7) 6 - R-Sample 7 (S7) 15 - L-Adlib-Melody 8 (A8) 7 - R-Sample 8 (S8) 16 - L-Adlib-Melody 9 (A9) 26 - L-Adlib-Bassdrum (AB) 17 - R-Adlib-Melody 1 (B1) 27 - L-Adlib-Snare (AS) 18 - R-Adlib-Melody 2 (B2) 28 - L-Adlib-Tom (AT) 19 - R-Adlib-Melody 3 (B3) 29 - L-Adlib-Cymbal (AC) 20 - R-Adlib-Melody 4 (B4) 30 - L-Adlib-Hihat (AH) 21 - R-Adlib-Melody 5 (B5) 31 - R-Adlib-Bassdrum (BB) 22 - R-Adlib-Melody 6 (B6) 32 - R-Adlib-Snare (BS) 23 - R-Adlib-Melody 7 (B7) 33 - R-Adlib-Tom (BT) 24 - R-Adlib-Melody 8 (B8) 34 - R-Adlib-Cymbal (BC) 25 - R-Adlib-Melody 9 (B9) 35 - R-Adlib-Hihat (BH) ^Digiplayer/ST3.0 samplefileformat % 0 1 2 3 4 5 6 7 8 9 A B C D E F ÚÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄ¿ 0000: ³[T]³ Dos filename (12345678.ABC) ³ MemSeg ³ ÃÄÄÄÁÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÅÄÄÄÂÄÄÄÂÄÄÄ´ 0010: ³Length ³HI:leng³LoopBeg³HI:LBeg³LoopEnd³HI:Lend³Vol³Dsk³[P]³[F]³ ÃÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÂÄÄÄÅÄÄÄÂÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄ´ 0020: ³C2Spd ³HI:C2sp³ x ³ x ³ x ³ x ³GVSPOS ³Int:512³Int:lastused ³ ÃÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ 0030: ³ Sample name, 28 characters max... (incl. NUL) ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ´ 0040: ³ ...sample name... ³'S'³'C'³'R'³'S'³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ xxxx: sampledata % NOTES: Inside module, MemSeg tells the paragraph position of the actual sampledata (offset/16). In separate insfile the same, in memory segment of data relative to beginning of module. GVSPOS=Position in gravis memory /32 (used inside player only) [T]ype, 1=Sample [F]lags, +1=loop on +2=stereo (after Length bytes for LEFT channel, another Length bytes for RIGHT channel) +4=16-bit samples (intel LO-HI byteorder) { [P]ack, 0=8 bit normal (1=DP30ADPCM1 for holland project) } ^ST3.0 adlib instrument format % 0 1 2 3 4 5 6 7 8 9 A B C D E F ÚÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ 0000: ³[T]³ Dos filename (12345678.123) ³00h³00h³00h³ ÃÄÄÄÅÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ 0010: ³D00³D01³D02³D03³D04³D05³D06³D07³D08³D09³D0A³D0B³Vol³Dsk³ x ³ x ³ ÃÄÄÄÁÄÄÄÅÄÄÄÁÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ 0020: ³C2Spd ³HI:C2sp³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ x ³ ÃÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄ´ 0030: ³ Sample name, 28 characters max... (incl. NUL) ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ´ 0040: ³ ...sample name... ³'S'³'C'³'R'³'I'³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ % NOTES: [T]ype, 2..7=amel,abd,asnare,atom,acym,ahihat modulator: carrier: D00=[freq.muliplier]+[?scale env.]*16+[?sustain]*32+ [?pitch vib]*64+[?vol.vib]*128 =D01 D02=[63-volume]+[levelscale&1]*128+[l.s.&2]*64 =D03 D04=[Attack]*16+[decay] =D05 D06=[15-sustain]*16+[release] =D07 D08=[wave select] =D09 D0A=[modulation feedback]*2+[?additive synthesis] D0B=unused ^Unpacked Internal memoryformat for patterns %REMARK each channel takes 320 bytes, rows for each channel are sequential. % byte: 0 - Note; hi=oct, lo=note, 255=empty note,254=key off (used with adlib) 1 - Instrument ;255=.. 2 - Volume ;255=.. 3 - Special command ;255=.. 4 - Command info ^Packed Internal memoryformat for patterns Pattern length fixed for 64 rows. BYTE: flag, 0=end of row &31=channel &32=follows; BYTE:note, BYTE:instrument &64=follows; BYTE:volume &128=follows; BYTE:command, BYTE:info %NOTES on [memseg]. In memory, the memseg's highest byte (3) is always zero (thus also the ASCIIZ terminator). For the actual 16 bit memseg the following storage method is used: 0..EFFF = Segment to memory F000... = EMS page ####-F000 ^STM File Format Song/Module file structure: % Offset: Info: 0 Song/File name, max 20 chars, ASCIIZ, except if 20 chars long 20 Tracker name, max 8 chars, NO NUL 28 0x1A 29 File type: 1=song, 2=module 30 Version major (eg. 2) 31 Version minor (eg. 2) 32 byte; tempo 33 byte; num of patterns saved 34 byte; global volume 36 reserved, 13 bytes 48 Instruments (31 kpl) (see below) Instrument structure: % Offset Info 0 Inst. Filename, 12 bytes max, ASCIIZ 12 0x00 13 byte; instrument disk 14 word; reserved (used as internal segment while playing) 16 word; length in bytes 18 word; loop start 20 word; loop end 22 byte; volume 23 byte; reserved 24 word; speed for mid-C (in Hz) 26 reserved, 4 bytes 30 word; internal segment address/(in modules:)length in paragraphs XXXX Music pattern orders (64 bytes/orders) XXXX Patterns (number in header, each pattern 1KB) Patterns consist of 64 rows, each 4 channels. Each channel is 4 bytes in length, and the channels are stored from left to right, row by row. % Special [BYTE0] contents: 251=last 3 bytes NOT in file, all bytes 0 252=last 3 bytes NOT in file, note: -0- 253=last 3 bytes NOT in file, note: ... 254=(in memory), -0- 255=(in memory), ... % otherwise: note=[BYTE0] and 15 (C=0,C#=1,D=2...) octave=[BYTE0] / 16 instrument=[BYTE1]/8 volume=([BYTE1] and 7)+[BYTE2]/2 command=[BYTE2] and 15 command info=[BYTE3] [XXXX] In modules: Samples, padded to 16 byte limits. Sample lengths in paragraphs (and as saved) are storen in instruments internal segment address.