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.
27 # include <gnu/i386/isa/sound/awe_config.h>
29 # include "awe_config.h"
32 /*----------------------------------------------------------------*/
34 #ifdef CONFIG_AWE32_SYNTH
37 # include <gnu/i386/isa/sound/awe_hw.h>
38 # include <gnu/i386/isa/sound/awe_version.h>
39 # include <gnu/i386/isa/sound/awe_voice.h>
42 # include "awe_version.h"
43 # include <linux/awe_voice.h>
46 #ifdef AWE_HAS_GUS_COMPATIBILITY
47 /* include finetune table */
50 # ifdef AWE_OBSOLETE_VOXWARE
53 # include <i386/isa/sound/tuning.h>
55 # ifdef AWE_OBSOLETE_VOXWARE
58 # include "../tuning.h"
63 # include <linux/ultrasound.h>
64 #elif defined(__FreeBSD__)
65 # include <machine/ultrasound.h>
68 #endif /* AWE_HAS_GUS_COMPATIBILITY */
71 /*----------------------------------------------------------------
73 *----------------------------------------------------------------*/
75 static int debug_mode = 0;
77 #define AWE_DEBUG(LVL,XXX) {if (debug_mode > LVL) { XXX; }}
78 #define ERRMSG(XXX) {if (debug_mode) { XXX; }}
79 #define FATALERR(XXX) XXX
81 #define AWE_DEBUG(LVL,XXX) /**/
82 #define ERRMSG(XXX) XXX
83 #define FATALERR(XXX) XXX
86 /*----------------------------------------------------------------
87 * bank and voice record
88 *----------------------------------------------------------------*/
90 /* soundfont record */
91 typedef struct _sf_list {
94 int num_info; /* current info table index */
95 int num_sample; /* current sample table index */
96 int mem_ptr; /* current word byte pointer */
99 /*char name[AWE_PATCH_NAME_LEN];*/
103 typedef struct _awe_voice_list {
104 int next; /* linked list with same sf_id */
105 unsigned char bank, instr; /* preset number information */
106 char type, disabled; /* type=normal/mapped, disabled=boolean */
107 awe_voice_info v; /* voice information */
108 int next_instr; /* preset table list */
109 int next_bank; /* preset table list */
112 /* voice list type */
113 #define V_ST_NORMAL 0
114 #define V_ST_MAPPED 1
116 typedef struct _awe_sample_list {
117 int next; /* linked list with same sf_id */
118 awe_sample_info v; /* sample information */
121 /* sample and information table */
122 static int current_sf_id = 0;
123 static int locked_sf_id = 0;
125 static sf_list *sflists = NULL;
127 #define awe_free_mem_ptr() (current_sf_id <= 0 ? 0 : sflists[current_sf_id-1].mem_ptr)
128 #define awe_free_info() (current_sf_id <= 0 ? 0 : sflists[current_sf_id-1].num_info)
129 #define awe_free_sample() (current_sf_id <= 0 ? 0 : sflists[current_sf_id-1].num_sample)
131 static int max_samples;
132 static awe_sample_list *samples = NULL;
134 static int max_infos;
135 static awe_voice_list *infos = NULL;
138 #define AWE_MAX_PRESETS 256
139 #define AWE_DEFAULT_PRESET 0
140 #define AWE_DEFAULT_BANK 0
141 #define AWE_DEFAULT_DRUM 0
142 #define AWE_DRUM_BANK 128
144 #define MAX_LAYERS AWE_MAX_VOICES
146 /* preset table index */
147 static int preset_table[AWE_MAX_PRESETS];
149 /*----------------------------------------------------------------
151 *----------------------------------------------------------------*/
154 typedef struct FX_Rec { /* channel effects */
155 unsigned char flags[AWE_FX_END];
156 short val[AWE_FX_END];
160 /* channel parameters */
161 typedef struct _awe_chan_info {
162 int channel; /* channel number */
163 int bank; /* current tone bank */
164 int instr; /* current program */
165 int bender; /* midi pitchbend (-8192 - 8192) */
166 int bender_range; /* midi bender range (x100) */
167 int panning; /* panning (0-127) */
168 int main_vol; /* channel volume (0-127) */
169 int expression_vol; /* midi expression (0-127) */
170 int chan_press; /* channel pressure */
171 int vrec; /* instrument list */
172 int def_vrec; /* default instrument list */
173 int sustained; /* sustain status in MIDI */
174 FX_Rec fx; /* effects */
175 FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */
178 /* voice parameters */
179 typedef struct _voice_info {
181 #define AWE_ST_OFF (1<<0) /* no sound */
182 #define AWE_ST_ON (1<<1) /* playing */
183 #define AWE_ST_STANDBY (1<<2) /* stand by for playing */
184 #define AWE_ST_SUSTAINED (1<<3) /* sustained */
185 #define AWE_ST_MARK (1<<4) /* marked for allocation */
186 #define AWE_ST_DRAM (1<<5) /* DRAM read/write */
187 #define AWE_ST_FM (1<<6) /* reserved for FM */
188 #define AWE_ST_RELEASED (1<<7) /* released */
190 int ch; /* midi channel */
191 int key; /* internal key for search */
192 int layer; /* layer number (for channel mode only) */
193 int time; /* allocated time */
194 awe_chan_info *cinfo; /* channel info */
196 int note; /* midi key (0-127) */
197 int velocity; /* midi velocity (0-127) */
198 int sostenuto; /* sostenuto on/off */
199 awe_voice_info *sample; /* assigned voice */
201 /* EMU8000 parameters */
202 int apitch; /* pitch parameter */
203 int avol; /* volume parameter */
204 int apan; /* panning parameter */
207 /* voice information */
208 static voice_info *voices;
210 #define IS_NO_SOUND(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED))
211 #define IS_NO_EFFECT(v) (voices[v].state != AWE_ST_ON)
212 #define IS_PLAYING(v) (voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED))
213 #define IS_EMPTY(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM))
216 /* MIDI channel effects information (for hw control) */
217 static awe_chan_info *channels;
220 /*----------------------------------------------------------------
222 *----------------------------------------------------------------*/
224 #ifndef AWE_DEFAULT_BASE_ADDR
225 #define AWE_DEFAULT_BASE_ADDR 0 /* autodetect */
228 #ifndef AWE_DEFAULT_MEM_SIZE
229 #define AWE_DEFAULT_MEM_SIZE 0 /* autodetect */
232 /* awe32 base address (overwritten at initialization) */
233 static int awe_base = AWE_DEFAULT_BASE_ADDR;
234 /* memory byte size */
235 static int awe_mem_size = AWE_DEFAULT_MEM_SIZE;
236 /* DRAM start offset */
237 static int awe_mem_start = AWE_DRAM_OFFSET;
239 /* maximum channels for playing */
240 static int awe_max_voices = AWE_MAX_VOICES;
242 static int patch_opened = 0; /* sample already loaded? */
244 static int reverb_mode = 4; /* reverb mode */
245 static int chorus_mode = 2; /* chorus mode */
246 static short init_atten = AWE_DEFAULT_ATTENUATION; /* 12dB below */
248 static int awe_present = FALSE; /* awe device present? */
249 static int awe_busy = FALSE; /* awe device opened? */
251 #define DEFAULT_DRUM_FLAGS ((1 << 9) | (1 << 25))
252 #define IS_DRUM_CHANNEL(c) (drum_flags & (1 << (c)))
253 #define DRUM_CHANNEL_ON(c) (drum_flags |= (1 << (c)))
254 #define DRUM_CHANNEL_OFF(c) (drum_flags &= ~(1 << (c)))
255 static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */
257 static int playing_mode = AWE_PLAY_INDIRECT;
258 #define SINGLE_LAYER_MODE() (playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT)
259 #define MULTI_LAYER_MODE() (playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2)
261 static int current_alloc_time = 0; /* voice allocation index for channel mode */
263 static struct MiscModeDef {
266 } misc_modes_default[AWE_MD_END] = {
267 {0,0}, {0,0}, /* <-- not used */
268 {AWE_VERSION_NUMBER, FALSE},
269 {TRUE, TRUE}, /* exclusive */
270 {TRUE, TRUE}, /* realpan */
271 {AWE_DEFAULT_BANK, TRUE}, /* gusbank */
272 {FALSE, TRUE}, /* keep effect */
273 {AWE_DEFAULT_ATTENUATION, FALSE}, /* zero_atten */
274 {FALSE, TRUE}, /* chn_prior */
275 {AWE_DEFAULT_MOD_SENSE, TRUE}, /* modwheel sense */
276 {AWE_DEFAULT_PRESET, TRUE}, /* def_preset */
277 {AWE_DEFAULT_BANK, TRUE}, /* def_bank */
278 {AWE_DEFAULT_DRUM, TRUE}, /* def_drum */
279 {FALSE, TRUE}, /* toggle_drum_bank */
282 static int misc_modes[AWE_MD_END];
284 static int awe_bass_level = 5;
285 static int awe_treble_level = 9;
288 static struct synth_info awe_info = {
289 "AWE32 Synth", /* name */
291 SYNTH_TYPE_SAMPLE, /* synth_type */
292 SAMPLE_TYPE_AWE32, /* synth_subtype */
293 0, /* perc_mode (obsolete) */
294 AWE_MAX_VOICES, /* nr_voices */
295 0, /* nr_drums (obsolete) */
296 AWE_MAX_INFOS /* instr_bank_size */
300 static struct voice_alloc_info *voice_alloc; /* set at initialization */
303 /*----------------------------------------------------------------
304 * function prototypes
305 *----------------------------------------------------------------*/
307 #if defined(linux) && !defined(AWE_OBSOLETE_VOXWARE)
308 static int awe_check_port(void);
309 static void awe_request_region(void);
310 static void awe_release_region(void);
313 static void awe_reset_samples(void);
314 /* emu8000 chip i/o access */
315 static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);
316 static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);
317 static unsigned short awe_peek(unsigned short cmd, unsigned short port);
318 static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);
319 static void awe_wait(unsigned short delay);
321 /* initialize emu8000 chip */
322 static void awe_initialize(void);
324 /* set voice parameters */
325 static void awe_init_misc_modes(int init_all);
326 static void awe_init_voice_info(awe_voice_info *vp);
327 static void awe_init_voice_parm(awe_voice_parm *pp);
328 #ifdef AWE_HAS_GUS_COMPATIBILITY
329 static int freq_to_note(int freq);
330 static int calc_rate_offset(int Hz);
331 /*static int calc_parm_delay(int msec);*/
332 static int calc_parm_hold(int msec);
333 static int calc_parm_attack(int msec);
334 static int calc_parm_decay(int msec);
335 static int calc_parm_search(int msec, short *table);
338 /* turn on/off note */
339 static void awe_note_on(int voice);
340 static void awe_note_off(int voice);
341 static void awe_terminate(int voice);
342 static void awe_exclusive_off(int voice);
343 static void awe_note_off_all(int do_sustain);
345 /* calculate voice parameters */
346 typedef void (*fx_affect_func)(int voice, int forced);
347 static void awe_set_pitch(int voice, int forced);
348 static void awe_set_voice_pitch(int voice, int forced);
349 static void awe_set_volume(int voice, int forced);
350 static void awe_set_voice_vol(int voice, int forced);
351 static void awe_set_pan(int voice, int forced);
352 static void awe_fx_fmmod(int voice, int forced);
353 static void awe_fx_tremfrq(int voice, int forced);
354 static void awe_fx_fm2frq2(int voice, int forced);
355 static void awe_fx_filterQ(int voice, int forced);
356 static void awe_calc_pitch(int voice);
357 #ifdef AWE_HAS_GUS_COMPATIBILITY
358 static void awe_calc_pitch_from_freq(int voice, int freq);
360 static void awe_calc_volume(int voice);
361 static void awe_voice_init(int voice, int init_all);
362 static void awe_channel_init(int ch, int init_all);
363 static void awe_fx_init(int ch);
365 /* sequencer interface */
366 static int awe_open(int dev, int mode);
367 static void awe_close(int dev);
368 static int awe_ioctl(int dev, unsigned int cmd, caddr_t arg);
369 static int awe_kill_note(int dev, int voice, int note, int velocity);
370 static int awe_start_note(int dev, int v, int note_num, int volume);
371 static int awe_set_instr(int dev, int voice, int instr_no);
372 static int awe_set_instr_2(int dev, int voice, int instr_no);
373 static void awe_reset(int dev);
374 static void awe_hw_control(int dev, unsigned char *event);
375 static int awe_load_patch(int dev, int format, const char *addr,
376 int offs, int count, int pmgr_flag);
377 static void awe_aftertouch(int dev, int voice, int pressure);
378 static void awe_controller(int dev, int voice, int ctrl_num, int value);
379 static void awe_panning(int dev, int voice, int value);
380 static void awe_volume_method(int dev, int mode);
381 #ifndef AWE_NO_PATCHMGR
382 static int awe_patchmgr(int dev, struct patmgr_info *rec);
384 static void awe_bender(int dev, int voice, int value);
385 static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc);
386 static void awe_setup_voice(int dev, int voice, int chn);
388 /* hardware controls */
389 #ifdef AWE_HAS_GUS_COMPATIBILITY
390 static void awe_hw_gus_control(int dev, int cmd, unsigned char *event);
392 static void awe_hw_awe_control(int dev, int cmd, unsigned char *event);
393 static void awe_voice_change(int voice, fx_affect_func func);
394 static void awe_sostenuto_on(int voice, int forced);
395 static void awe_sustain_off(int voice, int forced);
396 static void awe_terminate_and_init(int voice, int forced);
399 static int awe_search_instr(int bank, int preset);
400 static int awe_search_multi_voices(int rec, int note, int velocity, awe_voice_info **vlist);
401 static void awe_alloc_multi_voices(int ch, int note, int velocity, int key);
402 static void awe_alloc_one_voice(int voice, int note, int velocity);
403 static int awe_clear_voice(void);
405 /* load / remove patches */
406 static int awe_open_patch(awe_patch_info *patch, const char *addr, int count);
407 static int awe_close_patch(awe_patch_info *patch, const char *addr, int count);
408 static int awe_unload_patch(awe_patch_info *patch, const char *addr, int count);
409 static int awe_load_info(awe_patch_info *patch, const char *addr, int count);
410 static int awe_load_data(awe_patch_info *patch, const char *addr, int count);
411 static int awe_replace_data(awe_patch_info *patch, const char *addr, int count);
412 static int awe_load_map(awe_patch_info *patch, const char *addr, int count);
413 #ifdef AWE_HAS_GUS_COMPATIBILITY
414 static int awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag);
416 static int check_patch_opened(int type, char *name);
417 static int awe_write_wave_data(const char *addr, int offset, awe_sample_info *sp, int channels);
418 static void add_sf_info(int rec);
419 static void add_sf_sample(int rec);
420 static void purge_old_list(int rec, int next);
421 static void add_info_list(int rec);
422 static void awe_remove_samples(int sf_id);
423 static void rebuild_preset_list(void);
424 static short awe_set_sample(awe_voice_info *vp);
426 /* lowlevel functions */
427 static void awe_init_audio(void);
428 static void awe_init_dma(void);
429 static void awe_init_array(void);
430 static void awe_send_array(unsigned short *data);
431 static void awe_tweak_voice(int voice);
432 static void awe_tweak(void);
433 static void awe_init_fm(void);
434 static int awe_open_dram_for_write(int offset, int channels);
435 static void awe_open_dram_for_check(void);
436 static void awe_close_dram(void);
437 static void awe_write_dram(unsigned short c);
438 static int awe_detect_base(int addr);
439 static int awe_detect(void);
440 static int awe_check_dram(void);
441 static int awe_load_chorus_fx(awe_patch_info *patch, const char *addr, int count);
442 static void awe_set_chorus_mode(int mode);
443 static int awe_load_reverb_fx(awe_patch_info *patch, const char *addr, int count);
444 static void awe_set_reverb_mode(int mode);
445 static void awe_equalizer(int bass, int treble);
446 #ifdef CONFIG_AWE32_MIXER
447 static int awe_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg);
450 /* define macros for compatibility */
452 # include <gnu/i386/isa/sound/awe_compat.h>
454 # include "awe_compat.h"
457 /*----------------------------------------------------------------
458 * synth operation table
459 *----------------------------------------------------------------*/
461 static struct synth_operations awe_operations =
483 #ifndef AWE_NO_PATCHMGR
491 #ifdef CONFIG_AWE32_MIXER
492 static struct mixer_operations awe_mixer_operations = {
502 /*================================================================
503 * attach / unload interface
504 *================================================================*/
506 #ifdef AWE_OBSOLETE_VOXWARE
507 #define ATTACH_DECL static
509 #define ATTACH_DECL /**/
512 #if defined(__FreeBSD__) && !defined(AWE_OBSOLETE_VOXWARE)
514 void attach_awe(struct address_info *hw_config)
516 # define ATTACH_RET ret
523 /* check presence of AWE32 card */
524 if (! awe_detect()) {
525 printk("AWE32: not detected\n");
529 /* check AWE32 ports are available */
530 if (awe_check_port()) {
531 printk("AWE32: I/O area already used.\n");
535 /* set buffers to NULL */
542 /* voice & channel info */
543 voices = (voice_info*)my_malloc(AWE_MAX_VOICES * sizeof(voice_info));
544 channels = (awe_chan_info*)my_malloc(AWE_MAX_CHANNELS * sizeof(awe_chan_info));
546 if (voices == NULL || channels == NULL) {
549 printk("AWE32: can't allocate sample tables\n");
553 /* allocate sample tables */
554 INIT_TABLE(sflists, max_sfs, AWE_MAX_SF_LISTS, sf_list);
555 INIT_TABLE(samples, max_samples, AWE_MAX_SAMPLES, awe_sample_list);
556 INIT_TABLE(infos, max_infos, AWE_MAX_INFOS, awe_voice_list);
558 if (num_synths >= MAX_SYNTH_DEV)
559 printk("AWE32 Error: too many synthesizers\n");
561 voice_alloc = &awe_operations.alloc;
562 voice_alloc->max_voice = awe_max_voices;
563 synth_devs[num_synths++] = &awe_operations;
566 #ifdef CONFIG_AWE32_MIXER
567 if (num_mixers < MAX_MIXER_DEV) {
568 mixer_devs[num_mixers++] = &awe_mixer_operations;
572 /* reserve I/O ports for awedrv */
573 awe_request_region();
575 /* clear all samples */
578 /* intialize AWE32 hardware */
581 snprintf(awe_info.name, sizeof(awe_info.name), "AWE32-%s (RAM%dk)",
582 AWEDRV_VERSION, awe_mem_size/1024);
584 printk("awe0: <SoundBlaster EMU8000 MIDI (RAM%dk)>", awe_mem_size/1024);
585 #elif defined(AWE_DEBUG_ON)
586 printk("%s\n", awe_info.name);
589 /* set default values */
590 awe_init_misc_modes(TRUE);
592 /* set reverb & chorus modes */
593 awe_set_reverb_mode(reverb_mode);
594 awe_set_chorus_mode(chorus_mode);
603 #ifdef AWE_DYNAMIC_BUFFER
604 static void free_tables(void)
607 sflists = NULL; max_sfs = 0;
609 samples = NULL; max_samples = 0;
611 infos = NULL; max_infos = 0;
614 #define free_buffers() /**/
620 void unload_awe(void)
624 awe_release_region();
634 /*----------------------------------------------------------------
636 *----------------------------------------------------------------*/
638 #ifdef AWE_OBSOLETE_VOXWARE
641 long attach_awe_obsolete(long mem_start, struct address_info *hw_config)
643 int attach_awe_obsolete(int mem_start, struct address_info *hw_config)
646 my_malloc_init(mem_start);
649 return my_malloc_memptr();
652 int probe_awe_obsolete(struct address_info *hw_config)
655 /*return awe_detect();*/
659 #if defined(__FreeBSD__ )
660 int probe_awe(struct address_info *hw_config)
665 #endif /* AWE_OBSOLETE_VOXWARE */
668 /*================================================================
669 * clear sample tables
670 *================================================================*/
673 awe_reset_samples(void)
677 /* free all bank tables */
678 for (i = 0; i < AWE_MAX_PRESETS; i++)
679 preset_table[i] = -1;
689 /*================================================================
690 * EMU register access
691 *================================================================*/
693 /* select a given AWE32 pointer */
694 static int awe_cur_cmd = -1;
695 #define awe_set_cmd(cmd) \
696 if (awe_cur_cmd != cmd) { OUTW(cmd, awe_base + 0x802); awe_cur_cmd = cmd; }
697 #define awe_port(port) (awe_base - 0x620 + port)
699 /* write 16bit data */
701 awe_poke(unsigned short cmd, unsigned short port, unsigned short data)
704 OUTW(data, awe_port(port));
707 /* write 32bit data */
709 awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data)
712 OUTW(data, awe_port(port)); /* write lower 16 bits */
713 OUTW(data >> 16, awe_port(port)+2); /* write higher 16 bits */
716 /* read 16bit data */
717 INLINE static unsigned short
718 awe_peek(unsigned short cmd, unsigned short port)
722 k = inw(awe_port(port));
726 /* read 32bit data */
727 INLINE static unsigned int
728 awe_peek_dw(unsigned short cmd, unsigned short port)
732 k1 = inw(awe_port(port));
733 k2 = inw(awe_port(port)+2);
738 /* wait delay number of AWE32 44100Hz clocks */
740 awe_wait(unsigned short delay)
742 unsigned short clock, target;
743 unsigned short port = awe_port(AWE_WC_Port);
747 awe_set_cmd(AWE_WC_Cmd);
748 clock = (unsigned short)inw(port);
749 target = clock + delay;
751 if (target < clock) {
752 for (; (unsigned short)inw(port) > target; counter++)
756 for (; (unsigned short)inw(port) < target; counter++)
761 /* write a word data */
763 awe_write_dram(unsigned short c)
765 awe_poke(AWE_SMLD, c);
769 #if defined(linux) && !defined(AWE_OBSOLETE_VOXWARE)
771 /*================================================================
772 * port check / request
773 * 0x620-622, 0xA20-A22, 0xE20-E22
774 *================================================================*/
779 return (check_region(awe_port(Data0), 4) ||
780 check_region(awe_port(Data1), 4) ||
781 check_region(awe_port(Data3), 4));
785 awe_request_region(void)
787 request_region(awe_port(Data0), 4, "sound driver (AWE32)");
788 request_region(awe_port(Data1), 4, "sound driver (AWE32)");
789 request_region(awe_port(Data3), 4, "sound driver (AWE32)");
793 awe_release_region(void)
795 release_region(awe_port(Data0), 4);
796 release_region(awe_port(Data1), 4);
797 release_region(awe_port(Data3), 4);
800 #endif /* !AWE_OBSOLETE_VOXWARE */
803 /*================================================================
804 * AWE32 initialization
805 *================================================================*/
809 AWE_DEBUG(0,printk("AWE32: initializing..\n"));
811 /* initialize hardware configuration */
812 awe_poke(AWE_HWCF1, 0x0059);
813 awe_poke(AWE_HWCF2, 0x0020);
815 /* disable audio; this seems to reduce a clicking noise a bit.. */
816 awe_poke(AWE_HWCF3, 0);
818 /* initialize audio channels */
824 /* initialize init array */
827 /* check DRAM memory size */
828 awe_mem_size = awe_check_dram();
830 /* initialize the FM section of the AWE32 */
833 /* set up voice envelopes */
837 awe_poke(AWE_HWCF3, 0x0004);
844 /*================================================================
845 * AWE32 voice parameters
846 *================================================================*/
848 /* initialize voice_info record */
850 awe_init_voice_info(awe_voice_info *vp)
852 vp->sf_id = 0; /* normal mode */
873 vp->exclusiveClass = 0;
876 vp->scaleTuning = 100;
878 awe_init_voice_parm(&vp->parm);
881 /* initialize voice_parm record:
882 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
883 * Vibrato and Tremolo effects are zero.
885 * Chorus and Reverb effects are zero.
888 awe_init_voice_parm(awe_voice_parm *pp)
890 pp->moddelay = 0x8000;
891 pp->modatkhld = 0x7f7f;
892 pp->moddcysus = 0x7f7f;
893 pp->modrelease = 0x807f;
897 pp->voldelay = 0x8000;
898 pp->volatkhld = 0x7f7f;
899 pp->voldcysus = 0x7f7f;
900 pp->volrelease = 0x807f;
904 pp->lfo1delay = 0x8000;
905 pp->lfo2delay = 0x8000;
920 #ifdef AWE_HAS_GUS_COMPATIBILITY
922 /* convert frequency mHz to abstract cents (= midi key * 100) */
924 freq_to_note(int mHz)
926 /* abscents = log(mHz/8176) / log(2) * 1200 */
927 unsigned int max_val = (unsigned int)0xffffffff / 10000;
936 return 12799; /* maximum */
940 for (base = 8176 * 2; freq >= base; base *= 2) {
942 if (note >= 128) /* over maximum */
947 /* to avoid overflow... */
949 while (freq > max_val) {
955 freq = freq * times / base;
956 for (i = 0; i < 12; i++) {
957 if (freq < semitone_tuning[i+1])
963 freq = freq * 10000 / semitone_tuning[i];
964 for (i = 0; i < 100; i++) {
965 if (freq < cent_tuning[i+1])
970 return note * 100 + tune;
974 /* convert Hz to AWE32 rate offset:
975 * sample pitch offset for the specified sample rate
976 * rate=44100 is no offset, each 4096 is 1 octave (twice).
977 * eg, when rate is 22050, this offset becomes -4096.
980 calc_rate_offset(int Hz)
982 /* offset = log(Hz / 44100) / log(2) * 4096 */
985 /* maybe smaller than max (44100Hz) */
986 if (Hz <= 0 || Hz >= 44100) return 0;
989 for (freq = Hz * 2; freq < 44100; freq *= 2)
993 freq = 44100 * 10000 / (freq/2);
994 for (i = 0; i < 12; i++) {
995 if (freq < semitone_tuning[i+1])
999 freq = freq * 10000 / semitone_tuning[i];
1000 for (i = 0; i < 100; i++) {
1001 if (freq < cent_tuning[i+1])
1005 return -base * 4096 / 1200;
1009 /*----------------------------------------------------------------
1010 * convert envelope time parameter to AWE32 raw parameter
1011 *----------------------------------------------------------------*/
1013 /* attack & decay/release time table (msec) */
1014 static short attack_time_tbl[128] = {
1015 32767, 11878, 5939, 3959, 2969, 2375, 1979, 1696, 1484, 1319, 1187, 1079, 989, 913, 848, 791, 742,
1016 698, 659, 625, 593, 565, 539, 516, 494, 475, 456, 439, 424, 409, 395, 383, 371,
1017 359, 344, 330, 316, 302, 290, 277, 266, 255, 244, 233, 224, 214, 205, 196, 188,
1018 180, 173, 165, 158, 152, 145, 139, 133, 127, 122, 117, 112, 107, 103, 98, 94,
1019 90, 86, 83, 79, 76, 73, 69, 67, 64, 61, 58, 56, 54, 51, 49, 47,
1020 45, 43, 41, 39, 38, 36, 35, 33, 32, 30, 29, 28, 27, 25, 24, 23,
1021 22, 21, 20, 20, 19, 18, 17, 16, 16, 15, 14, 14, 13, 13, 12, 11,
1022 11, 10, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 0,
1025 static short decay_time_tbl[128] = {
1026 32767, 32766, 4589, 4400, 4219, 4045, 3879, 3719, 3566, 3419, 3279, 3144, 3014, 2890, 2771, 2657,
1027 2548, 2443, 2343, 2246, 2154, 2065, 1980, 1899, 1820, 1746, 1674, 1605, 1539, 1475, 1415, 1356,
1028 1301, 1247, 1196, 1146, 1099, 1054, 1011, 969, 929, 891, 854, 819, 785, 753, 722, 692,
1029 664, 636, 610, 585, 561, 538, 516, 494, 474, 455, 436, 418, 401, 384, 368, 353,
1030 339, 325, 311, 298, 286, 274, 263, 252, 242, 232, 222, 213, 204, 196, 188, 180,
1031 173, 166, 159, 152, 146, 140, 134, 129, 123, 118, 113, 109, 104, 100, 96, 92,
1032 88, 84, 81, 77, 74, 71, 68, 65, 63, 60, 58, 55, 53, 51, 49, 47,
1033 45, 43, 41, 39, 38, 36, 35, 33, 32, 30, 29, 28, 27, 26, 25, 24,
1038 calc_parm_delay(int msec)
1040 return (0x8000 - msec * 1000 / 725);
1044 /* delay time = 0x8000 - msec/92 */
1046 calc_parm_hold(int msec)
1048 int val = (0x7f * 92 - msec) / 92;
1049 if (val < 1) val = 1;
1050 if (val > 127) val = 127;
1054 /* attack time: search from time table */
1056 calc_parm_attack(int msec)
1058 return calc_parm_search(msec, attack_time_tbl);
1061 /* decay/release time: search from time table */
1063 calc_parm_decay(int msec)
1065 return calc_parm_search(msec, decay_time_tbl);
1068 /* search an index for specified time from given time table */
1070 calc_parm_search(int msec, short *table)
1072 int left = 1, right = 127, mid;
1073 while (left < right) {
1074 mid = (left + right) / 2;
1075 if (msec < (int)table[mid])
1082 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1085 /*================================================================
1087 *================================================================*/
1089 /* set an effect value */
1090 #define FX_FLAG_OFF 0
1091 #define FX_FLAG_SET 1
1092 #define FX_FLAG_ADD 2
1094 #define FX_SET(rec,type,value) \
1095 ((rec)->flags[type] = FX_FLAG_SET, (rec)->val[type] = (value))
1096 #define FX_ADD(rec,type,value) \
1097 ((rec)->flags[type] = FX_FLAG_ADD, (rec)->val[type] = (value))
1098 #define FX_UNSET(rec,type) \
1099 ((rec)->flags[type] = FX_FLAG_OFF, (rec)->val[type] = 0)
1101 /* check the effect value is set */
1102 #define FX_ON(rec,type) ((rec)->flags[type])
1107 static struct PARM_DEFS {
1108 int type; /* byte or word */
1109 int low, high; /* value range */
1110 fx_affect_func realtime; /* realtime paramater change */
1112 {PARM_WORD, 0, 0x8000, NULL}, /* env1 delay */
1113 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 attack */
1114 {PARM_BYTE, 0, 0x7e, NULL}, /* env1 hold */
1115 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 decay */
1116 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 release */
1117 {PARM_BYTE, 0, 0x7f, NULL}, /* env1 sustain */
1118 {PARM_BYTE, 0, 0xff, NULL}, /* env1 pitch */
1119 {PARM_BYTE, 0, 0xff, NULL}, /* env1 cutoff */
1121 {PARM_WORD, 0, 0x8000, NULL}, /* env2 delay */
1122 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 attack */
1123 {PARM_BYTE, 0, 0x7e, NULL}, /* env2 hold */
1124 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 decay */
1125 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 release */
1126 {PARM_BYTE, 0, 0x7f, NULL}, /* env2 sustain */
1128 {PARM_WORD, 0, 0x8000, NULL}, /* lfo1 delay */
1129 {PARM_BYTE, 0, 0xff, awe_fx_tremfrq}, /* lfo1 freq */
1130 {PARM_BYTE, 0, 0x7f, awe_fx_tremfrq}, /* lfo1 volume (positive only)*/
1131 {PARM_BYTE, 0, 0x7f, awe_fx_fmmod}, /* lfo1 pitch (positive only)*/
1132 {PARM_BYTE, 0, 0xff, awe_fx_fmmod}, /* lfo1 cutoff (positive only)*/
1134 {PARM_WORD, 0, 0x8000, NULL}, /* lfo2 delay */
1135 {PARM_BYTE, 0, 0xff, awe_fx_fm2frq2}, /* lfo2 freq */
1136 {PARM_BYTE, 0, 0x7f, awe_fx_fm2frq2}, /* lfo2 pitch (positive only)*/
1138 {PARM_WORD, 0, 0xffff, awe_set_voice_pitch}, /* initial pitch */
1139 {PARM_BYTE, 0, 0xff, NULL}, /* chorus */
1140 {PARM_BYTE, 0, 0xff, NULL}, /* reverb */
1141 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial cutoff */
1142 {PARM_BYTE, 0, 15, awe_fx_filterQ}, /* initial resonance */
1144 {PARM_WORD, 0, 0xffff, NULL}, /* sample start */
1145 {PARM_WORD, 0, 0xffff, NULL}, /* loop start */
1146 {PARM_WORD, 0, 0xffff, NULL}, /* loop end */
1147 {PARM_WORD, 0, 0xffff, NULL}, /* coarse sample start */
1148 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop start */
1149 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop end */
1150 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial attenuation */
1154 static unsigned char
1155 FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value)
1159 if (lay && (on = FX_ON(lay, type)) != 0)
1160 effect = lay->val[type];
1161 if (!on && (on = FX_ON(rec, type)) != 0)
1162 effect = rec->val[type];
1163 if (on == FX_FLAG_ADD)
1164 effect += (int)value;
1166 if (effect < parm_defs[type].low)
1167 effect = parm_defs[type].low;
1168 else if (effect > parm_defs[type].high)
1169 effect = parm_defs[type].high;
1170 return (unsigned char)effect;
1175 /* get word effect value */
1176 static unsigned short
1177 FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value)
1181 if (lay && (on = FX_ON(lay, type)) != 0)
1182 effect = lay->val[type];
1183 if (!on && (on = FX_ON(rec, type)) != 0)
1184 effect = rec->val[type];
1185 if (on == FX_FLAG_ADD)
1186 effect += (int)value;
1188 if (effect < parm_defs[type].low)
1189 effect = parm_defs[type].low;
1190 else if (effect > parm_defs[type].high)
1191 effect = parm_defs[type].high;
1192 return (unsigned short)effect;
1197 /* get word (upper=type1/lower=type2) effect value */
1198 static unsigned short
1199 FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value)
1202 tmp = FX_BYTE(rec, lay, type1, (unsigned char)(value >> 8));
1204 tmp |= FX_BYTE(rec, lay, type2, (unsigned char)(value & 0xff));
1208 /* address offset */
1210 FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode)
1213 if (lay && FX_ON(lay, hi))
1214 addr = (short)lay->val[hi];
1215 else if (FX_ON(rec, hi))
1216 addr = (short)rec->val[hi];
1218 if (lay && FX_ON(lay, lo))
1219 addr += (short)lay->val[lo];
1220 else if (FX_ON(rec, lo))
1221 addr += (short)rec->val[lo];
1222 if (!(mode & AWE_SAMPLE_8BITS))
1228 /*================================================================
1229 * turn on/off sample
1230 *================================================================*/
1233 awe_note_on(int voice)
1238 FX_Rec *fx = &voices[voice].cinfo->fx;
1239 FX_Rec *fx_lay = NULL;
1240 if (voices[voice].layer < MAX_LAYERS)
1241 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1243 /* A voice sample must assigned before calling */
1244 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1247 /* channel to be silent and idle */
1248 awe_poke(AWE_DCYSUSV(voice), 0x0080);
1249 awe_poke(AWE_VTFT(voice), 0);
1250 awe_poke(AWE_CVCF(voice), 0);
1251 awe_poke(AWE_PTRX(voice), 0);
1252 awe_poke(AWE_CPF(voice), 0);
1254 /* modulation & volume envelope */
1255 awe_poke(AWE_ENVVAL(voice),
1256 FX_WORD(fx, fx_lay, AWE_FX_ENV1_DELAY, vp->parm.moddelay));
1257 awe_poke(AWE_ATKHLD(voice),
1258 FX_COMB(fx, fx_lay, AWE_FX_ENV1_HOLD, AWE_FX_ENV1_ATTACK,
1259 vp->parm.modatkhld));
1260 awe_poke(AWE_DCYSUS(voice),
1261 FX_COMB(fx, fx_lay, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY,
1262 vp->parm.moddcysus));
1263 awe_poke(AWE_ENVVOL(voice),
1264 FX_WORD(fx, fx_lay, AWE_FX_ENV2_DELAY, vp->parm.voldelay));
1265 awe_poke(AWE_ATKHLDV(voice),
1266 FX_COMB(fx, fx_lay, AWE_FX_ENV2_HOLD, AWE_FX_ENV2_ATTACK,
1267 vp->parm.volatkhld));
1268 /* decay/sustain parameter for volume envelope must be set at last */
1271 awe_set_pitch(voice, TRUE);
1273 /* cutoff and volume */
1274 awe_set_volume(voice, TRUE);
1276 /* modulation envelope heights */
1277 awe_poke(AWE_PEFE(voice),
1278 FX_COMB(fx, fx_lay, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF,
1282 awe_poke(AWE_LFO1VAL(voice),
1283 FX_WORD(fx, fx_lay, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay));
1284 awe_poke(AWE_LFO2VAL(voice),
1285 FX_WORD(fx, fx_lay, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay));
1287 /* lfo1 pitch & cutoff shift */
1288 awe_fx_fmmod(voice, TRUE);
1289 /* lfo1 volume & freq */
1290 awe_fx_tremfrq(voice, TRUE);
1291 /* lfo2 pitch & freq */
1292 awe_fx_fm2frq2(voice, TRUE);
1293 /* pan & loop start */
1294 awe_set_pan(voice, TRUE);
1296 /* chorus & loop end (chorus 8bit, MSB) */
1297 addr = vp->loopend - 1;
1298 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_END,
1299 AWE_FX_COARSE_LOOP_END, vp->mode);
1300 temp = FX_BYTE(fx, fx_lay, AWE_FX_CHORUS, vp->parm.chorus);
1301 temp = (temp <<24) | (unsigned int)addr;
1302 awe_poke_dw(AWE_CSL(voice), temp);
1303 AWE_DEBUG(4,printk("AWE32: [-- loopend=%x/%x]\n", vp->loopend, addr));
1305 /* Q & current address (Q 4bit value, MSB) */
1306 addr = vp->start - 1;
1307 addr += FX_OFFSET(fx, fx_lay, AWE_FX_SAMPLE_START,
1308 AWE_FX_COARSE_SAMPLE_START, vp->mode);
1309 temp = FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ);
1310 temp = (temp<<28) | (unsigned int)addr;
1311 awe_poke_dw(AWE_CCCA(voice), temp);
1312 AWE_DEBUG(4,printk("AWE32: [-- startaddr=%x/%x]\n", vp->start, addr));
1315 awe_poke_dw(AWE_VTFT(voice), 0x0000FFFF);
1316 awe_poke_dw(AWE_CVCF(voice), 0x0000FFFF);
1318 /* turn on envelope */
1319 awe_poke(AWE_DCYSUSV(voice),
1320 FX_COMB(fx, fx_lay, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY,
1321 vp->parm.voldcysus));
1323 temp = FX_BYTE(fx, fx_lay, AWE_FX_REVERB, vp->parm.reverb);
1324 temp = (awe_peek_dw(AWE_PTRX(voice)) & 0xffff0000) | (temp<<8);
1325 awe_poke_dw(AWE_PTRX(voice), temp);
1326 awe_poke_dw(AWE_CPF(voice), 0x40000000);
1328 voices[voice].state = AWE_ST_ON;
1330 /* clear voice position for the next note on this channel */
1331 if (SINGLE_LAYER_MODE()) {
1332 FX_UNSET(fx, AWE_FX_SAMPLE_START);
1333 FX_UNSET(fx, AWE_FX_COARSE_SAMPLE_START);
1338 /* turn off the voice */
1340 awe_note_off(int voice)
1344 FX_Rec *fx = &voices[voice].cinfo->fx;
1345 FX_Rec *fx_lay = NULL;
1346 if (voices[voice].layer < MAX_LAYERS)
1347 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1349 if ((vp = voices[voice].sample) == NULL) {
1350 voices[voice].state = AWE_ST_OFF;
1354 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_RELEASE,
1355 (unsigned char)vp->parm.modrelease);
1356 awe_poke(AWE_DCYSUS(voice), tmp);
1357 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_RELEASE,
1358 (unsigned char)vp->parm.volrelease);
1359 awe_poke(AWE_DCYSUSV(voice), tmp);
1360 voices[voice].state = AWE_ST_RELEASED;
1363 /* force to terminate the voice (no releasing echo) */
1365 awe_terminate(int voice)
1367 awe_poke(AWE_DCYSUSV(voice), 0x807F);
1368 awe_tweak_voice(voice);
1369 voices[voice].state = AWE_ST_OFF;
1372 /* turn off other voices with the same exclusive class (for drums) */
1374 awe_exclusive_off(int voice)
1378 if (voices[voice].sample == NULL)
1380 if ((exclass = voices[voice].sample->exclusiveClass) == 0)
1381 return; /* not exclusive */
1383 /* turn off voices with the same class */
1384 for (i = 0; i < awe_max_voices; i++) {
1385 if (i != voice && IS_PLAYING(i) &&
1386 voices[i].sample && voices[i].ch == voices[voice].ch &&
1387 voices[i].sample->exclusiveClass == exclass) {
1388 AWE_DEBUG(4,printk("AWE32: [exoff(%d)]\n", i));
1390 awe_voice_init(i, TRUE);
1396 /*================================================================
1397 * change the parameters of an audible voice
1398 *================================================================*/
1402 awe_set_pitch(int voice, int forced)
1404 if (IS_NO_EFFECT(voice) && !forced) return;
1405 awe_poke(AWE_IP(voice), voices[voice].apitch);
1406 AWE_DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch));
1409 /* calculate & change pitch */
1411 awe_set_voice_pitch(int voice, int forced)
1413 awe_calc_pitch(voice);
1414 awe_set_pitch(voice, forced);
1417 /* change volume & cutoff */
1419 awe_set_volume(int voice, int forced)
1422 unsigned short tmp2;
1423 FX_Rec *fx = &voices[voice].cinfo->fx;
1424 FX_Rec *fx_lay = NULL;
1425 if (voices[voice].layer < MAX_LAYERS)
1426 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1428 if (!IS_PLAYING(voice) && !forced) return;
1429 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1432 tmp2 = FX_BYTE(fx, fx_lay, AWE_FX_CUTOFF, vp->parm.cutoff);
1434 tmp2 |= FX_BYTE(fx, fx_lay, AWE_FX_ATTEN,
1435 (unsigned char)voices[voice].avol);
1436 awe_poke(AWE_IFATN(voice), tmp2);
1439 /* calculate & change volume */
1441 awe_set_voice_vol(int voice, int forced)
1443 if (IS_EMPTY(voice))
1445 awe_calc_volume(voice);
1446 awe_set_volume(voice, forced);
1450 /* change pan; this could make a click noise.. */
1452 awe_set_pan(int voice, int forced)
1457 FX_Rec *fx = &voices[voice].cinfo->fx;
1458 FX_Rec *fx_lay = NULL;
1459 if (voices[voice].layer < MAX_LAYERS)
1460 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1462 if (IS_NO_EFFECT(voice) && !forced) return;
1463 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1466 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
1467 if (vp->fixpan > 0) /* 0-127 */
1468 temp = 255 - (int)vp->fixpan * 2;
1471 if (vp->pan >= 0) /* 0-127 */
1472 pos = (int)vp->pan * 2 - 128;
1473 pos += voices[voice].cinfo->panning; /* -128 - 127 */
1482 if (forced || temp != voices[voice].apan) {
1483 addr = vp->loopstart - 1;
1484 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START,
1485 AWE_FX_COARSE_LOOP_START, vp->mode);
1486 temp = (temp<<24) | (unsigned int)addr;
1487 awe_poke_dw(AWE_PSST(voice), temp);
1488 voices[voice].apan = temp;
1489 AWE_DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr));
1493 /* effects change during playing */
1495 awe_fx_fmmod(int voice, int forced)
1498 FX_Rec *fx = &voices[voice].cinfo->fx;
1499 FX_Rec *fx_lay = NULL;
1500 if (voices[voice].layer < MAX_LAYERS)
1501 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1503 if (IS_NO_EFFECT(voice) && !forced) return;
1504 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1506 awe_poke(AWE_FMMOD(voice),
1507 FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,
1511 /* set tremolo (lfo1) volume & frequency */
1513 awe_fx_tremfrq(int voice, int forced)
1516 FX_Rec *fx = &voices[voice].cinfo->fx;
1517 FX_Rec *fx_lay = NULL;
1518 if (voices[voice].layer < MAX_LAYERS)
1519 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1521 if (IS_NO_EFFECT(voice) && !forced) return;
1522 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1524 awe_poke(AWE_TREMFRQ(voice),
1525 FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,
1529 /* set lfo2 pitch & frequency */
1531 awe_fx_fm2frq2(int voice, int forced)
1534 FX_Rec *fx = &voices[voice].cinfo->fx;
1535 FX_Rec *fx_lay = NULL;
1536 if (voices[voice].layer < MAX_LAYERS)
1537 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1539 if (IS_NO_EFFECT(voice) && !forced) return;
1540 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1542 awe_poke(AWE_FM2FRQ2(voice),
1543 FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,
1548 /* Q & current address (Q 4bit value, MSB) */
1550 awe_fx_filterQ(int voice, int forced)
1554 FX_Rec *fx = &voices[voice].cinfo->fx;
1555 FX_Rec *fx_lay = NULL;
1556 if (voices[voice].layer < MAX_LAYERS)
1557 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1559 if (IS_NO_EFFECT(voice) && !forced) return;
1560 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1563 addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff;
1564 addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28);
1565 awe_poke_dw(AWE_CCCA(voice), addr);
1568 /*================================================================
1569 * calculate pitch offset
1570 *----------------------------------------------------------------
1571 * 0xE000 is no pitch offset at 44100Hz sample.
1572 * Every 4096 is one octave.
1573 *================================================================*/
1576 awe_calc_pitch(int voice)
1578 voice_info *vp = &voices[voice];
1580 awe_chan_info *cp = voices[voice].cinfo;
1583 /* search voice information */
1584 if ((ap = vp->sample) == NULL)
1586 if (ap->index < 0) {
1587 AWE_DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1588 if (awe_set_sample(ap) < 0)
1592 /* calculate offset */
1593 if (ap->fixkey >= 0) {
1594 AWE_DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune));
1595 offset = (ap->fixkey - ap->root) * 4096 / 12;
1597 AWE_DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune));
1598 offset = (vp->note - ap->root) * 4096 / 12;
1599 AWE_DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset));
1601 offset = (offset * ap->scaleTuning) / 100;
1602 AWE_DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));
1603 offset += ap->tune * 4096 / 1200;
1604 AWE_DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));
1605 if (cp->bender != 0) {
1606 AWE_DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender));
1607 /* (819200: 1 semitone) ==> (4096: 12 semitones) */
1608 offset += cp->bender * cp->bender_range / 2400;
1611 /* add initial pitch correction */
1612 if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH))
1613 offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH];
1614 else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH))
1615 offset += cp->fx.val[AWE_FX_INIT_PITCH];
1617 /* 0xe000: root pitch */
1618 vp->apitch = 0xe000 + ap->rate_offset + offset;
1619 AWE_DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset));
1620 if (vp->apitch > 0xffff)
1621 vp->apitch = 0xffff;
1627 #ifdef AWE_HAS_GUS_COMPATIBILITY
1628 /* calculate MIDI key and semitone from the specified frequency */
1630 awe_calc_pitch_from_freq(int voice, int freq)
1632 voice_info *vp = &voices[voice];
1634 FX_Rec *fx = &voices[voice].cinfo->fx;
1635 FX_Rec *fx_lay = NULL;
1639 if (voices[voice].layer < MAX_LAYERS)
1640 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1642 /* search voice information */
1643 if ((ap = vp->sample) == NULL)
1645 if (ap->index < 0) {
1646 AWE_DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1647 if (awe_set_sample(ap) < 0)
1650 note = freq_to_note(freq);
1651 offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;
1652 offset = (offset * ap->scaleTuning) / 100;
1653 if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH))
1654 offset += fx_lay->val[AWE_FX_INIT_PITCH];
1655 else if (FX_ON(fx, AWE_FX_INIT_PITCH))
1656 offset += fx->val[AWE_FX_INIT_PITCH];
1657 vp->apitch = 0xe000 + ap->rate_offset + offset;
1658 if (vp->apitch > 0xffff)
1659 vp->apitch = 0xffff;
1663 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1666 /*================================================================
1667 * calculate volume attenuation
1668 *----------------------------------------------------------------
1669 * Voice volume is controlled by volume attenuation parameter.
1670 * So volume becomes maximum when avol is 0 (no attenuation), and
1671 * minimum when 255 (-96dB or silence).
1672 *================================================================*/
1674 static int vol_table[128] = {
1675 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
1676 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
1677 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
1678 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
1679 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
1680 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
1681 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
1682 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
1686 awe_calc_volume(int voice)
1688 voice_info *vp = &voices[voice];
1690 awe_chan_info *cp = voices[voice].cinfo;
1693 /* search voice information */
1694 if ((ap = vp->sample) == NULL)
1698 if (ap->index < 0) {
1699 AWE_DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1700 if (awe_set_sample(ap) < 0)
1705 vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127);
1706 vol = vol * ap->amplitude / 127;
1708 if (vol < 0) vol = 0;
1709 if (vol > 127) vol = 127;
1711 /* calc to attenuation */
1712 vol = vol_table[vol];
1713 vol = vol + (int)ap->attenuation + init_atten;
1714 if (vol > 255) vol = 255;
1717 AWE_DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));
1721 /* set sostenuto on */
1722 static void awe_sostenuto_on(int voice, int forced)
1724 if (IS_NO_EFFECT(voice) && !forced) return;
1725 voices[voice].sostenuto = 127;
1730 static void awe_sustain_off(int voice, int forced)
1732 if (voices[voice].state == AWE_ST_SUSTAINED) {
1733 awe_note_off(voice);
1734 awe_fx_init(voices[voice].ch);
1735 awe_voice_init(voice, FALSE);
1740 /* terminate and initialize voice */
1741 static void awe_terminate_and_init(int voice, int forced)
1743 awe_terminate(voice);
1744 awe_fx_init(voices[voice].ch);
1745 awe_voice_init(voice, TRUE);
1749 /*================================================================
1750 * synth operation routines
1751 *================================================================*/
1753 #define AWE_VOICE_KEY(v) (0x8000 | (v))
1754 #define AWE_CHAN_KEY(c,n) (((c) << 8) | ((n) + 1))
1755 #define KEY_CHAN_MATCH(key,c) (((key) >> 8) == (c))
1757 /* initialize the voice */
1759 awe_voice_init(int voice, int init_all)
1761 voice_info *vp = &voices[voice];
1763 /* reset voice search key */
1764 if (playing_mode == AWE_PLAY_DIRECT)
1765 vp->key = AWE_VOICE_KEY(voice);
1769 /* clear voice mapping */
1770 voice_alloc->map[voice] = 0;
1772 /* touch the timing flag */
1773 vp->time = current_alloc_time;
1775 /* initialize other parameters if necessary */
1782 vp->cinfo = &channels[voice];
1784 vp->state = AWE_ST_OFF;
1786 /* emu8000 parameters */
1794 static void awe_fx_init(int ch)
1796 if (SINGLE_LAYER_MODE() && !misc_modes[AWE_MD_KEEP_EFFECT]) {
1797 BZERO(&channels[ch].fx, sizeof(channels[ch].fx));
1798 BZERO(&channels[ch].fx_layer, sizeof(&channels[ch].fx_layer));
1802 /* initialize channel info */
1803 static void awe_channel_init(int ch, int init_all)
1805 awe_chan_info *cp = &channels[ch];
1808 cp->panning = 0; /* zero center */
1809 cp->bender_range = 200; /* sense * 100 */
1811 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) {
1812 cp->instr = misc_modes[AWE_MD_DEF_DRUM];
1813 cp->bank = AWE_DRUM_BANK;
1815 cp->instr = misc_modes[AWE_MD_DEF_PRESET];
1816 cp->bank = misc_modes[AWE_MD_DEF_BANK];
1822 cp->bender = 0; /* zero tune skew */
1823 cp->expression_vol = 127;
1827 if (! misc_modes[AWE_MD_KEEP_EFFECT]) {
1828 BZERO(&cp->fx, sizeof(cp->fx));
1829 BZERO(&cp->fx_layer, sizeof(cp->fx_layer));
1834 /* change the voice parameters; voice = channel */
1835 static void awe_voice_change(int voice, fx_affect_func func)
1838 switch (playing_mode) {
1839 case AWE_PLAY_DIRECT:
1842 case AWE_PLAY_INDIRECT:
1843 for (i = 0; i < awe_max_voices; i++)
1844 if (voices[i].key == AWE_VOICE_KEY(voice))
1848 for (i = 0; i < awe_max_voices; i++)
1849 if (KEY_CHAN_MATCH(voices[i].key, voice))
1856 /*----------------------------------------------------------------
1857 * device open / close
1858 *----------------------------------------------------------------*/
1861 * reset status of all voices, and clear sample position flag
1864 awe_open(int dev, int mode)
1867 return RET_ERROR(EBUSY);
1871 /* set default mode */
1872 awe_init_misc_modes(FALSE);
1873 init_atten = misc_modes[AWE_MD_ZERO_ATTEN];
1874 drum_flags = DEFAULT_DRUM_FLAGS;
1875 playing_mode = AWE_PLAY_INDIRECT;
1877 /* reset voices & channels */
1887 * reset all voices again (terminate sounds)
1897 /* set miscellaneous mode parameters
1900 awe_init_misc_modes(int init_all)
1903 for (i = 0; i < AWE_MD_END; i++) {
1904 if (init_all || misc_modes_default[i].init_each_time)
1905 misc_modes[i] = misc_modes_default[i].value;
1910 /* sequencer I/O control:
1913 awe_ioctl(int dev, unsigned int cmd, caddr_t arg)
1916 case SNDCTL_SYNTH_INFO:
1917 if (playing_mode == AWE_PLAY_DIRECT)
1918 awe_info.nr_voices = awe_max_voices;
1920 awe_info.nr_voices = AWE_MAX_CHANNELS;
1921 IOCTL_TO_USER((char*)arg, 0, &awe_info, sizeof(awe_info));
1925 case SNDCTL_SEQ_RESETSAMPLES:
1926 awe_reset_samples();
1931 case SNDCTL_SEQ_PERCMODE:
1936 case SNDCTL_SYNTH_MEMAVL:
1937 return awe_mem_size - awe_free_mem_ptr() * 2;
1940 printk("AWE32: unsupported ioctl %d\n", cmd);
1941 return RET_ERROR(EINVAL);
1946 static int voice_in_range(int voice)
1948 if (playing_mode == AWE_PLAY_DIRECT) {
1949 if (voice < 0 || voice >= awe_max_voices)
1952 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
1958 static void release_voice(int voice, int do_sustain)
1960 if (IS_NO_SOUND(voice))
1962 if (do_sustain && (voices[voice].cinfo->sustained == 127 ||
1963 voices[voice].sostenuto == 127))
1964 voices[voice].state = AWE_ST_SUSTAINED;
1966 awe_note_off(voice);
1967 awe_fx_init(voices[voice].ch);
1968 awe_voice_init(voice, FALSE);
1972 /* release all notes */
1973 static void awe_note_off_all(int do_sustain)
1976 for (i = 0; i < awe_max_voices; i++)
1977 release_voice(i, do_sustain);
1981 * not terminate, just release the voice.
1984 awe_kill_note(int dev, int voice, int note, int velocity)
1988 AWE_DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));
1989 if (! voice_in_range(voice))
1990 return RET_ERROR(EINVAL);
1992 switch (playing_mode) {
1993 case AWE_PLAY_DIRECT:
1994 case AWE_PLAY_INDIRECT:
1995 key = AWE_VOICE_KEY(voice);
1998 case AWE_PLAY_MULTI2:
1999 v2 = voice_alloc->map[voice] >> 8;
2000 voice_alloc->map[voice] = 0;
2002 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2003 return RET_ERROR(EINVAL);
2004 /* continue to below */
2006 key = AWE_CHAN_KEY(voice, note);
2010 for (i = 0; i < awe_max_voices; i++) {
2011 if (voices[i].key == key)
2012 release_voice(i, TRUE);
2018 static void start_or_volume_change(int voice, int velocity)
2020 voices[voice].velocity = velocity;
2021 awe_calc_volume(voice);
2022 if (voices[voice].state == AWE_ST_STANDBY)
2024 else if (voices[voice].state == AWE_ST_ON)
2025 awe_set_volume(voice, FALSE);
2028 static void set_and_start_voice(int voice, int state)
2030 /* calculate pitch & volume parameters */
2031 voices[voice].state = state;
2032 awe_calc_pitch(voice);
2033 awe_calc_volume(voice);
2034 if (state == AWE_ST_ON)
2039 * if note is 255, identical with aftertouch function.
2040 * Otherwise, start a voice with specified not and volume.
2043 awe_start_note(int dev, int voice, int note, int velocity)
2045 int i, key, state, volonly;
2047 AWE_DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));
2048 if (! voice_in_range(voice))
2049 return RET_ERROR(EINVAL);
2052 state = AWE_ST_STANDBY; /* stand by for playing */
2054 state = AWE_ST_ON; /* really play */
2057 switch (playing_mode) {
2058 case AWE_PLAY_DIRECT:
2059 case AWE_PLAY_INDIRECT:
2060 key = AWE_VOICE_KEY(voice);
2065 case AWE_PLAY_MULTI2:
2066 voice = voice_alloc->map[voice] >> 8;
2067 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2068 return RET_ERROR(EINVAL);
2069 /* continue to below */
2071 if (note >= 128) { /* key volume mode */
2075 key = AWE_CHAN_KEY(voice, note);
2079 /* dynamic volume change */
2081 for (i = 0; i < awe_max_voices; i++) {
2082 if (voices[i].key == key)
2083 start_or_volume_change(i, velocity);
2088 /* if the same note still playing, stop it */
2089 for (i = 0; i < awe_max_voices; i++)
2090 if (voices[i].key == key) {
2091 if (voices[i].state == AWE_ST_ON) {
2093 awe_voice_init(i, FALSE);
2094 } else if (voices[i].state == AWE_ST_STANDBY)
2095 awe_voice_init(i, TRUE);
2098 /* allocate voices */
2099 if (playing_mode == AWE_PLAY_DIRECT)
2100 awe_alloc_one_voice(voice, note, velocity);
2102 awe_alloc_multi_voices(voice, note, velocity, key);
2104 /* turn off other voices exlusively (for drums) */
2105 for (i = 0; i < awe_max_voices; i++)
2106 if (voices[i].key == key)
2107 awe_exclusive_off(i);
2109 /* set up pitch and volume parameters */
2110 for (i = 0; i < awe_max_voices; i++) {
2111 if (voices[i].key == key && voices[i].state == AWE_ST_OFF)
2112 set_and_start_voice(i, state);
2119 /* search instrument from preset table with the specified bank */
2121 awe_search_instr(int bank, int preset)
2125 for (i = preset_table[preset]; i >= 0; i = infos[i].next_bank) {
2126 if (infos[i].bank == bank)
2133 /* assign the instrument to a voice */
2135 awe_set_instr_2(int dev, int voice, int instr_no)
2137 if (playing_mode == AWE_PLAY_MULTI2) {
2138 voice = voice_alloc->map[voice] >> 8;
2139 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2140 return RET_ERROR(EINVAL);
2142 return awe_set_instr(dev, voice, instr_no);
2145 /* assign the instrument to a channel; voice is the channel number */
2147 awe_set_instr(int dev, int voice, int instr_no)
2149 awe_chan_info *cinfo;
2152 if (! voice_in_range(voice))
2153 return RET_ERROR(EINVAL);
2155 if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)
2156 return RET_ERROR(EINVAL);
2158 cinfo = &channels[voice];
2160 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice))
2161 def_bank = AWE_DRUM_BANK; /* always search drumset */
2163 def_bank = cinfo->bank;
2166 cinfo->def_vrec = -1;
2167 cinfo->vrec = awe_search_instr(def_bank, instr_no);
2168 if (def_bank == AWE_DRUM_BANK) /* search default drumset */
2169 cinfo->def_vrec = awe_search_instr(def_bank, misc_modes[AWE_MD_DEF_DRUM]);
2170 else /* search default preset */
2171 cinfo->def_vrec = awe_search_instr(misc_modes[AWE_MD_DEF_BANK], instr_no);
2173 if (cinfo->vrec < 0 && cinfo->def_vrec < 0) {
2174 AWE_DEBUG(1,printk("AWE32 Warning: can't find instrument %d\n", instr_no));
2177 cinfo->instr = instr_no;
2183 /* reset all voices; terminate sounds and initialize parameters */
2188 current_alloc_time = 0;
2189 /* don't turn off voice 31 and 32. they are used also for FM voices */
2190 for (i = 0; i < awe_max_voices; i++) {
2192 awe_voice_init(i, TRUE);
2194 for (i = 0; i < AWE_MAX_CHANNELS; i++)
2195 awe_channel_init(i, TRUE);
2196 for (i = 0; i < 16; i++) {
2197 awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127;
2198 awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127;
2205 /* hardware specific control:
2206 * GUS specific and AWE32 specific controls are available.
2209 awe_hw_control(int dev, unsigned char *event)
2212 if (cmd & _AWE_MODE_FLAG)
2213 awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2214 #ifdef AWE_HAS_GUS_COMPATIBILITY
2216 awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2221 #ifdef AWE_HAS_GUS_COMPATIBILITY
2223 /* GUS compatible controls */
2225 awe_hw_gus_control(int dev, int cmd, unsigned char *event)
2232 if (MULTI_LAYER_MODE())
2234 if (cmd == _GUS_NUMVOICES)
2238 if (! voice_in_range(voice))
2241 p1 = *(unsigned short *) &event[4];
2242 p2 = *(short *) &event[6];
2243 plong = *(int*) &event[4];
2246 case _GUS_VOICESAMPLE:
2247 awe_set_instr(dev, voice, p1);
2250 case _GUS_VOICEBALA:
2251 /* 0 to 15 --> -128 to 127 */
2252 awe_panning(dev, voice, ((int)p1 << 4) - 128);
2256 case _GUS_VOICEVOL2:
2257 /* not supported yet */
2260 case _GUS_RAMPRANGE:
2265 /* volume ramping not supported */
2268 case _GUS_VOLUME_SCALE:
2271 case _GUS_VOICE_POS:
2272 FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START,
2273 (short)(plong & 0x7fff));
2274 FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START,
2275 (plong >> 15) & 0xffff);
2279 key = AWE_VOICE_KEY(voice);
2280 for (i = 0; i < awe_max_voices; i++) {
2281 if (voices[i].key == key) {
2289 awe_fx_init(voices[i].ch);
2290 awe_voice_init(i, TRUE);
2293 case _GUS_VOICEFADE:
2295 awe_fx_init(voices[i].ch);
2296 awe_voice_init(i, FALSE);
2299 case _GUS_VOICEFREQ:
2300 awe_calc_pitch_from_freq(i, plong);
2310 /* AWE32 specific controls */
2312 awe_hw_awe_control(int dev, int cmd, unsigned char *event)
2317 awe_chan_info *cinfo;
2322 if (! voice_in_range(voice))
2325 if (playing_mode == AWE_PLAY_MULTI2) {
2326 voice = voice_alloc->map[voice] >> 8;
2327 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2331 p1 = *(unsigned short *) &event[4];
2332 p2 = *(short *) &event[6];
2333 cinfo = &channels[voice];
2336 case _AWE_DEBUG_MODE:
2338 printk("AWE32: debug mode = %d\n", debug_mode);
2340 case _AWE_REVERB_MODE:
2341 awe_set_reverb_mode(p1);
2344 case _AWE_CHORUS_MODE:
2345 awe_set_chorus_mode(p1);
2348 case _AWE_REMOVE_LAST_SAMPLES:
2349 AWE_DEBUG(0,printk("AWE32: remove last samples\n"));
2350 if (locked_sf_id > 0)
2351 awe_remove_samples(locked_sf_id);
2354 case _AWE_INITIALIZE_CHIP:
2358 case _AWE_SEND_EFFECT:
2362 int layer = (p1 >> 8);
2363 if (layer >= 0 && layer < MAX_LAYERS)
2364 fx = &cinfo->fx_layer[layer];
2367 if (p1 & 0x40) i = FX_FLAG_OFF;
2368 if (p1 & 0x80) i = FX_FLAG_ADD;
2370 if (p1 < AWE_FX_END) {
2371 AWE_DEBUG(0,printk("AWE32: effects (%d) %d %d\n", voice, p1, p2));
2372 if (i == FX_FLAG_SET)
2374 else if (i == FX_FLAG_ADD)
2378 if (i != FX_FLAG_OFF && parm_defs[p1].realtime) {
2379 AWE_DEBUG(0,printk("AWE32: fx_realtime (%d)\n", voice));
2380 awe_voice_change(voice, parm_defs[p1].realtime);
2385 case _AWE_RESET_CHANNEL:
2386 awe_channel_init(voice, !p1);
2389 case _AWE_TERMINATE_ALL:
2393 case _AWE_TERMINATE_CHANNEL:
2394 awe_voice_change(voice, awe_terminate_and_init);
2397 case _AWE_RELEASE_ALL:
2398 awe_note_off_all(FALSE);
2400 case _AWE_NOTEOFF_ALL:
2401 awe_note_off_all(TRUE);
2404 case _AWE_INITIAL_VOLUME:
2405 AWE_DEBUG(0,printk("AWE32: init attenuation %d\n", p1));
2406 if (p2 == 0) /* absolute value */
2407 init_atten = (short)p1;
2408 else /* relative value */
2409 init_atten = misc_modes[AWE_MD_ZERO_ATTEN] + (short)p1;
2410 if (init_atten < 0) init_atten = 0;
2411 for (i = 0; i < awe_max_voices; i++)
2412 awe_set_voice_vol(i, TRUE);
2415 case _AWE_CHN_PRESSURE:
2416 cinfo->chan_press = p1;
2417 p1 = p1 * misc_modes[AWE_MD_MOD_SENSE] / 1200;
2418 FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, p1);
2419 awe_voice_change(voice, awe_fx_fmmod);
2420 FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, p1);
2421 awe_voice_change(voice, awe_fx_fm2frq2);
2424 case _AWE_CHANNEL_MODE:
2425 AWE_DEBUG(0,printk("AWE32: channel mode = %d\n", p1));
2430 case _AWE_DRUM_CHANNELS:
2431 AWE_DEBUG(0,printk("AWE32: drum flags = %x\n", p1));
2432 drum_flags = *(unsigned int*)&event[4];
2435 case _AWE_MISC_MODE:
2436 AWE_DEBUG(0,printk("AWE32: misc mode = %d %d\n", p1, p2));
2437 if (p1 > AWE_MD_VERSION && p1 < AWE_MD_END)
2438 misc_modes[p1] = p2;
2441 case _AWE_EQUALIZER:
2442 awe_equalizer((int)p1, (int)p2);
2446 AWE_DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice));
2452 /* voice pressure change */
2454 awe_aftertouch(int dev, int voice, int pressure)
2458 AWE_DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure));
2459 if (! voice_in_range(voice))
2462 switch (playing_mode) {
2463 case AWE_PLAY_DIRECT:
2464 case AWE_PLAY_INDIRECT:
2465 awe_start_note(dev, voice, 255, pressure);
2467 case AWE_PLAY_MULTI2:
2468 note = (voice_alloc->map[voice] & 0xff) - 1;
2469 awe_start_note(dev, voice, note + 0x80, pressure);
2475 /* voice control change */
2477 awe_controller(int dev, int voice, int ctrl_num, int value)
2480 awe_chan_info *cinfo;
2482 if (! voice_in_range(voice))
2485 if (playing_mode == AWE_PLAY_MULTI2) {
2486 voice = voice_alloc->map[voice] >> 8;
2487 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2491 cinfo = &channels[voice];
2494 case CTL_BANK_SELECT: /* MIDI control #0 */
2495 AWE_DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value));
2496 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice) &&
2497 !misc_modes[AWE_MD_TOGGLE_DRUM_BANK])
2499 cinfo->bank = value;
2500 if (cinfo->bank == AWE_DRUM_BANK)
2501 DRUM_CHANNEL_ON(cinfo->channel);
2503 DRUM_CHANNEL_OFF(cinfo->channel);
2504 awe_set_instr(dev, voice, cinfo->instr);
2507 case CTL_MODWHEEL: /* MIDI control #1 */
2508 AWE_DEBUG(2,printk("AWE32: [modwheel(%d) %d]\n", voice, value));
2509 i = value * misc_modes[AWE_MD_MOD_SENSE] / 1200;
2510 FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, i);
2511 awe_voice_change(voice, awe_fx_fmmod);
2512 FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, i);
2513 awe_voice_change(voice, awe_fx_fm2frq2);
2516 case CTRL_PITCH_BENDER: /* SEQ1 V2 contorl */
2517 AWE_DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value));
2519 cinfo->bender = value;
2520 awe_voice_change(voice, awe_set_voice_pitch);
2523 case CTRL_PITCH_BENDER_RANGE: /* SEQ1 V2 control */
2524 AWE_DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value));
2525 /* value = sense x 100 */
2526 cinfo->bender_range = value;
2527 /* no audible pitch change yet.. */
2530 case CTL_EXPRESSION: /* MIDI control #11 */
2531 if (SINGLE_LAYER_MODE())
2533 case CTRL_EXPRESSION: /* SEQ1 V2 control */
2534 AWE_DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value));
2536 cinfo->expression_vol = value;
2537 awe_voice_change(voice, awe_set_voice_vol);
2540 case CTL_PAN: /* MIDI control #10 */
2541 AWE_DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value));
2542 /* (0-127) -> signed 8bit */
2543 cinfo->panning = value * 2 - 128;
2544 if (misc_modes[AWE_MD_REALTIME_PAN])
2545 awe_voice_change(voice, awe_set_pan);
2548 case CTL_MAIN_VOLUME: /* MIDI control #7 */
2549 if (SINGLE_LAYER_MODE())
2550 value = (value * 100) / 16383;
2551 case CTRL_MAIN_VOLUME: /* SEQ1 V2 control */
2552 AWE_DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value));
2554 cinfo->main_vol = value;
2555 awe_voice_change(voice, awe_set_voice_vol);
2558 case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */
2559 AWE_DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value));
2560 FX_SET(&cinfo->fx, AWE_FX_REVERB, value * 2);
2563 case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */
2564 AWE_DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value));
2565 FX_SET(&cinfo->fx, AWE_FX_CHORUS, value * 2);
2568 #ifdef AWE_ACCEPT_ALL_SOUNDS_CONTROLL
2569 case 120: /* all sounds off */
2570 awe_note_off_all(FALSE);
2572 case 123: /* all notes off */
2573 awe_note_off_all(TRUE);
2577 case CTL_SUSTAIN: /* MIDI control #64 */
2578 cinfo->sustained = value;
2580 awe_voice_change(voice, awe_sustain_off);
2583 case CTL_SOSTENUTO: /* MIDI control #66 */
2585 awe_voice_change(voice, awe_sostenuto_on);
2587 awe_voice_change(voice, awe_sustain_off);
2591 AWE_DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n",
2592 voice, ctrl_num, value));
2598 /* voice pan change (value = -128 - 127) */
2600 awe_panning(int dev, int voice, int value)
2602 awe_chan_info *cinfo;
2604 if (! voice_in_range(voice))
2607 if (playing_mode == AWE_PLAY_MULTI2) {
2608 voice = voice_alloc->map[voice] >> 8;
2609 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2613 cinfo = &channels[voice];
2614 cinfo->panning = value;
2615 AWE_DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, cinfo->panning));
2616 if (misc_modes[AWE_MD_REALTIME_PAN])
2617 awe_voice_change(voice, awe_set_pan);
2621 /* volume mode change */
2623 awe_volume_method(int dev, int mode)
2625 /* not impremented */
2626 AWE_DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode));
2630 #ifndef AWE_NO_PATCHMGR
2633 awe_patchmgr(int dev, struct patmgr_info *rec)
2635 printk("AWE32 Warning: patch manager control not supported\n");
2641 /* pitch wheel change: 0-16384 */
2643 awe_bender(int dev, int voice, int value)
2645 awe_chan_info *cinfo;
2647 if (! voice_in_range(voice))
2650 if (playing_mode == AWE_PLAY_MULTI2) {
2651 voice = voice_alloc->map[voice] >> 8;
2652 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2656 /* convert to zero centered value */
2657 cinfo = &channels[voice];
2658 cinfo->bender = value - 8192;
2659 AWE_DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, cinfo->bender));
2660 awe_voice_change(voice, awe_set_voice_pitch);
2664 /*----------------------------------------------------------------
2665 * load a sound patch:
2666 * three types of patches are accepted: AWE, GUS, and SYSEX.
2667 *----------------------------------------------------------------*/
2670 awe_load_patch(int dev, int format, const char *addr,
2671 int offs, int count, int pmgr_flag)
2673 awe_patch_info patch;
2676 #ifdef AWE_HAS_GUS_COMPATIBILITY
2677 if (format == GUS_PATCH) {
2678 return awe_load_guspatch(addr, offs, count, pmgr_flag);
2681 if (format == SYSEX_PATCH) {
2682 /* no system exclusive message supported yet */
2684 } else if (format != AWE_PATCH) {
2685 printk("AWE32 Error: Invalid patch format (key) 0x%x\n", format);
2686 return RET_ERROR(EINVAL);
2689 if (count < AWE_PATCH_INFO_SIZE) {
2690 printk("AWE32 Error: Patch header too short\n");
2691 return RET_ERROR(EINVAL);
2693 COPY_FROM_USER(((char*)&patch) + offs, addr, offs,
2694 AWE_PATCH_INFO_SIZE - offs);
2696 count -= AWE_PATCH_INFO_SIZE;
2697 if (count < patch.len) {
2698 printk("AWE32: sample: Patch record too short (%d<%d)\n",
2700 return RET_ERROR(EINVAL);
2703 switch (patch.type) {
2705 rc = awe_load_info(&patch, addr, count);
2708 rc = awe_load_data(&patch, addr, count);
2710 case AWE_OPEN_PATCH:
2711 rc = awe_open_patch(&patch, addr, count);
2713 case AWE_CLOSE_PATCH:
2714 rc = awe_close_patch(&patch, addr, count);
2716 case AWE_UNLOAD_PATCH:
2717 rc = awe_unload_patch(&patch, addr, count);
2719 case AWE_REPLACE_DATA:
2720 rc = awe_replace_data(&patch, addr, count);
2722 case AWE_MAP_PRESET:
2723 rc = awe_load_map(&patch, addr, count);
2725 case AWE_LOAD_CHORUS_FX:
2726 rc = awe_load_chorus_fx(&patch, addr, count);
2728 case AWE_LOAD_REVERB_FX:
2729 rc = awe_load_reverb_fx(&patch, addr, count);
2733 printk("AWE32 Error: unknown patch format type %d\n",
2735 rc = RET_ERROR(EINVAL);
2742 /* create an sflist record */
2744 awe_create_sf(int type, char *name)
2748 /* terminate sounds */
2750 if (current_sf_id >= max_sfs) {
2751 int newsize = max_sfs + AWE_MAX_SF_LISTS;
2752 sf_list *newlist = my_realloc(sflists, sizeof(sf_list)*max_sfs,
2753 sizeof(sf_list)*newsize);
2754 if (newlist == NULL)
2759 rec = &sflists[current_sf_id];
2760 rec->sf_id = current_sf_id + 1;
2762 if (current_sf_id == 0 || (type & AWE_PAT_LOCKED) != 0)
2763 locked_sf_id = current_sf_id + 1;
2766 MEMCPY(rec->name, name, AWE_PATCH_NAME_LEN);
2768 BZERO(rec->name, AWE_PATCH_NAME_LEN);
2770 rec->num_info = awe_free_info();
2771 rec->num_sample = awe_free_sample();
2772 rec->mem_ptr = awe_free_mem_ptr();
2781 /* open patch; create sf list and set opened flag */
2783 awe_open_patch(awe_patch_info *patch, const char *addr, int count)
2786 COPY_FROM_USER(&parm, addr, AWE_PATCH_INFO_SIZE, sizeof(parm));
2787 if (awe_create_sf(parm.type, parm.name)) {
2788 printk("AWE32: can't open: failed to alloc new list\n");
2789 return RET_ERROR(ENOSPC);
2791 patch_opened = TRUE;
2792 return current_sf_id;
2795 /* check if the patch is already opened */
2797 check_patch_opened(int type, char *name)
2799 if (! patch_opened) {
2800 if (awe_create_sf(type, name)) {
2801 printk("AWE32: failed to alloc new list\n");
2802 return RET_ERROR(ENOSPC);
2804 patch_opened = TRUE;
2805 return current_sf_id;
2807 return current_sf_id;
2810 /* close the patch; if no voice is loaded, remove the patch */
2812 awe_close_patch(awe_patch_info *patch, const char *addr, int count)
2814 if (patch_opened && current_sf_id > 0) {
2815 /* if no voice is loaded, release the current patch */
2816 if (sflists[current_sf_id-1].infos == -1)
2817 awe_remove_samples(current_sf_id - 1);
2824 /* remove the latest patch */
2826 awe_unload_patch(awe_patch_info *patch, const char *addr, int count)
2828 if (current_sf_id > 0)
2829 awe_remove_samples(current_sf_id - 1);
2833 /* allocate voice info list records */
2834 static int alloc_new_info(int nvoices)
2836 int newsize, free_info;
2837 awe_voice_list *newlist;
2838 free_info = awe_free_info();
2839 if (free_info + nvoices >= max_infos) {
2841 newsize = max_infos + AWE_MAX_INFOS;
2842 } while (free_info + nvoices >= newsize);
2843 newlist = my_realloc(infos, sizeof(awe_voice_list)*max_infos,
2844 sizeof(awe_voice_list)*newsize);
2845 if (newlist == NULL) {
2846 printk("AWE32: can't alloc info table\n");
2847 return RET_ERROR(ENOSPC);
2850 max_infos = newsize;
2855 /* allocate sample info list records */
2856 static int alloc_new_sample(void)
2858 int newsize, free_sample;
2859 awe_sample_list *newlist;
2860 free_sample = awe_free_sample();
2861 if (free_sample >= max_samples) {
2862 newsize = max_samples + AWE_MAX_SAMPLES;
2863 newlist = my_realloc(samples,
2864 sizeof(awe_sample_list)*max_samples,
2865 sizeof(awe_sample_list)*newsize);
2866 if (newlist == NULL) {
2867 printk("AWE32: can't alloc sample table\n");
2868 return RET_ERROR(ENOSPC);
2871 max_samples = newsize;
2876 /* load voice map */
2878 awe_load_map(awe_patch_info *patch, const char *addr, int count)
2881 awe_voice_list *rec;
2884 if (check_patch_opened(AWE_PAT_TYPE_MAP, NULL) < 0)
2885 return RET_ERROR(ENOSPC);
2886 if (alloc_new_info(1) < 0)
2887 return RET_ERROR(ENOSPC);
2889 COPY_FROM_USER(&map, addr, AWE_PATCH_INFO_SIZE, sizeof(map));
2891 free_info = awe_free_info();
2892 rec = &infos[free_info];
2893 rec->bank = map.map_bank;
2894 rec->instr = map.map_instr;
2895 rec->type = V_ST_MAPPED;
2896 rec->disabled = FALSE;
2897 awe_init_voice_info(&rec->v);
2898 if (map.map_key >= 0) {
2899 rec->v.low = map.map_key;
2900 rec->v.high = map.map_key;
2902 rec->v.start = map.src_instr;
2903 rec->v.end = map.src_bank;
2904 rec->v.fixkey = map.src_key;
2905 rec->v.sf_id = current_sf_id;
2906 add_info_list(free_info);
2907 add_sf_info(free_info);
2912 /* load voice information data */
2914 awe_load_info(awe_patch_info *patch, const char *addr, int count)
2917 awe_voice_rec_hdr hdr;
2921 if (count < AWE_VOICE_REC_SIZE) {
2922 printk("AWE32 Error: invalid patch info length\n");
2923 return RET_ERROR(EINVAL);
2926 offset = AWE_PATCH_INFO_SIZE;
2927 COPY_FROM_USER((char*)&hdr, addr, offset, AWE_VOICE_REC_SIZE);
2928 offset += AWE_VOICE_REC_SIZE;
2930 if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
2931 printk("AWE32 Error: Illegal voice number %d\n", hdr.nvoices);
2932 return RET_ERROR(EINVAL);
2934 total_size = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE * hdr.nvoices;
2935 if (count < total_size) {
2936 printk("AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n",
2937 count, hdr.nvoices);
2938 return RET_ERROR(EINVAL);
2941 if (check_patch_opened(AWE_PAT_TYPE_MISC, NULL) < 0)
2942 return RET_ERROR(ENOSPC);
2944 #if 0 /* it looks like not so useful.. */
2945 /* check if the same preset already exists in the info list */
2946 for (i = sflists[current_sf_id-1].infos; i >= 0; i = infos[i].next) {
2947 if (infos[i].disabled) continue;
2948 if (infos[i].bank == hdr.bank && infos[i].instr == hdr.instr) {
2949 /* in exclusive mode, do skip loading this */
2950 if (hdr.write_mode == AWE_WR_EXCLUSIVE)
2952 /* in replace mode, disable the old data */
2953 else if (hdr.write_mode == AWE_WR_REPLACE)
2954 infos[i].disabled = TRUE;
2957 if (hdr.write_mode == AWE_WR_REPLACE)
2958 rebuild_preset_list();
2961 if (alloc_new_info(hdr.nvoices) < 0)
2962 return RET_ERROR(ENOSPC);
2964 for (i = 0; i < hdr.nvoices; i++) {
2965 int rec = awe_free_info();
2967 infos[rec].bank = hdr.bank;
2968 infos[rec].instr = hdr.instr;
2969 infos[rec].type = V_ST_NORMAL;
2970 infos[rec].disabled = FALSE;
2972 /* copy awe_voice_info parameters */
2973 COPY_FROM_USER(&infos[rec].v, addr, offset, AWE_VOICE_INFO_SIZE);
2974 offset += AWE_VOICE_INFO_SIZE;
2975 infos[rec].v.sf_id = current_sf_id;
2976 if (infos[rec].v.mode & AWE_MODE_INIT_PARM)
2977 awe_init_voice_parm(&infos[rec].v.parm);
2978 awe_set_sample(&infos[rec].v);
2986 /* load wave sample data */
2988 awe_load_data(awe_patch_info *patch, const char *addr, int count)
2991 int rc, free_sample;
2992 awe_sample_info *rec;
2994 if (check_patch_opened(AWE_PAT_TYPE_MISC, NULL) < 0)
2995 return RET_ERROR(ENOSPC);
2997 if (alloc_new_sample() < 0)
2998 return RET_ERROR(ENOSPC);
3000 free_sample = awe_free_sample();
3001 rec = &samples[free_sample].v;
3003 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3004 offset = AWE_PATCH_INFO_SIZE;
3005 COPY_FROM_USER(rec, addr, offset, AWE_SAMPLE_INFO_SIZE);
3006 offset += AWE_SAMPLE_INFO_SIZE;
3007 if (size != rec->size) {
3008 printk("AWE32: load: sample size differed (%d != %d)\n",
3010 return RET_ERROR(EINVAL);
3013 if ((rc = awe_write_wave_data(addr, offset, rec, -1)) != 0)
3016 rec->sf_id = current_sf_id;
3018 add_sf_sample(free_sample);
3024 /* replace wave sample data */
3026 awe_replace_data(awe_patch_info *patch, const char *addr, int count)
3032 awe_sample_info cursmp;
3035 if (! patch_opened) {
3036 printk("AWE32: replace: patch not opened\n");
3037 return RET_ERROR(EINVAL);
3040 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3041 offset = AWE_PATCH_INFO_SIZE;
3042 COPY_FROM_USER(&cursmp, addr, offset, AWE_SAMPLE_INFO_SIZE);
3043 offset += AWE_SAMPLE_INFO_SIZE;
3044 if (cursmp.size == 0 || size != cursmp.size) {
3045 printk("AWE32: replace: illegal sample size (%d!=%d)\n",
3047 return RET_ERROR(EINVAL);
3049 channels = patch->optarg;
3050 if (channels <= 0 || channels > AWE_NORMAL_VOICES) {
3051 printk("AWE32: replace: illegal channels %d\n", channels);
3052 return RET_ERROR(EINVAL);
3055 for (i = sflists[current_sf_id-1].samples;
3056 i >= 0; i = samples[i].next) {
3057 if (samples[i].v.sample == cursmp.sample)
3061 printk("AWE32: replace: cannot find existing sample data %d\n",
3063 return RET_ERROR(EINVAL);
3066 if (samples[i].v.size != cursmp.size) {
3067 printk("AWE32: replace: exiting size differed (%d!=%d)\n",
3068 samples[i].v.size, cursmp.size);
3069 return RET_ERROR(EINVAL);
3072 save_mem_ptr = awe_free_mem_ptr();
3073 sflists[current_sf_id-1].mem_ptr = samples[i].v.start - awe_mem_start;
3074 MEMCPY(&samples[i].v, &cursmp, sizeof(cursmp));
3075 if ((rc = awe_write_wave_data(addr, offset, &samples[i].v, channels)) != 0)
3077 sflists[current_sf_id-1].mem_ptr = save_mem_ptr;
3078 samples[i].v.sf_id = current_sf_id;
3084 /*----------------------------------------------------------------*/
3086 static const char *readbuf_addr;
3087 static int readbuf_offs;
3088 static int readbuf_flags;
3090 static unsigned short *readbuf_loop;
3091 static int readbuf_loopstart, readbuf_loopend;
3094 /* initialize read buffer */
3096 readbuf_init(const char *addr, int offset, awe_sample_info *sp)
3099 readbuf_loop = NULL;
3100 readbuf_loopstart = sp->loopstart;
3101 readbuf_loopend = sp->loopend;
3102 if (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP)) {
3103 int looplen = sp->loopend - sp->loopstart;
3104 readbuf_loop = my_malloc(looplen * 2);
3105 if (readbuf_loop == NULL) {
3106 printk("AWE32: can't malloc temp buffer\n");
3107 return RET_ERROR(ENOSPC);
3111 readbuf_addr = addr;
3112 readbuf_offs = offset;
3113 readbuf_flags = sp->mode_flags;
3117 /* read directly from user buffer */
3118 static unsigned short
3119 readbuf_word(int pos)
3122 /* read from user buffer */
3123 if (readbuf_flags & AWE_SAMPLE_8BITS) {
3125 GET_BYTE_FROM_USER(cc, readbuf_addr, readbuf_offs + pos);
3126 c = cc << 8; /* convert 8bit -> 16bit */
3128 GET_SHORT_FROM_USER(c, readbuf_addr, readbuf_offs + pos * 2);
3130 if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
3131 c ^= 0x8000; /* unsigned -> signed */
3133 /* write on cache for reverse loop */
3134 if (readbuf_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP)) {
3135 if (pos >= readbuf_loopstart && pos < readbuf_loopend)
3136 readbuf_loop[pos - readbuf_loopstart] = c;
3143 /* read from cache */
3144 static unsigned short
3145 readbuf_word_cache(int pos)
3147 if (pos >= readbuf_loopstart && pos < readbuf_loopend)
3148 return readbuf_loop[pos - readbuf_loopstart];
3156 my_free(readbuf_loop);
3158 readbuf_loop = NULL;
3163 #define readbuf_word_cache readbuf_word
3164 #define readbuf_end() /**/
3168 /*----------------------------------------------------------------*/
3170 #define BLANK_LOOP_START 8
3171 #define BLANK_LOOP_END 40
3172 #define BLANK_LOOP_SIZE 48
3174 /* loading onto memory */
3176 awe_write_wave_data(const char *addr, int offset, awe_sample_info *sp, int channels)
3178 int i, truesize, dram_offset;
3181 /* be sure loop points start < end */
3182 if (sp->loopstart > sp->loopend) {
3183 int tmp = sp->loopstart;
3184 sp->loopstart = sp->loopend;
3188 /* compute true data size to be loaded */
3189 truesize = sp->size;
3190 if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP)
3191 truesize += sp->loopend - sp->loopstart;
3192 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK)
3193 truesize += BLANK_LOOP_SIZE;
3194 if (awe_free_mem_ptr() + truesize >= awe_mem_size/2) {
3195 printk("AWE32 Error: Sample memory full\n");
3196 return RET_ERROR(ENOSPC);
3199 /* recalculate address offset */
3200 sp->end -= sp->start;
3201 sp->loopstart -= sp->start;
3202 sp->loopend -= sp->start;
3204 dram_offset = awe_free_mem_ptr() + awe_mem_start;
3205 sp->start = dram_offset;
3206 sp->end += dram_offset;
3207 sp->loopstart += dram_offset;
3208 sp->loopend += dram_offset;
3210 /* set the total size (store onto obsolete checksum value) */
3214 sp->checksum = truesize;
3216 if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0)
3219 if (readbuf_init(addr, offset, sp) < 0)
3220 return RET_ERROR(ENOSPC);
3222 for (i = 0; i < sp->size; i++) {
3224 c = readbuf_word(i);
3226 if (i == sp->loopend &&
3227 (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))) {
3228 int looplen = sp->loopend - sp->loopstart;
3229 /* copy reverse loop */
3231 for (k = 1; k <= looplen; k++) {
3232 c = readbuf_word_cache(i - k);
3235 if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) {
3238 sp->start += looplen;
3245 /* if no blank loop is attached in the sample, add it */
3246 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) {
3247 for (i = 0; i < BLANK_LOOP_SIZE; i++)
3249 if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) {
3250 sp->loopstart = sp->end + BLANK_LOOP_START;
3251 sp->loopend = sp->end + BLANK_LOOP_END;
3255 sflists[current_sf_id-1].mem_ptr += truesize;
3265 /*----------------------------------------------------------------*/
3267 #ifdef AWE_HAS_GUS_COMPATIBILITY
3269 /* calculate GUS envelope time:
3270 * is this correct? i have no idea..
3273 calc_gus_envelope_time(int rate, int start, int end)
3276 r = (3 - ((rate >> 6) & 3)) * 3;
3284 return (t * 10) / (p * 441);
3287 #define calc_gus_sustain(val) (0x7f - vol_table[(val)/2])
3288 #define calc_gus_attenuation(val) vol_table[(val)/2]
3290 /* load GUS patch */
3292 awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag)
3294 struct patch_info patch;
3295 awe_voice_info *rec;
3296 awe_sample_info *smp;
3298 int note, free_sample, free_info;
3301 sizeof_patch = offsetof(struct patch_info, data); /* header size */
3302 if (size < sizeof_patch) {
3303 printk("AWE32 Error: Patch header too short\n");
3304 return RET_ERROR(EINVAL);
3306 COPY_FROM_USER(((char*)&patch) + offs, addr, offs, sizeof_patch - offs);
3307 size -= sizeof_patch;
3308 if (size < patch.len) {
3309 printk("AWE32 Warning: Patch record too short (%d<%ld)\n",
3311 return RET_ERROR(EINVAL);
3313 if (check_patch_opened(AWE_PAT_TYPE_GUS, NULL) < 0)
3314 return RET_ERROR(ENOSPC);
3315 if (alloc_new_sample() < 0)
3316 return RET_ERROR(ENOSPC);
3317 if (alloc_new_info(1))
3318 return RET_ERROR(ENOSPC);
3320 free_sample = awe_free_sample();
3321 smp = &samples[free_sample].v;
3323 smp->sample = free_sample;
3325 smp->end = patch.len;
3326 smp->loopstart = patch.loop_start;
3327 smp->loopend = patch.loop_end;
3328 smp->size = patch.len;
3330 /* set up mode flags */
3331 smp->mode_flags = 0;
3332 if (!(patch.mode & WAVE_16_BITS))
3333 smp->mode_flags |= AWE_SAMPLE_8BITS;
3334 if (patch.mode & WAVE_UNSIGNED)
3335 smp->mode_flags |= AWE_SAMPLE_UNSIGNED;
3336 smp->mode_flags |= AWE_SAMPLE_NO_BLANK;
3337 if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
3338 smp->mode_flags |= AWE_SAMPLE_SINGLESHOT;
3339 if (patch.mode & WAVE_BIDIR_LOOP)
3340 smp->mode_flags |= AWE_SAMPLE_BIDIR_LOOP;
3341 if (patch.mode & WAVE_LOOP_BACK)
3342 smp->mode_flags |= AWE_SAMPLE_REVERSE_LOOP;
3344 AWE_DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, smp->mode_flags));
3345 if (patch.mode & WAVE_16_BITS) {
3346 /* convert to word offsets */
3349 smp->loopstart /= 2;
3352 smp->checksum_flag = 0;
3355 if ((rc = awe_write_wave_data(addr, sizeof_patch, smp, -1)) != 0)
3358 smp->sf_id = current_sf_id;
3359 add_sf_sample(free_sample);
3361 /* set up voice info */
3362 free_info = awe_free_info();
3363 rec = &infos[free_info].v;
3364 awe_init_voice_info(rec);
3365 rec->sample = free_sample; /* the last sample */
3366 rec->rate_offset = calc_rate_offset(patch.base_freq);
3367 note = freq_to_note(patch.base_note);
3368 rec->root = note / 100;
3369 rec->tune = -(note % 100);
3370 rec->low = freq_to_note(patch.low_note) / 100;
3371 rec->high = freq_to_note(patch.high_note) / 100;
3372 AWE_DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%lu-%lu)]\n",
3373 rec->rate_offset, note,
3374 rec->low, rec->high,
3375 patch.low_note, patch.high_note));
3376 /* panning position; -128 - 127 => 0-127 */
3377 rec->pan = (patch.panning + 128) / 2;
3379 /* detuning is ignored */
3380 /* 6points volume envelope */
3381 if (patch.mode & WAVE_ENVELOPES) {
3382 int attack, hold, decay, release;
3383 attack = calc_gus_envelope_time
3384 (patch.env_rate[0], 0, patch.env_offset[0]);
3385 hold = calc_gus_envelope_time
3386 (patch.env_rate[1], patch.env_offset[0],
3387 patch.env_offset[1]);
3388 decay = calc_gus_envelope_time
3389 (patch.env_rate[2], patch.env_offset[1],
3390 patch.env_offset[2]);
3391 release = calc_gus_envelope_time
3392 (patch.env_rate[3], patch.env_offset[1],
3393 patch.env_offset[4]);
3394 release += calc_gus_envelope_time
3395 (patch.env_rate[4], patch.env_offset[3],
3396 patch.env_offset[4]);
3397 release += calc_gus_envelope_time
3398 (patch.env_rate[5], patch.env_offset[4],
3399 patch.env_offset[5]);
3400 rec->parm.volatkhld = (calc_parm_attack(attack) << 8) |
3401 calc_parm_hold(hold);
3402 rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
3403 calc_parm_decay(decay);
3404 rec->parm.volrelease = 0x8000 | calc_parm_decay(release);
3405 AWE_DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release));
3406 rec->attenuation = calc_gus_attenuation(patch.env_offset[0]);
3409 /* tremolo effect */
3410 if (patch.mode & WAVE_TREMOLO) {
3411 int rate = (patch.tremolo_rate * 1000 / 38) / 42;
3412 rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
3413 AWE_DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n",
3414 patch.tremolo_rate, patch.tremolo_depth,
3415 rec->parm.tremfrq));
3417 /* vibrato effect */
3418 if (patch.mode & WAVE_VIBRATO) {
3419 int rate = (patch.vibrato_rate * 1000 / 38) / 42;
3420 rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
3421 AWE_DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n",
3422 patch.tremolo_rate, patch.tremolo_depth,
3423 rec->parm.tremfrq));
3426 /* scale_freq, scale_factor, volume, and fractions not implemented */
3428 /* append to the tail of the list */
3429 infos[free_info].bank = misc_modes[AWE_MD_GUS_BANK];
3430 infos[free_info].instr = patch.instr_no;
3431 infos[free_info].disabled = FALSE;
3432 infos[free_info].type = V_ST_NORMAL;
3433 infos[free_info].v.sf_id = current_sf_id;
3435 add_info_list(free_info);
3436 add_sf_info(free_info);
3438 /* set the voice index */
3439 awe_set_sample(rec);
3444 #endif /* AWE_HAS_GUS_COMPATIBILITY */
3446 /*----------------------------------------------------------------
3447 * sample and voice list handlers
3448 *----------------------------------------------------------------*/
3450 /* append this to the sf list */
3451 static void add_sf_info(int rec)
3453 int sf_id = infos[rec].v.sf_id;
3454 if (sf_id == 0) return;
3456 if (sflists[sf_id].infos < 0)
3457 sflists[sf_id].infos = rec;
3460 prev = sflists[sf_id].infos;
3461 while ((i = infos[prev].next) >= 0)
3463 infos[prev].next = rec;
3465 infos[rec].next = -1;
3466 sflists[sf_id].num_info++;
3469 /* prepend this sample to sf list */
3470 static void add_sf_sample(int rec)
3472 int sf_id = samples[rec].v.sf_id;
3473 if (sf_id == 0) return;
3475 samples[rec].next = sflists[sf_id].samples;
3476 sflists[sf_id].samples = rec;
3477 sflists[sf_id].num_sample++;
3480 /* purge the old records which don't belong with the same file id */
3481 static void purge_old_list(int rec, int next)
3483 infos[rec].next_instr = next;
3484 if (infos[rec].bank == AWE_DRUM_BANK) {
3485 /* remove samples with the same note range */
3486 int cur, *prevp = &infos[rec].next_instr;
3487 int low = infos[rec].v.low;
3488 int high = infos[rec].v.high;
3489 for (cur = next; cur >= 0; cur = infos[cur].next_instr) {
3490 if (infos[cur].v.low == low &&
3491 infos[cur].v.high == high &&
3492 infos[cur].v.sf_id != infos[rec].v.sf_id)
3493 *prevp = infos[cur].next_instr;
3494 prevp = &infos[cur].next_instr;
3497 if (infos[next].v.sf_id != infos[rec].v.sf_id)
3498 infos[rec].next_instr = -1;
3502 /* prepend to top of the preset table */
3503 static void add_info_list(int rec)
3506 int instr = infos[rec].instr;
3507 int bank = infos[rec].bank;
3509 if (infos[rec].disabled)
3512 prevp = &preset_table[instr];
3515 /* search the first record with the same bank number */
3516 if (infos[cur].bank == bank) {
3517 /* replace the list with the new record */
3518 infos[rec].next_bank = infos[cur].next_bank;
3520 purge_old_list(rec, cur);
3523 prevp = &infos[cur].next_bank;
3524 cur = infos[cur].next_bank;
3527 /* this is the first bank record.. just add this */
3528 infos[rec].next_instr = -1;
3529 infos[rec].next_bank = preset_table[instr];
3530 preset_table[instr] = rec;
3533 /* remove samples later than the specified sf_id */
3535 awe_remove_samples(int sf_id)
3538 awe_reset_samples();
3541 /* already removed? */
3542 if (current_sf_id <= sf_id)
3545 current_sf_id = sf_id;
3546 if (locked_sf_id > sf_id)
3547 locked_sf_id = sf_id;
3549 rebuild_preset_list();
3552 /* rebuild preset search list */
3553 static void rebuild_preset_list(void)
3557 for (i = 0; i < AWE_MAX_PRESETS; i++)
3558 preset_table[i] = -1;
3560 for (i = 0; i < current_sf_id; i++) {
3561 for (j = sflists[i].infos; j >= 0; j = infos[j].next)
3566 /* search the specified sample */
3568 awe_set_sample(awe_voice_info *vp)
3572 for (i = sflists[vp->sf_id-1].samples; i >= 0; i = samples[i].next) {
3573 if (samples[i].v.sample == vp->sample) {
3574 /* set the actual sample offsets */
3575 vp->start += samples[i].v.start;
3576 vp->end += samples[i].v.end;
3577 vp->loopstart += samples[i].v.loopstart;
3578 vp->loopend += samples[i].v.loopend;
3579 /* copy mode flags */
3580 vp->mode = samples[i].v.mode_flags;
3590 /*----------------------------------------------------------------
3592 *----------------------------------------------------------------*/
3594 /* look for all voices associated with the specified note & velocity */
3596 awe_search_multi_voices(int rec, int note, int velocity, awe_voice_info **vlist)
3601 for (; rec >= 0; rec = infos[rec].next_instr) {
3602 if (note >= infos[rec].v.low &&
3603 note <= infos[rec].v.high &&
3604 velocity >= infos[rec].v.vellow &&
3605 velocity <= infos[rec].v.velhigh) {
3606 vlist[nvoices] = &infos[rec].v;
3607 if (infos[rec].type == V_ST_MAPPED) /* mapper */
3610 if (nvoices >= AWE_MAX_VOICES)
3617 /* store the voice list from the specified note and velocity.
3618 if the preset is mapped, seek for the destination preset, and rewrite
3619 the note number if necessary.
3622 really_alloc_voices(int vrec, int def_vrec, int *note, int velocity, awe_voice_info **vlist, int level)
3626 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3628 nvoices = awe_search_multi_voices(def_vrec, *note, velocity, vlist);
3629 if (nvoices < 0) { /* mapping */
3630 int preset = vlist[0]->start;
3631 int bank = vlist[0]->end;
3632 int key = vlist[0]->fixkey;
3634 printk("AWE32: too deep mapping level\n");
3637 vrec = awe_search_instr(bank, preset);
3638 if (bank == AWE_DRUM_BANK)
3639 def_vrec = awe_search_instr(bank, 0);
3641 def_vrec = awe_search_instr(0, preset);
3644 return really_alloc_voices(vrec, def_vrec, note, velocity, vlist, level+1);
3650 /* allocate voices corresponding note and velocity; supports multiple insts. */
3652 awe_alloc_multi_voices(int ch, int note, int velocity, int key)
3655 awe_voice_info *vlist[AWE_MAX_VOICES];
3657 if (channels[ch].vrec < 0 && channels[ch].def_vrec < 0)
3658 awe_set_instr(0, ch, channels[ch].instr);
3660 /* check the possible voices; note may be changeable if mapped */
3661 nvoices = really_alloc_voices(channels[ch].vrec, channels[ch].def_vrec,
3662 ¬e, velocity, vlist, 0);
3664 /* set the voices */
3665 current_alloc_time++;
3666 for (i = 0; i < nvoices; i++) {
3667 v = awe_clear_voice();
3668 voices[v].key = key;
3670 voices[v].note = note;
3671 voices[v].velocity = velocity;
3672 voices[v].time = current_alloc_time;
3673 voices[v].cinfo = &channels[ch];
3674 voices[v].sample = vlist[i];
3675 voices[v].state = AWE_ST_MARK;
3676 voices[v].layer = nvoices - i - 1; /* in reverse order */
3679 /* clear the mark in allocated voices */
3680 for (i = 0; i < awe_max_voices; i++) {
3681 if (voices[i].state == AWE_ST_MARK)
3682 voices[i].state = AWE_ST_OFF;
3688 /* search the best voice from the specified status condition */
3690 search_best_voice(int condition)
3694 time = current_alloc_time + 1;
3695 for (i = 0; i < awe_max_voices; i++) {
3696 if ((voices[i].state & condition) &&
3697 (best < 0 || voices[i].time < time)) {
3699 time = voices[i].time;
3704 if (voices[best].state != AWE_ST_OFF)
3705 awe_terminate(best);
3706 awe_voice_init(best, TRUE);
3712 /* search an empty voice.
3713 if no empty voice is found, at least terminate a voice
3716 awe_clear_voice(void)
3720 /* looking for the oldest empty voice */
3721 if ((best = search_best_voice(AWE_ST_OFF)) >= 0)
3723 if ((best = search_best_voice(AWE_ST_RELEASED)) >= 0)
3725 /* looking for the oldest sustained voice */
3726 if ((best = search_best_voice(AWE_ST_SUSTAINED)) >= 0)
3729 #ifdef AWE_LOOKUP_MIDI_PRIORITY
3730 if (MULTI_LAYER_MODE() && misc_modes[AWE_MD_CHN_PRIOR]) {
3732 int time = current_alloc_time + 1;
3734 /* looking for the voices from high channel (except drum ch) */
3735 for (i = 0; i < awe_max_voices; i++) {
3736 if (IS_DRUM_CHANNEL(voices[i].ch)) continue;
3737 if (voices[i].ch < ch) continue;
3738 if (voices[i].state != AWE_ST_MARK &&
3739 (voices[i].ch > ch || voices[i].time < time)) {
3741 time = voices[i].time;
3748 best = search_best_voice(~AWE_ST_MARK);
3757 /* search sample for the specified note & velocity and set it on the voice;
3758 * note that voice is the voice index (not channel index)
3761 awe_alloc_one_voice(int voice, int note, int velocity)
3764 awe_voice_info *vlist[AWE_MAX_VOICES];
3766 ch = voices[voice].ch;
3767 if (channels[ch].vrec < 0 && channels[ch].def_vrec < 0)
3768 awe_set_instr(0, ch, channels[ch].instr);
3770 nvoices = really_alloc_voices(voices[voice].cinfo->vrec,
3771 voices[voice].cinfo->def_vrec,
3772 ¬e, velocity, vlist, 0);
3774 voices[voice].time = ++current_alloc_time;
3775 voices[voice].sample = vlist[0]; /* use the first one */
3776 voices[voice].layer = 0;
3777 voices[voice].note = note;
3778 voices[voice].velocity = velocity;
3783 /*----------------------------------------------------------------
3784 * sequencer2 functions
3785 *----------------------------------------------------------------*/
3787 /* search an empty voice; used by sequencer2 */
3789 awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
3791 playing_mode = AWE_PLAY_MULTI2;
3792 awe_info.nr_voices = AWE_MAX_CHANNELS;
3793 return awe_clear_voice();
3797 /* set up voice; used by sequencer2 */
3799 awe_setup_voice(int dev, int voice, int chn)
3801 struct channel_info *info;
3802 if (synth_devs[dev] == NULL ||
3803 (info = &synth_devs[dev]->chn_info[chn]) == NULL)
3806 if (voice < 0 || voice >= awe_max_voices)
3809 AWE_DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn));
3810 channels[chn].expression_vol = info->controllers[CTL_EXPRESSION];
3811 channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME];
3812 channels[chn].panning =
3813 info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */
3814 channels[chn].bender = info->bender_value; /* zero center */
3815 channels[chn].bank = info->controllers[CTL_BANK_SELECT];
3816 channels[chn].sustained = info->controllers[CTL_SUSTAIN];
3817 if (info->controllers[CTL_EXT_EFF_DEPTH]) {
3818 FX_SET(&channels[chn].fx, AWE_FX_REVERB,
3819 info->controllers[CTL_EXT_EFF_DEPTH] * 2);
3821 if (info->controllers[CTL_CHORUS_DEPTH]) {
3822 FX_SET(&channels[chn].fx, AWE_FX_CHORUS,
3823 info->controllers[CTL_CHORUS_DEPTH] * 2);
3825 awe_set_instr(dev, chn, info->pgm_num);
3829 #ifdef CONFIG_AWE32_MIXER
3830 /*================================================================
3831 * AWE32 mixer device control
3832 *================================================================*/
3835 awe_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
3839 if (((cmd >> 8) & 0xff) != 'M')
3840 return RET_ERROR(EINVAL);
3842 level = (int)IOCTL_IN(arg);
3843 level = ((level & 0xff) + (level >> 8)) / 2;
3844 AWE_DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
3846 if (IO_WRITE_CHECK(cmd)) {
3847 switch (cmd & 0xff) {
3848 case SOUND_MIXER_BASS:
3849 awe_bass_level = level * 12 / 100;
3850 if (awe_bass_level >= 12)
3851 awe_bass_level = 11;
3852 awe_equalizer(awe_bass_level, awe_treble_level);
3854 case SOUND_MIXER_TREBLE:
3855 awe_treble_level = level * 12 / 100;
3856 if (awe_treble_level >= 12)
3857 awe_treble_level = 11;
3858 awe_equalizer(awe_bass_level, awe_treble_level);
3860 case SOUND_MIXER_VOLUME:
3861 level = level * 127 / 100;
3862 if (level >= 128) level = 127;
3863 init_atten = vol_table[level];
3864 for (i = 0; i < awe_max_voices; i++)
3865 awe_set_voice_vol(i, TRUE);
3869 switch (cmd & 0xff) {
3870 case SOUND_MIXER_BASS:
3871 level = awe_bass_level * 100 / 24;
3872 level = (level << 8) | level;
3874 case SOUND_MIXER_TREBLE:
3875 level = awe_treble_level * 100 / 24;
3876 level = (level << 8) | level;
3878 case SOUND_MIXER_VOLUME:
3879 for (i = 127; i > 0; i--) {
3880 if (init_atten <= vol_table[i])
3883 level = i * 100 / 127;
3884 level = (level << 8) | level;
3886 case SOUND_MIXER_DEVMASK:
3887 level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME;
3893 return IOCTL_OUT(arg, level);
3895 #endif /* CONFIG_AWE32_MIXER */
3898 /*================================================================
3899 * initialization of AWE32
3900 *================================================================*/
3902 /* intiailize audio channels */
3904 awe_init_audio(void)
3908 /* turn off envelope engines */
3909 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
3910 awe_poke(AWE_DCYSUSV(ch), 0x80);
3913 /* reset all other parameters to zero */
3914 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
3915 awe_poke(AWE_ENVVOL(ch), 0);
3916 awe_poke(AWE_ENVVAL(ch), 0);
3917 awe_poke(AWE_DCYSUS(ch), 0);
3918 awe_poke(AWE_ATKHLDV(ch), 0);
3919 awe_poke(AWE_LFO1VAL(ch), 0);
3920 awe_poke(AWE_ATKHLD(ch), 0);
3921 awe_poke(AWE_LFO2VAL(ch), 0);
3922 awe_poke(AWE_IP(ch), 0);
3923 awe_poke(AWE_IFATN(ch), 0);
3924 awe_poke(AWE_PEFE(ch), 0);
3925 awe_poke(AWE_FMMOD(ch), 0);
3926 awe_poke(AWE_TREMFRQ(ch), 0);
3927 awe_poke(AWE_FM2FRQ2(ch), 0);
3928 awe_poke_dw(AWE_PTRX(ch), 0);
3929 awe_poke_dw(AWE_VTFT(ch), 0);
3930 awe_poke_dw(AWE_PSST(ch), 0);
3931 awe_poke_dw(AWE_CSL(ch), 0);
3932 awe_poke_dw(AWE_CCCA(ch), 0);
3935 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
3936 awe_poke_dw(AWE_CPF(ch), 0);
3937 awe_poke_dw(AWE_CVCF(ch), 0);
3942 /* initialize DMA address */
3946 awe_poke_dw(AWE_SMALR, 0);
3947 awe_poke_dw(AWE_SMARR, 0);
3948 awe_poke_dw(AWE_SMALW, 0);
3949 awe_poke_dw(AWE_SMARW, 0);
3953 /* initialization arrays; from ADIP */
3955 static unsigned short init1[128] = {
3956 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330,
3957 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730,
3958 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30,
3959 0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30,
3961 0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330,
3962 0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730,
3963 0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30,
3964 0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30,
3966 0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330,
3967 0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730,
3968 0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30,
3969 0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30,
3971 0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330,
3972 0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730,
3973 0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30,
3974 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30,
3977 static unsigned short init2[128] = {
3978 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
3979 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
3980 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
3981 0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
3983 0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
3984 0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
3985 0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
3986 0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
3988 0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
3989 0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
3990 0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
3991 0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
3993 0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
3994 0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
3995 0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
3996 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
3999 static unsigned short init3[128] = {
4000 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4001 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
4002 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
4003 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
4005 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
4006 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
4007 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
4008 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
4010 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
4011 0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
4012 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
4013 0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
4015 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
4016 0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
4017 0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
4018 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
4021 static unsigned short init4[128] = {
4022 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4023 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
4024 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
4025 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
4027 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
4028 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
4029 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
4030 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
4032 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
4033 0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
4034 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
4035 0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
4037 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
4038 0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
4039 0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
4040 0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
4044 /* send initialization arrays to start up */
4046 awe_init_array(void)
4048 awe_send_array(init1);
4050 awe_send_array(init2);
4051 awe_send_array(init3);
4052 awe_poke_dw(AWE_HWCF4, 0);
4053 awe_poke_dw(AWE_HWCF5, 0x83);
4054 awe_poke_dw(AWE_HWCF6, 0x8000);
4055 awe_send_array(init4);
4058 /* send an initialization array */
4060 awe_send_array(unsigned short *data)
4066 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4067 awe_poke(AWE_INIT1(i), *p);
4068 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4069 awe_poke(AWE_INIT2(i), *p);
4070 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4071 awe_poke(AWE_INIT3(i), *p);
4072 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4073 awe_poke(AWE_INIT4(i), *p);
4078 * set up awe32 channels to some known state.
4081 /* set the envelope & LFO parameters to the default values; see ADIP */
4083 awe_tweak_voice(int i)
4085 /* set all mod/vol envelope shape to minimum */
4086 awe_poke(AWE_ENVVOL(i), 0x8000);
4087 awe_poke(AWE_ENVVAL(i), 0x8000);
4088 awe_poke(AWE_DCYSUS(i), 0x7F7F);
4089 awe_poke(AWE_ATKHLDV(i), 0x7F7F);
4090 awe_poke(AWE_ATKHLD(i), 0x7F7F);
4091 awe_poke(AWE_PEFE(i), 0); /* mod envelope height to zero */
4092 awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */
4093 awe_poke(AWE_LFO2VAL(i), 0x8000);
4094 awe_poke(AWE_IP(i), 0xE000); /* no pitch shift */
4095 awe_poke(AWE_IFATN(i), 0xFF00); /* volume to minimum */
4096 awe_poke(AWE_FMMOD(i), 0);
4097 awe_poke(AWE_TREMFRQ(i), 0);
4098 awe_poke(AWE_FM2FRQ2(i), 0);
4105 /* reset all channels */
4106 for (i = 0; i < awe_max_voices; i++)
4112 * initializes the FM section of AWE32;
4113 * see Vince Vu's unofficial AWE32 programming guide
4119 #ifndef AWE_ALWAYS_INIT_FM
4120 /* if no extended memory is on board.. */
4121 if (awe_mem_size <= 0)
4124 AWE_DEBUG(3,printk("AWE32: initializing FM\n"));
4126 /* Initialize the last two channels for DRAM refresh and producing
4127 the reverb and chorus effects for Yamaha OPL-3 synthesizer */
4129 /* 31: FM left channel, 0xffffe0-0xffffe8 */
4130 awe_poke(AWE_DCYSUSV(30), 0x80);
4131 awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */
4132 awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 |
4133 (DEF_FM_CHORUS_DEPTH << 24));
4134 awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8));
4135 awe_poke_dw(AWE_CPF(30), 0);
4136 awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3);
4138 /* 32: FM right channel, 0xfffff0-0xfffff8 */
4139 awe_poke(AWE_DCYSUSV(31), 0x80);
4140 awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */
4141 awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 |
4142 (DEF_FM_CHORUS_DEPTH << 24));
4143 awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8));
4144 awe_poke_dw(AWE_CPF(31), 0x8000);
4145 awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3);
4147 /* skew volume & cutoff */
4148 awe_poke_dw(AWE_VTFT(30), 0x8000FFFF);
4149 awe_poke_dw(AWE_VTFT(31), 0x8000FFFF);
4151 voices[30].state = AWE_ST_FM;
4152 voices[31].state = AWE_ST_FM;
4154 /* change maximum channels to 30 */
4155 awe_max_voices = AWE_NORMAL_VOICES;
4156 if (playing_mode == AWE_PLAY_DIRECT)
4157 awe_info.nr_voices = awe_max_voices;
4159 awe_info.nr_voices = AWE_MAX_CHANNELS;
4160 voice_alloc->max_voice = awe_max_voices;
4164 * AWE32 DRAM access routines
4167 /* open DRAM write accessing mode */
4169 awe_open_dram_for_write(int offset, int channels)
4171 int vidx[AWE_NORMAL_VOICES];
4174 if (channels < 0 || channels >= AWE_NORMAL_VOICES) {
4175 channels = AWE_NORMAL_VOICES;
4176 for (i = 0; i < AWE_NORMAL_VOICES; i++)
4179 for (i = 0; i < channels; i++)
4180 vidx[i] = awe_clear_voice();
4183 /* use all channels for DMA transfer */
4184 for (i = 0; i < channels; i++) {
4185 if (vidx[i] < 0) continue;
4186 awe_poke(AWE_DCYSUSV(vidx[i]), 0x80);
4187 awe_poke_dw(AWE_VTFT(vidx[i]), 0);
4188 awe_poke_dw(AWE_CVCF(vidx[i]), 0);
4189 awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000);
4190 awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000);
4191 awe_poke_dw(AWE_PSST(vidx[i]), 0);
4192 awe_poke_dw(AWE_CSL(vidx[i]), 0);
4193 awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000);
4194 voices[vidx[i]].state = AWE_ST_DRAM;
4196 /* point channels 31 & 32 to ROM samples for DRAM refresh */
4197 awe_poke_dw(AWE_VTFT(30), 0);
4198 awe_poke_dw(AWE_PSST(30), 0x1d8);
4199 awe_poke_dw(AWE_CSL(30), 0x1e0);
4200 awe_poke_dw(AWE_CCCA(30), 0x1d8);
4201 awe_poke_dw(AWE_VTFT(31), 0);
4202 awe_poke_dw(AWE_PSST(31), 0x1d8);
4203 awe_poke_dw(AWE_CSL(31), 0x1e0);
4204 awe_poke_dw(AWE_CCCA(31), 0x1d8);
4205 voices[30].state = AWE_ST_FM;
4206 voices[31].state = AWE_ST_FM;
4208 /* if full bit is on, not ready to write on */
4209 if (awe_peek_dw(AWE_SMALW) & 0x80000000) {
4210 for (i = 0; i < channels; i++) {
4211 awe_poke_dw(AWE_CCCA(vidx[i]), 0);
4212 voices[i].state = AWE_ST_OFF;
4214 return RET_ERROR(ENOSPC);
4217 /* set address to write */
4218 awe_poke_dw(AWE_SMALW, offset);
4223 /* open DRAM for RAM size detection */
4225 awe_open_dram_for_check(void)
4228 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4229 awe_poke(AWE_DCYSUSV(i), 0x80);
4230 awe_poke_dw(AWE_VTFT(i), 0);
4231 awe_poke_dw(AWE_CVCF(i), 0);
4232 awe_poke_dw(AWE_PTRX(i), 0x40000000);
4233 awe_poke_dw(AWE_CPF(i), 0x40000000);
4234 awe_poke_dw(AWE_PSST(i), 0);
4235 awe_poke_dw(AWE_CSL(i), 0);
4236 if (i & 1) /* DMA write */
4237 awe_poke_dw(AWE_CCCA(i), 0x06000000);
4239 awe_poke_dw(AWE_CCCA(i), 0x04000000);
4240 voices[i].state = AWE_ST_DRAM;
4245 /* close dram access */
4247 awe_close_dram(void)
4250 /* wait until FULL bit in SMAxW register be false */
4251 for (i = 0; i < 10000; i++) {
4252 if (!(awe_peek_dw(AWE_SMALW) & 0x80000000))
4257 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4258 if (voices[i].state == AWE_ST_DRAM) {
4259 awe_poke_dw(AWE_CCCA(i), 0);
4260 awe_poke(AWE_DCYSUSV(i), 0x807F);
4261 voices[i].state = AWE_ST_OFF;
4267 /*================================================================
4268 * detect presence of AWE32 and check memory size
4269 *================================================================*/
4271 /* detect emu8000 chip on the specified address; from VV's guide */
4274 awe_detect_base(int addr)
4277 if ((awe_peek(AWE_U1) & 0x000F) != 0x000C)
4279 if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058)
4281 if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003)
4283 AWE_DEBUG(0,printk("AWE32 found at %x\n", awe_base));
4291 if (awe_base == 0) {
4292 for (base = 0x620; base <= 0x680; base += 0x20)
4293 if (awe_detect_base(base))
4295 AWE_DEBUG(0,printk("AWE32 not found\n"));
4302 /*================================================================
4303 * check dram size on AWE board
4304 *================================================================*/
4306 /* any three numbers you like */
4307 #define UNIQUE_ID1 0x1234
4308 #define UNIQUE_ID2 0x4321
4309 #define UNIQUE_ID3 0xFFFF
4312 awe_check_dram(void)
4314 if (awe_mem_size > 0) {
4315 awe_mem_size *= 1024; /* convert to Kbytes */
4316 return awe_mem_size;
4319 awe_open_dram_for_check();
4323 /* set up unique two id numbers */
4324 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET);
4325 awe_poke(AWE_SMLD, UNIQUE_ID1);
4326 awe_poke(AWE_SMLD, UNIQUE_ID2);
4328 while (awe_mem_size < AWE_MAX_DRAM_SIZE) {
4330 /* read a data on the DRAM start address */
4331 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET);
4332 awe_peek(AWE_SMLD); /* discard stale data */
4333 if (awe_peek(AWE_SMLD) != UNIQUE_ID1)
4335 if (awe_peek(AWE_SMLD) != UNIQUE_ID2)
4337 awe_mem_size += 32; /* increment 32 Kbytes */
4338 /* Write a unique data on the test address;
4339 * if the address is out of range, the data is written on
4340 * 0x200000(=AWE_DRAM_OFFSET). Then the two id words are
4341 * broken by this data.
4343 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + awe_mem_size*512L);
4344 awe_poke(AWE_SMLD, UNIQUE_ID3);
4346 /* read a data on the just written DRAM address */
4347 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + awe_mem_size*512L);
4348 awe_peek(AWE_SMLD); /* discard stale data */
4349 if (awe_peek(AWE_SMLD) != UNIQUE_ID3)
4354 AWE_DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", awe_mem_size));
4356 /* convert to Kbytes */
4357 awe_mem_size *= 1024;
4358 return awe_mem_size;
4362 /*================================================================
4363 * chorus and reverb controls; from VV's guide
4364 *================================================================*/
4366 /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
4367 static char chorus_defined[AWE_CHORUS_NUMBERS];
4368 static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = {
4369 {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
4370 {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
4371 {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
4372 {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
4373 {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
4374 {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
4375 {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */
4376 {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */
4380 awe_load_chorus_fx(awe_patch_info *patch, const char *addr, int count)
4382 if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) {
4383 printk("AWE32 Error: illegal chorus mode %d for uploading\n", patch->optarg);
4384 return RET_ERROR(EINVAL);
4386 if (count < sizeof(awe_chorus_fx_rec)) {
4387 printk("AWE32 Error: too short chorus fx parameters\n");
4388 return RET_ERROR(EINVAL);
4390 COPY_FROM_USER(&chorus_parm[patch->optarg], addr, AWE_PATCH_INFO_SIZE,
4391 sizeof(awe_chorus_fx_rec));
4392 chorus_defined[patch->optarg] = TRUE;
4397 awe_set_chorus_mode(int effect)
4399 if (effect < 0 || effect >= AWE_CHORUS_NUMBERS ||
4400 (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect]))
4402 awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback);
4403 awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset);
4404 awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth);
4405 awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay);
4406 awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq);
4407 awe_poke_dw(AWE_HWCF6, 0x8000);
4408 awe_poke_dw(AWE_HWCF7, 0x0000);
4409 chorus_mode = effect;
4412 /*----------------------------------------------------------------*/
4414 /* reverb mode settings; write the following 28 data of 16 bit length
4415 * on the corresponding ports in the reverb_cmds array
4417 static char reverb_defined[AWE_CHORUS_NUMBERS];
4418 static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = {
4420 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
4421 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
4422 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4423 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4426 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4427 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4428 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4429 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4432 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4433 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
4434 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
4435 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
4438 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4439 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4440 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
4441 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
4444 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
4445 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
4446 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4447 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4450 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
4451 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
4452 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4453 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4456 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
4457 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4458 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4459 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4461 {{ /* panning delay */
4462 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
4463 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4464 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4465 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4469 static struct ReverbCmdPair {
4470 unsigned short cmd, port;
4471 } reverb_cmds[28] = {
4472 {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
4473 {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
4474 {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
4475 {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
4476 {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
4477 {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
4478 {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
4482 awe_load_reverb_fx(awe_patch_info *patch, const char *addr, int count)
4484 if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) {
4485 printk("AWE32 Error: illegal reverb mode %d for uploading\n", patch->optarg);
4486 return RET_ERROR(EINVAL);
4488 if (count < sizeof(awe_reverb_fx_rec)) {
4489 printk("AWE32 Error: too short reverb fx parameters\n");
4490 return RET_ERROR(EINVAL);
4492 COPY_FROM_USER(&reverb_parm[patch->optarg], addr, AWE_PATCH_INFO_SIZE,
4493 sizeof(awe_reverb_fx_rec));
4494 reverb_defined[patch->optarg] = TRUE;
4499 awe_set_reverb_mode(int effect)
4502 if (effect < 0 || effect >= AWE_REVERB_NUMBERS ||
4503 (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect]))
4505 for (i = 0; i < 28; i++)
4506 awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port,
4507 reverb_parm[effect].parms[i]);
4508 reverb_mode = effect;
4511 /*================================================================
4512 * treble/bass equalizer control
4513 *================================================================*/
4515 static unsigned short bass_parm[12][3] = {
4516 {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
4517 {0xD25B, 0xD35B, 0x0000}, /* -8 */
4518 {0xD24C, 0xD34C, 0x0000}, /* -6 */
4519 {0xD23D, 0xD33D, 0x0000}, /* -4 */
4520 {0xD21F, 0xD31F, 0x0000}, /* -2 */
4521 {0xC208, 0xC308, 0x0001}, /* 0 (HW default) */
4522 {0xC219, 0xC319, 0x0001}, /* +2 */
4523 {0xC22A, 0xC32A, 0x0001}, /* +4 */
4524 {0xC24C, 0xC34C, 0x0001}, /* +6 */
4525 {0xC26E, 0xC36E, 0x0001}, /* +8 */
4526 {0xC248, 0xC348, 0x0002}, /* +10 */
4527 {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
4530 static unsigned short treble_parm[12][9] = {
4531 {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
4532 {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4533 {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4534 {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4535 {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4536 {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
4537 {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
4538 {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
4539 {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
4540 {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
4541 {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
4542 {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */
4547 * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
4550 awe_equalizer(int bass, int treble)
4554 if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
4556 awe_bass_level = bass;
4557 awe_treble_level = treble;
4558 awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]);
4559 awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]);
4560 awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]);
4561 awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]);
4562 awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]);
4563 awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]);
4564 awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]);
4565 awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]);
4566 awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]);
4567 awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]);
4568 w = bass_parm[bass][2] + treble_parm[treble][8];
4569 awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262));
4570 awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362));
4574 #endif /* CONFIG_AWE32_SYNTH */