4 * The low level driver for the AWE32/Sound Blaster 32 wave table synth.
5 * version 0.4.2c; Oct. 7, 1997
7 * Copyright (C) 1996,1997 Takashi Iwai
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * $DragonFly: src/sys/i386/gnu/isa/sound/Attic/awe_wave.c,v 1.2 2003/08/07 21:17:21 dillon Exp $
29 # include "awe_config.h"
31 # include "awe_config.h"
34 /*----------------------------------------------------------------*/
36 #ifdef CONFIG_AWE32_SYNTH
40 # include "awe_version.h"
41 # include "awe_voice.h"
44 # include "awe_version.h"
45 # include "awe_voice.h"
48 #ifdef AWE_HAS_GUS_COMPATIBILITY
49 /* include finetune table */
52 # ifdef AWE_OBSOLETE_VOXWARE
55 # include <i386/isa/sound/tuning.h>
57 # ifdef AWE_OBSOLETE_VOXWARE
60 # include "../tuning.h"
65 # include <linux/ultrasound.h>
66 #elif defined(__FreeBSD__)
67 # include <machine/ultrasound.h>
70 #endif /* AWE_HAS_GUS_COMPATIBILITY */
73 /*----------------------------------------------------------------
75 *----------------------------------------------------------------*/
77 static int debug_mode = 0;
79 #define AWE_DEBUG(LVL,XXX) {if (debug_mode > LVL) { XXX; }}
80 #define ERRMSG(XXX) {if (debug_mode) { XXX; }}
81 #define FATALERR(XXX) XXX
83 #define AWE_DEBUG(LVL,XXX) /**/
84 #define ERRMSG(XXX) XXX
85 #define FATALERR(XXX) XXX
88 /*----------------------------------------------------------------
89 * bank and voice record
90 *----------------------------------------------------------------*/
92 /* soundfont record */
93 typedef struct _sf_list {
96 int num_info; /* current info table index */
97 int num_sample; /* current sample table index */
98 int mem_ptr; /* current word byte pointer */
101 /*char name[AWE_PATCH_NAME_LEN];*/
105 typedef struct _awe_voice_list {
106 int next; /* linked list with same sf_id */
107 unsigned char bank, instr; /* preset number information */
108 char type, disabled; /* type=normal/mapped, disabled=boolean */
109 awe_voice_info v; /* voice information */
110 int next_instr; /* preset table list */
111 int next_bank; /* preset table list */
114 /* voice list type */
115 #define V_ST_NORMAL 0
116 #define V_ST_MAPPED 1
118 typedef struct _awe_sample_list {
119 int next; /* linked list with same sf_id */
120 awe_sample_info v; /* sample information */
123 /* sample and information table */
124 static int current_sf_id = 0;
125 static int locked_sf_id = 0;
127 static sf_list *sflists = NULL;
129 #define awe_free_mem_ptr() (current_sf_id <= 0 ? 0 : sflists[current_sf_id-1].mem_ptr)
130 #define awe_free_info() (current_sf_id <= 0 ? 0 : sflists[current_sf_id-1].num_info)
131 #define awe_free_sample() (current_sf_id <= 0 ? 0 : sflists[current_sf_id-1].num_sample)
133 static int max_samples;
134 static awe_sample_list *samples = NULL;
136 static int max_infos;
137 static awe_voice_list *infos = NULL;
140 #define AWE_MAX_PRESETS 256
141 #define AWE_DEFAULT_PRESET 0
142 #define AWE_DEFAULT_BANK 0
143 #define AWE_DEFAULT_DRUM 0
144 #define AWE_DRUM_BANK 128
146 #define MAX_LAYERS AWE_MAX_VOICES
148 /* preset table index */
149 static int preset_table[AWE_MAX_PRESETS];
151 /*----------------------------------------------------------------
153 *----------------------------------------------------------------*/
156 typedef struct FX_Rec { /* channel effects */
157 unsigned char flags[AWE_FX_END];
158 short val[AWE_FX_END];
162 /* channel parameters */
163 typedef struct _awe_chan_info {
164 int channel; /* channel number */
165 int bank; /* current tone bank */
166 int instr; /* current program */
167 int bender; /* midi pitchbend (-8192 - 8192) */
168 int bender_range; /* midi bender range (x100) */
169 int panning; /* panning (0-127) */
170 int main_vol; /* channel volume (0-127) */
171 int expression_vol; /* midi expression (0-127) */
172 int chan_press; /* channel pressure */
173 int vrec; /* instrument list */
174 int def_vrec; /* default instrument list */
175 int sustained; /* sustain status in MIDI */
176 FX_Rec fx; /* effects */
177 FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */
180 /* voice parameters */
181 typedef struct _voice_info {
183 #define AWE_ST_OFF (1<<0) /* no sound */
184 #define AWE_ST_ON (1<<1) /* playing */
185 #define AWE_ST_STANDBY (1<<2) /* stand by for playing */
186 #define AWE_ST_SUSTAINED (1<<3) /* sustained */
187 #define AWE_ST_MARK (1<<4) /* marked for allocation */
188 #define AWE_ST_DRAM (1<<5) /* DRAM read/write */
189 #define AWE_ST_FM (1<<6) /* reserved for FM */
190 #define AWE_ST_RELEASED (1<<7) /* released */
192 int ch; /* midi channel */
193 int key; /* internal key for search */
194 int layer; /* layer number (for channel mode only) */
195 int time; /* allocated time */
196 awe_chan_info *cinfo; /* channel info */
198 int note; /* midi key (0-127) */
199 int velocity; /* midi velocity (0-127) */
200 int sostenuto; /* sostenuto on/off */
201 awe_voice_info *sample; /* assigned voice */
203 /* EMU8000 parameters */
204 int apitch; /* pitch parameter */
205 int avol; /* volume parameter */
206 int apan; /* panning parameter */
209 /* voice information */
210 static voice_info *voices;
212 #define IS_NO_SOUND(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED))
213 #define IS_NO_EFFECT(v) (voices[v].state != AWE_ST_ON)
214 #define IS_PLAYING(v) (voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED))
215 #define IS_EMPTY(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM))
218 /* MIDI channel effects information (for hw control) */
219 static awe_chan_info *channels;
222 /*----------------------------------------------------------------
224 *----------------------------------------------------------------*/
226 #ifndef AWE_DEFAULT_BASE_ADDR
227 #define AWE_DEFAULT_BASE_ADDR 0 /* autodetect */
230 #ifndef AWE_DEFAULT_MEM_SIZE
231 #define AWE_DEFAULT_MEM_SIZE 0 /* autodetect */
234 /* awe32 base address (overwritten at initialization) */
235 static int awe_base = AWE_DEFAULT_BASE_ADDR;
236 /* memory byte size */
237 static int awe_mem_size = AWE_DEFAULT_MEM_SIZE;
238 /* DRAM start offset */
239 static int awe_mem_start = AWE_DRAM_OFFSET;
241 /* maximum channels for playing */
242 static int awe_max_voices = AWE_MAX_VOICES;
244 static int patch_opened = 0; /* sample already loaded? */
246 static int reverb_mode = 4; /* reverb mode */
247 static int chorus_mode = 2; /* chorus mode */
248 static short init_atten = AWE_DEFAULT_ATTENUATION; /* 12dB below */
250 static int awe_present = FALSE; /* awe device present? */
251 static int awe_busy = FALSE; /* awe device opened? */
253 #define DEFAULT_DRUM_FLAGS ((1 << 9) | (1 << 25))
254 #define IS_DRUM_CHANNEL(c) (drum_flags & (1 << (c)))
255 #define DRUM_CHANNEL_ON(c) (drum_flags |= (1 << (c)))
256 #define DRUM_CHANNEL_OFF(c) (drum_flags &= ~(1 << (c)))
257 static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */
259 static int playing_mode = AWE_PLAY_INDIRECT;
260 #define SINGLE_LAYER_MODE() (playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT)
261 #define MULTI_LAYER_MODE() (playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2)
263 static int current_alloc_time = 0; /* voice allocation index for channel mode */
265 static struct MiscModeDef {
268 } misc_modes_default[AWE_MD_END] = {
269 {0,0}, {0,0}, /* <-- not used */
270 {AWE_VERSION_NUMBER, FALSE},
271 {TRUE, TRUE}, /* exclusive */
272 {TRUE, TRUE}, /* realpan */
273 {AWE_DEFAULT_BANK, TRUE}, /* gusbank */
274 {FALSE, TRUE}, /* keep effect */
275 {AWE_DEFAULT_ATTENUATION, FALSE}, /* zero_atten */
276 {FALSE, TRUE}, /* chn_prior */
277 {AWE_DEFAULT_MOD_SENSE, TRUE}, /* modwheel sense */
278 {AWE_DEFAULT_PRESET, TRUE}, /* def_preset */
279 {AWE_DEFAULT_BANK, TRUE}, /* def_bank */
280 {AWE_DEFAULT_DRUM, TRUE}, /* def_drum */
281 {FALSE, TRUE}, /* toggle_drum_bank */
284 static int misc_modes[AWE_MD_END];
286 static int awe_bass_level = 5;
287 static int awe_treble_level = 9;
290 static struct synth_info awe_info = {
291 "AWE32 Synth", /* name */
293 SYNTH_TYPE_SAMPLE, /* synth_type */
294 SAMPLE_TYPE_AWE32, /* synth_subtype */
295 0, /* perc_mode (obsolete) */
296 AWE_MAX_VOICES, /* nr_voices */
297 0, /* nr_drums (obsolete) */
298 AWE_MAX_INFOS /* instr_bank_size */
302 static struct voice_alloc_info *voice_alloc; /* set at initialization */
305 /*----------------------------------------------------------------
306 * function prototypes
307 *----------------------------------------------------------------*/
309 #if defined(linux) && !defined(AWE_OBSOLETE_VOXWARE)
310 static int awe_check_port(void);
311 static void awe_request_region(void);
312 static void awe_release_region(void);
315 static void awe_reset_samples(void);
316 /* emu8000 chip i/o access */
317 static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);
318 static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);
319 static unsigned short awe_peek(unsigned short cmd, unsigned short port);
320 static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);
321 static void awe_wait(unsigned short delay);
323 /* initialize emu8000 chip */
324 static void awe_initialize(void);
326 /* set voice parameters */
327 static void awe_init_misc_modes(int init_all);
328 static void awe_init_voice_info(awe_voice_info *vp);
329 static void awe_init_voice_parm(awe_voice_parm *pp);
330 #ifdef AWE_HAS_GUS_COMPATIBILITY
331 static int freq_to_note(int freq);
332 static int calc_rate_offset(int Hz);
333 /*static int calc_parm_delay(int msec);*/
334 static int calc_parm_hold(int msec);
335 static int calc_parm_attack(int msec);
336 static int calc_parm_decay(int msec);
337 static int calc_parm_search(int msec, short *table);
340 /* turn on/off note */
341 static void awe_note_on(int voice);
342 static void awe_note_off(int voice);
343 static void awe_terminate(int voice);
344 static void awe_exclusive_off(int voice);
345 static void awe_note_off_all(int do_sustain);
347 /* calculate voice parameters */
348 typedef void (*fx_affect_func)(int voice, int forced);
349 static void awe_set_pitch(int voice, int forced);
350 static void awe_set_voice_pitch(int voice, int forced);
351 static void awe_set_volume(int voice, int forced);
352 static void awe_set_voice_vol(int voice, int forced);
353 static void awe_set_pan(int voice, int forced);
354 static void awe_fx_fmmod(int voice, int forced);
355 static void awe_fx_tremfrq(int voice, int forced);
356 static void awe_fx_fm2frq2(int voice, int forced);
357 static void awe_fx_filterQ(int voice, int forced);
358 static void awe_calc_pitch(int voice);
359 #ifdef AWE_HAS_GUS_COMPATIBILITY
360 static void awe_calc_pitch_from_freq(int voice, int freq);
362 static void awe_calc_volume(int voice);
363 static void awe_voice_init(int voice, int init_all);
364 static void awe_channel_init(int ch, int init_all);
365 static void awe_fx_init(int ch);
367 /* sequencer interface */
368 static int awe_open(int dev, int mode);
369 static void awe_close(int dev);
370 static int awe_ioctl(int dev, unsigned int cmd, caddr_t arg);
371 static int awe_kill_note(int dev, int voice, int note, int velocity);
372 static int awe_start_note(int dev, int v, int note_num, int volume);
373 static int awe_set_instr(int dev, int voice, int instr_no);
374 static int awe_set_instr_2(int dev, int voice, int instr_no);
375 static void awe_reset(int dev);
376 static void awe_hw_control(int dev, unsigned char *event);
377 static int awe_load_patch(int dev, int format, const char *addr,
378 int offs, int count, int pmgr_flag);
379 static void awe_aftertouch(int dev, int voice, int pressure);
380 static void awe_controller(int dev, int voice, int ctrl_num, int value);
381 static void awe_panning(int dev, int voice, int value);
382 static void awe_volume_method(int dev, int mode);
383 #ifndef AWE_NO_PATCHMGR
384 static int awe_patchmgr(int dev, struct patmgr_info *rec);
386 static void awe_bender(int dev, int voice, int value);
387 static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc);
388 static void awe_setup_voice(int dev, int voice, int chn);
390 /* hardware controls */
391 #ifdef AWE_HAS_GUS_COMPATIBILITY
392 static void awe_hw_gus_control(int dev, int cmd, unsigned char *event);
394 static void awe_hw_awe_control(int dev, int cmd, unsigned char *event);
395 static void awe_voice_change(int voice, fx_affect_func func);
396 static void awe_sostenuto_on(int voice, int forced);
397 static void awe_sustain_off(int voice, int forced);
398 static void awe_terminate_and_init(int voice, int forced);
401 static int awe_search_instr(int bank, int preset);
402 static int awe_search_multi_voices(int rec, int note, int velocity, awe_voice_info **vlist);
403 static void awe_alloc_multi_voices(int ch, int note, int velocity, int key);
404 static void awe_alloc_one_voice(int voice, int note, int velocity);
405 static int awe_clear_voice(void);
407 /* load / remove patches */
408 static int awe_open_patch(awe_patch_info *patch, const char *addr, int count);
409 static int awe_close_patch(awe_patch_info *patch, const char *addr, int count);
410 static int awe_unload_patch(awe_patch_info *patch, const char *addr, int count);
411 static int awe_load_info(awe_patch_info *patch, const char *addr, int count);
412 static int awe_load_data(awe_patch_info *patch, const char *addr, int count);
413 static int awe_replace_data(awe_patch_info *patch, const char *addr, int count);
414 static int awe_load_map(awe_patch_info *patch, const char *addr, int count);
415 #ifdef AWE_HAS_GUS_COMPATIBILITY
416 static int awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag);
418 static int check_patch_opened(int type, char *name);
419 static int awe_write_wave_data(const char *addr, int offset, awe_sample_info *sp, int channels);
420 static void add_sf_info(int rec);
421 static void add_sf_sample(int rec);
422 static void purge_old_list(int rec, int next);
423 static void add_info_list(int rec);
424 static void awe_remove_samples(int sf_id);
425 static void rebuild_preset_list(void);
426 static short awe_set_sample(awe_voice_info *vp);
428 /* lowlevel functions */
429 static void awe_init_audio(void);
430 static void awe_init_dma(void);
431 static void awe_init_array(void);
432 static void awe_send_array(unsigned short *data);
433 static void awe_tweak_voice(int voice);
434 static void awe_tweak(void);
435 static void awe_init_fm(void);
436 static int awe_open_dram_for_write(int offset, int channels);
437 static void awe_open_dram_for_check(void);
438 static void awe_close_dram(void);
439 static void awe_write_dram(unsigned short c);
440 static int awe_detect_base(int addr);
441 static int awe_detect(void);
442 static int awe_check_dram(void);
443 static int awe_load_chorus_fx(awe_patch_info *patch, const char *addr, int count);
444 static void awe_set_chorus_mode(int mode);
445 static int awe_load_reverb_fx(awe_patch_info *patch, const char *addr, int count);
446 static void awe_set_reverb_mode(int mode);
447 static void awe_equalizer(int bass, int treble);
448 #ifdef CONFIG_AWE32_MIXER
449 static int awe_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg);
452 /* define macros for compatibility */
454 # include "awe_compat.h"
456 # include "awe_compat.h"
459 /*----------------------------------------------------------------
460 * synth operation table
461 *----------------------------------------------------------------*/
463 static struct synth_operations awe_operations =
485 #ifndef AWE_NO_PATCHMGR
493 #ifdef CONFIG_AWE32_MIXER
494 static struct mixer_operations awe_mixer_operations = {
504 /*================================================================
505 * attach / unload interface
506 *================================================================*/
508 #ifdef AWE_OBSOLETE_VOXWARE
509 #define ATTACH_DECL static
511 #define ATTACH_DECL /**/
514 #if defined(__FreeBSD__) && !defined(AWE_OBSOLETE_VOXWARE)
516 void attach_awe(struct address_info *hw_config)
518 # define ATTACH_RET ret
525 /* check presence of AWE32 card */
526 if (! awe_detect()) {
527 printk("AWE32: not detected\n");
531 /* check AWE32 ports are available */
532 if (awe_check_port()) {
533 printk("AWE32: I/O area already used.\n");
537 /* set buffers to NULL */
544 /* voice & channel info */
545 voices = (voice_info*)my_malloc(AWE_MAX_VOICES * sizeof(voice_info));
546 channels = (awe_chan_info*)my_malloc(AWE_MAX_CHANNELS * sizeof(awe_chan_info));
548 if (voices == NULL || channels == NULL) {
551 printk("AWE32: can't allocate sample tables\n");
555 /* allocate sample tables */
556 INIT_TABLE(sflists, max_sfs, AWE_MAX_SF_LISTS, sf_list);
557 INIT_TABLE(samples, max_samples, AWE_MAX_SAMPLES, awe_sample_list);
558 INIT_TABLE(infos, max_infos, AWE_MAX_INFOS, awe_voice_list);
560 if (num_synths >= MAX_SYNTH_DEV)
561 printk("AWE32 Error: too many synthesizers\n");
563 voice_alloc = &awe_operations.alloc;
564 voice_alloc->max_voice = awe_max_voices;
565 synth_devs[num_synths++] = &awe_operations;
568 #ifdef CONFIG_AWE32_MIXER
569 if (num_mixers < MAX_MIXER_DEV) {
570 mixer_devs[num_mixers++] = &awe_mixer_operations;
574 /* reserve I/O ports for awedrv */
575 awe_request_region();
577 /* clear all samples */
580 /* intialize AWE32 hardware */
583 snprintf(awe_info.name, sizeof(awe_info.name), "AWE32-%s (RAM%dk)",
584 AWEDRV_VERSION, awe_mem_size/1024);
586 printk("awe0: <SoundBlaster EMU8000 MIDI (RAM%dk)>", awe_mem_size/1024);
587 #elif defined(AWE_DEBUG_ON)
588 printk("%s\n", awe_info.name);
591 /* set default values */
592 awe_init_misc_modes(TRUE);
594 /* set reverb & chorus modes */
595 awe_set_reverb_mode(reverb_mode);
596 awe_set_chorus_mode(chorus_mode);
605 #ifdef AWE_DYNAMIC_BUFFER
606 static void free_tables(void)
609 sflists = NULL; max_sfs = 0;
611 samples = NULL; max_samples = 0;
613 infos = NULL; max_infos = 0;
616 #define free_buffers() /**/
622 void unload_awe(void)
626 awe_release_region();
636 /*----------------------------------------------------------------
638 *----------------------------------------------------------------*/
640 #ifdef AWE_OBSOLETE_VOXWARE
643 long attach_awe_obsolete(long mem_start, struct address_info *hw_config)
645 int attach_awe_obsolete(int mem_start, struct address_info *hw_config)
648 my_malloc_init(mem_start);
651 return my_malloc_memptr();
654 int probe_awe_obsolete(struct address_info *hw_config)
657 /*return awe_detect();*/
661 #if defined(__FreeBSD__ )
662 int probe_awe(struct address_info *hw_config)
667 #endif /* AWE_OBSOLETE_VOXWARE */
670 /*================================================================
671 * clear sample tables
672 *================================================================*/
675 awe_reset_samples(void)
679 /* free all bank tables */
680 for (i = 0; i < AWE_MAX_PRESETS; i++)
681 preset_table[i] = -1;
691 /*================================================================
692 * EMU register access
693 *================================================================*/
695 /* select a given AWE32 pointer */
696 static int awe_cur_cmd = -1;
697 #define awe_set_cmd(cmd) \
698 if (awe_cur_cmd != cmd) { OUTW(cmd, awe_base + 0x802); awe_cur_cmd = cmd; }
699 #define awe_port(port) (awe_base - 0x620 + port)
701 /* write 16bit data */
703 awe_poke(unsigned short cmd, unsigned short port, unsigned short data)
706 OUTW(data, awe_port(port));
709 /* write 32bit data */
711 awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data)
714 OUTW(data, awe_port(port)); /* write lower 16 bits */
715 OUTW(data >> 16, awe_port(port)+2); /* write higher 16 bits */
718 /* read 16bit data */
719 INLINE static unsigned short
720 awe_peek(unsigned short cmd, unsigned short port)
724 k = inw(awe_port(port));
728 /* read 32bit data */
729 INLINE static unsigned int
730 awe_peek_dw(unsigned short cmd, unsigned short port)
734 k1 = inw(awe_port(port));
735 k2 = inw(awe_port(port)+2);
740 /* wait delay number of AWE32 44100Hz clocks */
742 awe_wait(unsigned short delay)
744 unsigned short clock, target;
745 unsigned short port = awe_port(AWE_WC_Port);
749 awe_set_cmd(AWE_WC_Cmd);
750 clock = (unsigned short)inw(port);
751 target = clock + delay;
753 if (target < clock) {
754 for (; (unsigned short)inw(port) > target; counter++)
758 for (; (unsigned short)inw(port) < target; counter++)
763 /* write a word data */
765 awe_write_dram(unsigned short c)
767 awe_poke(AWE_SMLD, c);
771 #if defined(linux) && !defined(AWE_OBSOLETE_VOXWARE)
773 /*================================================================
774 * port check / request
775 * 0x620-622, 0xA20-A22, 0xE20-E22
776 *================================================================*/
781 return (check_region(awe_port(Data0), 4) ||
782 check_region(awe_port(Data1), 4) ||
783 check_region(awe_port(Data3), 4));
787 awe_request_region(void)
789 request_region(awe_port(Data0), 4, "sound driver (AWE32)");
790 request_region(awe_port(Data1), 4, "sound driver (AWE32)");
791 request_region(awe_port(Data3), 4, "sound driver (AWE32)");
795 awe_release_region(void)
797 release_region(awe_port(Data0), 4);
798 release_region(awe_port(Data1), 4);
799 release_region(awe_port(Data3), 4);
802 #endif /* !AWE_OBSOLETE_VOXWARE */
805 /*================================================================
806 * AWE32 initialization
807 *================================================================*/
811 AWE_DEBUG(0,printk("AWE32: initializing..\n"));
813 /* initialize hardware configuration */
814 awe_poke(AWE_HWCF1, 0x0059);
815 awe_poke(AWE_HWCF2, 0x0020);
817 /* disable audio; this seems to reduce a clicking noise a bit.. */
818 awe_poke(AWE_HWCF3, 0);
820 /* initialize audio channels */
826 /* initialize init array */
829 /* check DRAM memory size */
830 awe_mem_size = awe_check_dram();
832 /* initialize the FM section of the AWE32 */
835 /* set up voice envelopes */
839 awe_poke(AWE_HWCF3, 0x0004);
846 /*================================================================
847 * AWE32 voice parameters
848 *================================================================*/
850 /* initialize voice_info record */
852 awe_init_voice_info(awe_voice_info *vp)
854 vp->sf_id = 0; /* normal mode */
875 vp->exclusiveClass = 0;
878 vp->scaleTuning = 100;
880 awe_init_voice_parm(&vp->parm);
883 /* initialize voice_parm record:
884 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
885 * Vibrato and Tremolo effects are zero.
887 * Chorus and Reverb effects are zero.
890 awe_init_voice_parm(awe_voice_parm *pp)
892 pp->moddelay = 0x8000;
893 pp->modatkhld = 0x7f7f;
894 pp->moddcysus = 0x7f7f;
895 pp->modrelease = 0x807f;
899 pp->voldelay = 0x8000;
900 pp->volatkhld = 0x7f7f;
901 pp->voldcysus = 0x7f7f;
902 pp->volrelease = 0x807f;
906 pp->lfo1delay = 0x8000;
907 pp->lfo2delay = 0x8000;
922 #ifdef AWE_HAS_GUS_COMPATIBILITY
924 /* convert frequency mHz to abstract cents (= midi key * 100) */
926 freq_to_note(int mHz)
928 /* abscents = log(mHz/8176) / log(2) * 1200 */
929 unsigned int max_val = (unsigned int)0xffffffff / 10000;
938 return 12799; /* maximum */
942 for (base = 8176 * 2; freq >= base; base *= 2) {
944 if (note >= 128) /* over maximum */
949 /* to avoid overflow... */
951 while (freq > max_val) {
957 freq = freq * times / base;
958 for (i = 0; i < 12; i++) {
959 if (freq < semitone_tuning[i+1])
965 freq = freq * 10000 / semitone_tuning[i];
966 for (i = 0; i < 100; i++) {
967 if (freq < cent_tuning[i+1])
972 return note * 100 + tune;
976 /* convert Hz to AWE32 rate offset:
977 * sample pitch offset for the specified sample rate
978 * rate=44100 is no offset, each 4096 is 1 octave (twice).
979 * eg, when rate is 22050, this offset becomes -4096.
982 calc_rate_offset(int Hz)
984 /* offset = log(Hz / 44100) / log(2) * 4096 */
987 /* maybe smaller than max (44100Hz) */
988 if (Hz <= 0 || Hz >= 44100) return 0;
991 for (freq = Hz * 2; freq < 44100; freq *= 2)
995 freq = 44100 * 10000 / (freq/2);
996 for (i = 0; i < 12; i++) {
997 if (freq < semitone_tuning[i+1])
1001 freq = freq * 10000 / semitone_tuning[i];
1002 for (i = 0; i < 100; i++) {
1003 if (freq < cent_tuning[i+1])
1007 return -base * 4096 / 1200;
1011 /*----------------------------------------------------------------
1012 * convert envelope time parameter to AWE32 raw parameter
1013 *----------------------------------------------------------------*/
1015 /* attack & decay/release time table (msec) */
1016 static short attack_time_tbl[128] = {
1017 32767, 11878, 5939, 3959, 2969, 2375, 1979, 1696, 1484, 1319, 1187, 1079, 989, 913, 848, 791, 742,
1018 698, 659, 625, 593, 565, 539, 516, 494, 475, 456, 439, 424, 409, 395, 383, 371,
1019 359, 344, 330, 316, 302, 290, 277, 266, 255, 244, 233, 224, 214, 205, 196, 188,
1020 180, 173, 165, 158, 152, 145, 139, 133, 127, 122, 117, 112, 107, 103, 98, 94,
1021 90, 86, 83, 79, 76, 73, 69, 67, 64, 61, 58, 56, 54, 51, 49, 47,
1022 45, 43, 41, 39, 38, 36, 35, 33, 32, 30, 29, 28, 27, 25, 24, 23,
1023 22, 21, 20, 20, 19, 18, 17, 16, 16, 15, 14, 14, 13, 13, 12, 11,
1024 11, 10, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 0,
1027 static short decay_time_tbl[128] = {
1028 32767, 32766, 4589, 4400, 4219, 4045, 3879, 3719, 3566, 3419, 3279, 3144, 3014, 2890, 2771, 2657,
1029 2548, 2443, 2343, 2246, 2154, 2065, 1980, 1899, 1820, 1746, 1674, 1605, 1539, 1475, 1415, 1356,
1030 1301, 1247, 1196, 1146, 1099, 1054, 1011, 969, 929, 891, 854, 819, 785, 753, 722, 692,
1031 664, 636, 610, 585, 561, 538, 516, 494, 474, 455, 436, 418, 401, 384, 368, 353,
1032 339, 325, 311, 298, 286, 274, 263, 252, 242, 232, 222, 213, 204, 196, 188, 180,
1033 173, 166, 159, 152, 146, 140, 134, 129, 123, 118, 113, 109, 104, 100, 96, 92,
1034 88, 84, 81, 77, 74, 71, 68, 65, 63, 60, 58, 55, 53, 51, 49, 47,
1035 45, 43, 41, 39, 38, 36, 35, 33, 32, 30, 29, 28, 27, 26, 25, 24,
1040 calc_parm_delay(int msec)
1042 return (0x8000 - msec * 1000 / 725);
1046 /* delay time = 0x8000 - msec/92 */
1048 calc_parm_hold(int msec)
1050 int val = (0x7f * 92 - msec) / 92;
1051 if (val < 1) val = 1;
1052 if (val > 127) val = 127;
1056 /* attack time: search from time table */
1058 calc_parm_attack(int msec)
1060 return calc_parm_search(msec, attack_time_tbl);
1063 /* decay/release time: search from time table */
1065 calc_parm_decay(int msec)
1067 return calc_parm_search(msec, decay_time_tbl);
1070 /* search an index for specified time from given time table */
1072 calc_parm_search(int msec, short *table)
1074 int left = 1, right = 127, mid;
1075 while (left < right) {
1076 mid = (left + right) / 2;
1077 if (msec < (int)table[mid])
1084 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1087 /*================================================================
1089 *================================================================*/
1091 /* set an effect value */
1092 #define FX_FLAG_OFF 0
1093 #define FX_FLAG_SET 1
1094 #define FX_FLAG_ADD 2
1096 #define FX_SET(rec,type,value) \
1097 ((rec)->flags[type] = FX_FLAG_SET, (rec)->val[type] = (value))
1098 #define FX_ADD(rec,type,value) \
1099 ((rec)->flags[type] = FX_FLAG_ADD, (rec)->val[type] = (value))
1100 #define FX_UNSET(rec,type) \
1101 ((rec)->flags[type] = FX_FLAG_OFF, (rec)->val[type] = 0)
1103 /* check the effect value is set */
1104 #define FX_ON(rec,type) ((rec)->flags[type])
1109 static struct PARM_DEFS {
1110 int type; /* byte or word */
1111 int low, high; /* value range */
1112 fx_affect_func realtime; /* realtime paramater change */
1114 {PARM_WORD, 0, 0x8000, NULL}, /* env1 delay */
1115 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 attack */
1116 {PARM_BYTE, 0, 0x7e, NULL}, /* env1 hold */
1117 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 decay */
1118 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 release */
1119 {PARM_BYTE, 0, 0x7f, NULL}, /* env1 sustain */
1120 {PARM_BYTE, 0, 0xff, NULL}, /* env1 pitch */
1121 {PARM_BYTE, 0, 0xff, NULL}, /* env1 cutoff */
1123 {PARM_WORD, 0, 0x8000, NULL}, /* env2 delay */
1124 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 attack */
1125 {PARM_BYTE, 0, 0x7e, NULL}, /* env2 hold */
1126 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 decay */
1127 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 release */
1128 {PARM_BYTE, 0, 0x7f, NULL}, /* env2 sustain */
1130 {PARM_WORD, 0, 0x8000, NULL}, /* lfo1 delay */
1131 {PARM_BYTE, 0, 0xff, awe_fx_tremfrq}, /* lfo1 freq */
1132 {PARM_BYTE, 0, 0x7f, awe_fx_tremfrq}, /* lfo1 volume (positive only)*/
1133 {PARM_BYTE, 0, 0x7f, awe_fx_fmmod}, /* lfo1 pitch (positive only)*/
1134 {PARM_BYTE, 0, 0xff, awe_fx_fmmod}, /* lfo1 cutoff (positive only)*/
1136 {PARM_WORD, 0, 0x8000, NULL}, /* lfo2 delay */
1137 {PARM_BYTE, 0, 0xff, awe_fx_fm2frq2}, /* lfo2 freq */
1138 {PARM_BYTE, 0, 0x7f, awe_fx_fm2frq2}, /* lfo2 pitch (positive only)*/
1140 {PARM_WORD, 0, 0xffff, awe_set_voice_pitch}, /* initial pitch */
1141 {PARM_BYTE, 0, 0xff, NULL}, /* chorus */
1142 {PARM_BYTE, 0, 0xff, NULL}, /* reverb */
1143 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial cutoff */
1144 {PARM_BYTE, 0, 15, awe_fx_filterQ}, /* initial resonance */
1146 {PARM_WORD, 0, 0xffff, NULL}, /* sample start */
1147 {PARM_WORD, 0, 0xffff, NULL}, /* loop start */
1148 {PARM_WORD, 0, 0xffff, NULL}, /* loop end */
1149 {PARM_WORD, 0, 0xffff, NULL}, /* coarse sample start */
1150 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop start */
1151 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop end */
1152 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial attenuation */
1156 static unsigned char
1157 FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value)
1161 if (lay && (on = FX_ON(lay, type)) != 0)
1162 effect = lay->val[type];
1163 if (!on && (on = FX_ON(rec, type)) != 0)
1164 effect = rec->val[type];
1165 if (on == FX_FLAG_ADD)
1166 effect += (int)value;
1168 if (effect < parm_defs[type].low)
1169 effect = parm_defs[type].low;
1170 else if (effect > parm_defs[type].high)
1171 effect = parm_defs[type].high;
1172 return (unsigned char)effect;
1177 /* get word effect value */
1178 static unsigned short
1179 FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value)
1183 if (lay && (on = FX_ON(lay, type)) != 0)
1184 effect = lay->val[type];
1185 if (!on && (on = FX_ON(rec, type)) != 0)
1186 effect = rec->val[type];
1187 if (on == FX_FLAG_ADD)
1188 effect += (int)value;
1190 if (effect < parm_defs[type].low)
1191 effect = parm_defs[type].low;
1192 else if (effect > parm_defs[type].high)
1193 effect = parm_defs[type].high;
1194 return (unsigned short)effect;
1199 /* get word (upper=type1/lower=type2) effect value */
1200 static unsigned short
1201 FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value)
1204 tmp = FX_BYTE(rec, lay, type1, (unsigned char)(value >> 8));
1206 tmp |= FX_BYTE(rec, lay, type2, (unsigned char)(value & 0xff));
1210 /* address offset */
1212 FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode)
1215 if (lay && FX_ON(lay, hi))
1216 addr = (short)lay->val[hi];
1217 else if (FX_ON(rec, hi))
1218 addr = (short)rec->val[hi];
1220 if (lay && FX_ON(lay, lo))
1221 addr += (short)lay->val[lo];
1222 else if (FX_ON(rec, lo))
1223 addr += (short)rec->val[lo];
1224 if (!(mode & AWE_SAMPLE_8BITS))
1230 /*================================================================
1231 * turn on/off sample
1232 *================================================================*/
1235 awe_note_on(int voice)
1240 FX_Rec *fx = &voices[voice].cinfo->fx;
1241 FX_Rec *fx_lay = NULL;
1242 if (voices[voice].layer < MAX_LAYERS)
1243 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1245 /* A voice sample must assigned before calling */
1246 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1249 /* channel to be silent and idle */
1250 awe_poke(AWE_DCYSUSV(voice), 0x0080);
1251 awe_poke(AWE_VTFT(voice), 0);
1252 awe_poke(AWE_CVCF(voice), 0);
1253 awe_poke(AWE_PTRX(voice), 0);
1254 awe_poke(AWE_CPF(voice), 0);
1256 /* modulation & volume envelope */
1257 awe_poke(AWE_ENVVAL(voice),
1258 FX_WORD(fx, fx_lay, AWE_FX_ENV1_DELAY, vp->parm.moddelay));
1259 awe_poke(AWE_ATKHLD(voice),
1260 FX_COMB(fx, fx_lay, AWE_FX_ENV1_HOLD, AWE_FX_ENV1_ATTACK,
1261 vp->parm.modatkhld));
1262 awe_poke(AWE_DCYSUS(voice),
1263 FX_COMB(fx, fx_lay, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY,
1264 vp->parm.moddcysus));
1265 awe_poke(AWE_ENVVOL(voice),
1266 FX_WORD(fx, fx_lay, AWE_FX_ENV2_DELAY, vp->parm.voldelay));
1267 awe_poke(AWE_ATKHLDV(voice),
1268 FX_COMB(fx, fx_lay, AWE_FX_ENV2_HOLD, AWE_FX_ENV2_ATTACK,
1269 vp->parm.volatkhld));
1270 /* decay/sustain parameter for volume envelope must be set at last */
1273 awe_set_pitch(voice, TRUE);
1275 /* cutoff and volume */
1276 awe_set_volume(voice, TRUE);
1278 /* modulation envelope heights */
1279 awe_poke(AWE_PEFE(voice),
1280 FX_COMB(fx, fx_lay, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF,
1284 awe_poke(AWE_LFO1VAL(voice),
1285 FX_WORD(fx, fx_lay, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay));
1286 awe_poke(AWE_LFO2VAL(voice),
1287 FX_WORD(fx, fx_lay, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay));
1289 /* lfo1 pitch & cutoff shift */
1290 awe_fx_fmmod(voice, TRUE);
1291 /* lfo1 volume & freq */
1292 awe_fx_tremfrq(voice, TRUE);
1293 /* lfo2 pitch & freq */
1294 awe_fx_fm2frq2(voice, TRUE);
1295 /* pan & loop start */
1296 awe_set_pan(voice, TRUE);
1298 /* chorus & loop end (chorus 8bit, MSB) */
1299 addr = vp->loopend - 1;
1300 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_END,
1301 AWE_FX_COARSE_LOOP_END, vp->mode);
1302 temp = FX_BYTE(fx, fx_lay, AWE_FX_CHORUS, vp->parm.chorus);
1303 temp = (temp <<24) | (unsigned int)addr;
1304 awe_poke_dw(AWE_CSL(voice), temp);
1305 AWE_DEBUG(4,printk("AWE32: [-- loopend=%x/%x]\n", vp->loopend, addr));
1307 /* Q & current address (Q 4bit value, MSB) */
1308 addr = vp->start - 1;
1309 addr += FX_OFFSET(fx, fx_lay, AWE_FX_SAMPLE_START,
1310 AWE_FX_COARSE_SAMPLE_START, vp->mode);
1311 temp = FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ);
1312 temp = (temp<<28) | (unsigned int)addr;
1313 awe_poke_dw(AWE_CCCA(voice), temp);
1314 AWE_DEBUG(4,printk("AWE32: [-- startaddr=%x/%x]\n", vp->start, addr));
1317 awe_poke_dw(AWE_VTFT(voice), 0x0000FFFF);
1318 awe_poke_dw(AWE_CVCF(voice), 0x0000FFFF);
1320 /* turn on envelope */
1321 awe_poke(AWE_DCYSUSV(voice),
1322 FX_COMB(fx, fx_lay, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY,
1323 vp->parm.voldcysus));
1325 temp = FX_BYTE(fx, fx_lay, AWE_FX_REVERB, vp->parm.reverb);
1326 temp = (awe_peek_dw(AWE_PTRX(voice)) & 0xffff0000) | (temp<<8);
1327 awe_poke_dw(AWE_PTRX(voice), temp);
1328 awe_poke_dw(AWE_CPF(voice), 0x40000000);
1330 voices[voice].state = AWE_ST_ON;
1332 /* clear voice position for the next note on this channel */
1333 if (SINGLE_LAYER_MODE()) {
1334 FX_UNSET(fx, AWE_FX_SAMPLE_START);
1335 FX_UNSET(fx, AWE_FX_COARSE_SAMPLE_START);
1340 /* turn off the voice */
1342 awe_note_off(int voice)
1346 FX_Rec *fx = &voices[voice].cinfo->fx;
1347 FX_Rec *fx_lay = NULL;
1348 if (voices[voice].layer < MAX_LAYERS)
1349 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1351 if ((vp = voices[voice].sample) == NULL) {
1352 voices[voice].state = AWE_ST_OFF;
1356 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_RELEASE,
1357 (unsigned char)vp->parm.modrelease);
1358 awe_poke(AWE_DCYSUS(voice), tmp);
1359 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_RELEASE,
1360 (unsigned char)vp->parm.volrelease);
1361 awe_poke(AWE_DCYSUSV(voice), tmp);
1362 voices[voice].state = AWE_ST_RELEASED;
1365 /* force to terminate the voice (no releasing echo) */
1367 awe_terminate(int voice)
1369 awe_poke(AWE_DCYSUSV(voice), 0x807F);
1370 awe_tweak_voice(voice);
1371 voices[voice].state = AWE_ST_OFF;
1374 /* turn off other voices with the same exclusive class (for drums) */
1376 awe_exclusive_off(int voice)
1380 if (voices[voice].sample == NULL)
1382 if ((exclass = voices[voice].sample->exclusiveClass) == 0)
1383 return; /* not exclusive */
1385 /* turn off voices with the same class */
1386 for (i = 0; i < awe_max_voices; i++) {
1387 if (i != voice && IS_PLAYING(i) &&
1388 voices[i].sample && voices[i].ch == voices[voice].ch &&
1389 voices[i].sample->exclusiveClass == exclass) {
1390 AWE_DEBUG(4,printk("AWE32: [exoff(%d)]\n", i));
1392 awe_voice_init(i, TRUE);
1398 /*================================================================
1399 * change the parameters of an audible voice
1400 *================================================================*/
1404 awe_set_pitch(int voice, int forced)
1406 if (IS_NO_EFFECT(voice) && !forced) return;
1407 awe_poke(AWE_IP(voice), voices[voice].apitch);
1408 AWE_DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch));
1411 /* calculate & change pitch */
1413 awe_set_voice_pitch(int voice, int forced)
1415 awe_calc_pitch(voice);
1416 awe_set_pitch(voice, forced);
1419 /* change volume & cutoff */
1421 awe_set_volume(int voice, int forced)
1424 unsigned short tmp2;
1425 FX_Rec *fx = &voices[voice].cinfo->fx;
1426 FX_Rec *fx_lay = NULL;
1427 if (voices[voice].layer < MAX_LAYERS)
1428 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1430 if (!IS_PLAYING(voice) && !forced) return;
1431 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1434 tmp2 = FX_BYTE(fx, fx_lay, AWE_FX_CUTOFF, vp->parm.cutoff);
1436 tmp2 |= FX_BYTE(fx, fx_lay, AWE_FX_ATTEN,
1437 (unsigned char)voices[voice].avol);
1438 awe_poke(AWE_IFATN(voice), tmp2);
1441 /* calculate & change volume */
1443 awe_set_voice_vol(int voice, int forced)
1445 if (IS_EMPTY(voice))
1447 awe_calc_volume(voice);
1448 awe_set_volume(voice, forced);
1452 /* change pan; this could make a click noise.. */
1454 awe_set_pan(int voice, int forced)
1459 FX_Rec *fx = &voices[voice].cinfo->fx;
1460 FX_Rec *fx_lay = NULL;
1461 if (voices[voice].layer < MAX_LAYERS)
1462 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1464 if (IS_NO_EFFECT(voice) && !forced) return;
1465 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1468 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
1469 if (vp->fixpan > 0) /* 0-127 */
1470 temp = 255 - (int)vp->fixpan * 2;
1473 if (vp->pan >= 0) /* 0-127 */
1474 pos = (int)vp->pan * 2 - 128;
1475 pos += voices[voice].cinfo->panning; /* -128 - 127 */
1484 if (forced || temp != voices[voice].apan) {
1485 addr = vp->loopstart - 1;
1486 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START,
1487 AWE_FX_COARSE_LOOP_START, vp->mode);
1488 temp = (temp<<24) | (unsigned int)addr;
1489 awe_poke_dw(AWE_PSST(voice), temp);
1490 voices[voice].apan = temp;
1491 AWE_DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr));
1495 /* effects change during playing */
1497 awe_fx_fmmod(int voice, int forced)
1500 FX_Rec *fx = &voices[voice].cinfo->fx;
1501 FX_Rec *fx_lay = NULL;
1502 if (voices[voice].layer < MAX_LAYERS)
1503 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1505 if (IS_NO_EFFECT(voice) && !forced) return;
1506 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1508 awe_poke(AWE_FMMOD(voice),
1509 FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,
1513 /* set tremolo (lfo1) volume & frequency */
1515 awe_fx_tremfrq(int voice, int forced)
1518 FX_Rec *fx = &voices[voice].cinfo->fx;
1519 FX_Rec *fx_lay = NULL;
1520 if (voices[voice].layer < MAX_LAYERS)
1521 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1523 if (IS_NO_EFFECT(voice) && !forced) return;
1524 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1526 awe_poke(AWE_TREMFRQ(voice),
1527 FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,
1531 /* set lfo2 pitch & frequency */
1533 awe_fx_fm2frq2(int voice, int forced)
1536 FX_Rec *fx = &voices[voice].cinfo->fx;
1537 FX_Rec *fx_lay = NULL;
1538 if (voices[voice].layer < MAX_LAYERS)
1539 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1541 if (IS_NO_EFFECT(voice) && !forced) return;
1542 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1544 awe_poke(AWE_FM2FRQ2(voice),
1545 FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,
1550 /* Q & current address (Q 4bit value, MSB) */
1552 awe_fx_filterQ(int voice, int forced)
1556 FX_Rec *fx = &voices[voice].cinfo->fx;
1557 FX_Rec *fx_lay = NULL;
1558 if (voices[voice].layer < MAX_LAYERS)
1559 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1561 if (IS_NO_EFFECT(voice) && !forced) return;
1562 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1565 addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff;
1566 addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28);
1567 awe_poke_dw(AWE_CCCA(voice), addr);
1570 /*================================================================
1571 * calculate pitch offset
1572 *----------------------------------------------------------------
1573 * 0xE000 is no pitch offset at 44100Hz sample.
1574 * Every 4096 is one octave.
1575 *================================================================*/
1578 awe_calc_pitch(int voice)
1580 voice_info *vp = &voices[voice];
1582 awe_chan_info *cp = voices[voice].cinfo;
1585 /* search voice information */
1586 if ((ap = vp->sample) == NULL)
1588 if (ap->index < 0) {
1589 AWE_DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1590 if (awe_set_sample(ap) < 0)
1594 /* calculate offset */
1595 if (ap->fixkey >= 0) {
1596 AWE_DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune));
1597 offset = (ap->fixkey - ap->root) * 4096 / 12;
1599 AWE_DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune));
1600 offset = (vp->note - ap->root) * 4096 / 12;
1601 AWE_DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset));
1603 offset = (offset * ap->scaleTuning) / 100;
1604 AWE_DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));
1605 offset += ap->tune * 4096 / 1200;
1606 AWE_DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));
1607 if (cp->bender != 0) {
1608 AWE_DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender));
1609 /* (819200: 1 semitone) ==> (4096: 12 semitones) */
1610 offset += cp->bender * cp->bender_range / 2400;
1613 /* add initial pitch correction */
1614 if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH))
1615 offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH];
1616 else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH))
1617 offset += cp->fx.val[AWE_FX_INIT_PITCH];
1619 /* 0xe000: root pitch */
1620 vp->apitch = 0xe000 + ap->rate_offset + offset;
1621 AWE_DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset));
1622 if (vp->apitch > 0xffff)
1623 vp->apitch = 0xffff;
1629 #ifdef AWE_HAS_GUS_COMPATIBILITY
1630 /* calculate MIDI key and semitone from the specified frequency */
1632 awe_calc_pitch_from_freq(int voice, int freq)
1634 voice_info *vp = &voices[voice];
1636 FX_Rec *fx = &voices[voice].cinfo->fx;
1637 FX_Rec *fx_lay = NULL;
1641 if (voices[voice].layer < MAX_LAYERS)
1642 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1644 /* search voice information */
1645 if ((ap = vp->sample) == NULL)
1647 if (ap->index < 0) {
1648 AWE_DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1649 if (awe_set_sample(ap) < 0)
1652 note = freq_to_note(freq);
1653 offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;
1654 offset = (offset * ap->scaleTuning) / 100;
1655 if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH))
1656 offset += fx_lay->val[AWE_FX_INIT_PITCH];
1657 else if (FX_ON(fx, AWE_FX_INIT_PITCH))
1658 offset += fx->val[AWE_FX_INIT_PITCH];
1659 vp->apitch = 0xe000 + ap->rate_offset + offset;
1660 if (vp->apitch > 0xffff)
1661 vp->apitch = 0xffff;
1665 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1668 /*================================================================
1669 * calculate volume attenuation
1670 *----------------------------------------------------------------
1671 * Voice volume is controlled by volume attenuation parameter.
1672 * So volume becomes maximum when avol is 0 (no attenuation), and
1673 * minimum when 255 (-96dB or silence).
1674 *================================================================*/
1676 static int vol_table[128] = {
1677 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
1678 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
1679 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
1680 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
1681 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
1682 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
1683 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
1684 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
1688 awe_calc_volume(int voice)
1690 voice_info *vp = &voices[voice];
1692 awe_chan_info *cp = voices[voice].cinfo;
1695 /* search voice information */
1696 if ((ap = vp->sample) == NULL)
1700 if (ap->index < 0) {
1701 AWE_DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1702 if (awe_set_sample(ap) < 0)
1707 vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127);
1708 vol = vol * ap->amplitude / 127;
1710 if (vol < 0) vol = 0;
1711 if (vol > 127) vol = 127;
1713 /* calc to attenuation */
1714 vol = vol_table[vol];
1715 vol = vol + (int)ap->attenuation + init_atten;
1716 if (vol > 255) vol = 255;
1719 AWE_DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));
1723 /* set sostenuto on */
1724 static void awe_sostenuto_on(int voice, int forced)
1726 if (IS_NO_EFFECT(voice) && !forced) return;
1727 voices[voice].sostenuto = 127;
1732 static void awe_sustain_off(int voice, int forced)
1734 if (voices[voice].state == AWE_ST_SUSTAINED) {
1735 awe_note_off(voice);
1736 awe_fx_init(voices[voice].ch);
1737 awe_voice_init(voice, FALSE);
1742 /* terminate and initialize voice */
1743 static void awe_terminate_and_init(int voice, int forced)
1745 awe_terminate(voice);
1746 awe_fx_init(voices[voice].ch);
1747 awe_voice_init(voice, TRUE);
1751 /*================================================================
1752 * synth operation routines
1753 *================================================================*/
1755 #define AWE_VOICE_KEY(v) (0x8000 | (v))
1756 #define AWE_CHAN_KEY(c,n) (((c) << 8) | ((n) + 1))
1757 #define KEY_CHAN_MATCH(key,c) (((key) >> 8) == (c))
1759 /* initialize the voice */
1761 awe_voice_init(int voice, int init_all)
1763 voice_info *vp = &voices[voice];
1765 /* reset voice search key */
1766 if (playing_mode == AWE_PLAY_DIRECT)
1767 vp->key = AWE_VOICE_KEY(voice);
1771 /* clear voice mapping */
1772 voice_alloc->map[voice] = 0;
1774 /* touch the timing flag */
1775 vp->time = current_alloc_time;
1777 /* initialize other parameters if necessary */
1784 vp->cinfo = &channels[voice];
1786 vp->state = AWE_ST_OFF;
1788 /* emu8000 parameters */
1796 static void awe_fx_init(int ch)
1798 if (SINGLE_LAYER_MODE() && !misc_modes[AWE_MD_KEEP_EFFECT]) {
1799 BZERO(&channels[ch].fx, sizeof(channels[ch].fx));
1800 BZERO(&channels[ch].fx_layer, sizeof(&channels[ch].fx_layer));
1804 /* initialize channel info */
1805 static void awe_channel_init(int ch, int init_all)
1807 awe_chan_info *cp = &channels[ch];
1810 cp->panning = 0; /* zero center */
1811 cp->bender_range = 200; /* sense * 100 */
1813 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) {
1814 cp->instr = misc_modes[AWE_MD_DEF_DRUM];
1815 cp->bank = AWE_DRUM_BANK;
1817 cp->instr = misc_modes[AWE_MD_DEF_PRESET];
1818 cp->bank = misc_modes[AWE_MD_DEF_BANK];
1824 cp->bender = 0; /* zero tune skew */
1825 cp->expression_vol = 127;
1829 if (! misc_modes[AWE_MD_KEEP_EFFECT]) {
1830 BZERO(&cp->fx, sizeof(cp->fx));
1831 BZERO(&cp->fx_layer, sizeof(cp->fx_layer));
1836 /* change the voice parameters; voice = channel */
1837 static void awe_voice_change(int voice, fx_affect_func func)
1840 switch (playing_mode) {
1841 case AWE_PLAY_DIRECT:
1844 case AWE_PLAY_INDIRECT:
1845 for (i = 0; i < awe_max_voices; i++)
1846 if (voices[i].key == AWE_VOICE_KEY(voice))
1850 for (i = 0; i < awe_max_voices; i++)
1851 if (KEY_CHAN_MATCH(voices[i].key, voice))
1858 /*----------------------------------------------------------------
1859 * device open / close
1860 *----------------------------------------------------------------*/
1863 * reset status of all voices, and clear sample position flag
1866 awe_open(int dev, int mode)
1869 return RET_ERROR(EBUSY);
1873 /* set default mode */
1874 awe_init_misc_modes(FALSE);
1875 init_atten = misc_modes[AWE_MD_ZERO_ATTEN];
1876 drum_flags = DEFAULT_DRUM_FLAGS;
1877 playing_mode = AWE_PLAY_INDIRECT;
1879 /* reset voices & channels */
1889 * reset all voices again (terminate sounds)
1899 /* set miscellaneous mode parameters
1902 awe_init_misc_modes(int init_all)
1905 for (i = 0; i < AWE_MD_END; i++) {
1906 if (init_all || misc_modes_default[i].init_each_time)
1907 misc_modes[i] = misc_modes_default[i].value;
1912 /* sequencer I/O control:
1915 awe_ioctl(int dev, unsigned int cmd, caddr_t arg)
1918 case SNDCTL_SYNTH_INFO:
1919 if (playing_mode == AWE_PLAY_DIRECT)
1920 awe_info.nr_voices = awe_max_voices;
1922 awe_info.nr_voices = AWE_MAX_CHANNELS;
1923 IOCTL_TO_USER((char*)arg, 0, &awe_info, sizeof(awe_info));
1927 case SNDCTL_SEQ_RESETSAMPLES:
1928 awe_reset_samples();
1933 case SNDCTL_SEQ_PERCMODE:
1938 case SNDCTL_SYNTH_MEMAVL:
1939 return awe_mem_size - awe_free_mem_ptr() * 2;
1942 printk("AWE32: unsupported ioctl %d\n", cmd);
1943 return RET_ERROR(EINVAL);
1948 static int voice_in_range(int voice)
1950 if (playing_mode == AWE_PLAY_DIRECT) {
1951 if (voice < 0 || voice >= awe_max_voices)
1954 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
1960 static void release_voice(int voice, int do_sustain)
1962 if (IS_NO_SOUND(voice))
1964 if (do_sustain && (voices[voice].cinfo->sustained == 127 ||
1965 voices[voice].sostenuto == 127))
1966 voices[voice].state = AWE_ST_SUSTAINED;
1968 awe_note_off(voice);
1969 awe_fx_init(voices[voice].ch);
1970 awe_voice_init(voice, FALSE);
1974 /* release all notes */
1975 static void awe_note_off_all(int do_sustain)
1978 for (i = 0; i < awe_max_voices; i++)
1979 release_voice(i, do_sustain);
1983 * not terminate, just release the voice.
1986 awe_kill_note(int dev, int voice, int note, int velocity)
1990 AWE_DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));
1991 if (! voice_in_range(voice))
1992 return RET_ERROR(EINVAL);
1994 switch (playing_mode) {
1995 case AWE_PLAY_DIRECT:
1996 case AWE_PLAY_INDIRECT:
1997 key = AWE_VOICE_KEY(voice);
2000 case AWE_PLAY_MULTI2:
2001 v2 = voice_alloc->map[voice] >> 8;
2002 voice_alloc->map[voice] = 0;
2004 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2005 return RET_ERROR(EINVAL);
2006 /* continue to below */
2008 key = AWE_CHAN_KEY(voice, note);
2012 for (i = 0; i < awe_max_voices; i++) {
2013 if (voices[i].key == key)
2014 release_voice(i, TRUE);
2020 static void start_or_volume_change(int voice, int velocity)
2022 voices[voice].velocity = velocity;
2023 awe_calc_volume(voice);
2024 if (voices[voice].state == AWE_ST_STANDBY)
2026 else if (voices[voice].state == AWE_ST_ON)
2027 awe_set_volume(voice, FALSE);
2030 static void set_and_start_voice(int voice, int state)
2032 /* calculate pitch & volume parameters */
2033 voices[voice].state = state;
2034 awe_calc_pitch(voice);
2035 awe_calc_volume(voice);
2036 if (state == AWE_ST_ON)
2041 * if note is 255, identical with aftertouch function.
2042 * Otherwise, start a voice with specified not and volume.
2045 awe_start_note(int dev, int voice, int note, int velocity)
2047 int i, key, state, volonly;
2049 AWE_DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));
2050 if (! voice_in_range(voice))
2051 return RET_ERROR(EINVAL);
2054 state = AWE_ST_STANDBY; /* stand by for playing */
2056 state = AWE_ST_ON; /* really play */
2059 switch (playing_mode) {
2060 case AWE_PLAY_DIRECT:
2061 case AWE_PLAY_INDIRECT:
2062 key = AWE_VOICE_KEY(voice);
2067 case AWE_PLAY_MULTI2:
2068 voice = voice_alloc->map[voice] >> 8;
2069 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2070 return RET_ERROR(EINVAL);
2071 /* continue to below */
2073 if (note >= 128) { /* key volume mode */
2077 key = AWE_CHAN_KEY(voice, note);
2081 /* dynamic volume change */
2083 for (i = 0; i < awe_max_voices; i++) {
2084 if (voices[i].key == key)
2085 start_or_volume_change(i, velocity);
2090 /* if the same note still playing, stop it */
2091 for (i = 0; i < awe_max_voices; i++)
2092 if (voices[i].key == key) {
2093 if (voices[i].state == AWE_ST_ON) {
2095 awe_voice_init(i, FALSE);
2096 } else if (voices[i].state == AWE_ST_STANDBY)
2097 awe_voice_init(i, TRUE);
2100 /* allocate voices */
2101 if (playing_mode == AWE_PLAY_DIRECT)
2102 awe_alloc_one_voice(voice, note, velocity);
2104 awe_alloc_multi_voices(voice, note, velocity, key);
2106 /* turn off other voices exlusively (for drums) */
2107 for (i = 0; i < awe_max_voices; i++)
2108 if (voices[i].key == key)
2109 awe_exclusive_off(i);
2111 /* set up pitch and volume parameters */
2112 for (i = 0; i < awe_max_voices; i++) {
2113 if (voices[i].key == key && voices[i].state == AWE_ST_OFF)
2114 set_and_start_voice(i, state);
2121 /* search instrument from preset table with the specified bank */
2123 awe_search_instr(int bank, int preset)
2127 for (i = preset_table[preset]; i >= 0; i = infos[i].next_bank) {
2128 if (infos[i].bank == bank)
2135 /* assign the instrument to a voice */
2137 awe_set_instr_2(int dev, int voice, int instr_no)
2139 if (playing_mode == AWE_PLAY_MULTI2) {
2140 voice = voice_alloc->map[voice] >> 8;
2141 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2142 return RET_ERROR(EINVAL);
2144 return awe_set_instr(dev, voice, instr_no);
2147 /* assign the instrument to a channel; voice is the channel number */
2149 awe_set_instr(int dev, int voice, int instr_no)
2151 awe_chan_info *cinfo;
2154 if (! voice_in_range(voice))
2155 return RET_ERROR(EINVAL);
2157 if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)
2158 return RET_ERROR(EINVAL);
2160 cinfo = &channels[voice];
2162 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice))
2163 def_bank = AWE_DRUM_BANK; /* always search drumset */
2165 def_bank = cinfo->bank;
2168 cinfo->def_vrec = -1;
2169 cinfo->vrec = awe_search_instr(def_bank, instr_no);
2170 if (def_bank == AWE_DRUM_BANK) /* search default drumset */
2171 cinfo->def_vrec = awe_search_instr(def_bank, misc_modes[AWE_MD_DEF_DRUM]);
2172 else /* search default preset */
2173 cinfo->def_vrec = awe_search_instr(misc_modes[AWE_MD_DEF_BANK], instr_no);
2175 if (cinfo->vrec < 0 && cinfo->def_vrec < 0) {
2176 AWE_DEBUG(1,printk("AWE32 Warning: can't find instrument %d\n", instr_no));
2179 cinfo->instr = instr_no;
2185 /* reset all voices; terminate sounds and initialize parameters */
2190 current_alloc_time = 0;
2191 /* don't turn off voice 31 and 32. they are used also for FM voices */
2192 for (i = 0; i < awe_max_voices; i++) {
2194 awe_voice_init(i, TRUE);
2196 for (i = 0; i < AWE_MAX_CHANNELS; i++)
2197 awe_channel_init(i, TRUE);
2198 for (i = 0; i < 16; i++) {
2199 awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127;
2200 awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127;
2207 /* hardware specific control:
2208 * GUS specific and AWE32 specific controls are available.
2211 awe_hw_control(int dev, unsigned char *event)
2214 if (cmd & _AWE_MODE_FLAG)
2215 awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2216 #ifdef AWE_HAS_GUS_COMPATIBILITY
2218 awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2223 #ifdef AWE_HAS_GUS_COMPATIBILITY
2225 /* GUS compatible controls */
2227 awe_hw_gus_control(int dev, int cmd, unsigned char *event)
2234 if (MULTI_LAYER_MODE())
2236 if (cmd == _GUS_NUMVOICES)
2240 if (! voice_in_range(voice))
2243 p1 = *(unsigned short *) &event[4];
2244 p2 = *(short *) &event[6];
2245 plong = *(int*) &event[4];
2248 case _GUS_VOICESAMPLE:
2249 awe_set_instr(dev, voice, p1);
2252 case _GUS_VOICEBALA:
2253 /* 0 to 15 --> -128 to 127 */
2254 awe_panning(dev, voice, ((int)p1 << 4) - 128);
2258 case _GUS_VOICEVOL2:
2259 /* not supported yet */
2262 case _GUS_RAMPRANGE:
2267 /* volume ramping not supported */
2270 case _GUS_VOLUME_SCALE:
2273 case _GUS_VOICE_POS:
2274 FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START,
2275 (short)(plong & 0x7fff));
2276 FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START,
2277 (plong >> 15) & 0xffff);
2281 key = AWE_VOICE_KEY(voice);
2282 for (i = 0; i < awe_max_voices; i++) {
2283 if (voices[i].key == key) {
2291 awe_fx_init(voices[i].ch);
2292 awe_voice_init(i, TRUE);
2295 case _GUS_VOICEFADE:
2297 awe_fx_init(voices[i].ch);
2298 awe_voice_init(i, FALSE);
2301 case _GUS_VOICEFREQ:
2302 awe_calc_pitch_from_freq(i, plong);
2312 /* AWE32 specific controls */
2314 awe_hw_awe_control(int dev, int cmd, unsigned char *event)
2319 awe_chan_info *cinfo;
2324 if (! voice_in_range(voice))
2327 if (playing_mode == AWE_PLAY_MULTI2) {
2328 voice = voice_alloc->map[voice] >> 8;
2329 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2333 p1 = *(unsigned short *) &event[4];
2334 p2 = *(short *) &event[6];
2335 cinfo = &channels[voice];
2338 case _AWE_DEBUG_MODE:
2340 printk("AWE32: debug mode = %d\n", debug_mode);
2342 case _AWE_REVERB_MODE:
2343 awe_set_reverb_mode(p1);
2346 case _AWE_CHORUS_MODE:
2347 awe_set_chorus_mode(p1);
2350 case _AWE_REMOVE_LAST_SAMPLES:
2351 AWE_DEBUG(0,printk("AWE32: remove last samples\n"));
2352 if (locked_sf_id > 0)
2353 awe_remove_samples(locked_sf_id);
2356 case _AWE_INITIALIZE_CHIP:
2360 case _AWE_SEND_EFFECT:
2364 int layer = (p1 >> 8);
2365 if (layer >= 0 && layer < MAX_LAYERS)
2366 fx = &cinfo->fx_layer[layer];
2369 if (p1 & 0x40) i = FX_FLAG_OFF;
2370 if (p1 & 0x80) i = FX_FLAG_ADD;
2372 if (p1 < AWE_FX_END) {
2373 AWE_DEBUG(0,printk("AWE32: effects (%d) %d %d\n", voice, p1, p2));
2374 if (i == FX_FLAG_SET)
2376 else if (i == FX_FLAG_ADD)
2380 if (i != FX_FLAG_OFF && parm_defs[p1].realtime) {
2381 AWE_DEBUG(0,printk("AWE32: fx_realtime (%d)\n", voice));
2382 awe_voice_change(voice, parm_defs[p1].realtime);
2387 case _AWE_RESET_CHANNEL:
2388 awe_channel_init(voice, !p1);
2391 case _AWE_TERMINATE_ALL:
2395 case _AWE_TERMINATE_CHANNEL:
2396 awe_voice_change(voice, awe_terminate_and_init);
2399 case _AWE_RELEASE_ALL:
2400 awe_note_off_all(FALSE);
2402 case _AWE_NOTEOFF_ALL:
2403 awe_note_off_all(TRUE);
2406 case _AWE_INITIAL_VOLUME:
2407 AWE_DEBUG(0,printk("AWE32: init attenuation %d\n", p1));
2408 if (p2 == 0) /* absolute value */
2409 init_atten = (short)p1;
2410 else /* relative value */
2411 init_atten = misc_modes[AWE_MD_ZERO_ATTEN] + (short)p1;
2412 if (init_atten < 0) init_atten = 0;
2413 for (i = 0; i < awe_max_voices; i++)
2414 awe_set_voice_vol(i, TRUE);
2417 case _AWE_CHN_PRESSURE:
2418 cinfo->chan_press = p1;
2419 p1 = p1 * misc_modes[AWE_MD_MOD_SENSE] / 1200;
2420 FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, p1);
2421 awe_voice_change(voice, awe_fx_fmmod);
2422 FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, p1);
2423 awe_voice_change(voice, awe_fx_fm2frq2);
2426 case _AWE_CHANNEL_MODE:
2427 AWE_DEBUG(0,printk("AWE32: channel mode = %d\n", p1));
2432 case _AWE_DRUM_CHANNELS:
2433 AWE_DEBUG(0,printk("AWE32: drum flags = %x\n", p1));
2434 drum_flags = *(unsigned int*)&event[4];
2437 case _AWE_MISC_MODE:
2438 AWE_DEBUG(0,printk("AWE32: misc mode = %d %d\n", p1, p2));
2439 if (p1 > AWE_MD_VERSION && p1 < AWE_MD_END)
2440 misc_modes[p1] = p2;
2443 case _AWE_EQUALIZER:
2444 awe_equalizer((int)p1, (int)p2);
2448 AWE_DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice));
2454 /* voice pressure change */
2456 awe_aftertouch(int dev, int voice, int pressure)
2460 AWE_DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure));
2461 if (! voice_in_range(voice))
2464 switch (playing_mode) {
2465 case AWE_PLAY_DIRECT:
2466 case AWE_PLAY_INDIRECT:
2467 awe_start_note(dev, voice, 255, pressure);
2469 case AWE_PLAY_MULTI2:
2470 note = (voice_alloc->map[voice] & 0xff) - 1;
2471 awe_start_note(dev, voice, note + 0x80, pressure);
2477 /* voice control change */
2479 awe_controller(int dev, int voice, int ctrl_num, int value)
2482 awe_chan_info *cinfo;
2484 if (! voice_in_range(voice))
2487 if (playing_mode == AWE_PLAY_MULTI2) {
2488 voice = voice_alloc->map[voice] >> 8;
2489 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2493 cinfo = &channels[voice];
2496 case CTL_BANK_SELECT: /* MIDI control #0 */
2497 AWE_DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value));
2498 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice) &&
2499 !misc_modes[AWE_MD_TOGGLE_DRUM_BANK])
2501 cinfo->bank = value;
2502 if (cinfo->bank == AWE_DRUM_BANK)
2503 DRUM_CHANNEL_ON(cinfo->channel);
2505 DRUM_CHANNEL_OFF(cinfo->channel);
2506 awe_set_instr(dev, voice, cinfo->instr);
2509 case CTL_MODWHEEL: /* MIDI control #1 */
2510 AWE_DEBUG(2,printk("AWE32: [modwheel(%d) %d]\n", voice, value));
2511 i = value * misc_modes[AWE_MD_MOD_SENSE] / 1200;
2512 FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, i);
2513 awe_voice_change(voice, awe_fx_fmmod);
2514 FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, i);
2515 awe_voice_change(voice, awe_fx_fm2frq2);
2518 case CTRL_PITCH_BENDER: /* SEQ1 V2 contorl */
2519 AWE_DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value));
2521 cinfo->bender = value;
2522 awe_voice_change(voice, awe_set_voice_pitch);
2525 case CTRL_PITCH_BENDER_RANGE: /* SEQ1 V2 control */
2526 AWE_DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value));
2527 /* value = sense x 100 */
2528 cinfo->bender_range = value;
2529 /* no audible pitch change yet.. */
2532 case CTL_EXPRESSION: /* MIDI control #11 */
2533 if (SINGLE_LAYER_MODE())
2535 case CTRL_EXPRESSION: /* SEQ1 V2 control */
2536 AWE_DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value));
2538 cinfo->expression_vol = value;
2539 awe_voice_change(voice, awe_set_voice_vol);
2542 case CTL_PAN: /* MIDI control #10 */
2543 AWE_DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value));
2544 /* (0-127) -> signed 8bit */
2545 cinfo->panning = value * 2 - 128;
2546 if (misc_modes[AWE_MD_REALTIME_PAN])
2547 awe_voice_change(voice, awe_set_pan);
2550 case CTL_MAIN_VOLUME: /* MIDI control #7 */
2551 if (SINGLE_LAYER_MODE())
2552 value = (value * 100) / 16383;
2553 case CTRL_MAIN_VOLUME: /* SEQ1 V2 control */
2554 AWE_DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value));
2556 cinfo->main_vol = value;
2557 awe_voice_change(voice, awe_set_voice_vol);
2560 case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */
2561 AWE_DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value));
2562 FX_SET(&cinfo->fx, AWE_FX_REVERB, value * 2);
2565 case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */
2566 AWE_DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value));
2567 FX_SET(&cinfo->fx, AWE_FX_CHORUS, value * 2);
2570 #ifdef AWE_ACCEPT_ALL_SOUNDS_CONTROLL
2571 case 120: /* all sounds off */
2572 awe_note_off_all(FALSE);
2574 case 123: /* all notes off */
2575 awe_note_off_all(TRUE);
2579 case CTL_SUSTAIN: /* MIDI control #64 */
2580 cinfo->sustained = value;
2582 awe_voice_change(voice, awe_sustain_off);
2585 case CTL_SOSTENUTO: /* MIDI control #66 */
2587 awe_voice_change(voice, awe_sostenuto_on);
2589 awe_voice_change(voice, awe_sustain_off);
2593 AWE_DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n",
2594 voice, ctrl_num, value));
2600 /* voice pan change (value = -128 - 127) */
2602 awe_panning(int dev, int voice, int value)
2604 awe_chan_info *cinfo;
2606 if (! voice_in_range(voice))
2609 if (playing_mode == AWE_PLAY_MULTI2) {
2610 voice = voice_alloc->map[voice] >> 8;
2611 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2615 cinfo = &channels[voice];
2616 cinfo->panning = value;
2617 AWE_DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, cinfo->panning));
2618 if (misc_modes[AWE_MD_REALTIME_PAN])
2619 awe_voice_change(voice, awe_set_pan);
2623 /* volume mode change */
2625 awe_volume_method(int dev, int mode)
2627 /* not impremented */
2628 AWE_DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode));
2632 #ifndef AWE_NO_PATCHMGR
2635 awe_patchmgr(int dev, struct patmgr_info *rec)
2637 printk("AWE32 Warning: patch manager control not supported\n");
2643 /* pitch wheel change: 0-16384 */
2645 awe_bender(int dev, int voice, int value)
2647 awe_chan_info *cinfo;
2649 if (! voice_in_range(voice))
2652 if (playing_mode == AWE_PLAY_MULTI2) {
2653 voice = voice_alloc->map[voice] >> 8;
2654 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2658 /* convert to zero centered value */
2659 cinfo = &channels[voice];
2660 cinfo->bender = value - 8192;
2661 AWE_DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, cinfo->bender));
2662 awe_voice_change(voice, awe_set_voice_pitch);
2666 /*----------------------------------------------------------------
2667 * load a sound patch:
2668 * three types of patches are accepted: AWE, GUS, and SYSEX.
2669 *----------------------------------------------------------------*/
2672 awe_load_patch(int dev, int format, const char *addr,
2673 int offs, int count, int pmgr_flag)
2675 awe_patch_info patch;
2678 #ifdef AWE_HAS_GUS_COMPATIBILITY
2679 if (format == GUS_PATCH) {
2680 return awe_load_guspatch(addr, offs, count, pmgr_flag);
2683 if (format == SYSEX_PATCH) {
2684 /* no system exclusive message supported yet */
2686 } else if (format != AWE_PATCH) {
2687 printk("AWE32 Error: Invalid patch format (key) 0x%x\n", format);
2688 return RET_ERROR(EINVAL);
2691 if (count < AWE_PATCH_INFO_SIZE) {
2692 printk("AWE32 Error: Patch header too short\n");
2693 return RET_ERROR(EINVAL);
2695 COPY_FROM_USER(((char*)&patch) + offs, addr, offs,
2696 AWE_PATCH_INFO_SIZE - offs);
2698 count -= AWE_PATCH_INFO_SIZE;
2699 if (count < patch.len) {
2700 printk("AWE32: sample: Patch record too short (%d<%d)\n",
2702 return RET_ERROR(EINVAL);
2705 switch (patch.type) {
2707 rc = awe_load_info(&patch, addr, count);
2710 rc = awe_load_data(&patch, addr, count);
2712 case AWE_OPEN_PATCH:
2713 rc = awe_open_patch(&patch, addr, count);
2715 case AWE_CLOSE_PATCH:
2716 rc = awe_close_patch(&patch, addr, count);
2718 case AWE_UNLOAD_PATCH:
2719 rc = awe_unload_patch(&patch, addr, count);
2721 case AWE_REPLACE_DATA:
2722 rc = awe_replace_data(&patch, addr, count);
2724 case AWE_MAP_PRESET:
2725 rc = awe_load_map(&patch, addr, count);
2727 case AWE_LOAD_CHORUS_FX:
2728 rc = awe_load_chorus_fx(&patch, addr, count);
2730 case AWE_LOAD_REVERB_FX:
2731 rc = awe_load_reverb_fx(&patch, addr, count);
2735 printk("AWE32 Error: unknown patch format type %d\n",
2737 rc = RET_ERROR(EINVAL);
2744 /* create an sflist record */
2746 awe_create_sf(int type, char *name)
2750 /* terminate sounds */
2752 if (current_sf_id >= max_sfs) {
2753 int newsize = max_sfs + AWE_MAX_SF_LISTS;
2754 sf_list *newlist = my_realloc(sflists, sizeof(sf_list)*max_sfs,
2755 sizeof(sf_list)*newsize);
2756 if (newlist == NULL)
2761 rec = &sflists[current_sf_id];
2762 rec->sf_id = current_sf_id + 1;
2764 if (current_sf_id == 0 || (type & AWE_PAT_LOCKED) != 0)
2765 locked_sf_id = current_sf_id + 1;
2768 MEMCPY(rec->name, name, AWE_PATCH_NAME_LEN);
2770 BZERO(rec->name, AWE_PATCH_NAME_LEN);
2772 rec->num_info = awe_free_info();
2773 rec->num_sample = awe_free_sample();
2774 rec->mem_ptr = awe_free_mem_ptr();
2783 /* open patch; create sf list and set opened flag */
2785 awe_open_patch(awe_patch_info *patch, const char *addr, int count)
2788 COPY_FROM_USER(&parm, addr, AWE_PATCH_INFO_SIZE, sizeof(parm));
2789 if (awe_create_sf(parm.type, parm.name)) {
2790 printk("AWE32: can't open: failed to alloc new list\n");
2791 return RET_ERROR(ENOSPC);
2793 patch_opened = TRUE;
2794 return current_sf_id;
2797 /* check if the patch is already opened */
2799 check_patch_opened(int type, char *name)
2801 if (! patch_opened) {
2802 if (awe_create_sf(type, name)) {
2803 printk("AWE32: failed to alloc new list\n");
2804 return RET_ERROR(ENOSPC);
2806 patch_opened = TRUE;
2807 return current_sf_id;
2809 return current_sf_id;
2812 /* close the patch; if no voice is loaded, remove the patch */
2814 awe_close_patch(awe_patch_info *patch, const char *addr, int count)
2816 if (patch_opened && current_sf_id > 0) {
2817 /* if no voice is loaded, release the current patch */
2818 if (sflists[current_sf_id-1].infos == -1)
2819 awe_remove_samples(current_sf_id - 1);
2826 /* remove the latest patch */
2828 awe_unload_patch(awe_patch_info *patch, const char *addr, int count)
2830 if (current_sf_id > 0)
2831 awe_remove_samples(current_sf_id - 1);
2835 /* allocate voice info list records */
2836 static int alloc_new_info(int nvoices)
2838 int newsize, free_info;
2839 awe_voice_list *newlist;
2840 free_info = awe_free_info();
2841 if (free_info + nvoices >= max_infos) {
2843 newsize = max_infos + AWE_MAX_INFOS;
2844 } while (free_info + nvoices >= newsize);
2845 newlist = my_realloc(infos, sizeof(awe_voice_list)*max_infos,
2846 sizeof(awe_voice_list)*newsize);
2847 if (newlist == NULL) {
2848 printk("AWE32: can't alloc info table\n");
2849 return RET_ERROR(ENOSPC);
2852 max_infos = newsize;
2857 /* allocate sample info list records */
2858 static int alloc_new_sample(void)
2860 int newsize, free_sample;
2861 awe_sample_list *newlist;
2862 free_sample = awe_free_sample();
2863 if (free_sample >= max_samples) {
2864 newsize = max_samples + AWE_MAX_SAMPLES;
2865 newlist = my_realloc(samples,
2866 sizeof(awe_sample_list)*max_samples,
2867 sizeof(awe_sample_list)*newsize);
2868 if (newlist == NULL) {
2869 printk("AWE32: can't alloc sample table\n");
2870 return RET_ERROR(ENOSPC);
2873 max_samples = newsize;
2878 /* load voice map */
2880 awe_load_map(awe_patch_info *patch, const char *addr, int count)
2883 awe_voice_list *rec;
2886 if (check_patch_opened(AWE_PAT_TYPE_MAP, NULL) < 0)
2887 return RET_ERROR(ENOSPC);
2888 if (alloc_new_info(1) < 0)
2889 return RET_ERROR(ENOSPC);
2891 COPY_FROM_USER(&map, addr, AWE_PATCH_INFO_SIZE, sizeof(map));
2893 free_info = awe_free_info();
2894 rec = &infos[free_info];
2895 rec->bank = map.map_bank;
2896 rec->instr = map.map_instr;
2897 rec->type = V_ST_MAPPED;
2898 rec->disabled = FALSE;
2899 awe_init_voice_info(&rec->v);
2900 if (map.map_key >= 0) {
2901 rec->v.low = map.map_key;
2902 rec->v.high = map.map_key;
2904 rec->v.start = map.src_instr;
2905 rec->v.end = map.src_bank;
2906 rec->v.fixkey = map.src_key;
2907 rec->v.sf_id = current_sf_id;
2908 add_info_list(free_info);
2909 add_sf_info(free_info);
2914 /* load voice information data */
2916 awe_load_info(awe_patch_info *patch, const char *addr, int count)
2919 awe_voice_rec_hdr hdr;
2923 if (count < AWE_VOICE_REC_SIZE) {
2924 printk("AWE32 Error: invalid patch info length\n");
2925 return RET_ERROR(EINVAL);
2928 offset = AWE_PATCH_INFO_SIZE;
2929 COPY_FROM_USER((char*)&hdr, addr, offset, AWE_VOICE_REC_SIZE);
2930 offset += AWE_VOICE_REC_SIZE;
2932 if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
2933 printk("AWE32 Error: Illegal voice number %d\n", hdr.nvoices);
2934 return RET_ERROR(EINVAL);
2936 total_size = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE * hdr.nvoices;
2937 if (count < total_size) {
2938 printk("AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n",
2939 count, hdr.nvoices);
2940 return RET_ERROR(EINVAL);
2943 if (check_patch_opened(AWE_PAT_TYPE_MISC, NULL) < 0)
2944 return RET_ERROR(ENOSPC);
2946 #if 0 /* it looks like not so useful.. */
2947 /* check if the same preset already exists in the info list */
2948 for (i = sflists[current_sf_id-1].infos; i >= 0; i = infos[i].next) {
2949 if (infos[i].disabled) continue;
2950 if (infos[i].bank == hdr.bank && infos[i].instr == hdr.instr) {
2951 /* in exclusive mode, do skip loading this */
2952 if (hdr.write_mode == AWE_WR_EXCLUSIVE)
2954 /* in replace mode, disable the old data */
2955 else if (hdr.write_mode == AWE_WR_REPLACE)
2956 infos[i].disabled = TRUE;
2959 if (hdr.write_mode == AWE_WR_REPLACE)
2960 rebuild_preset_list();
2963 if (alloc_new_info(hdr.nvoices) < 0)
2964 return RET_ERROR(ENOSPC);
2966 for (i = 0; i < hdr.nvoices; i++) {
2967 int rec = awe_free_info();
2969 infos[rec].bank = hdr.bank;
2970 infos[rec].instr = hdr.instr;
2971 infos[rec].type = V_ST_NORMAL;
2972 infos[rec].disabled = FALSE;
2974 /* copy awe_voice_info parameters */
2975 COPY_FROM_USER(&infos[rec].v, addr, offset, AWE_VOICE_INFO_SIZE);
2976 offset += AWE_VOICE_INFO_SIZE;
2977 infos[rec].v.sf_id = current_sf_id;
2978 if (infos[rec].v.mode & AWE_MODE_INIT_PARM)
2979 awe_init_voice_parm(&infos[rec].v.parm);
2980 awe_set_sample(&infos[rec].v);
2988 /* load wave sample data */
2990 awe_load_data(awe_patch_info *patch, const char *addr, int count)
2993 int rc, free_sample;
2994 awe_sample_info *rec;
2996 if (check_patch_opened(AWE_PAT_TYPE_MISC, NULL) < 0)
2997 return RET_ERROR(ENOSPC);
2999 if (alloc_new_sample() < 0)
3000 return RET_ERROR(ENOSPC);
3002 free_sample = awe_free_sample();
3003 rec = &samples[free_sample].v;
3005 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3006 offset = AWE_PATCH_INFO_SIZE;
3007 COPY_FROM_USER(rec, addr, offset, AWE_SAMPLE_INFO_SIZE);
3008 offset += AWE_SAMPLE_INFO_SIZE;
3009 if (size != rec->size) {
3010 printk("AWE32: load: sample size differed (%d != %d)\n",
3012 return RET_ERROR(EINVAL);
3015 if ((rc = awe_write_wave_data(addr, offset, rec, -1)) != 0)
3018 rec->sf_id = current_sf_id;
3020 add_sf_sample(free_sample);
3026 /* replace wave sample data */
3028 awe_replace_data(awe_patch_info *patch, const char *addr, int count)
3034 awe_sample_info cursmp;
3037 if (! patch_opened) {
3038 printk("AWE32: replace: patch not opened\n");
3039 return RET_ERROR(EINVAL);
3042 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3043 offset = AWE_PATCH_INFO_SIZE;
3044 COPY_FROM_USER(&cursmp, addr, offset, AWE_SAMPLE_INFO_SIZE);
3045 offset += AWE_SAMPLE_INFO_SIZE;
3046 if (cursmp.size == 0 || size != cursmp.size) {
3047 printk("AWE32: replace: illegal sample size (%d!=%d)\n",
3049 return RET_ERROR(EINVAL);
3051 channels = patch->optarg;
3052 if (channels <= 0 || channels > AWE_NORMAL_VOICES) {
3053 printk("AWE32: replace: illegal channels %d\n", channels);
3054 return RET_ERROR(EINVAL);
3057 for (i = sflists[current_sf_id-1].samples;
3058 i >= 0; i = samples[i].next) {
3059 if (samples[i].v.sample == cursmp.sample)
3063 printk("AWE32: replace: cannot find existing sample data %d\n",
3065 return RET_ERROR(EINVAL);
3068 if (samples[i].v.size != cursmp.size) {
3069 printk("AWE32: replace: exiting size differed (%d!=%d)\n",
3070 samples[i].v.size, cursmp.size);
3071 return RET_ERROR(EINVAL);
3074 save_mem_ptr = awe_free_mem_ptr();
3075 sflists[current_sf_id-1].mem_ptr = samples[i].v.start - awe_mem_start;
3076 MEMCPY(&samples[i].v, &cursmp, sizeof(cursmp));
3077 if ((rc = awe_write_wave_data(addr, offset, &samples[i].v, channels)) != 0)
3079 sflists[current_sf_id-1].mem_ptr = save_mem_ptr;
3080 samples[i].v.sf_id = current_sf_id;
3086 /*----------------------------------------------------------------*/
3088 static const char *readbuf_addr;
3089 static int readbuf_offs;
3090 static int readbuf_flags;
3092 static unsigned short *readbuf_loop;
3093 static int readbuf_loopstart, readbuf_loopend;
3096 /* initialize read buffer */
3098 readbuf_init(const char *addr, int offset, awe_sample_info *sp)
3101 readbuf_loop = NULL;
3102 readbuf_loopstart = sp->loopstart;
3103 readbuf_loopend = sp->loopend;
3104 if (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP)) {
3105 int looplen = sp->loopend - sp->loopstart;
3106 readbuf_loop = my_malloc(looplen * 2);
3107 if (readbuf_loop == NULL) {
3108 printk("AWE32: can't malloc temp buffer\n");
3109 return RET_ERROR(ENOSPC);
3113 readbuf_addr = addr;
3114 readbuf_offs = offset;
3115 readbuf_flags = sp->mode_flags;
3119 /* read directly from user buffer */
3120 static unsigned short
3121 readbuf_word(int pos)
3124 /* read from user buffer */
3125 if (readbuf_flags & AWE_SAMPLE_8BITS) {
3127 GET_BYTE_FROM_USER(cc, readbuf_addr, readbuf_offs + pos);
3128 c = cc << 8; /* convert 8bit -> 16bit */
3130 GET_SHORT_FROM_USER(c, readbuf_addr, readbuf_offs + pos * 2);
3132 if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
3133 c ^= 0x8000; /* unsigned -> signed */
3135 /* write on cache for reverse loop */
3136 if (readbuf_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP)) {
3137 if (pos >= readbuf_loopstart && pos < readbuf_loopend)
3138 readbuf_loop[pos - readbuf_loopstart] = c;
3145 /* read from cache */
3146 static unsigned short
3147 readbuf_word_cache(int pos)
3149 if (pos >= readbuf_loopstart && pos < readbuf_loopend)
3150 return readbuf_loop[pos - readbuf_loopstart];
3158 my_free(readbuf_loop);
3160 readbuf_loop = NULL;
3165 #define readbuf_word_cache readbuf_word
3166 #define readbuf_end() /**/
3170 /*----------------------------------------------------------------*/
3172 #define BLANK_LOOP_START 8
3173 #define BLANK_LOOP_END 40
3174 #define BLANK_LOOP_SIZE 48
3176 /* loading onto memory */
3178 awe_write_wave_data(const char *addr, int offset, awe_sample_info *sp, int channels)
3180 int i, truesize, dram_offset;
3183 /* be sure loop points start < end */
3184 if (sp->loopstart > sp->loopend) {
3185 int tmp = sp->loopstart;
3186 sp->loopstart = sp->loopend;
3190 /* compute true data size to be loaded */
3191 truesize = sp->size;
3192 if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP)
3193 truesize += sp->loopend - sp->loopstart;
3194 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK)
3195 truesize += BLANK_LOOP_SIZE;
3196 if (awe_free_mem_ptr() + truesize >= awe_mem_size/2) {
3197 printk("AWE32 Error: Sample memory full\n");
3198 return RET_ERROR(ENOSPC);
3201 /* recalculate address offset */
3202 sp->end -= sp->start;
3203 sp->loopstart -= sp->start;
3204 sp->loopend -= sp->start;
3206 dram_offset = awe_free_mem_ptr() + awe_mem_start;
3207 sp->start = dram_offset;
3208 sp->end += dram_offset;
3209 sp->loopstart += dram_offset;
3210 sp->loopend += dram_offset;
3212 /* set the total size (store onto obsolete checksum value) */
3216 sp->checksum = truesize;
3218 if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0)
3221 if (readbuf_init(addr, offset, sp) < 0)
3222 return RET_ERROR(ENOSPC);
3224 for (i = 0; i < sp->size; i++) {
3226 c = readbuf_word(i);
3228 if (i == sp->loopend &&
3229 (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))) {
3230 int looplen = sp->loopend - sp->loopstart;
3231 /* copy reverse loop */
3233 for (k = 1; k <= looplen; k++) {
3234 c = readbuf_word_cache(i - k);
3237 if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) {
3240 sp->start += looplen;
3247 /* if no blank loop is attached in the sample, add it */
3248 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) {
3249 for (i = 0; i < BLANK_LOOP_SIZE; i++)
3251 if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) {
3252 sp->loopstart = sp->end + BLANK_LOOP_START;
3253 sp->loopend = sp->end + BLANK_LOOP_END;
3257 sflists[current_sf_id-1].mem_ptr += truesize;
3267 /*----------------------------------------------------------------*/
3269 #ifdef AWE_HAS_GUS_COMPATIBILITY
3271 /* calculate GUS envelope time:
3272 * is this correct? i have no idea..
3275 calc_gus_envelope_time(int rate, int start, int end)
3278 r = (3 - ((rate >> 6) & 3)) * 3;
3286 return (t * 10) / (p * 441);
3289 #define calc_gus_sustain(val) (0x7f - vol_table[(val)/2])
3290 #define calc_gus_attenuation(val) vol_table[(val)/2]
3292 /* load GUS patch */
3294 awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag)
3296 struct patch_info patch;
3297 awe_voice_info *rec;
3298 awe_sample_info *smp;
3300 int note, free_sample, free_info;
3303 sizeof_patch = offsetof(struct patch_info, data); /* header size */
3304 if (size < sizeof_patch) {
3305 printk("AWE32 Error: Patch header too short\n");
3306 return RET_ERROR(EINVAL);
3308 COPY_FROM_USER(((char*)&patch) + offs, addr, offs, sizeof_patch - offs);
3309 size -= sizeof_patch;
3310 if (size < patch.len) {
3311 printk("AWE32 Warning: Patch record too short (%d<%ld)\n",
3313 return RET_ERROR(EINVAL);
3315 if (check_patch_opened(AWE_PAT_TYPE_GUS, NULL) < 0)
3316 return RET_ERROR(ENOSPC);
3317 if (alloc_new_sample() < 0)
3318 return RET_ERROR(ENOSPC);
3319 if (alloc_new_info(1))
3320 return RET_ERROR(ENOSPC);
3322 free_sample = awe_free_sample();
3323 smp = &samples[free_sample].v;
3325 smp->sample = free_sample;
3327 smp->end = patch.len;
3328 smp->loopstart = patch.loop_start;
3329 smp->loopend = patch.loop_end;
3330 smp->size = patch.len;
3332 /* set up mode flags */
3333 smp->mode_flags = 0;
3334 if (!(patch.mode & WAVE_16_BITS))
3335 smp->mode_flags |= AWE_SAMPLE_8BITS;
3336 if (patch.mode & WAVE_UNSIGNED)
3337 smp->mode_flags |= AWE_SAMPLE_UNSIGNED;
3338 smp->mode_flags |= AWE_SAMPLE_NO_BLANK;
3339 if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
3340 smp->mode_flags |= AWE_SAMPLE_SINGLESHOT;
3341 if (patch.mode & WAVE_BIDIR_LOOP)
3342 smp->mode_flags |= AWE_SAMPLE_BIDIR_LOOP;
3343 if (patch.mode & WAVE_LOOP_BACK)
3344 smp->mode_flags |= AWE_SAMPLE_REVERSE_LOOP;
3346 AWE_DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, smp->mode_flags));
3347 if (patch.mode & WAVE_16_BITS) {
3348 /* convert to word offsets */
3351 smp->loopstart /= 2;
3354 smp->checksum_flag = 0;
3357 if ((rc = awe_write_wave_data(addr, sizeof_patch, smp, -1)) != 0)
3360 smp->sf_id = current_sf_id;
3361 add_sf_sample(free_sample);
3363 /* set up voice info */
3364 free_info = awe_free_info();
3365 rec = &infos[free_info].v;
3366 awe_init_voice_info(rec);
3367 rec->sample = free_sample; /* the last sample */
3368 rec->rate_offset = calc_rate_offset(patch.base_freq);
3369 note = freq_to_note(patch.base_note);
3370 rec->root = note / 100;
3371 rec->tune = -(note % 100);
3372 rec->low = freq_to_note(patch.low_note) / 100;
3373 rec->high = freq_to_note(patch.high_note) / 100;
3374 AWE_DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%lu-%lu)]\n",
3375 rec->rate_offset, note,
3376 rec->low, rec->high,
3377 patch.low_note, patch.high_note));
3378 /* panning position; -128 - 127 => 0-127 */
3379 rec->pan = (patch.panning + 128) / 2;
3381 /* detuning is ignored */
3382 /* 6points volume envelope */
3383 if (patch.mode & WAVE_ENVELOPES) {
3384 int attack, hold, decay, release;
3385 attack = calc_gus_envelope_time
3386 (patch.env_rate[0], 0, patch.env_offset[0]);
3387 hold = calc_gus_envelope_time
3388 (patch.env_rate[1], patch.env_offset[0],
3389 patch.env_offset[1]);
3390 decay = calc_gus_envelope_time
3391 (patch.env_rate[2], patch.env_offset[1],
3392 patch.env_offset[2]);
3393 release = calc_gus_envelope_time
3394 (patch.env_rate[3], patch.env_offset[1],
3395 patch.env_offset[4]);
3396 release += calc_gus_envelope_time
3397 (patch.env_rate[4], patch.env_offset[3],
3398 patch.env_offset[4]);
3399 release += calc_gus_envelope_time
3400 (patch.env_rate[5], patch.env_offset[4],
3401 patch.env_offset[5]);
3402 rec->parm.volatkhld = (calc_parm_attack(attack) << 8) |
3403 calc_parm_hold(hold);
3404 rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
3405 calc_parm_decay(decay);
3406 rec->parm.volrelease = 0x8000 | calc_parm_decay(release);
3407 AWE_DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release));
3408 rec->attenuation = calc_gus_attenuation(patch.env_offset[0]);
3411 /* tremolo effect */
3412 if (patch.mode & WAVE_TREMOLO) {
3413 int rate = (patch.tremolo_rate * 1000 / 38) / 42;
3414 rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
3415 AWE_DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n",
3416 patch.tremolo_rate, patch.tremolo_depth,
3417 rec->parm.tremfrq));
3419 /* vibrato effect */
3420 if (patch.mode & WAVE_VIBRATO) {
3421 int rate = (patch.vibrato_rate * 1000 / 38) / 42;
3422 rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
3423 AWE_DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n",
3424 patch.tremolo_rate, patch.tremolo_depth,
3425 rec->parm.tremfrq));
3428 /* scale_freq, scale_factor, volume, and fractions not implemented */
3430 /* append to the tail of the list */
3431 infos[free_info].bank = misc_modes[AWE_MD_GUS_BANK];
3432 infos[free_info].instr = patch.instr_no;
3433 infos[free_info].disabled = FALSE;
3434 infos[free_info].type = V_ST_NORMAL;
3435 infos[free_info].v.sf_id = current_sf_id;
3437 add_info_list(free_info);
3438 add_sf_info(free_info);
3440 /* set the voice index */
3441 awe_set_sample(rec);
3446 #endif /* AWE_HAS_GUS_COMPATIBILITY */
3448 /*----------------------------------------------------------------
3449 * sample and voice list handlers
3450 *----------------------------------------------------------------*/
3452 /* append this to the sf list */
3453 static void add_sf_info(int rec)
3455 int sf_id = infos[rec].v.sf_id;
3456 if (sf_id == 0) return;
3458 if (sflists[sf_id].infos < 0)
3459 sflists[sf_id].infos = rec;
3462 prev = sflists[sf_id].infos;
3463 while ((i = infos[prev].next) >= 0)
3465 infos[prev].next = rec;
3467 infos[rec].next = -1;
3468 sflists[sf_id].num_info++;
3471 /* prepend this sample to sf list */
3472 static void add_sf_sample(int rec)
3474 int sf_id = samples[rec].v.sf_id;
3475 if (sf_id == 0) return;
3477 samples[rec].next = sflists[sf_id].samples;
3478 sflists[sf_id].samples = rec;
3479 sflists[sf_id].num_sample++;
3482 /* purge the old records which don't belong with the same file id */
3483 static void purge_old_list(int rec, int next)
3485 infos[rec].next_instr = next;
3486 if (infos[rec].bank == AWE_DRUM_BANK) {
3487 /* remove samples with the same note range */
3488 int cur, *prevp = &infos[rec].next_instr;
3489 int low = infos[rec].v.low;
3490 int high = infos[rec].v.high;
3491 for (cur = next; cur >= 0; cur = infos[cur].next_instr) {
3492 if (infos[cur].v.low == low &&
3493 infos[cur].v.high == high &&
3494 infos[cur].v.sf_id != infos[rec].v.sf_id)
3495 *prevp = infos[cur].next_instr;
3496 prevp = &infos[cur].next_instr;
3499 if (infos[next].v.sf_id != infos[rec].v.sf_id)
3500 infos[rec].next_instr = -1;
3504 /* prepend to top of the preset table */
3505 static void add_info_list(int rec)
3508 int instr = infos[rec].instr;
3509 int bank = infos[rec].bank;
3511 if (infos[rec].disabled)
3514 prevp = &preset_table[instr];
3517 /* search the first record with the same bank number */
3518 if (infos[cur].bank == bank) {
3519 /* replace the list with the new record */
3520 infos[rec].next_bank = infos[cur].next_bank;
3522 purge_old_list(rec, cur);
3525 prevp = &infos[cur].next_bank;
3526 cur = infos[cur].next_bank;
3529 /* this is the first bank record.. just add this */
3530 infos[rec].next_instr = -1;
3531 infos[rec].next_bank = preset_table[instr];
3532 preset_table[instr] = rec;
3535 /* remove samples later than the specified sf_id */
3537 awe_remove_samples(int sf_id)
3540 awe_reset_samples();
3543 /* already removed? */
3544 if (current_sf_id <= sf_id)
3547 current_sf_id = sf_id;
3548 if (locked_sf_id > sf_id)
3549 locked_sf_id = sf_id;
3551 rebuild_preset_list();
3554 /* rebuild preset search list */
3555 static void rebuild_preset_list(void)
3559 for (i = 0; i < AWE_MAX_PRESETS; i++)
3560 preset_table[i] = -1;
3562 for (i = 0; i < current_sf_id; i++) {
3563 for (j = sflists[i].infos; j >= 0; j = infos[j].next)
3568 /* search the specified sample */
3570 awe_set_sample(awe_voice_info *vp)
3574 for (i = sflists[vp->sf_id-1].samples; i >= 0; i = samples[i].next) {
3575 if (samples[i].v.sample == vp->sample) {
3576 /* set the actual sample offsets */
3577 vp->start += samples[i].v.start;
3578 vp->end += samples[i].v.end;
3579 vp->loopstart += samples[i].v.loopstart;
3580 vp->loopend += samples[i].v.loopend;
3581 /* copy mode flags */
3582 vp->mode = samples[i].v.mode_flags;
3592 /*----------------------------------------------------------------
3594 *----------------------------------------------------------------*/
3596 /* look for all voices associated with the specified note & velocity */
3598 awe_search_multi_voices(int rec, int note, int velocity, awe_voice_info **vlist)
3603 for (; rec >= 0; rec = infos[rec].next_instr) {
3604 if (note >= infos[rec].v.low &&
3605 note <= infos[rec].v.high &&
3606 velocity >= infos[rec].v.vellow &&
3607 velocity <= infos[rec].v.velhigh) {
3608 vlist[nvoices] = &infos[rec].v;
3609 if (infos[rec].type == V_ST_MAPPED) /* mapper */
3612 if (nvoices >= AWE_MAX_VOICES)
3619 /* store the voice list from the specified note and velocity.
3620 if the preset is mapped, seek for the destination preset, and rewrite
3621 the note number if necessary.
3624 really_alloc_voices(int vrec, int def_vrec, int *note, int velocity, awe_voice_info **vlist, int level)
3628 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3630 nvoices = awe_search_multi_voices(def_vrec, *note, velocity, vlist);
3631 if (nvoices < 0) { /* mapping */
3632 int preset = vlist[0]->start;
3633 int bank = vlist[0]->end;
3634 int key = vlist[0]->fixkey;
3636 printk("AWE32: too deep mapping level\n");
3639 vrec = awe_search_instr(bank, preset);
3640 if (bank == AWE_DRUM_BANK)
3641 def_vrec = awe_search_instr(bank, 0);
3643 def_vrec = awe_search_instr(0, preset);
3646 return really_alloc_voices(vrec, def_vrec, note, velocity, vlist, level+1);
3652 /* allocate voices corresponding note and velocity; supports multiple insts. */
3654 awe_alloc_multi_voices(int ch, int note, int velocity, int key)
3657 awe_voice_info *vlist[AWE_MAX_VOICES];
3659 if (channels[ch].vrec < 0 && channels[ch].def_vrec < 0)
3660 awe_set_instr(0, ch, channels[ch].instr);
3662 /* check the possible voices; note may be changeable if mapped */
3663 nvoices = really_alloc_voices(channels[ch].vrec, channels[ch].def_vrec,
3664 ¬e, velocity, vlist, 0);
3666 /* set the voices */
3667 current_alloc_time++;
3668 for (i = 0; i < nvoices; i++) {
3669 v = awe_clear_voice();
3670 voices[v].key = key;
3672 voices[v].note = note;
3673 voices[v].velocity = velocity;
3674 voices[v].time = current_alloc_time;
3675 voices[v].cinfo = &channels[ch];
3676 voices[v].sample = vlist[i];
3677 voices[v].state = AWE_ST_MARK;
3678 voices[v].layer = nvoices - i - 1; /* in reverse order */
3681 /* clear the mark in allocated voices */
3682 for (i = 0; i < awe_max_voices; i++) {
3683 if (voices[i].state == AWE_ST_MARK)
3684 voices[i].state = AWE_ST_OFF;
3690 /* search the best voice from the specified status condition */
3692 search_best_voice(int condition)
3696 time = current_alloc_time + 1;
3697 for (i = 0; i < awe_max_voices; i++) {
3698 if ((voices[i].state & condition) &&
3699 (best < 0 || voices[i].time < time)) {
3701 time = voices[i].time;
3706 if (voices[best].state != AWE_ST_OFF)
3707 awe_terminate(best);
3708 awe_voice_init(best, TRUE);
3714 /* search an empty voice.
3715 if no empty voice is found, at least terminate a voice
3718 awe_clear_voice(void)
3722 /* looking for the oldest empty voice */
3723 if ((best = search_best_voice(AWE_ST_OFF)) >= 0)
3725 if ((best = search_best_voice(AWE_ST_RELEASED)) >= 0)
3727 /* looking for the oldest sustained voice */
3728 if ((best = search_best_voice(AWE_ST_SUSTAINED)) >= 0)
3731 #ifdef AWE_LOOKUP_MIDI_PRIORITY
3732 if (MULTI_LAYER_MODE() && misc_modes[AWE_MD_CHN_PRIOR]) {
3734 int time = current_alloc_time + 1;
3736 /* looking for the voices from high channel (except drum ch) */
3737 for (i = 0; i < awe_max_voices; i++) {
3738 if (IS_DRUM_CHANNEL(voices[i].ch)) continue;
3739 if (voices[i].ch < ch) continue;
3740 if (voices[i].state != AWE_ST_MARK &&
3741 (voices[i].ch > ch || voices[i].time < time)) {
3743 time = voices[i].time;
3750 best = search_best_voice(~AWE_ST_MARK);
3759 /* search sample for the specified note & velocity and set it on the voice;
3760 * note that voice is the voice index (not channel index)
3763 awe_alloc_one_voice(int voice, int note, int velocity)
3766 awe_voice_info *vlist[AWE_MAX_VOICES];
3768 ch = voices[voice].ch;
3769 if (channels[ch].vrec < 0 && channels[ch].def_vrec < 0)
3770 awe_set_instr(0, ch, channels[ch].instr);
3772 nvoices = really_alloc_voices(voices[voice].cinfo->vrec,
3773 voices[voice].cinfo->def_vrec,
3774 ¬e, velocity, vlist, 0);
3776 voices[voice].time = ++current_alloc_time;
3777 voices[voice].sample = vlist[0]; /* use the first one */
3778 voices[voice].layer = 0;
3779 voices[voice].note = note;
3780 voices[voice].velocity = velocity;
3785 /*----------------------------------------------------------------
3786 * sequencer2 functions
3787 *----------------------------------------------------------------*/
3789 /* search an empty voice; used by sequencer2 */
3791 awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
3793 playing_mode = AWE_PLAY_MULTI2;
3794 awe_info.nr_voices = AWE_MAX_CHANNELS;
3795 return awe_clear_voice();
3799 /* set up voice; used by sequencer2 */
3801 awe_setup_voice(int dev, int voice, int chn)
3803 struct channel_info *info;
3804 if (synth_devs[dev] == NULL ||
3805 (info = &synth_devs[dev]->chn_info[chn]) == NULL)
3808 if (voice < 0 || voice >= awe_max_voices)
3811 AWE_DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn));
3812 channels[chn].expression_vol = info->controllers[CTL_EXPRESSION];
3813 channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME];
3814 channels[chn].panning =
3815 info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */
3816 channels[chn].bender = info->bender_value; /* zero center */
3817 channels[chn].bank = info->controllers[CTL_BANK_SELECT];
3818 channels[chn].sustained = info->controllers[CTL_SUSTAIN];
3819 if (info->controllers[CTL_EXT_EFF_DEPTH]) {
3820 FX_SET(&channels[chn].fx, AWE_FX_REVERB,
3821 info->controllers[CTL_EXT_EFF_DEPTH] * 2);
3823 if (info->controllers[CTL_CHORUS_DEPTH]) {
3824 FX_SET(&channels[chn].fx, AWE_FX_CHORUS,
3825 info->controllers[CTL_CHORUS_DEPTH] * 2);
3827 awe_set_instr(dev, chn, info->pgm_num);
3831 #ifdef CONFIG_AWE32_MIXER
3832 /*================================================================
3833 * AWE32 mixer device control
3834 *================================================================*/
3837 awe_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
3841 if (((cmd >> 8) & 0xff) != 'M')
3842 return RET_ERROR(EINVAL);
3844 level = (int)IOCTL_IN(arg);
3845 level = ((level & 0xff) + (level >> 8)) / 2;
3846 AWE_DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
3848 if (IO_WRITE_CHECK(cmd)) {
3849 switch (cmd & 0xff) {
3850 case SOUND_MIXER_BASS:
3851 awe_bass_level = level * 12 / 100;
3852 if (awe_bass_level >= 12)
3853 awe_bass_level = 11;
3854 awe_equalizer(awe_bass_level, awe_treble_level);
3856 case SOUND_MIXER_TREBLE:
3857 awe_treble_level = level * 12 / 100;
3858 if (awe_treble_level >= 12)
3859 awe_treble_level = 11;
3860 awe_equalizer(awe_bass_level, awe_treble_level);
3862 case SOUND_MIXER_VOLUME:
3863 level = level * 127 / 100;
3864 if (level >= 128) level = 127;
3865 init_atten = vol_table[level];
3866 for (i = 0; i < awe_max_voices; i++)
3867 awe_set_voice_vol(i, TRUE);
3871 switch (cmd & 0xff) {
3872 case SOUND_MIXER_BASS:
3873 level = awe_bass_level * 100 / 24;
3874 level = (level << 8) | level;
3876 case SOUND_MIXER_TREBLE:
3877 level = awe_treble_level * 100 / 24;
3878 level = (level << 8) | level;
3880 case SOUND_MIXER_VOLUME:
3881 for (i = 127; i > 0; i--) {
3882 if (init_atten <= vol_table[i])
3885 level = i * 100 / 127;
3886 level = (level << 8) | level;
3888 case SOUND_MIXER_DEVMASK:
3889 level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME;
3895 return IOCTL_OUT(arg, level);
3897 #endif /* CONFIG_AWE32_MIXER */
3900 /*================================================================
3901 * initialization of AWE32
3902 *================================================================*/
3904 /* intiailize audio channels */
3906 awe_init_audio(void)
3910 /* turn off envelope engines */
3911 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
3912 awe_poke(AWE_DCYSUSV(ch), 0x80);
3915 /* reset all other parameters to zero */
3916 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
3917 awe_poke(AWE_ENVVOL(ch), 0);
3918 awe_poke(AWE_ENVVAL(ch), 0);
3919 awe_poke(AWE_DCYSUS(ch), 0);
3920 awe_poke(AWE_ATKHLDV(ch), 0);
3921 awe_poke(AWE_LFO1VAL(ch), 0);
3922 awe_poke(AWE_ATKHLD(ch), 0);
3923 awe_poke(AWE_LFO2VAL(ch), 0);
3924 awe_poke(AWE_IP(ch), 0);
3925 awe_poke(AWE_IFATN(ch), 0);
3926 awe_poke(AWE_PEFE(ch), 0);
3927 awe_poke(AWE_FMMOD(ch), 0);
3928 awe_poke(AWE_TREMFRQ(ch), 0);
3929 awe_poke(AWE_FM2FRQ2(ch), 0);
3930 awe_poke_dw(AWE_PTRX(ch), 0);
3931 awe_poke_dw(AWE_VTFT(ch), 0);
3932 awe_poke_dw(AWE_PSST(ch), 0);
3933 awe_poke_dw(AWE_CSL(ch), 0);
3934 awe_poke_dw(AWE_CCCA(ch), 0);
3937 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
3938 awe_poke_dw(AWE_CPF(ch), 0);
3939 awe_poke_dw(AWE_CVCF(ch), 0);
3944 /* initialize DMA address */
3948 awe_poke_dw(AWE_SMALR, 0);
3949 awe_poke_dw(AWE_SMARR, 0);
3950 awe_poke_dw(AWE_SMALW, 0);
3951 awe_poke_dw(AWE_SMARW, 0);
3955 /* initialization arrays; from ADIP */
3957 static unsigned short init1[128] = {
3958 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330,
3959 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730,
3960 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30,
3961 0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30,
3963 0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330,
3964 0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730,
3965 0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30,
3966 0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30,
3968 0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330,
3969 0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730,
3970 0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30,
3971 0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30,
3973 0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330,
3974 0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730,
3975 0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30,
3976 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30,
3979 static unsigned short init2[128] = {
3980 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
3981 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
3982 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
3983 0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
3985 0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
3986 0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
3987 0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
3988 0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
3990 0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
3991 0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
3992 0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
3993 0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
3995 0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
3996 0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
3997 0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
3998 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
4001 static unsigned short init3[128] = {
4002 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4003 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
4004 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
4005 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
4007 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
4008 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
4009 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
4010 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
4012 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
4013 0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
4014 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
4015 0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
4017 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
4018 0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
4019 0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
4020 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
4023 static unsigned short init4[128] = {
4024 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4025 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
4026 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
4027 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
4029 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
4030 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
4031 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
4032 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
4034 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
4035 0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
4036 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
4037 0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
4039 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
4040 0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
4041 0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
4042 0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
4046 /* send initialization arrays to start up */
4048 awe_init_array(void)
4050 awe_send_array(init1);
4052 awe_send_array(init2);
4053 awe_send_array(init3);
4054 awe_poke_dw(AWE_HWCF4, 0);
4055 awe_poke_dw(AWE_HWCF5, 0x83);
4056 awe_poke_dw(AWE_HWCF6, 0x8000);
4057 awe_send_array(init4);
4060 /* send an initialization array */
4062 awe_send_array(unsigned short *data)
4068 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4069 awe_poke(AWE_INIT1(i), *p);
4070 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4071 awe_poke(AWE_INIT2(i), *p);
4072 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4073 awe_poke(AWE_INIT3(i), *p);
4074 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4075 awe_poke(AWE_INIT4(i), *p);
4080 * set up awe32 channels to some known state.
4083 /* set the envelope & LFO parameters to the default values; see ADIP */
4085 awe_tweak_voice(int i)
4087 /* set all mod/vol envelope shape to minimum */
4088 awe_poke(AWE_ENVVOL(i), 0x8000);
4089 awe_poke(AWE_ENVVAL(i), 0x8000);
4090 awe_poke(AWE_DCYSUS(i), 0x7F7F);
4091 awe_poke(AWE_ATKHLDV(i), 0x7F7F);
4092 awe_poke(AWE_ATKHLD(i), 0x7F7F);
4093 awe_poke(AWE_PEFE(i), 0); /* mod envelope height to zero */
4094 awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */
4095 awe_poke(AWE_LFO2VAL(i), 0x8000);
4096 awe_poke(AWE_IP(i), 0xE000); /* no pitch shift */
4097 awe_poke(AWE_IFATN(i), 0xFF00); /* volume to minimum */
4098 awe_poke(AWE_FMMOD(i), 0);
4099 awe_poke(AWE_TREMFRQ(i), 0);
4100 awe_poke(AWE_FM2FRQ2(i), 0);
4107 /* reset all channels */
4108 for (i = 0; i < awe_max_voices; i++)
4114 * initializes the FM section of AWE32;
4115 * see Vince Vu's unofficial AWE32 programming guide
4121 #ifndef AWE_ALWAYS_INIT_FM
4122 /* if no extended memory is on board.. */
4123 if (awe_mem_size <= 0)
4126 AWE_DEBUG(3,printk("AWE32: initializing FM\n"));
4128 /* Initialize the last two channels for DRAM refresh and producing
4129 the reverb and chorus effects for Yamaha OPL-3 synthesizer */
4131 /* 31: FM left channel, 0xffffe0-0xffffe8 */
4132 awe_poke(AWE_DCYSUSV(30), 0x80);
4133 awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */
4134 awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 |
4135 (DEF_FM_CHORUS_DEPTH << 24));
4136 awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8));
4137 awe_poke_dw(AWE_CPF(30), 0);
4138 awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3);
4140 /* 32: FM right channel, 0xfffff0-0xfffff8 */
4141 awe_poke(AWE_DCYSUSV(31), 0x80);
4142 awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */
4143 awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 |
4144 (DEF_FM_CHORUS_DEPTH << 24));
4145 awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8));
4146 awe_poke_dw(AWE_CPF(31), 0x8000);
4147 awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3);
4149 /* skew volume & cutoff */
4150 awe_poke_dw(AWE_VTFT(30), 0x8000FFFF);
4151 awe_poke_dw(AWE_VTFT(31), 0x8000FFFF);
4153 voices[30].state = AWE_ST_FM;
4154 voices[31].state = AWE_ST_FM;
4156 /* change maximum channels to 30 */
4157 awe_max_voices = AWE_NORMAL_VOICES;
4158 if (playing_mode == AWE_PLAY_DIRECT)
4159 awe_info.nr_voices = awe_max_voices;
4161 awe_info.nr_voices = AWE_MAX_CHANNELS;
4162 voice_alloc->max_voice = awe_max_voices;
4166 * AWE32 DRAM access routines
4169 /* open DRAM write accessing mode */
4171 awe_open_dram_for_write(int offset, int channels)
4173 int vidx[AWE_NORMAL_VOICES];
4176 if (channels < 0 || channels >= AWE_NORMAL_VOICES) {
4177 channels = AWE_NORMAL_VOICES;
4178 for (i = 0; i < AWE_NORMAL_VOICES; i++)
4181 for (i = 0; i < channels; i++)
4182 vidx[i] = awe_clear_voice();
4185 /* use all channels for DMA transfer */
4186 for (i = 0; i < channels; i++) {
4187 if (vidx[i] < 0) continue;
4188 awe_poke(AWE_DCYSUSV(vidx[i]), 0x80);
4189 awe_poke_dw(AWE_VTFT(vidx[i]), 0);
4190 awe_poke_dw(AWE_CVCF(vidx[i]), 0);
4191 awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000);
4192 awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000);
4193 awe_poke_dw(AWE_PSST(vidx[i]), 0);
4194 awe_poke_dw(AWE_CSL(vidx[i]), 0);
4195 awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000);
4196 voices[vidx[i]].state = AWE_ST_DRAM;
4198 /* point channels 31 & 32 to ROM samples for DRAM refresh */
4199 awe_poke_dw(AWE_VTFT(30), 0);
4200 awe_poke_dw(AWE_PSST(30), 0x1d8);
4201 awe_poke_dw(AWE_CSL(30), 0x1e0);
4202 awe_poke_dw(AWE_CCCA(30), 0x1d8);
4203 awe_poke_dw(AWE_VTFT(31), 0);
4204 awe_poke_dw(AWE_PSST(31), 0x1d8);
4205 awe_poke_dw(AWE_CSL(31), 0x1e0);
4206 awe_poke_dw(AWE_CCCA(31), 0x1d8);
4207 voices[30].state = AWE_ST_FM;
4208 voices[31].state = AWE_ST_FM;
4210 /* if full bit is on, not ready to write on */
4211 if (awe_peek_dw(AWE_SMALW) & 0x80000000) {
4212 for (i = 0; i < channels; i++) {
4213 awe_poke_dw(AWE_CCCA(vidx[i]), 0);
4214 voices[i].state = AWE_ST_OFF;
4216 return RET_ERROR(ENOSPC);
4219 /* set address to write */
4220 awe_poke_dw(AWE_SMALW, offset);
4225 /* open DRAM for RAM size detection */
4227 awe_open_dram_for_check(void)
4230 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4231 awe_poke(AWE_DCYSUSV(i), 0x80);
4232 awe_poke_dw(AWE_VTFT(i), 0);
4233 awe_poke_dw(AWE_CVCF(i), 0);
4234 awe_poke_dw(AWE_PTRX(i), 0x40000000);
4235 awe_poke_dw(AWE_CPF(i), 0x40000000);
4236 awe_poke_dw(AWE_PSST(i), 0);
4237 awe_poke_dw(AWE_CSL(i), 0);
4238 if (i & 1) /* DMA write */
4239 awe_poke_dw(AWE_CCCA(i), 0x06000000);
4241 awe_poke_dw(AWE_CCCA(i), 0x04000000);
4242 voices[i].state = AWE_ST_DRAM;
4247 /* close dram access */
4249 awe_close_dram(void)
4252 /* wait until FULL bit in SMAxW register be false */
4253 for (i = 0; i < 10000; i++) {
4254 if (!(awe_peek_dw(AWE_SMALW) & 0x80000000))
4259 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4260 if (voices[i].state == AWE_ST_DRAM) {
4261 awe_poke_dw(AWE_CCCA(i), 0);
4262 awe_poke(AWE_DCYSUSV(i), 0x807F);
4263 voices[i].state = AWE_ST_OFF;
4269 /*================================================================
4270 * detect presence of AWE32 and check memory size
4271 *================================================================*/
4273 /* detect emu8000 chip on the specified address; from VV's guide */
4276 awe_detect_base(int addr)
4279 if ((awe_peek(AWE_U1) & 0x000F) != 0x000C)
4281 if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058)
4283 if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003)
4285 AWE_DEBUG(0,printk("AWE32 found at %x\n", awe_base));
4293 if (awe_base == 0) {
4294 for (base = 0x620; base <= 0x680; base += 0x20)
4295 if (awe_detect_base(base))
4297 AWE_DEBUG(0,printk("AWE32 not found\n"));
4304 /*================================================================
4305 * check dram size on AWE board
4306 *================================================================*/
4308 /* any three numbers you like */
4309 #define UNIQUE_ID1 0x1234
4310 #define UNIQUE_ID2 0x4321
4311 #define UNIQUE_ID3 0xFFFF
4314 awe_check_dram(void)
4316 if (awe_mem_size > 0) {
4317 awe_mem_size *= 1024; /* convert to Kbytes */
4318 return awe_mem_size;
4321 awe_open_dram_for_check();
4325 /* set up unique two id numbers */
4326 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET);
4327 awe_poke(AWE_SMLD, UNIQUE_ID1);
4328 awe_poke(AWE_SMLD, UNIQUE_ID2);
4330 while (awe_mem_size < AWE_MAX_DRAM_SIZE) {
4332 /* read a data on the DRAM start address */
4333 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET);
4334 awe_peek(AWE_SMLD); /* discard stale data */
4335 if (awe_peek(AWE_SMLD) != UNIQUE_ID1)
4337 if (awe_peek(AWE_SMLD) != UNIQUE_ID2)
4339 awe_mem_size += 32; /* increment 32 Kbytes */
4340 /* Write a unique data on the test address;
4341 * if the address is out of range, the data is written on
4342 * 0x200000(=AWE_DRAM_OFFSET). Then the two id words are
4343 * broken by this data.
4345 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + awe_mem_size*512L);
4346 awe_poke(AWE_SMLD, UNIQUE_ID3);
4348 /* read a data on the just written DRAM address */
4349 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + awe_mem_size*512L);
4350 awe_peek(AWE_SMLD); /* discard stale data */
4351 if (awe_peek(AWE_SMLD) != UNIQUE_ID3)
4356 AWE_DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", awe_mem_size));
4358 /* convert to Kbytes */
4359 awe_mem_size *= 1024;
4360 return awe_mem_size;
4364 /*================================================================
4365 * chorus and reverb controls; from VV's guide
4366 *================================================================*/
4368 /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
4369 static char chorus_defined[AWE_CHORUS_NUMBERS];
4370 static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = {
4371 {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
4372 {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
4373 {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
4374 {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
4375 {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
4376 {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
4377 {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */
4378 {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */
4382 awe_load_chorus_fx(awe_patch_info *patch, const char *addr, int count)
4384 if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) {
4385 printk("AWE32 Error: illegal chorus mode %d for uploading\n", patch->optarg);
4386 return RET_ERROR(EINVAL);
4388 if (count < sizeof(awe_chorus_fx_rec)) {
4389 printk("AWE32 Error: too short chorus fx parameters\n");
4390 return RET_ERROR(EINVAL);
4392 COPY_FROM_USER(&chorus_parm[patch->optarg], addr, AWE_PATCH_INFO_SIZE,
4393 sizeof(awe_chorus_fx_rec));
4394 chorus_defined[patch->optarg] = TRUE;
4399 awe_set_chorus_mode(int effect)
4401 if (effect < 0 || effect >= AWE_CHORUS_NUMBERS ||
4402 (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect]))
4404 awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback);
4405 awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset);
4406 awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth);
4407 awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay);
4408 awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq);
4409 awe_poke_dw(AWE_HWCF6, 0x8000);
4410 awe_poke_dw(AWE_HWCF7, 0x0000);
4411 chorus_mode = effect;
4414 /*----------------------------------------------------------------*/
4416 /* reverb mode settings; write the following 28 data of 16 bit length
4417 * on the corresponding ports in the reverb_cmds array
4419 static char reverb_defined[AWE_CHORUS_NUMBERS];
4420 static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = {
4422 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
4423 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
4424 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4425 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4428 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4429 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4430 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4431 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4434 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4435 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
4436 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
4437 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
4440 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4441 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4442 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
4443 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
4446 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
4447 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
4448 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4449 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4452 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
4453 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
4454 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4455 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4458 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
4459 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4460 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4461 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4463 {{ /* panning delay */
4464 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
4465 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4466 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4467 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4471 static struct ReverbCmdPair {
4472 unsigned short cmd, port;
4473 } reverb_cmds[28] = {
4474 {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
4475 {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
4476 {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
4477 {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
4478 {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
4479 {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
4480 {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
4484 awe_load_reverb_fx(awe_patch_info *patch, const char *addr, int count)
4486 if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) {
4487 printk("AWE32 Error: illegal reverb mode %d for uploading\n", patch->optarg);
4488 return RET_ERROR(EINVAL);
4490 if (count < sizeof(awe_reverb_fx_rec)) {
4491 printk("AWE32 Error: too short reverb fx parameters\n");
4492 return RET_ERROR(EINVAL);
4494 COPY_FROM_USER(&reverb_parm[patch->optarg], addr, AWE_PATCH_INFO_SIZE,
4495 sizeof(awe_reverb_fx_rec));
4496 reverb_defined[patch->optarg] = TRUE;
4501 awe_set_reverb_mode(int effect)
4504 if (effect < 0 || effect >= AWE_REVERB_NUMBERS ||
4505 (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect]))
4507 for (i = 0; i < 28; i++)
4508 awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port,
4509 reverb_parm[effect].parms[i]);
4510 reverb_mode = effect;
4513 /*================================================================
4514 * treble/bass equalizer control
4515 *================================================================*/
4517 static unsigned short bass_parm[12][3] = {
4518 {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
4519 {0xD25B, 0xD35B, 0x0000}, /* -8 */
4520 {0xD24C, 0xD34C, 0x0000}, /* -6 */
4521 {0xD23D, 0xD33D, 0x0000}, /* -4 */
4522 {0xD21F, 0xD31F, 0x0000}, /* -2 */
4523 {0xC208, 0xC308, 0x0001}, /* 0 (HW default) */
4524 {0xC219, 0xC319, 0x0001}, /* +2 */
4525 {0xC22A, 0xC32A, 0x0001}, /* +4 */
4526 {0xC24C, 0xC34C, 0x0001}, /* +6 */
4527 {0xC26E, 0xC36E, 0x0001}, /* +8 */
4528 {0xC248, 0xC348, 0x0002}, /* +10 */
4529 {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
4532 static unsigned short treble_parm[12][9] = {
4533 {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
4534 {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4535 {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4536 {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4537 {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4538 {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
4539 {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
4540 {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
4541 {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
4542 {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
4543 {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
4544 {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */
4549 * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
4552 awe_equalizer(int bass, int treble)
4556 if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
4558 awe_bass_level = bass;
4559 awe_treble_level = treble;
4560 awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]);
4561 awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]);
4562 awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]);
4563 awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]);
4564 awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]);
4565 awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]);
4566 awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]);
4567 awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]);
4568 awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]);
4569 awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]);
4570 w = bass_parm[bass][2] + treble_parm[treble][8];
4571 awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262));
4572 awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362));
4576 #endif /* CONFIG_AWE32_SYNTH */