diff options
author | Javier <dev.git@javispedro.com> | 2022-02-05 02:41:17 +0100 |
---|---|---|
committer | Javier <dev.git@javispedro.com> | 2022-02-05 02:41:17 +0100 |
commit | 176ec23dd48c50c87e5394b702e2cf0fe72957db (patch) | |
tree | 7137f296963e3a8638c24ca08c47e70d0456d2ec /emu8k_internal.h | |
parent | 4d13ee7785a4184cf2a349fdec1af6cf9f05bfdf (diff) | |
download | vmusic-176ec23dd48c50c87e5394b702e2cf0fe72957db.tar.gz vmusic-176ec23dd48c50c87e5394b702e2cf0fe72957db.zip |
add initial emu8k/SBAWE32 device using PCem's emu8k
Diffstat (limited to 'emu8k_internal.h')
-rw-r--r-- | emu8k_internal.h | 815 |
1 files changed, 815 insertions, 0 deletions
diff --git a/emu8k_internal.h b/emu8k_internal.h new file mode 100644 index 0000000..a8e3ea8 --- /dev/null +++ b/emu8k_internal.h @@ -0,0 +1,815 @@ +/* + * PCem - IBM PC emulator + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Portions: + * VMusic - a VirtualBox extension pack with various music devices + * Copyright (C) 2022 Javier S. Pedro + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _EMU8K_INTERNAL_H_ +#define _EMU8K_INTERNAL_H_ + +#include <stdint.h> + +#define MAXSOUNDBUFLEN (48000 / 10) + +#define BLOCK_SIZE_WORDS 0x10000 + +/* All these defines are in samples, not in bytes. */ +#define EMU8K_MEM_ADDRESS_MASK 0xFFFFFF +#define EMU8K_RAM_MEM_START 0x200000 +#define EMU8K_FM_MEM_ADDRESS 0xFFFFE0 +#define EMU8K_RAM_POINTERS_MASK 0x3F +#define EMU8K_LFOCHORUS_SIZE 0x4000 +/* + * Everything in this file assumes little endian + */ +/* used for the increment of oscillator position*/ +typedef struct emu8k_mem_internal_t { + union { + uint64_t addr; + struct { + uint16_t fract_lw_address; + uint16_t fract_address; + uint32_t int_address; + }; + }; +} emu8k_mem_internal_t; + +/* used for access to ram pointers from oscillator position. */ +typedef struct emu8k_mem_pointers_t { + union { + uint32_t addr; + struct { + uint16_t lw_address; + uint8_t hb_address; + uint8_t unused_address; + }; + }; +} emu8k_mem_pointers_t; + +/* + * From the Soundfount 2.0 fileformat Spec.: + * + An envelope generates a control signal in six phases. + When key-on occurs, a delay period begins during which the envelope value is zero. + The envelope then rises in a convex curve to a value of one during the attack phase. + " Note that the attack is convex; the curve is nominally such that when applied to a + decibel or semitone parameter, the result is linear in amplitude or Hz respectively" + + When a value of one is reached, the envelope enters a hold phase during which it remains at one. + When the hold phase ends, the envelope enters a decay phase during which its value decreases linearly to a sustain level. + " For the Volume Envelope, the decay phase linearly ramps toward the sustain level, causing a constant dB change for each time unit. " + When the sustain level is reached, the envelope enters sustain phase, during which the envelope stays at the sustain level. + + Whenever a key-off occurs, the envelope immediately enters a release phase during which the value linearly ramps from the current value to zero. + " For the Volume Envelope, the release phase linearly ramps toward zero from the current level, causing a constant dB change for each time unit" + + When zero is reached, the envelope value remains at zero. + + Modulation of pitch and filter cutoff are in octaves, semitones, and cents. + These parameters can be modulated to varying degree, either positively or negatively, by the modulation envelope. + The degree of modulation is specified in cents for the full-scale attack peak. + + The volume envelope operates in dB, with the attack peak providing a full scale output, appropriately scaled by the initial volume. + The zero value, however, is actually zero gain. + The implementation in the EMU8000 provides for 96 dB of amplitude control. + When 96 dB of attenuation is reached in the final gain amplifier, an abrupt jump to zero gain + (infinite dB of attenuation) occurs. In a 16-bit system, this jump is inaudible +*/ +/* It seems that the envelopes don't really have a decay/release stage, + * but instead they have a volume ramper that can be triggered + * automatically (after hold period), or manually (by activating release) + * and the "sustain" value is the target of any of both cases. + * Some programs like cubic player and AWEAmp use this, and it was + * described in the following way in Vince Vu/Judge Dredd's awe32p10.txt: + * If the MSB (most significant bit or bit 15) of this register is set, + * the Decay/Release will begin immediately, overriding the Delay, Attack, + * and Hold. Otherwise the Decay/Release will wait until the Delay, Attack, + * and Hold are finished. If you set the MSB of this register, you can use + * it as a volume ramper, as on the GUS. The upper byte (except the MSB), + * contains the destination volume, and the lower byte contains the ramp time. + */ + +/* attack_amount is linear amplitude (added directly to value). + * ramp_amount_db is linear dB (added directly to value too, but needs conversion to get linear amplitude). + * value range is 21bits for both, linear amplitude being 1<<21 = 0dBFS and 0 = -96dBFS (which is shortcut to silence), + * and db amplutide being 0 = 0dBFS and -(1<<21) = -96dBFS (which is shortcut to silence). + * This allows to operate db values by simply adding them. + */ +typedef struct emu8k_envelope_t { + int state; + int32_t delay_samples, hold_samples, attack_samples; + int32_t value_amp_hz, value_db_oct; + int32_t sustain_value_db_oct; + int32_t attack_amount_amp_hz, ramp_amount_db_oct; +} emu8k_envelope_t; + + + +typedef struct emu8k_chorus_eng_t { + int32_t write; + int32_t feedback; + int32_t delay_samples_central; + double lfodepth_multip; + double delay_offset_samples_right; + emu8k_mem_internal_t lfo_inc; + emu8k_mem_internal_t lfo_pos; + + int32_t chorus_left_buffer[EMU8K_LFOCHORUS_SIZE]; + int32_t chorus_right_buffer[EMU8K_LFOCHORUS_SIZE]; + +} emu8k_chorus_eng_t; + +/* 32 * 242. 32 comes from the "right" room resso case.*/ +#define MAX_REFL_SIZE 7744 + + +/* Reverb parameters description, extracted from AST sources. + Mix level + Decay + Link return amp + Link type Switches between normal or panned + Room reso ( ms) L&R (Ref 6 +1) + Ref 1 x2 (11 ms)R + Ref 2 x4 (22 ms)R + Ref 3 x8 (44 ms)L + Ref 4 x13(71 ms)R + Ref 5 x19(105ms)L + Ref 6 x ( ms)R (multiplier changes with room reso) + Ref 1-6 filter L&R + Ref 1-6 amp L&R + Ref 1 feedback L&R + Ref 2 feedback L&R + Ref 3 feedback L&R + Ref 4 feedback L&R + Ref 5 feedback L&R + Ref 6 feedback L&R +*/ +typedef struct emu8k_reverb_combfilter_t { + int read_pos; + int32_t reflection[MAX_REFL_SIZE]; + float output_gain; + float feedback; + float damp1; + float damp2; + int bufsize; + int32_t filterstore; +} emu8k_reverb_combfilter_t; + +typedef struct emu8k_reverb_eng_t { + + int16_t out_mix; + int16_t link_return_amp; /* tail part output gain ? */ + int8_t link_return_type; + + uint8_t refl_in_amp; + + emu8k_reverb_combfilter_t reflections[6]; + emu8k_reverb_combfilter_t allpass[8]; + emu8k_reverb_combfilter_t tailL; + emu8k_reverb_combfilter_t tailR; + + emu8k_reverb_combfilter_t damper; +} emu8k_reverb_eng_t; + +typedef struct emu8k_slide_t { + int32_t last; +} emu8k_slide_t; + + +typedef struct emu8k_voice_t +{ + union { + uint32_t cpf; + struct { + uint16_t cpf_curr_frac_addr; /* fractional part of the playing cursor. */ + uint16_t cpf_curr_pitch; /* 0x4000 = no shift. Linear increment */ + }; + }; + union { + uint32_t ptrx; + struct { + uint8_t ptrx_pan_aux; + uint8_t ptrx_revb_send; + uint16_t ptrx_pit_target; /* target pitch to which slide at curr_pitch speed. */ + }; + }; + union { + uint32_t cvcf; + struct { + uint16_t cvcf_curr_filt_ctoff; + uint16_t cvcf_curr_volume; + }; + }; + emu8k_slide_t volumeslide; + union { + uint32_t vtft; + struct { + uint16_t vtft_filter_target; + uint16_t vtft_vol_target; /* written to by the envelope engine. */ + }; + }; + /* These registers are used at least by the Windows drivers, and seem to be resetting + * something, similarly to targets and current, but... of what? + * what is curious is that if they are already zero, they are not written to, so it really + * looks like they are information about the status of the channel. (lfo position maybe?) */ + uint32_t unknown_data0_4; + uint32_t unknown_data0_5; + union { + uint32_t psst; + struct { + uint16_t psst_lw_address; + uint8_t psst_hw_address; + uint8_t psst_pan; + }; + #define PSST_LOOP_START_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ + }; + union { + uint32_t csl; + struct { + uint16_t csl_lw_address; + uint8_t csl_hw_address; + uint8_t csl_chor_send; + }; + #define CSL_LOOP_END_MASK 0x00FFFFFF /* In samples, i.e. uint16_t array[BOARD_RAM/2]; */ + }; + union { + uint32_t ccca; + struct { + uint16_t ccca_lw_addr; + uint8_t ccca_hb_addr; + uint8_t ccca_qcontrol; + }; + }; + #define CCCA_FILTQ_GET(ccca) (ccca>>28) + #define CCCA_FILTQ_SET(ccca,q) ccca = (ccca&0x0FFFFFFF) | (q<<28) + /* Bit 27 should always be zero */ + #define CCCA_DMA_ACTIVE(ccca) (ccca&0x04000000) + #define CCCA_DMA_WRITE_MODE(ccca) (ccca&0x02000000) + #define CCCA_DMA_WRITE_RIGHT(ccca) (ccca&0x01000000) + + uint16_t envvol; + #define ENVVOL_NODELAY(envol) (envvol&0x8000) + /* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ + #define ENVVOL_TO_EMU_SAMPLES(envvol) (envvol&0x8000) ? 0 : ((0x8000-(envvol&0x7FFF)) <<5) + + uint16_t dcysusv; + #define DCYSUSV_IS_RELEASE(dcysusv) (dcysusv&0x8000) + #define DCYSUSV_GENERATOR_ENGINE_ON(dcysusv) !(dcysusv&0x0080) + #define DCYSUSV_SUSVALUE_GET(dcysusv) ((dcysusv>>8)&0x7F) + /* Inverting the range compared to documentation because the envelope runs from 0dBFS = 0 to -96dBFS = (1 <<21) */ + #define DCYSUSV_SUS_TO_ENV_RANGE(susvalue) (((0x7F-susvalue) << 21)/0x7F) + #define DCYSUSV_DECAYRELEASE_GET(dcysusv) (dcysusv&0x7F) + + uint16_t envval; + #define ENVVAL_NODELAY(enval) (envval&0x8000) + /* Verified with a soundfont bank. 7FFF is the minimum delay time, and 0 is the max delay time */ + #define ENVVAL_TO_EMU_SAMPLES(envval)(envval&0x8000) ? 0 : ((0x8000-(envval&0x7FFF)) <<5) + + uint16_t dcysus; + #define DCYSUS_IS_RELEASE(dcysus) (dcysus&0x8000) + #define DCYSUS_SUSVALUE_GET(dcysus) ((dcysus>>8)&0x7F) + #define DCYSUS_SUS_TO_ENV_RANGE(susvalue) ((susvalue << 21)/0x7F) + #define DCYSUS_DECAYRELEASE_GET(dcysus) (dcysus&0x7F) + + uint16_t atkhldv; + #define ATKHLDV_TRIGGER(atkhldv) !(atkhldv&0x8000) + #define ATKHLDV_HOLD(atkhldv) ((atkhldv>>8)&0x7F) + #define ATKHLDV_HOLD_TO_EMU_SAMPLES(atkhldv) (4096*(0x7F-((atkhldv>>8)&0x7F))) + #define ATKHLDV_ATTACK(atkhldv) (atkhldv&0x7F) + + uint16_t lfo1val, lfo2val; + #define LFOxVAL_NODELAY(lfoxval) (lfoxval&0x8000) + #define LFOxVAL_TO_EMU_SAMPLES(lfoxval) (lfoxval&0x8000) ? 0 : ((0x8000-(lfoxval&0x7FFF)) <<5) + + uint16_t atkhld; + #define ATKHLD_TRIGGER(atkhld) !(atkhld&0x8000) + #define ATKHLD_HOLD(atkhld) ((atkhld>>8)&0x7F) + #define ATKHLD_HOLD_TO_EMU_SAMPLES(atkhld) (4096*(0x7F-((atkhld>>8)&0x7F))) + #define ATKHLD_ATTACK(atkhld) (atkhld&0x7F) + + + uint16_t ip; + #define INTIAL_PITCH_CENTER 0xE000 + #define INTIAL_PITCH_OCTAVE 0x1000 + + union { + uint16_t ifatn; + struct{ + uint8_t ifatn_attenuation; + uint8_t ifatn_init_filter; + }; + }; + union { + uint16_t pefe; + struct { + int8_t pefe_modenv_filter_height; + int8_t pefe_modenv_pitch_height; + }; + }; + union { + uint16_t fmmod; + struct { + int8_t fmmod_lfo1_filt_mod; + int8_t fmmod_lfo1_vibrato; + }; + }; + union { + uint16_t tremfrq; + struct { + uint8_t tremfrq_lfo1_freq; + int8_t tremfrq_lfo1_tremolo; + }; + }; + union { + uint16_t fm2frq2; + struct { + uint8_t fm2frq2_lfo2_freq; + int8_t fm2frq2_lfo2_vibrato; + }; + }; + + int env_engine_on; + + emu8k_mem_internal_t addr, loop_start, loop_end; + + int32_t initial_att; + int32_t initial_filter; + + emu8k_envelope_t vol_envelope; + emu8k_envelope_t mod_envelope; + + int64_t lfo1_speed, lfo2_speed; + emu8k_mem_internal_t lfo1_count, lfo2_count; + int32_t lfo1_delay_samples, lfo2_delay_samples; + int vol_l, vol_r; + + int16_t fixed_modenv_filter_height; + int16_t fixed_modenv_pitch_height; + int16_t fixed_lfo1_filt_mod; + int16_t fixed_lfo1_vibrato; + int16_t fixed_lfo1_tremolo; + int16_t fixed_lfo2_vibrato; + + /* filter internal data. */ + int filterq_idx; + int32_t filt_att; + int64_t filt_buffer[5]; + +} emu8k_voice_t; + +typedef struct emu8k_t +{ + emu8k_voice_t voice[32]; + + uint16_t hwcf1, hwcf2, hwcf3; + uint32_t hwcf4, hwcf5, hwcf6, hwcf7; + + uint16_t init1[32], init2[32], init3[32], init4[32]; + + uint32_t smalr, smarr, smalw, smarw; + uint16_t smld_buffer, smrd_buffer; + + uint16_t wc; + + uint16_t id; + + /* The empty block is used to act as an unallocated memory returning zero. */ + int16_t *ram, *rom, *empty; + + /* RAM pointers are a way to avoid checking ram boundaries on read */ + int16_t *ram_pointers[0x100]; + uint32_t ram_end_addr; + + int cur_reg, cur_voice; + + int16_t out_l, out_r; + + emu8k_chorus_eng_t chorus_engine; + int32_t chorus_in_buffer[MAXSOUNDBUFLEN]; + emu8k_reverb_eng_t reverb_engine; + int32_t reverb_in_buffer[MAXSOUNDBUFLEN]; + + int pos; + int32_t buffer[MAXSOUNDBUFLEN * 2]; +} emu8k_t; + + + +/* + +Section E - Introduction to the EMU8000 Chip + + The EMU8000 has its roots in E-mu's Proteus sample playback + modules and their renowned Emulator sampler. The EMU8000 has + 32 individual oscillators, each playing back at 44.1 kHz. By + incorporating sophisticated sample interpolation algorithms + and digital filtering, the EMU8000 is capable of producing + high fidelity sample playback. + + The EMU8000 has an extensive modulation capability using two + sine-wave LFOs (Low Frequency Oscillator) and two multi- + stage envelope generators. + + What exactly does modulation mean? Modulation means to + dynamically change a parameter of an audio signal, whether + it be the volume (amplitude modulation, or tremolo), pitch + (frequency modulation, or vibrato) or filter cutoff + frequency (filter modulation, or wah-wah). To modulate + something we would require a modulation source, and a + modulation destination. In the EMU8000, the modulation + sources are the LFOs and the envelope generators, and the + modulation destinations can be the pitch, the volume or the + filter cutoff frequency. + + The EMU8000's LFOs and envelope generators provide a complex + modulation environment. Each sound producing element of the + EMU8000 consists of a resonant low-pass filter, two LFOs, in + which one modulates the pitch (LFO2), and the other + modulates pitch, filter cutoff and volume (LFO1) + simultaneously. There are two envelope generators; envelope + 1 contours both pitch and filter cutoff simultaneously, and + envelope 2 contours volume. The output stage consists of an + effects engine that mixes the dry signals with the + Reverb/chorus level signals to produce the final mix. + + What are the EMU8000 sound elements? + + Each of the sound elements in an EMU8000 consists of the + following: + + Oscillator + An oscillator is the source of an audio signal. + + Low Pass Filter + The low pass filter is responsible for modifying the + timbres of an instrument. The low pass filter's filter + cutoff values can be varied from 100 Hz to 8000 Hz. By + changing the values of the filter cutoff, a myriad of + analogue sounding filter sweeps can be achieved. An + example of a GM instrument that makes use of filter sweep + is instrument number 87, Lead 7 (fifths). + + Amplifier + The amplifier determines the loudness of an audio signal. + + LFO1 + An LFO, or Low Frequency Oscillator, is normally used to + periodically modulate, that is, change a sound parameter, + whether it be volume (amplitude modulation), pitch + (frequency modulation) or filter cutoff (filter + modulation). It operates at sub-audio frequency from + 0.042 Hz to 10.71 Hz. The LFO1 in the EMU8000 modulates + the pitch, volume and filter cutoff simultaneously. + + LFO2 + The LFO2 is similar to the LFO1, except that it modulates + the pitch of the audio signal only. + + Resonance + A filter alone would be like an equalizer, making a + bright audio signal duller, but the addition of resonance + greatly increases the creative potential of a filter. + Increasing the resonance of a filter makes it emphasize + signals at the cutoff frequency, giving the audio signal + a subtle wah-wah, that is, imagine a siren sound going + from bright to dull to bright again periodically. + + LFO1 to Volume (Tremolo) + The LFO1's output is routed to the amplifier, with the + depth of oscillation determined by LFO1 to Volume. LFO1 + to Volume produces tremolo, which is a periodic + fluctuation of volume. Lets say you are listening to a + piece of music on your home stereo system. When you + rapidly increase and decrease the playback volume, you + are creating tremolo effect, and the speed in which you + increases and decreases the volume is the tremolo rate + (which corresponds to the speed at which the LFO is + oscillating). An example of a GM instrument that makes + use of LFO1 to Volume is instrument number 45, Tremolo + Strings. + + LFO1 to Filter Cutoff (Wah-Wah) + The LFO1's output is routed to the filter, with the depth + of oscillation determined by LFO1 to Filter. LFO1 to + Filter produces a periodic fluctuation in the filter + cutoff frequency, producing an effect very similar to + that of a wah-wah guitar (see resonance for a description + of wah-wah) An example of a GM instrument that makes + use of LFO1 to Filter Cutoff is instrument number 19, + Rock Organ. + + LFO1 to Pitch (Vibrato) + The LFO1's output is routed to the oscillator, with the + depth of oscillation determined by LFO1 to Pitch. LFO1 to + Pitch produces a periodic fluctuation in the pitch of the + oscillator, producing a vibrato effect. An example of a + GM instrument that makes use of LFO1 to Pitch is + instrument number 57, Trumpet. + + LFO2 to Pitch (Vibrato) + The LFO1 in the EMU8000 can simultaneously modulate + pitch, volume and filter. LFO2, on the other hand, + modulates only the pitch, with the depth of modulation + determined by LFO2 to Pitch. LFO2 to Pitch produces a + periodic fluctuation in the pitch of the oscillator, + producing a vibrato effect. When this is coupled with + LFO1 to Pitch, a complex vibrato effect can be achieved. + + Volume Envelope + The character of a musical instrument is largely + determined by its volume envelope, the way in which the + level of the sound changes with time. For example, + percussive sounds usually start suddenly and then die + away, whereas a bowed sound might take quite some time to + start and then sustain at a more or less fixed level. + + A six-stage envelope makes up the volume envelope of the + EMU8000. The six stages are delay, attack, hold, decay, + sustain and release. The stages can be described as + follows: + + Delay The time between when a key is played and when + the attack phase begins + Attack The time it takes to go from zero to the peak + (full) level. + Hold The time the envelope will stay at the peak + level before starting the decay phase. + Decay The time it takes the envelope to go from the + peak level to the sustain level. + Sustain The level at which the envelope remains as long + as a key is held down. + Release The time it takes the envelope to fall to the + zero level after the key is released. + + Using these six parameters can yield very realistic + reproduction of the volume envelope characteristics of + many musical instruments. + + Pitch and Filter Envelope + The pitch and filter envelope is similar to the volume + envelope in that it has the same envelope stages. The + difference between them is that whereas the volume + envelope contours the volume of the instrument over time, + the pitch and filter envelope contours the pitch and + filter values of the instrument over time. The pitch + envelope is particularly useful in putting the finishing + touches in simulating a natural instrument. For example, + some wind instruments tend to go slightly sharp when they + are first blown, and this characteristic can be simulated + by setting up a pitch envelope with a fairly fast attack + and decay. The filter envelope, on the other hand, is + useful in creating synthetic sci-fi sound textures. An + example of a GM instrument that makes use of the filter + envelope is instrument number 86, Pad 8 (Sweep). + + Pitch/Filter Envelope Modulation + These two parameters determine the modulation depth of + the pitch and filter envelope. In the wind instrument + example above, a small amount of pitch envelope + modulation is desirable to simulate its natural pitch + characteristics. + + This rich modulation capability of the EMU8000 is fully + exploited by the SB AWE32 MIDI drivers. The driver also + provides you with a means to change these parameters over + MIDI in real time. Refer to the section "How do I change an + instrument's sound parameter in real time" for more + information. + + + + + Room 1 - 3 + This group of reverb variation simulates the natural + ambiance of a room. Room 1 simulates a small room, Room 2 + simulates a slightly bigger room, and Room 3 simulates a + big room. + + Hall 1 - 2 + This group of reverb variation simulates the natural + ambiance of a concert hall. It has greater depth than the + room variations. Again, Hall 1 simulates a small hall, + and Hall 2 simulates a larger hall. + + Plate + Back in the old days, reverb effects were sometimes + produced using a metal plate, and this type of reverb + produces a metallic echo. The SB AWE32's Plate variation + simulates this form of reverb. + + Delay + This reverb produces a delay, that is, echo effect. + + Panning Delay + This reverb variation produces a delay effect that is + continuously panned left and right. + + Chorus 1 - 4 + Chorus produces a "beating" effect. The chorus effects + are more prominent going from chorus 1 to chorus 4. + + Feedback Chorus + This chorus variation simulates a soft "swishing" effect. + + Flanger + This chorus variation produces a more prominent feedback + chorus effect. + + Short Delay + This chorus variation simulates a delay repeated in a + short time. + + Short Delay (feed back) + This chorus variation simulates a short delay repeated + (feedback) many times. + + + +Registers to write the Chorus Parameters to (all are 16-bit, unless noted): +(codified as in register,port,voice. port 0=0x620, 2=0x622, 4=0xA20, 6=0xA22, 8=0xE20) +( 3409 = register 3, port A20, voice 9) + +0x3409 +0x340C +0x3603 +0x1409 (32-Bit) +0x140A (32-Bit) +then write 0x8000 to 0x140D (32-Bit) +and then 0x0000 to 0x140E (32-Bit) + +Chorus Parameters: + +Chorus 1 Chorus 2 Chorus 3 Chorus 4 Feedback Flanger + +0xE600 0xE608 0xE610 0xE620 0xE680 0xE6E0 +0x03F6 0x031A 0x031A 0x0269 0x04D3 0x044E +0xBC2C 0xBC6E 0xBC84 0xBC6E 0xBCA6 0xBC37 +0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 +0x006D 0x017C 0x0083 0x017C 0x005B 0x0026 + +Short Delay Short Delay + Feedback + +0xE600 0xE6C0 +0x0B06 0x0B06 +0xBC00 0xBC00 +0xE000 0xE000 +0x0083 0x0083 + +// Chorus Params +typedef struct { + WORD FbkLevel; // Feedback Level (0xE600-0xE6FF) + WORD Delay; // Delay (0-0x0DA3) [1/44100 sec] + WORD LfoDepth; // LFO Depth (0xBC00-0xBCFF) + DWORD DelayR; // Right Delay (0-0xFFFFFFFF) [1/256/44100 sec] + DWORD LfoFreq; // LFO Frequency (0-0xFFFFFFFF) + } CHORUS_TYPE; + + +Registers to write the Reverb Parameters to (they are all 16-bit): +(codified as in register,port,voice. port 0=0x620, 2=0x622, 4=0xA20, 6=0xA22, 8=0xE20) +( 3409 = register 3, port A20, voice 9) + +0x2403,0x2405,0x361F,0x2407,0x2614,0x2616,0x240F,0x2417, +0x241F,0x2607,0x260F,0x2617,0x261D,0x261F,0x3401,0x3403, +0x2409,0x240B,0x2411,0x2413,0x2419,0x241B,0x2601,0x2603, +0x2609,0x260B,0x2611,0x2613 + +Reverb Parameters: + +Room 1: + +0xB488,0xA450,0x9550,0x84B5,0x383A,0x3EB5,0x72F4,0x72A4, +0x7254,0x7204,0x7204,0x7204,0x4416,0x4516,0xA490,0xA590, +0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, +0x8428,0x8528,0x8428,0x8528 + +Room 2: + +0xB488,0xA458,0x9558,0x84B5,0x383A,0x3EB5,0x7284,0x7254, +0x7224,0x7224,0x7254,0x7284,0x4448,0x4548,0xA440,0xA540, +0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, +0x8428,0x8528,0x8428,0x8528 + +Room 3: + +0xB488,0xA460,0x9560,0x84B5,0x383A,0x3EB5,0x7284,0x7254, +0x7224,0x7224,0x7254,0x7284,0x4416,0x4516,0xA490,0xA590, +0x842C,0x852C,0x842C,0x852C,0x842B,0x852B,0x842B,0x852B, +0x842A,0x852A,0x842A,0x852A + +Hall 1: + +0xB488,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7284,0x7254, +0x7224,0x7224,0x7254,0x7284,0x4448,0x4548,0xA440,0xA540, +0x842B,0x852B,0x842B,0x852B,0x842A,0x852A,0x842A,0x852A, +0x8429,0x8529,0x8429,0x8529 + +Hall 2: + +0xB488,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7254,0x7234, +0x7224,0x7254,0x7264,0x7294,0x44C3,0x45C3,0xA404,0xA504, +0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, +0x8428,0x8528,0x8428,0x8528 + +Plate: + +0xB4FF,0xA470,0x9570,0x84B5,0x383A,0x3EB5,0x7234,0x7234, +0x7234,0x7234,0x7234,0x7234,0x4448,0x4548,0xA440,0xA540, +0x842A,0x852A,0x842A,0x852A,0x8429,0x8529,0x8429,0x8529, +0x8428,0x8528,0x8428,0x8528 + +Delay: + +0xB4FF,0xA470,0x9500,0x84B5,0x333A,0x39B5,0x7204,0x7204, +0x7204,0x7204,0x7204,0x72F4,0x4400,0x4500,0xA4FF,0xA5FF, +0x8420,0x8520,0x8420,0x8520,0x8420,0x8520,0x8420,0x8520, +0x8420,0x8520,0x8420,0x8520 + +Panning Delay: + +0xB4FF,0xA490,0x9590,0x8474,0x333A,0x39B5,0x7204,0x7204, +0x7204,0x7204,0x7204,0x72F4,0x4400,0x4500,0xA4FF,0xA5FF, +0x8420,0x8520,0x8420,0x8520,0x8420,0x8520,0x8420,0x8520, +0x8420,0x8520,0x8420,0x8520 + +Registers to write the EQ Parameters to (16-Bit): +(codified as in register,port,voice. port 0=0x620, 2=0x622, 4=0xA20, 6=0xA22, 8=0xE20) +( 3409 = register 3, port A20, voice 9) + +Bass: + +0x3601 +0x3611 + +Treble: + +0x3411 +0x3413 +0x341B +0x3607 +0x360B +0x360D +0x3617 +0x3619 + +Total: + +write the 0x0263 + 3rd parameter of the Bass EQ + 9th parameter of Treble EQ to 0x3615. +write the 0x8363 + 3rd parameter of the Bass EQ + 9th parameter of Treble EQ to 0x3615. + + +Bass Parameters: + +0: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: + +0xD26A 0xD25B 0xD24C 0xD23D 0xD21F 0xC208 0xC219 0xC22A 0xC24C 0xC26E 0xC248 0xC26A +0xD36A 0xD35B 0xD34C 0xD33D 0xC31F 0xC308 0xC308 0xC32A 0xC34C 0xC36E 0xC384 0xC36A +0x0000 0x0000 0x0000 0x0000 0x0000 0x0001 0x0001 0x0001 0x0001 0x0001 0x0002 0x0002 + +Treble Parameters: + +0: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: +0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821E 0x821D 0x821C +0xC26A 0xC25B 0xC24C 0xC23D 0xC21F 0xD208 0xD208 0xD208 0xD208 0xD208 0xD219 0xD22A +0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031E 0x031D 0x031C +0xC36A 0xC35B 0xC34C 0xC33D 0xC31F 0xD308 0xD308 0xD308 0xD308 0xD308 0xD319 0xD32A +0x021E 0x021E 0x021E 0x021E 0x021E 0x021E 0x021D 0x021C 0x021A 0x0219 0x0219 0x0219 +0xD208 0xD208 0xD208 0xD208 0xD208 0xD208 0xD219 0xD22A 0xD24C 0xD26E 0xD26E 0xD26E +0x831E 0x831E 0x831E 0x831E 0x831E 0x831E 0x831D 0x831C 0x831A 0x8319 0x8319 0x8319 +0xD308 0xD308 0xD308 0xD308 0xD308 0xD308 0xD3019 0xD32A 0xD34C 0xD36E 0xD36E 0xD36E +0x0001 0x0001 0x0001 0x0001 0x0001 0x0002 0x0002 0x0002 0x0002 0x0002 0x0002 0x0002 +*/ + +#endif /* _SOUND_EMU8K_H_ */ |