4 * The low level driver for the AWE32/Sound Blaster 32 wave table synth.
5 * version 0.4.2c; Oct. 7, 1997
7 * Copyright (C) 1996,1997 Takashi Iwai
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * $DragonFly: src/sys/i386/gnu/isa/sound/Attic/awe_wave.c,v 1.4 2004/12/08 20:36:39 joerg Exp $
26 #include "opt_depricated.h"
27 #ifndef I_WANT_DEPRICATED_STUFF
28 #error "Add options I_WANT_DEPRICATED_STUFF to your kernel config and send a mail to kernel@"
33 #if defined(__DragonFly__) || defined(__FreeBSD__)
34 # include "awe_config.h"
36 # include "awe_config.h"
39 /*----------------------------------------------------------------*/
41 #ifdef CONFIG_AWE32_SYNTH
43 #if defined(__DragonFly__) || defined(__FreeBSD__)
45 # include "awe_version.h"
46 # include "awe_voice.h"
49 # include "awe_version.h"
50 # include "awe_voice.h"
53 #ifdef AWE_HAS_GUS_COMPATIBILITY
54 /* include finetune table */
56 #if defined(__DragonFly__) || defined(__FreeBSD__)
57 # ifdef AWE_OBSOLETE_VOXWARE
60 # include <i386/isa/sound/tuning.h>
62 # ifdef AWE_OBSOLETE_VOXWARE
65 # include "../tuning.h"
70 # include <linux/ultrasound.h>
71 #elif defined(__DragonFly__) || defined(__FreeBSD__)
72 # include <machine/ultrasound.h>
75 #endif /* AWE_HAS_GUS_COMPATIBILITY */
78 /*----------------------------------------------------------------
80 *----------------------------------------------------------------*/
82 static int debug_mode = 0;
84 #define AWE_DEBUG(LVL,XXX) {if (debug_mode > LVL) { XXX; }}
85 #define ERRMSG(XXX) {if (debug_mode) { XXX; }}
86 #define FATALERR(XXX) XXX
88 #define AWE_DEBUG(LVL,XXX) /**/
89 #define ERRMSG(XXX) XXX
90 #define FATALERR(XXX) XXX
93 /*----------------------------------------------------------------
94 * bank and voice record
95 *----------------------------------------------------------------*/
97 /* soundfont record */
98 typedef struct _sf_list {
101 int num_info; /* current info table index */
102 int num_sample; /* current sample table index */
103 int mem_ptr; /* current word byte pointer */
106 /*char name[AWE_PATCH_NAME_LEN];*/
110 typedef struct _awe_voice_list {
111 int next; /* linked list with same sf_id */
112 unsigned char bank, instr; /* preset number information */
113 char type, disabled; /* type=normal/mapped, disabled=boolean */
114 awe_voice_info v; /* voice information */
115 int next_instr; /* preset table list */
116 int next_bank; /* preset table list */
119 /* voice list type */
120 #define V_ST_NORMAL 0
121 #define V_ST_MAPPED 1
123 typedef struct _awe_sample_list {
124 int next; /* linked list with same sf_id */
125 awe_sample_info v; /* sample information */
128 /* sample and information table */
129 static int current_sf_id = 0;
130 static int locked_sf_id = 0;
132 static sf_list *sflists = NULL;
134 #define awe_free_mem_ptr() (current_sf_id <= 0 ? 0 : sflists[current_sf_id-1].mem_ptr)
135 #define awe_free_info() (current_sf_id <= 0 ? 0 : sflists[current_sf_id-1].num_info)
136 #define awe_free_sample() (current_sf_id <= 0 ? 0 : sflists[current_sf_id-1].num_sample)
138 static int max_samples;
139 static awe_sample_list *samples = NULL;
141 static int max_infos;
142 static awe_voice_list *infos = NULL;
145 #define AWE_MAX_PRESETS 256
146 #define AWE_DEFAULT_PRESET 0
147 #define AWE_DEFAULT_BANK 0
148 #define AWE_DEFAULT_DRUM 0
149 #define AWE_DRUM_BANK 128
151 #define MAX_LAYERS AWE_MAX_VOICES
153 /* preset table index */
154 static int preset_table[AWE_MAX_PRESETS];
156 /*----------------------------------------------------------------
158 *----------------------------------------------------------------*/
161 typedef struct FX_Rec { /* channel effects */
162 unsigned char flags[AWE_FX_END];
163 short val[AWE_FX_END];
167 /* channel parameters */
168 typedef struct _awe_chan_info {
169 int channel; /* channel number */
170 int bank; /* current tone bank */
171 int instr; /* current program */
172 int bender; /* midi pitchbend (-8192 - 8192) */
173 int bender_range; /* midi bender range (x100) */
174 int panning; /* panning (0-127) */
175 int main_vol; /* channel volume (0-127) */
176 int expression_vol; /* midi expression (0-127) */
177 int chan_press; /* channel pressure */
178 int vrec; /* instrument list */
179 int def_vrec; /* default instrument list */
180 int sustained; /* sustain status in MIDI */
181 FX_Rec fx; /* effects */
182 FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */
185 /* voice parameters */
186 typedef struct _voice_info {
188 #define AWE_ST_OFF (1<<0) /* no sound */
189 #define AWE_ST_ON (1<<1) /* playing */
190 #define AWE_ST_STANDBY (1<<2) /* stand by for playing */
191 #define AWE_ST_SUSTAINED (1<<3) /* sustained */
192 #define AWE_ST_MARK (1<<4) /* marked for allocation */
193 #define AWE_ST_DRAM (1<<5) /* DRAM read/write */
194 #define AWE_ST_FM (1<<6) /* reserved for FM */
195 #define AWE_ST_RELEASED (1<<7) /* released */
197 int ch; /* midi channel */
198 int key; /* internal key for search */
199 int layer; /* layer number (for channel mode only) */
200 int time; /* allocated time */
201 awe_chan_info *cinfo; /* channel info */
203 int note; /* midi key (0-127) */
204 int velocity; /* midi velocity (0-127) */
205 int sostenuto; /* sostenuto on/off */
206 awe_voice_info *sample; /* assigned voice */
208 /* EMU8000 parameters */
209 int apitch; /* pitch parameter */
210 int avol; /* volume parameter */
211 int apan; /* panning parameter */
214 /* voice information */
215 static voice_info *voices;
217 #define IS_NO_SOUND(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED))
218 #define IS_NO_EFFECT(v) (voices[v].state != AWE_ST_ON)
219 #define IS_PLAYING(v) (voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED))
220 #define IS_EMPTY(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM))
223 /* MIDI channel effects information (for hw control) */
224 static awe_chan_info *channels;
227 /*----------------------------------------------------------------
229 *----------------------------------------------------------------*/
231 #ifndef AWE_DEFAULT_BASE_ADDR
232 #define AWE_DEFAULT_BASE_ADDR 0 /* autodetect */
235 #ifndef AWE_DEFAULT_MEM_SIZE
236 #define AWE_DEFAULT_MEM_SIZE 0 /* autodetect */
239 /* awe32 base address (overwritten at initialization) */
240 static int awe_base = AWE_DEFAULT_BASE_ADDR;
241 /* memory byte size */
242 static int awe_mem_size = AWE_DEFAULT_MEM_SIZE;
243 /* DRAM start offset */
244 static int awe_mem_start = AWE_DRAM_OFFSET;
246 /* maximum channels for playing */
247 static int awe_max_voices = AWE_MAX_VOICES;
249 static int patch_opened = 0; /* sample already loaded? */
251 static int reverb_mode = 4; /* reverb mode */
252 static int chorus_mode = 2; /* chorus mode */
253 static short init_atten = AWE_DEFAULT_ATTENUATION; /* 12dB below */
255 static int awe_present = FALSE; /* awe device present? */
256 static int awe_busy = FALSE; /* awe device opened? */
258 #define DEFAULT_DRUM_FLAGS ((1 << 9) | (1 << 25))
259 #define IS_DRUM_CHANNEL(c) (drum_flags & (1 << (c)))
260 #define DRUM_CHANNEL_ON(c) (drum_flags |= (1 << (c)))
261 #define DRUM_CHANNEL_OFF(c) (drum_flags &= ~(1 << (c)))
262 static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */
264 static int playing_mode = AWE_PLAY_INDIRECT;
265 #define SINGLE_LAYER_MODE() (playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT)
266 #define MULTI_LAYER_MODE() (playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2)
268 static int current_alloc_time = 0; /* voice allocation index for channel mode */
270 static struct MiscModeDef {
273 } misc_modes_default[AWE_MD_END] = {
274 {0,0}, {0,0}, /* <-- not used */
275 {AWE_VERSION_NUMBER, FALSE},
276 {TRUE, TRUE}, /* exclusive */
277 {TRUE, TRUE}, /* realpan */
278 {AWE_DEFAULT_BANK, TRUE}, /* gusbank */
279 {FALSE, TRUE}, /* keep effect */
280 {AWE_DEFAULT_ATTENUATION, FALSE}, /* zero_atten */
281 {FALSE, TRUE}, /* chn_prior */
282 {AWE_DEFAULT_MOD_SENSE, TRUE}, /* modwheel sense */
283 {AWE_DEFAULT_PRESET, TRUE}, /* def_preset */
284 {AWE_DEFAULT_BANK, TRUE}, /* def_bank */
285 {AWE_DEFAULT_DRUM, TRUE}, /* def_drum */
286 {FALSE, TRUE}, /* toggle_drum_bank */
289 static int misc_modes[AWE_MD_END];
291 static int awe_bass_level = 5;
292 static int awe_treble_level = 9;
295 static struct synth_info awe_info = {
296 "AWE32 Synth", /* name */
298 SYNTH_TYPE_SAMPLE, /* synth_type */
299 SAMPLE_TYPE_AWE32, /* synth_subtype */
300 0, /* perc_mode (obsolete) */
301 AWE_MAX_VOICES, /* nr_voices */
302 0, /* nr_drums (obsolete) */
303 AWE_MAX_INFOS /* instr_bank_size */
307 static struct voice_alloc_info *voice_alloc; /* set at initialization */
310 /*----------------------------------------------------------------
311 * function prototypes
312 *----------------------------------------------------------------*/
314 #if defined(linux) && !defined(AWE_OBSOLETE_VOXWARE)
315 static int awe_check_port(void);
316 static void awe_request_region(void);
317 static void awe_release_region(void);
320 static void awe_reset_samples(void);
321 /* emu8000 chip i/o access */
322 static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);
323 static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);
324 static unsigned short awe_peek(unsigned short cmd, unsigned short port);
325 static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);
326 static void awe_wait(unsigned short delay);
328 /* initialize emu8000 chip */
329 static void awe_initialize(void);
331 /* set voice parameters */
332 static void awe_init_misc_modes(int init_all);
333 static void awe_init_voice_info(awe_voice_info *vp);
334 static void awe_init_voice_parm(awe_voice_parm *pp);
335 #ifdef AWE_HAS_GUS_COMPATIBILITY
336 static int freq_to_note(int freq);
337 static int calc_rate_offset(int Hz);
338 /*static int calc_parm_delay(int msec);*/
339 static int calc_parm_hold(int msec);
340 static int calc_parm_attack(int msec);
341 static int calc_parm_decay(int msec);
342 static int calc_parm_search(int msec, short *table);
345 /* turn on/off note */
346 static void awe_note_on(int voice);
347 static void awe_note_off(int voice);
348 static void awe_terminate(int voice);
349 static void awe_exclusive_off(int voice);
350 static void awe_note_off_all(int do_sustain);
352 /* calculate voice parameters */
353 typedef void (*fx_affect_func)(int voice, int forced);
354 static void awe_set_pitch(int voice, int forced);
355 static void awe_set_voice_pitch(int voice, int forced);
356 static void awe_set_volume(int voice, int forced);
357 static void awe_set_voice_vol(int voice, int forced);
358 static void awe_set_pan(int voice, int forced);
359 static void awe_fx_fmmod(int voice, int forced);
360 static void awe_fx_tremfrq(int voice, int forced);
361 static void awe_fx_fm2frq2(int voice, int forced);
362 static void awe_fx_filterQ(int voice, int forced);
363 static void awe_calc_pitch(int voice);
364 #ifdef AWE_HAS_GUS_COMPATIBILITY
365 static void awe_calc_pitch_from_freq(int voice, int freq);
367 static void awe_calc_volume(int voice);
368 static void awe_voice_init(int voice, int init_all);
369 static void awe_channel_init(int ch, int init_all);
370 static void awe_fx_init(int ch);
372 /* sequencer interface */
373 static int awe_open(int dev, int mode);
374 static void awe_close(int dev);
375 static int awe_ioctl(int dev, unsigned int cmd, caddr_t arg);
376 static int awe_kill_note(int dev, int voice, int note, int velocity);
377 static int awe_start_note(int dev, int v, int note_num, int volume);
378 static int awe_set_instr(int dev, int voice, int instr_no);
379 static int awe_set_instr_2(int dev, int voice, int instr_no);
380 static void awe_reset(int dev);
381 static void awe_hw_control(int dev, unsigned char *event);
382 static int awe_load_patch(int dev, int format, const char *addr,
383 int offs, int count, int pmgr_flag);
384 static void awe_aftertouch(int dev, int voice, int pressure);
385 static void awe_controller(int dev, int voice, int ctrl_num, int value);
386 static void awe_panning(int dev, int voice, int value);
387 static void awe_volume_method(int dev, int mode);
388 #ifndef AWE_NO_PATCHMGR
389 static int awe_patchmgr(int dev, struct patmgr_info *rec);
391 static void awe_bender(int dev, int voice, int value);
392 static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc);
393 static void awe_setup_voice(int dev, int voice, int chn);
395 /* hardware controls */
396 #ifdef AWE_HAS_GUS_COMPATIBILITY
397 static void awe_hw_gus_control(int dev, int cmd, unsigned char *event);
399 static void awe_hw_awe_control(int dev, int cmd, unsigned char *event);
400 static void awe_voice_change(int voice, fx_affect_func func);
401 static void awe_sostenuto_on(int voice, int forced);
402 static void awe_sustain_off(int voice, int forced);
403 static void awe_terminate_and_init(int voice, int forced);
406 static int awe_search_instr(int bank, int preset);
407 static int awe_search_multi_voices(int rec, int note, int velocity, awe_voice_info **vlist);
408 static void awe_alloc_multi_voices(int ch, int note, int velocity, int key);
409 static void awe_alloc_one_voice(int voice, int note, int velocity);
410 static int awe_clear_voice(void);
412 /* load / remove patches */
413 static int awe_open_patch(awe_patch_info *patch, const char *addr, int count);
414 static int awe_close_patch(awe_patch_info *patch, const char *addr, int count);
415 static int awe_unload_patch(awe_patch_info *patch, const char *addr, int count);
416 static int awe_load_info(awe_patch_info *patch, const char *addr, int count);
417 static int awe_load_data(awe_patch_info *patch, const char *addr, int count);
418 static int awe_replace_data(awe_patch_info *patch, const char *addr, int count);
419 static int awe_load_map(awe_patch_info *patch, const char *addr, int count);
420 #ifdef AWE_HAS_GUS_COMPATIBILITY
421 static int awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag);
423 static int check_patch_opened(int type, char *name);
424 static int awe_write_wave_data(const char *addr, int offset, awe_sample_info *sp, int channels);
425 static void add_sf_info(int rec);
426 static void add_sf_sample(int rec);
427 static void purge_old_list(int rec, int next);
428 static void add_info_list(int rec);
429 static void awe_remove_samples(int sf_id);
430 static void rebuild_preset_list(void);
431 static short awe_set_sample(awe_voice_info *vp);
433 /* lowlevel functions */
434 static void awe_init_audio(void);
435 static void awe_init_dma(void);
436 static void awe_init_array(void);
437 static void awe_send_array(unsigned short *data);
438 static void awe_tweak_voice(int voice);
439 static void awe_tweak(void);
440 static void awe_init_fm(void);
441 static int awe_open_dram_for_write(int offset, int channels);
442 static void awe_open_dram_for_check(void);
443 static void awe_close_dram(void);
444 static void awe_write_dram(unsigned short c);
445 static int awe_detect_base(int addr);
446 static int awe_detect(void);
447 static int awe_check_dram(void);
448 static int awe_load_chorus_fx(awe_patch_info *patch, const char *addr, int count);
449 static void awe_set_chorus_mode(int mode);
450 static int awe_load_reverb_fx(awe_patch_info *patch, const char *addr, int count);
451 static void awe_set_reverb_mode(int mode);
452 static void awe_equalizer(int bass, int treble);
453 #ifdef CONFIG_AWE32_MIXER
454 static int awe_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg);
457 /* define macros for compatibility */
458 #if defined(__DragonFly__) || defined(__FreeBSD__)
459 # include "awe_compat.h"
461 # include "awe_compat.h"
464 /*----------------------------------------------------------------
465 * synth operation table
466 *----------------------------------------------------------------*/
468 static struct synth_operations awe_operations =
490 #ifndef AWE_NO_PATCHMGR
498 #ifdef CONFIG_AWE32_MIXER
499 static struct mixer_operations awe_mixer_operations = {
500 #if !defined(__DragonFly__) && !defined(__FreeBSD__)
509 /*================================================================
510 * attach / unload interface
511 *================================================================*/
513 #ifdef AWE_OBSOLETE_VOXWARE
514 #define ATTACH_DECL static
516 #define ATTACH_DECL /**/
519 #if (defined(__DragonFly__) || defined(__FreeBSD__)) && !defined(AWE_OBSOLETE_VOXWARE)
521 void attach_awe(struct address_info *hw_config)
523 # define ATTACH_RET ret
530 /* check presence of AWE32 card */
531 if (! awe_detect()) {
532 printk("AWE32: not detected\n");
536 /* check AWE32 ports are available */
537 if (awe_check_port()) {
538 printk("AWE32: I/O area already used.\n");
542 /* set buffers to NULL */
549 /* voice & channel info */
550 voices = (voice_info*)my_malloc(AWE_MAX_VOICES * sizeof(voice_info));
551 channels = (awe_chan_info*)my_malloc(AWE_MAX_CHANNELS * sizeof(awe_chan_info));
553 if (voices == NULL || channels == NULL) {
556 printk("AWE32: can't allocate sample tables\n");
560 /* allocate sample tables */
561 INIT_TABLE(sflists, max_sfs, AWE_MAX_SF_LISTS, sf_list);
562 INIT_TABLE(samples, max_samples, AWE_MAX_SAMPLES, awe_sample_list);
563 INIT_TABLE(infos, max_infos, AWE_MAX_INFOS, awe_voice_list);
565 if (num_synths >= MAX_SYNTH_DEV)
566 printk("AWE32 Error: too many synthesizers\n");
568 voice_alloc = &awe_operations.alloc;
569 voice_alloc->max_voice = awe_max_voices;
570 synth_devs[num_synths++] = &awe_operations;
573 #ifdef CONFIG_AWE32_MIXER
574 if (num_mixers < MAX_MIXER_DEV) {
575 mixer_devs[num_mixers++] = &awe_mixer_operations;
579 /* reserve I/O ports for awedrv */
580 awe_request_region();
582 /* clear all samples */
585 /* intialize AWE32 hardware */
588 snprintf(awe_info.name, sizeof(awe_info.name), "AWE32-%s (RAM%dk)",
589 AWEDRV_VERSION, awe_mem_size/1024);
590 #if defined(__DragonFly__) || defined(__FreeBSD__)
591 printk("awe0: <SoundBlaster EMU8000 MIDI (RAM%dk)>", awe_mem_size/1024);
592 #elif defined(AWE_DEBUG_ON)
593 printk("%s\n", awe_info.name);
596 /* set default values */
597 awe_init_misc_modes(TRUE);
599 /* set reverb & chorus modes */
600 awe_set_reverb_mode(reverb_mode);
601 awe_set_chorus_mode(chorus_mode);
610 #ifdef AWE_DYNAMIC_BUFFER
611 static void free_tables(void)
614 sflists = NULL; max_sfs = 0;
616 samples = NULL; max_samples = 0;
618 infos = NULL; max_infos = 0;
621 #define free_buffers() /**/
627 void unload_awe(void)
631 awe_release_region();
641 /*----------------------------------------------------------------
643 *----------------------------------------------------------------*/
645 #ifdef AWE_OBSOLETE_VOXWARE
647 #if defined(__DragonFly__) || defined(__FreeBSD__)
648 long attach_awe_obsolete(long mem_start, struct address_info *hw_config)
650 int attach_awe_obsolete(int mem_start, struct address_info *hw_config)
653 my_malloc_init(mem_start);
656 return my_malloc_memptr();
659 int probe_awe_obsolete(struct address_info *hw_config)
662 /*return awe_detect();*/
666 #if defined(__DragonFly__) || defined(__FreeBSD__ )
667 int probe_awe(struct address_info *hw_config)
672 #endif /* AWE_OBSOLETE_VOXWARE */
675 /*================================================================
676 * clear sample tables
677 *================================================================*/
680 awe_reset_samples(void)
684 /* free all bank tables */
685 for (i = 0; i < AWE_MAX_PRESETS; i++)
686 preset_table[i] = -1;
696 /*================================================================
697 * EMU register access
698 *================================================================*/
700 /* select a given AWE32 pointer */
701 static int awe_cur_cmd = -1;
702 #define awe_set_cmd(cmd) \
703 if (awe_cur_cmd != cmd) { OUTW(cmd, awe_base + 0x802); awe_cur_cmd = cmd; }
704 #define awe_port(port) (awe_base - 0x620 + port)
706 /* write 16bit data */
708 awe_poke(unsigned short cmd, unsigned short port, unsigned short data)
711 OUTW(data, awe_port(port));
714 /* write 32bit data */
716 awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data)
719 OUTW(data, awe_port(port)); /* write lower 16 bits */
720 OUTW(data >> 16, awe_port(port)+2); /* write higher 16 bits */
723 /* read 16bit data */
724 INLINE static unsigned short
725 awe_peek(unsigned short cmd, unsigned short port)
729 k = inw(awe_port(port));
733 /* read 32bit data */
734 INLINE static unsigned int
735 awe_peek_dw(unsigned short cmd, unsigned short port)
739 k1 = inw(awe_port(port));
740 k2 = inw(awe_port(port)+2);
745 /* wait delay number of AWE32 44100Hz clocks */
747 awe_wait(unsigned short delay)
749 unsigned short clock, target;
750 unsigned short port = awe_port(AWE_WC_Port);
754 awe_set_cmd(AWE_WC_Cmd);
755 clock = (unsigned short)inw(port);
756 target = clock + delay;
758 if (target < clock) {
759 for (; (unsigned short)inw(port) > target; counter++)
763 for (; (unsigned short)inw(port) < target; counter++)
768 /* write a word data */
770 awe_write_dram(unsigned short c)
772 awe_poke(AWE_SMLD, c);
776 #if defined(linux) && !defined(AWE_OBSOLETE_VOXWARE)
778 /*================================================================
779 * port check / request
780 * 0x620-622, 0xA20-A22, 0xE20-E22
781 *================================================================*/
786 return (check_region(awe_port(Data0), 4) ||
787 check_region(awe_port(Data1), 4) ||
788 check_region(awe_port(Data3), 4));
792 awe_request_region(void)
794 request_region(awe_port(Data0), 4, "sound driver (AWE32)");
795 request_region(awe_port(Data1), 4, "sound driver (AWE32)");
796 request_region(awe_port(Data3), 4, "sound driver (AWE32)");
800 awe_release_region(void)
802 release_region(awe_port(Data0), 4);
803 release_region(awe_port(Data1), 4);
804 release_region(awe_port(Data3), 4);
807 #endif /* !AWE_OBSOLETE_VOXWARE */
810 /*================================================================
811 * AWE32 initialization
812 *================================================================*/
816 AWE_DEBUG(0,printk("AWE32: initializing..\n"));
818 /* initialize hardware configuration */
819 awe_poke(AWE_HWCF1, 0x0059);
820 awe_poke(AWE_HWCF2, 0x0020);
822 /* disable audio; this seems to reduce a clicking noise a bit.. */
823 awe_poke(AWE_HWCF3, 0);
825 /* initialize audio channels */
831 /* initialize init array */
834 /* check DRAM memory size */
835 awe_mem_size = awe_check_dram();
837 /* initialize the FM section of the AWE32 */
840 /* set up voice envelopes */
844 awe_poke(AWE_HWCF3, 0x0004);
851 /*================================================================
852 * AWE32 voice parameters
853 *================================================================*/
855 /* initialize voice_info record */
857 awe_init_voice_info(awe_voice_info *vp)
859 vp->sf_id = 0; /* normal mode */
880 vp->exclusiveClass = 0;
883 vp->scaleTuning = 100;
885 awe_init_voice_parm(&vp->parm);
888 /* initialize voice_parm record:
889 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
890 * Vibrato and Tremolo effects are zero.
892 * Chorus and Reverb effects are zero.
895 awe_init_voice_parm(awe_voice_parm *pp)
897 pp->moddelay = 0x8000;
898 pp->modatkhld = 0x7f7f;
899 pp->moddcysus = 0x7f7f;
900 pp->modrelease = 0x807f;
904 pp->voldelay = 0x8000;
905 pp->volatkhld = 0x7f7f;
906 pp->voldcysus = 0x7f7f;
907 pp->volrelease = 0x807f;
911 pp->lfo1delay = 0x8000;
912 pp->lfo2delay = 0x8000;
927 #ifdef AWE_HAS_GUS_COMPATIBILITY
929 /* convert frequency mHz to abstract cents (= midi key * 100) */
931 freq_to_note(int mHz)
933 /* abscents = log(mHz/8176) / log(2) * 1200 */
934 unsigned int max_val = (unsigned int)0xffffffff / 10000;
943 return 12799; /* maximum */
947 for (base = 8176 * 2; freq >= base; base *= 2) {
949 if (note >= 128) /* over maximum */
954 /* to avoid overflow... */
956 while (freq > max_val) {
962 freq = freq * times / base;
963 for (i = 0; i < 12; i++) {
964 if (freq < semitone_tuning[i+1])
970 freq = freq * 10000 / semitone_tuning[i];
971 for (i = 0; i < 100; i++) {
972 if (freq < cent_tuning[i+1])
977 return note * 100 + tune;
981 /* convert Hz to AWE32 rate offset:
982 * sample pitch offset for the specified sample rate
983 * rate=44100 is no offset, each 4096 is 1 octave (twice).
984 * eg, when rate is 22050, this offset becomes -4096.
987 calc_rate_offset(int Hz)
989 /* offset = log(Hz / 44100) / log(2) * 4096 */
992 /* maybe smaller than max (44100Hz) */
993 if (Hz <= 0 || Hz >= 44100) return 0;
996 for (freq = Hz * 2; freq < 44100; freq *= 2)
1000 freq = 44100 * 10000 / (freq/2);
1001 for (i = 0; i < 12; i++) {
1002 if (freq < semitone_tuning[i+1])
1006 freq = freq * 10000 / semitone_tuning[i];
1007 for (i = 0; i < 100; i++) {
1008 if (freq < cent_tuning[i+1])
1012 return -base * 4096 / 1200;
1016 /*----------------------------------------------------------------
1017 * convert envelope time parameter to AWE32 raw parameter
1018 *----------------------------------------------------------------*/
1020 /* attack & decay/release time table (msec) */
1021 static short attack_time_tbl[128] = {
1022 32767, 11878, 5939, 3959, 2969, 2375, 1979, 1696, 1484, 1319, 1187, 1079, 989, 913, 848, 791, 742,
1023 698, 659, 625, 593, 565, 539, 516, 494, 475, 456, 439, 424, 409, 395, 383, 371,
1024 359, 344, 330, 316, 302, 290, 277, 266, 255, 244, 233, 224, 214, 205, 196, 188,
1025 180, 173, 165, 158, 152, 145, 139, 133, 127, 122, 117, 112, 107, 103, 98, 94,
1026 90, 86, 83, 79, 76, 73, 69, 67, 64, 61, 58, 56, 54, 51, 49, 47,
1027 45, 43, 41, 39, 38, 36, 35, 33, 32, 30, 29, 28, 27, 25, 24, 23,
1028 22, 21, 20, 20, 19, 18, 17, 16, 16, 15, 14, 14, 13, 13, 12, 11,
1029 11, 10, 10, 10, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 0,
1032 static short decay_time_tbl[128] = {
1033 32767, 32766, 4589, 4400, 4219, 4045, 3879, 3719, 3566, 3419, 3279, 3144, 3014, 2890, 2771, 2657,
1034 2548, 2443, 2343, 2246, 2154, 2065, 1980, 1899, 1820, 1746, 1674, 1605, 1539, 1475, 1415, 1356,
1035 1301, 1247, 1196, 1146, 1099, 1054, 1011, 969, 929, 891, 854, 819, 785, 753, 722, 692,
1036 664, 636, 610, 585, 561, 538, 516, 494, 474, 455, 436, 418, 401, 384, 368, 353,
1037 339, 325, 311, 298, 286, 274, 263, 252, 242, 232, 222, 213, 204, 196, 188, 180,
1038 173, 166, 159, 152, 146, 140, 134, 129, 123, 118, 113, 109, 104, 100, 96, 92,
1039 88, 84, 81, 77, 74, 71, 68, 65, 63, 60, 58, 55, 53, 51, 49, 47,
1040 45, 43, 41, 39, 38, 36, 35, 33, 32, 30, 29, 28, 27, 26, 25, 24,
1045 calc_parm_delay(int msec)
1047 return (0x8000 - msec * 1000 / 725);
1051 /* delay time = 0x8000 - msec/92 */
1053 calc_parm_hold(int msec)
1055 int val = (0x7f * 92 - msec) / 92;
1056 if (val < 1) val = 1;
1057 if (val > 127) val = 127;
1061 /* attack time: search from time table */
1063 calc_parm_attack(int msec)
1065 return calc_parm_search(msec, attack_time_tbl);
1068 /* decay/release time: search from time table */
1070 calc_parm_decay(int msec)
1072 return calc_parm_search(msec, decay_time_tbl);
1075 /* search an index for specified time from given time table */
1077 calc_parm_search(int msec, short *table)
1079 int left = 1, right = 127, mid;
1080 while (left < right) {
1081 mid = (left + right) / 2;
1082 if (msec < (int)table[mid])
1089 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1092 /*================================================================
1094 *================================================================*/
1096 /* set an effect value */
1097 #define FX_FLAG_OFF 0
1098 #define FX_FLAG_SET 1
1099 #define FX_FLAG_ADD 2
1101 #define FX_SET(rec,type,value) \
1102 ((rec)->flags[type] = FX_FLAG_SET, (rec)->val[type] = (value))
1103 #define FX_ADD(rec,type,value) \
1104 ((rec)->flags[type] = FX_FLAG_ADD, (rec)->val[type] = (value))
1105 #define FX_UNSET(rec,type) \
1106 ((rec)->flags[type] = FX_FLAG_OFF, (rec)->val[type] = 0)
1108 /* check the effect value is set */
1109 #define FX_ON(rec,type) ((rec)->flags[type])
1114 static struct PARM_DEFS {
1115 int type; /* byte or word */
1116 int low, high; /* value range */
1117 fx_affect_func realtime; /* realtime paramater change */
1119 {PARM_WORD, 0, 0x8000, NULL}, /* env1 delay */
1120 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 attack */
1121 {PARM_BYTE, 0, 0x7e, NULL}, /* env1 hold */
1122 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 decay */
1123 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 release */
1124 {PARM_BYTE, 0, 0x7f, NULL}, /* env1 sustain */
1125 {PARM_BYTE, 0, 0xff, NULL}, /* env1 pitch */
1126 {PARM_BYTE, 0, 0xff, NULL}, /* env1 cutoff */
1128 {PARM_WORD, 0, 0x8000, NULL}, /* env2 delay */
1129 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 attack */
1130 {PARM_BYTE, 0, 0x7e, NULL}, /* env2 hold */
1131 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 decay */
1132 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 release */
1133 {PARM_BYTE, 0, 0x7f, NULL}, /* env2 sustain */
1135 {PARM_WORD, 0, 0x8000, NULL}, /* lfo1 delay */
1136 {PARM_BYTE, 0, 0xff, awe_fx_tremfrq}, /* lfo1 freq */
1137 {PARM_BYTE, 0, 0x7f, awe_fx_tremfrq}, /* lfo1 volume (positive only)*/
1138 {PARM_BYTE, 0, 0x7f, awe_fx_fmmod}, /* lfo1 pitch (positive only)*/
1139 {PARM_BYTE, 0, 0xff, awe_fx_fmmod}, /* lfo1 cutoff (positive only)*/
1141 {PARM_WORD, 0, 0x8000, NULL}, /* lfo2 delay */
1142 {PARM_BYTE, 0, 0xff, awe_fx_fm2frq2}, /* lfo2 freq */
1143 {PARM_BYTE, 0, 0x7f, awe_fx_fm2frq2}, /* lfo2 pitch (positive only)*/
1145 {PARM_WORD, 0, 0xffff, awe_set_voice_pitch}, /* initial pitch */
1146 {PARM_BYTE, 0, 0xff, NULL}, /* chorus */
1147 {PARM_BYTE, 0, 0xff, NULL}, /* reverb */
1148 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial cutoff */
1149 {PARM_BYTE, 0, 15, awe_fx_filterQ}, /* initial resonance */
1151 {PARM_WORD, 0, 0xffff, NULL}, /* sample start */
1152 {PARM_WORD, 0, 0xffff, NULL}, /* loop start */
1153 {PARM_WORD, 0, 0xffff, NULL}, /* loop end */
1154 {PARM_WORD, 0, 0xffff, NULL}, /* coarse sample start */
1155 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop start */
1156 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop end */
1157 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial attenuation */
1161 static unsigned char
1162 FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value)
1166 if (lay && (on = FX_ON(lay, type)) != 0)
1167 effect = lay->val[type];
1168 if (!on && (on = FX_ON(rec, type)) != 0)
1169 effect = rec->val[type];
1170 if (on == FX_FLAG_ADD)
1171 effect += (int)value;
1173 if (effect < parm_defs[type].low)
1174 effect = parm_defs[type].low;
1175 else if (effect > parm_defs[type].high)
1176 effect = parm_defs[type].high;
1177 return (unsigned char)effect;
1182 /* get word effect value */
1183 static unsigned short
1184 FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value)
1188 if (lay && (on = FX_ON(lay, type)) != 0)
1189 effect = lay->val[type];
1190 if (!on && (on = FX_ON(rec, type)) != 0)
1191 effect = rec->val[type];
1192 if (on == FX_FLAG_ADD)
1193 effect += (int)value;
1195 if (effect < parm_defs[type].low)
1196 effect = parm_defs[type].low;
1197 else if (effect > parm_defs[type].high)
1198 effect = parm_defs[type].high;
1199 return (unsigned short)effect;
1204 /* get word (upper=type1/lower=type2) effect value */
1205 static unsigned short
1206 FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value)
1209 tmp = FX_BYTE(rec, lay, type1, (unsigned char)(value >> 8));
1211 tmp |= FX_BYTE(rec, lay, type2, (unsigned char)(value & 0xff));
1215 /* address offset */
1217 FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode)
1220 if (lay && FX_ON(lay, hi))
1221 addr = (short)lay->val[hi];
1222 else if (FX_ON(rec, hi))
1223 addr = (short)rec->val[hi];
1225 if (lay && FX_ON(lay, lo))
1226 addr += (short)lay->val[lo];
1227 else if (FX_ON(rec, lo))
1228 addr += (short)rec->val[lo];
1229 if (!(mode & AWE_SAMPLE_8BITS))
1235 /*================================================================
1236 * turn on/off sample
1237 *================================================================*/
1240 awe_note_on(int voice)
1245 FX_Rec *fx = &voices[voice].cinfo->fx;
1246 FX_Rec *fx_lay = NULL;
1247 if (voices[voice].layer < MAX_LAYERS)
1248 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1250 /* A voice sample must assigned before calling */
1251 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1254 /* channel to be silent and idle */
1255 awe_poke(AWE_DCYSUSV(voice), 0x0080);
1256 awe_poke(AWE_VTFT(voice), 0);
1257 awe_poke(AWE_CVCF(voice), 0);
1258 awe_poke(AWE_PTRX(voice), 0);
1259 awe_poke(AWE_CPF(voice), 0);
1261 /* modulation & volume envelope */
1262 awe_poke(AWE_ENVVAL(voice),
1263 FX_WORD(fx, fx_lay, AWE_FX_ENV1_DELAY, vp->parm.moddelay));
1264 awe_poke(AWE_ATKHLD(voice),
1265 FX_COMB(fx, fx_lay, AWE_FX_ENV1_HOLD, AWE_FX_ENV1_ATTACK,
1266 vp->parm.modatkhld));
1267 awe_poke(AWE_DCYSUS(voice),
1268 FX_COMB(fx, fx_lay, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY,
1269 vp->parm.moddcysus));
1270 awe_poke(AWE_ENVVOL(voice),
1271 FX_WORD(fx, fx_lay, AWE_FX_ENV2_DELAY, vp->parm.voldelay));
1272 awe_poke(AWE_ATKHLDV(voice),
1273 FX_COMB(fx, fx_lay, AWE_FX_ENV2_HOLD, AWE_FX_ENV2_ATTACK,
1274 vp->parm.volatkhld));
1275 /* decay/sustain parameter for volume envelope must be set at last */
1278 awe_set_pitch(voice, TRUE);
1280 /* cutoff and volume */
1281 awe_set_volume(voice, TRUE);
1283 /* modulation envelope heights */
1284 awe_poke(AWE_PEFE(voice),
1285 FX_COMB(fx, fx_lay, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF,
1289 awe_poke(AWE_LFO1VAL(voice),
1290 FX_WORD(fx, fx_lay, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay));
1291 awe_poke(AWE_LFO2VAL(voice),
1292 FX_WORD(fx, fx_lay, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay));
1294 /* lfo1 pitch & cutoff shift */
1295 awe_fx_fmmod(voice, TRUE);
1296 /* lfo1 volume & freq */
1297 awe_fx_tremfrq(voice, TRUE);
1298 /* lfo2 pitch & freq */
1299 awe_fx_fm2frq2(voice, TRUE);
1300 /* pan & loop start */
1301 awe_set_pan(voice, TRUE);
1303 /* chorus & loop end (chorus 8bit, MSB) */
1304 addr = vp->loopend - 1;
1305 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_END,
1306 AWE_FX_COARSE_LOOP_END, vp->mode);
1307 temp = FX_BYTE(fx, fx_lay, AWE_FX_CHORUS, vp->parm.chorus);
1308 temp = (temp <<24) | (unsigned int)addr;
1309 awe_poke_dw(AWE_CSL(voice), temp);
1310 AWE_DEBUG(4,printk("AWE32: [-- loopend=%x/%x]\n", vp->loopend, addr));
1312 /* Q & current address (Q 4bit value, MSB) */
1313 addr = vp->start - 1;
1314 addr += FX_OFFSET(fx, fx_lay, AWE_FX_SAMPLE_START,
1315 AWE_FX_COARSE_SAMPLE_START, vp->mode);
1316 temp = FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ);
1317 temp = (temp<<28) | (unsigned int)addr;
1318 awe_poke_dw(AWE_CCCA(voice), temp);
1319 AWE_DEBUG(4,printk("AWE32: [-- startaddr=%x/%x]\n", vp->start, addr));
1322 awe_poke_dw(AWE_VTFT(voice), 0x0000FFFF);
1323 awe_poke_dw(AWE_CVCF(voice), 0x0000FFFF);
1325 /* turn on envelope */
1326 awe_poke(AWE_DCYSUSV(voice),
1327 FX_COMB(fx, fx_lay, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY,
1328 vp->parm.voldcysus));
1330 temp = FX_BYTE(fx, fx_lay, AWE_FX_REVERB, vp->parm.reverb);
1331 temp = (awe_peek_dw(AWE_PTRX(voice)) & 0xffff0000) | (temp<<8);
1332 awe_poke_dw(AWE_PTRX(voice), temp);
1333 awe_poke_dw(AWE_CPF(voice), 0x40000000);
1335 voices[voice].state = AWE_ST_ON;
1337 /* clear voice position for the next note on this channel */
1338 if (SINGLE_LAYER_MODE()) {
1339 FX_UNSET(fx, AWE_FX_SAMPLE_START);
1340 FX_UNSET(fx, AWE_FX_COARSE_SAMPLE_START);
1345 /* turn off the voice */
1347 awe_note_off(int voice)
1351 FX_Rec *fx = &voices[voice].cinfo->fx;
1352 FX_Rec *fx_lay = NULL;
1353 if (voices[voice].layer < MAX_LAYERS)
1354 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1356 if ((vp = voices[voice].sample) == NULL) {
1357 voices[voice].state = AWE_ST_OFF;
1361 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_RELEASE,
1362 (unsigned char)vp->parm.modrelease);
1363 awe_poke(AWE_DCYSUS(voice), tmp);
1364 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_RELEASE,
1365 (unsigned char)vp->parm.volrelease);
1366 awe_poke(AWE_DCYSUSV(voice), tmp);
1367 voices[voice].state = AWE_ST_RELEASED;
1370 /* force to terminate the voice (no releasing echo) */
1372 awe_terminate(int voice)
1374 awe_poke(AWE_DCYSUSV(voice), 0x807F);
1375 awe_tweak_voice(voice);
1376 voices[voice].state = AWE_ST_OFF;
1379 /* turn off other voices with the same exclusive class (for drums) */
1381 awe_exclusive_off(int voice)
1385 if (voices[voice].sample == NULL)
1387 if ((exclass = voices[voice].sample->exclusiveClass) == 0)
1388 return; /* not exclusive */
1390 /* turn off voices with the same class */
1391 for (i = 0; i < awe_max_voices; i++) {
1392 if (i != voice && IS_PLAYING(i) &&
1393 voices[i].sample && voices[i].ch == voices[voice].ch &&
1394 voices[i].sample->exclusiveClass == exclass) {
1395 AWE_DEBUG(4,printk("AWE32: [exoff(%d)]\n", i));
1397 awe_voice_init(i, TRUE);
1403 /*================================================================
1404 * change the parameters of an audible voice
1405 *================================================================*/
1409 awe_set_pitch(int voice, int forced)
1411 if (IS_NO_EFFECT(voice) && !forced) return;
1412 awe_poke(AWE_IP(voice), voices[voice].apitch);
1413 AWE_DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch));
1416 /* calculate & change pitch */
1418 awe_set_voice_pitch(int voice, int forced)
1420 awe_calc_pitch(voice);
1421 awe_set_pitch(voice, forced);
1424 /* change volume & cutoff */
1426 awe_set_volume(int voice, int forced)
1429 unsigned short tmp2;
1430 FX_Rec *fx = &voices[voice].cinfo->fx;
1431 FX_Rec *fx_lay = NULL;
1432 if (voices[voice].layer < MAX_LAYERS)
1433 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1435 if (!IS_PLAYING(voice) && !forced) return;
1436 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1439 tmp2 = FX_BYTE(fx, fx_lay, AWE_FX_CUTOFF, vp->parm.cutoff);
1441 tmp2 |= FX_BYTE(fx, fx_lay, AWE_FX_ATTEN,
1442 (unsigned char)voices[voice].avol);
1443 awe_poke(AWE_IFATN(voice), tmp2);
1446 /* calculate & change volume */
1448 awe_set_voice_vol(int voice, int forced)
1450 if (IS_EMPTY(voice))
1452 awe_calc_volume(voice);
1453 awe_set_volume(voice, forced);
1457 /* change pan; this could make a click noise.. */
1459 awe_set_pan(int voice, int forced)
1464 FX_Rec *fx = &voices[voice].cinfo->fx;
1465 FX_Rec *fx_lay = NULL;
1466 if (voices[voice].layer < MAX_LAYERS)
1467 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1469 if (IS_NO_EFFECT(voice) && !forced) return;
1470 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1473 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
1474 if (vp->fixpan > 0) /* 0-127 */
1475 temp = 255 - (int)vp->fixpan * 2;
1478 if (vp->pan >= 0) /* 0-127 */
1479 pos = (int)vp->pan * 2 - 128;
1480 pos += voices[voice].cinfo->panning; /* -128 - 127 */
1489 if (forced || temp != voices[voice].apan) {
1490 addr = vp->loopstart - 1;
1491 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START,
1492 AWE_FX_COARSE_LOOP_START, vp->mode);
1493 temp = (temp<<24) | (unsigned int)addr;
1494 awe_poke_dw(AWE_PSST(voice), temp);
1495 voices[voice].apan = temp;
1496 AWE_DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr));
1500 /* effects change during playing */
1502 awe_fx_fmmod(int voice, int forced)
1505 FX_Rec *fx = &voices[voice].cinfo->fx;
1506 FX_Rec *fx_lay = NULL;
1507 if (voices[voice].layer < MAX_LAYERS)
1508 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1510 if (IS_NO_EFFECT(voice) && !forced) return;
1511 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1513 awe_poke(AWE_FMMOD(voice),
1514 FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,
1518 /* set tremolo (lfo1) volume & frequency */
1520 awe_fx_tremfrq(int voice, int forced)
1523 FX_Rec *fx = &voices[voice].cinfo->fx;
1524 FX_Rec *fx_lay = NULL;
1525 if (voices[voice].layer < MAX_LAYERS)
1526 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1528 if (IS_NO_EFFECT(voice) && !forced) return;
1529 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1531 awe_poke(AWE_TREMFRQ(voice),
1532 FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,
1536 /* set lfo2 pitch & frequency */
1538 awe_fx_fm2frq2(int voice, int forced)
1541 FX_Rec *fx = &voices[voice].cinfo->fx;
1542 FX_Rec *fx_lay = NULL;
1543 if (voices[voice].layer < MAX_LAYERS)
1544 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1546 if (IS_NO_EFFECT(voice) && !forced) return;
1547 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1549 awe_poke(AWE_FM2FRQ2(voice),
1550 FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,
1555 /* Q & current address (Q 4bit value, MSB) */
1557 awe_fx_filterQ(int voice, int forced)
1561 FX_Rec *fx = &voices[voice].cinfo->fx;
1562 FX_Rec *fx_lay = NULL;
1563 if (voices[voice].layer < MAX_LAYERS)
1564 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1566 if (IS_NO_EFFECT(voice) && !forced) return;
1567 if ((vp = voices[voice].sample) == NULL || vp->index < 0)
1570 addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff;
1571 addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28);
1572 awe_poke_dw(AWE_CCCA(voice), addr);
1575 /*================================================================
1576 * calculate pitch offset
1577 *----------------------------------------------------------------
1578 * 0xE000 is no pitch offset at 44100Hz sample.
1579 * Every 4096 is one octave.
1580 *================================================================*/
1583 awe_calc_pitch(int voice)
1585 voice_info *vp = &voices[voice];
1587 awe_chan_info *cp = voices[voice].cinfo;
1590 /* search voice information */
1591 if ((ap = vp->sample) == NULL)
1593 if (ap->index < 0) {
1594 AWE_DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1595 if (awe_set_sample(ap) < 0)
1599 /* calculate offset */
1600 if (ap->fixkey >= 0) {
1601 AWE_DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune));
1602 offset = (ap->fixkey - ap->root) * 4096 / 12;
1604 AWE_DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune));
1605 offset = (vp->note - ap->root) * 4096 / 12;
1606 AWE_DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset));
1608 offset = (offset * ap->scaleTuning) / 100;
1609 AWE_DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));
1610 offset += ap->tune * 4096 / 1200;
1611 AWE_DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));
1612 if (cp->bender != 0) {
1613 AWE_DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender));
1614 /* (819200: 1 semitone) ==> (4096: 12 semitones) */
1615 offset += cp->bender * cp->bender_range / 2400;
1618 /* add initial pitch correction */
1619 if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH))
1620 offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH];
1621 else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH))
1622 offset += cp->fx.val[AWE_FX_INIT_PITCH];
1624 /* 0xe000: root pitch */
1625 vp->apitch = 0xe000 + ap->rate_offset + offset;
1626 AWE_DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset));
1627 if (vp->apitch > 0xffff)
1628 vp->apitch = 0xffff;
1634 #ifdef AWE_HAS_GUS_COMPATIBILITY
1635 /* calculate MIDI key and semitone from the specified frequency */
1637 awe_calc_pitch_from_freq(int voice, int freq)
1639 voice_info *vp = &voices[voice];
1641 FX_Rec *fx = &voices[voice].cinfo->fx;
1642 FX_Rec *fx_lay = NULL;
1646 if (voices[voice].layer < MAX_LAYERS)
1647 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1649 /* search voice information */
1650 if ((ap = vp->sample) == NULL)
1652 if (ap->index < 0) {
1653 AWE_DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1654 if (awe_set_sample(ap) < 0)
1657 note = freq_to_note(freq);
1658 offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;
1659 offset = (offset * ap->scaleTuning) / 100;
1660 if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH))
1661 offset += fx_lay->val[AWE_FX_INIT_PITCH];
1662 else if (FX_ON(fx, AWE_FX_INIT_PITCH))
1663 offset += fx->val[AWE_FX_INIT_PITCH];
1664 vp->apitch = 0xe000 + ap->rate_offset + offset;
1665 if (vp->apitch > 0xffff)
1666 vp->apitch = 0xffff;
1670 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1673 /*================================================================
1674 * calculate volume attenuation
1675 *----------------------------------------------------------------
1676 * Voice volume is controlled by volume attenuation parameter.
1677 * So volume becomes maximum when avol is 0 (no attenuation), and
1678 * minimum when 255 (-96dB or silence).
1679 *================================================================*/
1681 static int vol_table[128] = {
1682 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
1683 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
1684 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
1685 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
1686 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
1687 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
1688 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
1689 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
1693 awe_calc_volume(int voice)
1695 voice_info *vp = &voices[voice];
1697 awe_chan_info *cp = voices[voice].cinfo;
1700 /* search voice information */
1701 if ((ap = vp->sample) == NULL)
1705 if (ap->index < 0) {
1706 AWE_DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1707 if (awe_set_sample(ap) < 0)
1712 vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127);
1713 vol = vol * ap->amplitude / 127;
1715 if (vol < 0) vol = 0;
1716 if (vol > 127) vol = 127;
1718 /* calc to attenuation */
1719 vol = vol_table[vol];
1720 vol = vol + (int)ap->attenuation + init_atten;
1721 if (vol > 255) vol = 255;
1724 AWE_DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));
1728 /* set sostenuto on */
1729 static void awe_sostenuto_on(int voice, int forced)
1731 if (IS_NO_EFFECT(voice) && !forced) return;
1732 voices[voice].sostenuto = 127;
1737 static void awe_sustain_off(int voice, int forced)
1739 if (voices[voice].state == AWE_ST_SUSTAINED) {
1740 awe_note_off(voice);
1741 awe_fx_init(voices[voice].ch);
1742 awe_voice_init(voice, FALSE);
1747 /* terminate and initialize voice */
1748 static void awe_terminate_and_init(int voice, int forced)
1750 awe_terminate(voice);
1751 awe_fx_init(voices[voice].ch);
1752 awe_voice_init(voice, TRUE);
1756 /*================================================================
1757 * synth operation routines
1758 *================================================================*/
1760 #define AWE_VOICE_KEY(v) (0x8000 | (v))
1761 #define AWE_CHAN_KEY(c,n) (((c) << 8) | ((n) + 1))
1762 #define KEY_CHAN_MATCH(key,c) (((key) >> 8) == (c))
1764 /* initialize the voice */
1766 awe_voice_init(int voice, int init_all)
1768 voice_info *vp = &voices[voice];
1770 /* reset voice search key */
1771 if (playing_mode == AWE_PLAY_DIRECT)
1772 vp->key = AWE_VOICE_KEY(voice);
1776 /* clear voice mapping */
1777 voice_alloc->map[voice] = 0;
1779 /* touch the timing flag */
1780 vp->time = current_alloc_time;
1782 /* initialize other parameters if necessary */
1789 vp->cinfo = &channels[voice];
1791 vp->state = AWE_ST_OFF;
1793 /* emu8000 parameters */
1801 static void awe_fx_init(int ch)
1803 if (SINGLE_LAYER_MODE() && !misc_modes[AWE_MD_KEEP_EFFECT]) {
1804 BZERO(&channels[ch].fx, sizeof(channels[ch].fx));
1805 BZERO(&channels[ch].fx_layer, sizeof(&channels[ch].fx_layer));
1809 /* initialize channel info */
1810 static void awe_channel_init(int ch, int init_all)
1812 awe_chan_info *cp = &channels[ch];
1815 cp->panning = 0; /* zero center */
1816 cp->bender_range = 200; /* sense * 100 */
1818 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) {
1819 cp->instr = misc_modes[AWE_MD_DEF_DRUM];
1820 cp->bank = AWE_DRUM_BANK;
1822 cp->instr = misc_modes[AWE_MD_DEF_PRESET];
1823 cp->bank = misc_modes[AWE_MD_DEF_BANK];
1829 cp->bender = 0; /* zero tune skew */
1830 cp->expression_vol = 127;
1834 if (! misc_modes[AWE_MD_KEEP_EFFECT]) {
1835 BZERO(&cp->fx, sizeof(cp->fx));
1836 BZERO(&cp->fx_layer, sizeof(cp->fx_layer));
1841 /* change the voice parameters; voice = channel */
1842 static void awe_voice_change(int voice, fx_affect_func func)
1845 switch (playing_mode) {
1846 case AWE_PLAY_DIRECT:
1849 case AWE_PLAY_INDIRECT:
1850 for (i = 0; i < awe_max_voices; i++)
1851 if (voices[i].key == AWE_VOICE_KEY(voice))
1855 for (i = 0; i < awe_max_voices; i++)
1856 if (KEY_CHAN_MATCH(voices[i].key, voice))
1863 /*----------------------------------------------------------------
1864 * device open / close
1865 *----------------------------------------------------------------*/
1868 * reset status of all voices, and clear sample position flag
1871 awe_open(int dev, int mode)
1874 return RET_ERROR(EBUSY);
1878 /* set default mode */
1879 awe_init_misc_modes(FALSE);
1880 init_atten = misc_modes[AWE_MD_ZERO_ATTEN];
1881 drum_flags = DEFAULT_DRUM_FLAGS;
1882 playing_mode = AWE_PLAY_INDIRECT;
1884 /* reset voices & channels */
1894 * reset all voices again (terminate sounds)
1904 /* set miscellaneous mode parameters
1907 awe_init_misc_modes(int init_all)
1910 for (i = 0; i < AWE_MD_END; i++) {
1911 if (init_all || misc_modes_default[i].init_each_time)
1912 misc_modes[i] = misc_modes_default[i].value;
1917 /* sequencer I/O control:
1920 awe_ioctl(int dev, unsigned int cmd, caddr_t arg)
1923 case SNDCTL_SYNTH_INFO:
1924 if (playing_mode == AWE_PLAY_DIRECT)
1925 awe_info.nr_voices = awe_max_voices;
1927 awe_info.nr_voices = AWE_MAX_CHANNELS;
1928 IOCTL_TO_USER((char*)arg, 0, &awe_info, sizeof(awe_info));
1932 case SNDCTL_SEQ_RESETSAMPLES:
1933 awe_reset_samples();
1938 case SNDCTL_SEQ_PERCMODE:
1943 case SNDCTL_SYNTH_MEMAVL:
1944 return awe_mem_size - awe_free_mem_ptr() * 2;
1947 printk("AWE32: unsupported ioctl %d\n", cmd);
1948 return RET_ERROR(EINVAL);
1953 static int voice_in_range(int voice)
1955 if (playing_mode == AWE_PLAY_DIRECT) {
1956 if (voice < 0 || voice >= awe_max_voices)
1959 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
1965 static void release_voice(int voice, int do_sustain)
1967 if (IS_NO_SOUND(voice))
1969 if (do_sustain && (voices[voice].cinfo->sustained == 127 ||
1970 voices[voice].sostenuto == 127))
1971 voices[voice].state = AWE_ST_SUSTAINED;
1973 awe_note_off(voice);
1974 awe_fx_init(voices[voice].ch);
1975 awe_voice_init(voice, FALSE);
1979 /* release all notes */
1980 static void awe_note_off_all(int do_sustain)
1983 for (i = 0; i < awe_max_voices; i++)
1984 release_voice(i, do_sustain);
1988 * not terminate, just release the voice.
1991 awe_kill_note(int dev, int voice, int note, int velocity)
1995 AWE_DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));
1996 if (! voice_in_range(voice))
1997 return RET_ERROR(EINVAL);
1999 switch (playing_mode) {
2000 case AWE_PLAY_DIRECT:
2001 case AWE_PLAY_INDIRECT:
2002 key = AWE_VOICE_KEY(voice);
2005 case AWE_PLAY_MULTI2:
2006 v2 = voice_alloc->map[voice] >> 8;
2007 voice_alloc->map[voice] = 0;
2009 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2010 return RET_ERROR(EINVAL);
2011 /* continue to below */
2013 key = AWE_CHAN_KEY(voice, note);
2017 for (i = 0; i < awe_max_voices; i++) {
2018 if (voices[i].key == key)
2019 release_voice(i, TRUE);
2025 static void start_or_volume_change(int voice, int velocity)
2027 voices[voice].velocity = velocity;
2028 awe_calc_volume(voice);
2029 if (voices[voice].state == AWE_ST_STANDBY)
2031 else if (voices[voice].state == AWE_ST_ON)
2032 awe_set_volume(voice, FALSE);
2035 static void set_and_start_voice(int voice, int state)
2037 /* calculate pitch & volume parameters */
2038 voices[voice].state = state;
2039 awe_calc_pitch(voice);
2040 awe_calc_volume(voice);
2041 if (state == AWE_ST_ON)
2046 * if note is 255, identical with aftertouch function.
2047 * Otherwise, start a voice with specified not and volume.
2050 awe_start_note(int dev, int voice, int note, int velocity)
2052 int i, key, state, volonly;
2054 AWE_DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));
2055 if (! voice_in_range(voice))
2056 return RET_ERROR(EINVAL);
2059 state = AWE_ST_STANDBY; /* stand by for playing */
2061 state = AWE_ST_ON; /* really play */
2064 switch (playing_mode) {
2065 case AWE_PLAY_DIRECT:
2066 case AWE_PLAY_INDIRECT:
2067 key = AWE_VOICE_KEY(voice);
2072 case AWE_PLAY_MULTI2:
2073 voice = voice_alloc->map[voice] >> 8;
2074 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2075 return RET_ERROR(EINVAL);
2076 /* continue to below */
2078 if (note >= 128) { /* key volume mode */
2082 key = AWE_CHAN_KEY(voice, note);
2086 /* dynamic volume change */
2088 for (i = 0; i < awe_max_voices; i++) {
2089 if (voices[i].key == key)
2090 start_or_volume_change(i, velocity);
2095 /* if the same note still playing, stop it */
2096 for (i = 0; i < awe_max_voices; i++)
2097 if (voices[i].key == key) {
2098 if (voices[i].state == AWE_ST_ON) {
2100 awe_voice_init(i, FALSE);
2101 } else if (voices[i].state == AWE_ST_STANDBY)
2102 awe_voice_init(i, TRUE);
2105 /* allocate voices */
2106 if (playing_mode == AWE_PLAY_DIRECT)
2107 awe_alloc_one_voice(voice, note, velocity);
2109 awe_alloc_multi_voices(voice, note, velocity, key);
2111 /* turn off other voices exlusively (for drums) */
2112 for (i = 0; i < awe_max_voices; i++)
2113 if (voices[i].key == key)
2114 awe_exclusive_off(i);
2116 /* set up pitch and volume parameters */
2117 for (i = 0; i < awe_max_voices; i++) {
2118 if (voices[i].key == key && voices[i].state == AWE_ST_OFF)
2119 set_and_start_voice(i, state);
2126 /* search instrument from preset table with the specified bank */
2128 awe_search_instr(int bank, int preset)
2132 for (i = preset_table[preset]; i >= 0; i = infos[i].next_bank) {
2133 if (infos[i].bank == bank)
2140 /* assign the instrument to a voice */
2142 awe_set_instr_2(int dev, int voice, int instr_no)
2144 if (playing_mode == AWE_PLAY_MULTI2) {
2145 voice = voice_alloc->map[voice] >> 8;
2146 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2147 return RET_ERROR(EINVAL);
2149 return awe_set_instr(dev, voice, instr_no);
2152 /* assign the instrument to a channel; voice is the channel number */
2154 awe_set_instr(int dev, int voice, int instr_no)
2156 awe_chan_info *cinfo;
2159 if (! voice_in_range(voice))
2160 return RET_ERROR(EINVAL);
2162 if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)
2163 return RET_ERROR(EINVAL);
2165 cinfo = &channels[voice];
2167 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice))
2168 def_bank = AWE_DRUM_BANK; /* always search drumset */
2170 def_bank = cinfo->bank;
2173 cinfo->def_vrec = -1;
2174 cinfo->vrec = awe_search_instr(def_bank, instr_no);
2175 if (def_bank == AWE_DRUM_BANK) /* search default drumset */
2176 cinfo->def_vrec = awe_search_instr(def_bank, misc_modes[AWE_MD_DEF_DRUM]);
2177 else /* search default preset */
2178 cinfo->def_vrec = awe_search_instr(misc_modes[AWE_MD_DEF_BANK], instr_no);
2180 if (cinfo->vrec < 0 && cinfo->def_vrec < 0) {
2181 AWE_DEBUG(1,printk("AWE32 Warning: can't find instrument %d\n", instr_no));
2184 cinfo->instr = instr_no;
2190 /* reset all voices; terminate sounds and initialize parameters */
2195 current_alloc_time = 0;
2196 /* don't turn off voice 31 and 32. they are used also for FM voices */
2197 for (i = 0; i < awe_max_voices; i++) {
2199 awe_voice_init(i, TRUE);
2201 for (i = 0; i < AWE_MAX_CHANNELS; i++)
2202 awe_channel_init(i, TRUE);
2203 for (i = 0; i < 16; i++) {
2204 awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127;
2205 awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127;
2212 /* hardware specific control:
2213 * GUS specific and AWE32 specific controls are available.
2216 awe_hw_control(int dev, unsigned char *event)
2219 if (cmd & _AWE_MODE_FLAG)
2220 awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2221 #ifdef AWE_HAS_GUS_COMPATIBILITY
2223 awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2228 #ifdef AWE_HAS_GUS_COMPATIBILITY
2230 /* GUS compatible controls */
2232 awe_hw_gus_control(int dev, int cmd, unsigned char *event)
2239 if (MULTI_LAYER_MODE())
2241 if (cmd == _GUS_NUMVOICES)
2245 if (! voice_in_range(voice))
2248 p1 = *(unsigned short *) &event[4];
2249 p2 = *(short *) &event[6];
2250 plong = *(int*) &event[4];
2253 case _GUS_VOICESAMPLE:
2254 awe_set_instr(dev, voice, p1);
2257 case _GUS_VOICEBALA:
2258 /* 0 to 15 --> -128 to 127 */
2259 awe_panning(dev, voice, ((int)p1 << 4) - 128);
2263 case _GUS_VOICEVOL2:
2264 /* not supported yet */
2267 case _GUS_RAMPRANGE:
2272 /* volume ramping not supported */
2275 case _GUS_VOLUME_SCALE:
2278 case _GUS_VOICE_POS:
2279 FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START,
2280 (short)(plong & 0x7fff));
2281 FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START,
2282 (plong >> 15) & 0xffff);
2286 key = AWE_VOICE_KEY(voice);
2287 for (i = 0; i < awe_max_voices; i++) {
2288 if (voices[i].key == key) {
2296 awe_fx_init(voices[i].ch);
2297 awe_voice_init(i, TRUE);
2300 case _GUS_VOICEFADE:
2302 awe_fx_init(voices[i].ch);
2303 awe_voice_init(i, FALSE);
2306 case _GUS_VOICEFREQ:
2307 awe_calc_pitch_from_freq(i, plong);
2317 /* AWE32 specific controls */
2319 awe_hw_awe_control(int dev, int cmd, unsigned char *event)
2324 awe_chan_info *cinfo;
2329 if (! voice_in_range(voice))
2332 if (playing_mode == AWE_PLAY_MULTI2) {
2333 voice = voice_alloc->map[voice] >> 8;
2334 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2338 p1 = *(unsigned short *) &event[4];
2339 p2 = *(short *) &event[6];
2340 cinfo = &channels[voice];
2343 case _AWE_DEBUG_MODE:
2345 printk("AWE32: debug mode = %d\n", debug_mode);
2347 case _AWE_REVERB_MODE:
2348 awe_set_reverb_mode(p1);
2351 case _AWE_CHORUS_MODE:
2352 awe_set_chorus_mode(p1);
2355 case _AWE_REMOVE_LAST_SAMPLES:
2356 AWE_DEBUG(0,printk("AWE32: remove last samples\n"));
2357 if (locked_sf_id > 0)
2358 awe_remove_samples(locked_sf_id);
2361 case _AWE_INITIALIZE_CHIP:
2365 case _AWE_SEND_EFFECT:
2369 int layer = (p1 >> 8);
2370 if (layer >= 0 && layer < MAX_LAYERS)
2371 fx = &cinfo->fx_layer[layer];
2374 if (p1 & 0x40) i = FX_FLAG_OFF;
2375 if (p1 & 0x80) i = FX_FLAG_ADD;
2377 if (p1 < AWE_FX_END) {
2378 AWE_DEBUG(0,printk("AWE32: effects (%d) %d %d\n", voice, p1, p2));
2379 if (i == FX_FLAG_SET)
2381 else if (i == FX_FLAG_ADD)
2385 if (i != FX_FLAG_OFF && parm_defs[p1].realtime) {
2386 AWE_DEBUG(0,printk("AWE32: fx_realtime (%d)\n", voice));
2387 awe_voice_change(voice, parm_defs[p1].realtime);
2392 case _AWE_RESET_CHANNEL:
2393 awe_channel_init(voice, !p1);
2396 case _AWE_TERMINATE_ALL:
2400 case _AWE_TERMINATE_CHANNEL:
2401 awe_voice_change(voice, awe_terminate_and_init);
2404 case _AWE_RELEASE_ALL:
2405 awe_note_off_all(FALSE);
2407 case _AWE_NOTEOFF_ALL:
2408 awe_note_off_all(TRUE);
2411 case _AWE_INITIAL_VOLUME:
2412 AWE_DEBUG(0,printk("AWE32: init attenuation %d\n", p1));
2413 if (p2 == 0) /* absolute value */
2414 init_atten = (short)p1;
2415 else /* relative value */
2416 init_atten = misc_modes[AWE_MD_ZERO_ATTEN] + (short)p1;
2417 if (init_atten < 0) init_atten = 0;
2418 for (i = 0; i < awe_max_voices; i++)
2419 awe_set_voice_vol(i, TRUE);
2422 case _AWE_CHN_PRESSURE:
2423 cinfo->chan_press = p1;
2424 p1 = p1 * misc_modes[AWE_MD_MOD_SENSE] / 1200;
2425 FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, p1);
2426 awe_voice_change(voice, awe_fx_fmmod);
2427 FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, p1);
2428 awe_voice_change(voice, awe_fx_fm2frq2);
2431 case _AWE_CHANNEL_MODE:
2432 AWE_DEBUG(0,printk("AWE32: channel mode = %d\n", p1));
2437 case _AWE_DRUM_CHANNELS:
2438 AWE_DEBUG(0,printk("AWE32: drum flags = %x\n", p1));
2439 drum_flags = *(unsigned int*)&event[4];
2442 case _AWE_MISC_MODE:
2443 AWE_DEBUG(0,printk("AWE32: misc mode = %d %d\n", p1, p2));
2444 if (p1 > AWE_MD_VERSION && p1 < AWE_MD_END)
2445 misc_modes[p1] = p2;
2448 case _AWE_EQUALIZER:
2449 awe_equalizer((int)p1, (int)p2);
2453 AWE_DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice));
2459 /* voice pressure change */
2461 awe_aftertouch(int dev, int voice, int pressure)
2465 AWE_DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure));
2466 if (! voice_in_range(voice))
2469 switch (playing_mode) {
2470 case AWE_PLAY_DIRECT:
2471 case AWE_PLAY_INDIRECT:
2472 awe_start_note(dev, voice, 255, pressure);
2474 case AWE_PLAY_MULTI2:
2475 note = (voice_alloc->map[voice] & 0xff) - 1;
2476 awe_start_note(dev, voice, note + 0x80, pressure);
2482 /* voice control change */
2484 awe_controller(int dev, int voice, int ctrl_num, int value)
2487 awe_chan_info *cinfo;
2489 if (! voice_in_range(voice))
2492 if (playing_mode == AWE_PLAY_MULTI2) {
2493 voice = voice_alloc->map[voice] >> 8;
2494 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2498 cinfo = &channels[voice];
2501 case CTL_BANK_SELECT: /* MIDI control #0 */
2502 AWE_DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value));
2503 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice) &&
2504 !misc_modes[AWE_MD_TOGGLE_DRUM_BANK])
2506 cinfo->bank = value;
2507 if (cinfo->bank == AWE_DRUM_BANK)
2508 DRUM_CHANNEL_ON(cinfo->channel);
2510 DRUM_CHANNEL_OFF(cinfo->channel);
2511 awe_set_instr(dev, voice, cinfo->instr);
2514 case CTL_MODWHEEL: /* MIDI control #1 */
2515 AWE_DEBUG(2,printk("AWE32: [modwheel(%d) %d]\n", voice, value));
2516 i = value * misc_modes[AWE_MD_MOD_SENSE] / 1200;
2517 FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, i);
2518 awe_voice_change(voice, awe_fx_fmmod);
2519 FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, i);
2520 awe_voice_change(voice, awe_fx_fm2frq2);
2523 case CTRL_PITCH_BENDER: /* SEQ1 V2 contorl */
2524 AWE_DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value));
2526 cinfo->bender = value;
2527 awe_voice_change(voice, awe_set_voice_pitch);
2530 case CTRL_PITCH_BENDER_RANGE: /* SEQ1 V2 control */
2531 AWE_DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value));
2532 /* value = sense x 100 */
2533 cinfo->bender_range = value;
2534 /* no audible pitch change yet.. */
2537 case CTL_EXPRESSION: /* MIDI control #11 */
2538 if (SINGLE_LAYER_MODE())
2540 case CTRL_EXPRESSION: /* SEQ1 V2 control */
2541 AWE_DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value));
2543 cinfo->expression_vol = value;
2544 awe_voice_change(voice, awe_set_voice_vol);
2547 case CTL_PAN: /* MIDI control #10 */
2548 AWE_DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value));
2549 /* (0-127) -> signed 8bit */
2550 cinfo->panning = value * 2 - 128;
2551 if (misc_modes[AWE_MD_REALTIME_PAN])
2552 awe_voice_change(voice, awe_set_pan);
2555 case CTL_MAIN_VOLUME: /* MIDI control #7 */
2556 if (SINGLE_LAYER_MODE())
2557 value = (value * 100) / 16383;
2558 case CTRL_MAIN_VOLUME: /* SEQ1 V2 control */
2559 AWE_DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value));
2561 cinfo->main_vol = value;
2562 awe_voice_change(voice, awe_set_voice_vol);
2565 case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */
2566 AWE_DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value));
2567 FX_SET(&cinfo->fx, AWE_FX_REVERB, value * 2);
2570 case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */
2571 AWE_DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value));
2572 FX_SET(&cinfo->fx, AWE_FX_CHORUS, value * 2);
2575 #ifdef AWE_ACCEPT_ALL_SOUNDS_CONTROLL
2576 case 120: /* all sounds off */
2577 awe_note_off_all(FALSE);
2579 case 123: /* all notes off */
2580 awe_note_off_all(TRUE);
2584 case CTL_SUSTAIN: /* MIDI control #64 */
2585 cinfo->sustained = value;
2587 awe_voice_change(voice, awe_sustain_off);
2590 case CTL_SOSTENUTO: /* MIDI control #66 */
2592 awe_voice_change(voice, awe_sostenuto_on);
2594 awe_voice_change(voice, awe_sustain_off);
2598 AWE_DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n",
2599 voice, ctrl_num, value));
2605 /* voice pan change (value = -128 - 127) */
2607 awe_panning(int dev, int voice, int value)
2609 awe_chan_info *cinfo;
2611 if (! voice_in_range(voice))
2614 if (playing_mode == AWE_PLAY_MULTI2) {
2615 voice = voice_alloc->map[voice] >> 8;
2616 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2620 cinfo = &channels[voice];
2621 cinfo->panning = value;
2622 AWE_DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, cinfo->panning));
2623 if (misc_modes[AWE_MD_REALTIME_PAN])
2624 awe_voice_change(voice, awe_set_pan);
2628 /* volume mode change */
2630 awe_volume_method(int dev, int mode)
2632 /* not impremented */
2633 AWE_DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode));
2637 #ifndef AWE_NO_PATCHMGR
2640 awe_patchmgr(int dev, struct patmgr_info *rec)
2642 printk("AWE32 Warning: patch manager control not supported\n");
2648 /* pitch wheel change: 0-16384 */
2650 awe_bender(int dev, int voice, int value)
2652 awe_chan_info *cinfo;
2654 if (! voice_in_range(voice))
2657 if (playing_mode == AWE_PLAY_MULTI2) {
2658 voice = voice_alloc->map[voice] >> 8;
2659 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2663 /* convert to zero centered value */
2664 cinfo = &channels[voice];
2665 cinfo->bender = value - 8192;
2666 AWE_DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, cinfo->bender));
2667 awe_voice_change(voice, awe_set_voice_pitch);
2671 /*----------------------------------------------------------------
2672 * load a sound patch:
2673 * three types of patches are accepted: AWE, GUS, and SYSEX.
2674 *----------------------------------------------------------------*/
2677 awe_load_patch(int dev, int format, const char *addr,
2678 int offs, int count, int pmgr_flag)
2680 awe_patch_info patch;
2683 #ifdef AWE_HAS_GUS_COMPATIBILITY
2684 if (format == GUS_PATCH) {
2685 return awe_load_guspatch(addr, offs, count, pmgr_flag);
2688 if (format == SYSEX_PATCH) {
2689 /* no system exclusive message supported yet */
2691 } else if (format != AWE_PATCH) {
2692 printk("AWE32 Error: Invalid patch format (key) 0x%x\n", format);
2693 return RET_ERROR(EINVAL);
2696 if (count < AWE_PATCH_INFO_SIZE) {
2697 printk("AWE32 Error: Patch header too short\n");
2698 return RET_ERROR(EINVAL);
2700 COPY_FROM_USER(((char*)&patch) + offs, addr, offs,
2701 AWE_PATCH_INFO_SIZE - offs);
2703 count -= AWE_PATCH_INFO_SIZE;
2704 if (count < patch.len) {
2705 printk("AWE32: sample: Patch record too short (%d<%d)\n",
2707 return RET_ERROR(EINVAL);
2710 switch (patch.type) {
2712 rc = awe_load_info(&patch, addr, count);
2715 rc = awe_load_data(&patch, addr, count);
2717 case AWE_OPEN_PATCH:
2718 rc = awe_open_patch(&patch, addr, count);
2720 case AWE_CLOSE_PATCH:
2721 rc = awe_close_patch(&patch, addr, count);
2723 case AWE_UNLOAD_PATCH:
2724 rc = awe_unload_patch(&patch, addr, count);
2726 case AWE_REPLACE_DATA:
2727 rc = awe_replace_data(&patch, addr, count);
2729 case AWE_MAP_PRESET:
2730 rc = awe_load_map(&patch, addr, count);
2732 case AWE_LOAD_CHORUS_FX:
2733 rc = awe_load_chorus_fx(&patch, addr, count);
2735 case AWE_LOAD_REVERB_FX:
2736 rc = awe_load_reverb_fx(&patch, addr, count);
2740 printk("AWE32 Error: unknown patch format type %d\n",
2742 rc = RET_ERROR(EINVAL);
2749 /* create an sflist record */
2751 awe_create_sf(int type, char *name)
2755 /* terminate sounds */
2757 if (current_sf_id >= max_sfs) {
2758 int newsize = max_sfs + AWE_MAX_SF_LISTS;
2759 sf_list *newlist = my_realloc(sflists, sizeof(sf_list)*max_sfs,
2760 sizeof(sf_list)*newsize);
2761 if (newlist == NULL)
2766 rec = &sflists[current_sf_id];
2767 rec->sf_id = current_sf_id + 1;
2769 if (current_sf_id == 0 || (type & AWE_PAT_LOCKED) != 0)
2770 locked_sf_id = current_sf_id + 1;
2773 MEMCPY(rec->name, name, AWE_PATCH_NAME_LEN);
2775 BZERO(rec->name, AWE_PATCH_NAME_LEN);
2777 rec->num_info = awe_free_info();
2778 rec->num_sample = awe_free_sample();
2779 rec->mem_ptr = awe_free_mem_ptr();
2788 /* open patch; create sf list and set opened flag */
2790 awe_open_patch(awe_patch_info *patch, const char *addr, int count)
2793 COPY_FROM_USER(&parm, addr, AWE_PATCH_INFO_SIZE, sizeof(parm));
2794 if (awe_create_sf(parm.type, parm.name)) {
2795 printk("AWE32: can't open: failed to alloc new list\n");
2796 return RET_ERROR(ENOSPC);
2798 patch_opened = TRUE;
2799 return current_sf_id;
2802 /* check if the patch is already opened */
2804 check_patch_opened(int type, char *name)
2806 if (! patch_opened) {
2807 if (awe_create_sf(type, name)) {
2808 printk("AWE32: failed to alloc new list\n");
2809 return RET_ERROR(ENOSPC);
2811 patch_opened = TRUE;
2812 return current_sf_id;
2814 return current_sf_id;
2817 /* close the patch; if no voice is loaded, remove the patch */
2819 awe_close_patch(awe_patch_info *patch, const char *addr, int count)
2821 if (patch_opened && current_sf_id > 0) {
2822 /* if no voice is loaded, release the current patch */
2823 if (sflists[current_sf_id-1].infos == -1)
2824 awe_remove_samples(current_sf_id - 1);
2831 /* remove the latest patch */
2833 awe_unload_patch(awe_patch_info *patch, const char *addr, int count)
2835 if (current_sf_id > 0)
2836 awe_remove_samples(current_sf_id - 1);
2840 /* allocate voice info list records */
2841 static int alloc_new_info(int nvoices)
2843 int newsize, free_info;
2844 awe_voice_list *newlist;
2845 free_info = awe_free_info();
2846 if (free_info + nvoices >= max_infos) {
2848 newsize = max_infos + AWE_MAX_INFOS;
2849 } while (free_info + nvoices >= newsize);
2850 newlist = my_realloc(infos, sizeof(awe_voice_list)*max_infos,
2851 sizeof(awe_voice_list)*newsize);
2852 if (newlist == NULL) {
2853 printk("AWE32: can't alloc info table\n");
2854 return RET_ERROR(ENOSPC);
2857 max_infos = newsize;
2862 /* allocate sample info list records */
2863 static int alloc_new_sample(void)
2865 int newsize, free_sample;
2866 awe_sample_list *newlist;
2867 free_sample = awe_free_sample();
2868 if (free_sample >= max_samples) {
2869 newsize = max_samples + AWE_MAX_SAMPLES;
2870 newlist = my_realloc(samples,
2871 sizeof(awe_sample_list)*max_samples,
2872 sizeof(awe_sample_list)*newsize);
2873 if (newlist == NULL) {
2874 printk("AWE32: can't alloc sample table\n");
2875 return RET_ERROR(ENOSPC);
2878 max_samples = newsize;
2883 /* load voice map */
2885 awe_load_map(awe_patch_info *patch, const char *addr, int count)
2888 awe_voice_list *rec;
2891 if (check_patch_opened(AWE_PAT_TYPE_MAP, NULL) < 0)
2892 return RET_ERROR(ENOSPC);
2893 if (alloc_new_info(1) < 0)
2894 return RET_ERROR(ENOSPC);
2896 COPY_FROM_USER(&map, addr, AWE_PATCH_INFO_SIZE, sizeof(map));
2898 free_info = awe_free_info();
2899 rec = &infos[free_info];
2900 rec->bank = map.map_bank;
2901 rec->instr = map.map_instr;
2902 rec->type = V_ST_MAPPED;
2903 rec->disabled = FALSE;
2904 awe_init_voice_info(&rec->v);
2905 if (map.map_key >= 0) {
2906 rec->v.low = map.map_key;
2907 rec->v.high = map.map_key;
2909 rec->v.start = map.src_instr;
2910 rec->v.end = map.src_bank;
2911 rec->v.fixkey = map.src_key;
2912 rec->v.sf_id = current_sf_id;
2913 add_info_list(free_info);
2914 add_sf_info(free_info);
2919 /* load voice information data */
2921 awe_load_info(awe_patch_info *patch, const char *addr, int count)
2924 awe_voice_rec_hdr hdr;
2928 if (count < AWE_VOICE_REC_SIZE) {
2929 printk("AWE32 Error: invalid patch info length\n");
2930 return RET_ERROR(EINVAL);
2933 offset = AWE_PATCH_INFO_SIZE;
2934 COPY_FROM_USER((char*)&hdr, addr, offset, AWE_VOICE_REC_SIZE);
2935 offset += AWE_VOICE_REC_SIZE;
2937 if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
2938 printk("AWE32 Error: Illegal voice number %d\n", hdr.nvoices);
2939 return RET_ERROR(EINVAL);
2941 total_size = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE * hdr.nvoices;
2942 if (count < total_size) {
2943 printk("AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n",
2944 count, hdr.nvoices);
2945 return RET_ERROR(EINVAL);
2948 if (check_patch_opened(AWE_PAT_TYPE_MISC, NULL) < 0)
2949 return RET_ERROR(ENOSPC);
2951 #if 0 /* it looks like not so useful.. */
2952 /* check if the same preset already exists in the info list */
2953 for (i = sflists[current_sf_id-1].infos; i >= 0; i = infos[i].next) {
2954 if (infos[i].disabled) continue;
2955 if (infos[i].bank == hdr.bank && infos[i].instr == hdr.instr) {
2956 /* in exclusive mode, do skip loading this */
2957 if (hdr.write_mode == AWE_WR_EXCLUSIVE)
2959 /* in replace mode, disable the old data */
2960 else if (hdr.write_mode == AWE_WR_REPLACE)
2961 infos[i].disabled = TRUE;
2964 if (hdr.write_mode == AWE_WR_REPLACE)
2965 rebuild_preset_list();
2968 if (alloc_new_info(hdr.nvoices) < 0)
2969 return RET_ERROR(ENOSPC);
2971 for (i = 0; i < hdr.nvoices; i++) {
2972 int rec = awe_free_info();
2974 infos[rec].bank = hdr.bank;
2975 infos[rec].instr = hdr.instr;
2976 infos[rec].type = V_ST_NORMAL;
2977 infos[rec].disabled = FALSE;
2979 /* copy awe_voice_info parameters */
2980 COPY_FROM_USER(&infos[rec].v, addr, offset, AWE_VOICE_INFO_SIZE);
2981 offset += AWE_VOICE_INFO_SIZE;
2982 infos[rec].v.sf_id = current_sf_id;
2983 if (infos[rec].v.mode & AWE_MODE_INIT_PARM)
2984 awe_init_voice_parm(&infos[rec].v.parm);
2985 awe_set_sample(&infos[rec].v);
2993 /* load wave sample data */
2995 awe_load_data(awe_patch_info *patch, const char *addr, int count)
2998 int rc, free_sample;
2999 awe_sample_info *rec;
3001 if (check_patch_opened(AWE_PAT_TYPE_MISC, NULL) < 0)
3002 return RET_ERROR(ENOSPC);
3004 if (alloc_new_sample() < 0)
3005 return RET_ERROR(ENOSPC);
3007 free_sample = awe_free_sample();
3008 rec = &samples[free_sample].v;
3010 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3011 offset = AWE_PATCH_INFO_SIZE;
3012 COPY_FROM_USER(rec, addr, offset, AWE_SAMPLE_INFO_SIZE);
3013 offset += AWE_SAMPLE_INFO_SIZE;
3014 if (size != rec->size) {
3015 printk("AWE32: load: sample size differed (%d != %d)\n",
3017 return RET_ERROR(EINVAL);
3020 if ((rc = awe_write_wave_data(addr, offset, rec, -1)) != 0)
3023 rec->sf_id = current_sf_id;
3025 add_sf_sample(free_sample);
3031 /* replace wave sample data */
3033 awe_replace_data(awe_patch_info *patch, const char *addr, int count)
3039 awe_sample_info cursmp;
3042 if (! patch_opened) {
3043 printk("AWE32: replace: patch not opened\n");
3044 return RET_ERROR(EINVAL);
3047 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3048 offset = AWE_PATCH_INFO_SIZE;
3049 COPY_FROM_USER(&cursmp, addr, offset, AWE_SAMPLE_INFO_SIZE);
3050 offset += AWE_SAMPLE_INFO_SIZE;
3051 if (cursmp.size == 0 || size != cursmp.size) {
3052 printk("AWE32: replace: illegal sample size (%d!=%d)\n",
3054 return RET_ERROR(EINVAL);
3056 channels = patch->optarg;
3057 if (channels <= 0 || channels > AWE_NORMAL_VOICES) {
3058 printk("AWE32: replace: illegal channels %d\n", channels);
3059 return RET_ERROR(EINVAL);
3062 for (i = sflists[current_sf_id-1].samples;
3063 i >= 0; i = samples[i].next) {
3064 if (samples[i].v.sample == cursmp.sample)
3068 printk("AWE32: replace: cannot find existing sample data %d\n",
3070 return RET_ERROR(EINVAL);
3073 if (samples[i].v.size != cursmp.size) {
3074 printk("AWE32: replace: exiting size differed (%d!=%d)\n",
3075 samples[i].v.size, cursmp.size);
3076 return RET_ERROR(EINVAL);
3079 save_mem_ptr = awe_free_mem_ptr();
3080 sflists[current_sf_id-1].mem_ptr = samples[i].v.start - awe_mem_start;
3081 MEMCPY(&samples[i].v, &cursmp, sizeof(cursmp));
3082 if ((rc = awe_write_wave_data(addr, offset, &samples[i].v, channels)) != 0)
3084 sflists[current_sf_id-1].mem_ptr = save_mem_ptr;
3085 samples[i].v.sf_id = current_sf_id;
3091 /*----------------------------------------------------------------*/
3093 static const char *readbuf_addr;
3094 static int readbuf_offs;
3095 static int readbuf_flags;
3096 #if defined(__DragonFly__) || defined(__FreeBSD__)
3097 static unsigned short *readbuf_loop;
3098 static int readbuf_loopstart, readbuf_loopend;
3101 /* initialize read buffer */
3103 readbuf_init(const char *addr, int offset, awe_sample_info *sp)
3105 #if defined(__DragonFly__) || defined(__FreeBSD__)
3106 readbuf_loop = NULL;
3107 readbuf_loopstart = sp->loopstart;
3108 readbuf_loopend = sp->loopend;
3109 if (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP)) {
3110 int looplen = sp->loopend - sp->loopstart;
3111 readbuf_loop = my_malloc(looplen * 2);
3112 if (readbuf_loop == NULL) {
3113 printk("AWE32: can't malloc temp buffer\n");
3114 return RET_ERROR(ENOSPC);
3118 readbuf_addr = addr;
3119 readbuf_offs = offset;
3120 readbuf_flags = sp->mode_flags;
3124 /* read directly from user buffer */
3125 static unsigned short
3126 readbuf_word(int pos)
3129 /* read from user buffer */
3130 if (readbuf_flags & AWE_SAMPLE_8BITS) {
3132 GET_BYTE_FROM_USER(cc, readbuf_addr, readbuf_offs + pos);
3133 c = cc << 8; /* convert 8bit -> 16bit */
3135 GET_SHORT_FROM_USER(c, readbuf_addr, readbuf_offs + pos * 2);
3137 if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
3138 c ^= 0x8000; /* unsigned -> signed */
3139 #if defined(__DragonFly__) || defined(__FreeBSD__)
3140 /* write on cache for reverse loop */
3141 if (readbuf_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP)) {
3142 if (pos >= readbuf_loopstart && pos < readbuf_loopend)
3143 readbuf_loop[pos - readbuf_loopstart] = c;
3149 #if defined(__DragonFly__) || defined(__FreeBSD__)
3150 /* read from cache */
3151 static unsigned short
3152 readbuf_word_cache(int pos)
3154 if (pos >= readbuf_loopstart && pos < readbuf_loopend)
3155 return readbuf_loop[pos - readbuf_loopstart];
3163 my_free(readbuf_loop);
3165 readbuf_loop = NULL;
3170 #define readbuf_word_cache readbuf_word
3171 #define readbuf_end() /**/
3175 /*----------------------------------------------------------------*/
3177 #define BLANK_LOOP_START 8
3178 #define BLANK_LOOP_END 40
3179 #define BLANK_LOOP_SIZE 48
3181 /* loading onto memory */
3183 awe_write_wave_data(const char *addr, int offset, awe_sample_info *sp, int channels)
3185 int i, truesize, dram_offset;
3188 /* be sure loop points start < end */
3189 if (sp->loopstart > sp->loopend) {
3190 int tmp = sp->loopstart;
3191 sp->loopstart = sp->loopend;
3195 /* compute true data size to be loaded */
3196 truesize = sp->size;
3197 if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP)
3198 truesize += sp->loopend - sp->loopstart;
3199 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK)
3200 truesize += BLANK_LOOP_SIZE;
3201 if (awe_free_mem_ptr() + truesize >= awe_mem_size/2) {
3202 printk("AWE32 Error: Sample memory full\n");
3203 return RET_ERROR(ENOSPC);
3206 /* recalculate address offset */
3207 sp->end -= sp->start;
3208 sp->loopstart -= sp->start;
3209 sp->loopend -= sp->start;
3211 dram_offset = awe_free_mem_ptr() + awe_mem_start;
3212 sp->start = dram_offset;
3213 sp->end += dram_offset;
3214 sp->loopstart += dram_offset;
3215 sp->loopend += dram_offset;
3217 /* set the total size (store onto obsolete checksum value) */
3221 sp->checksum = truesize;
3223 if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0)
3226 if (readbuf_init(addr, offset, sp) < 0)
3227 return RET_ERROR(ENOSPC);
3229 for (i = 0; i < sp->size; i++) {
3231 c = readbuf_word(i);
3233 if (i == sp->loopend &&
3234 (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))) {
3235 int looplen = sp->loopend - sp->loopstart;
3236 /* copy reverse loop */
3238 for (k = 1; k <= looplen; k++) {
3239 c = readbuf_word_cache(i - k);
3242 if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) {
3245 sp->start += looplen;
3252 /* if no blank loop is attached in the sample, add it */
3253 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) {
3254 for (i = 0; i < BLANK_LOOP_SIZE; i++)
3256 if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) {
3257 sp->loopstart = sp->end + BLANK_LOOP_START;
3258 sp->loopend = sp->end + BLANK_LOOP_END;
3262 sflists[current_sf_id-1].mem_ptr += truesize;
3272 /*----------------------------------------------------------------*/
3274 #ifdef AWE_HAS_GUS_COMPATIBILITY
3276 /* calculate GUS envelope time:
3277 * is this correct? i have no idea..
3280 calc_gus_envelope_time(int rate, int start, int end)
3283 r = (3 - ((rate >> 6) & 3)) * 3;
3291 return (t * 10) / (p * 441);
3294 #define calc_gus_sustain(val) (0x7f - vol_table[(val)/2])
3295 #define calc_gus_attenuation(val) vol_table[(val)/2]
3297 /* load GUS patch */
3299 awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag)
3301 struct patch_info patch;
3302 awe_voice_info *rec;
3303 awe_sample_info *smp;
3305 int note, free_sample, free_info;
3308 sizeof_patch = offsetof(struct patch_info, data); /* header size */
3309 if (size < sizeof_patch) {
3310 printk("AWE32 Error: Patch header too short\n");
3311 return RET_ERROR(EINVAL);
3313 COPY_FROM_USER(((char*)&patch) + offs, addr, offs, sizeof_patch - offs);
3314 size -= sizeof_patch;
3315 if (size < patch.len) {
3316 printk("AWE32 Warning: Patch record too short (%d<%ld)\n",
3318 return RET_ERROR(EINVAL);
3320 if (check_patch_opened(AWE_PAT_TYPE_GUS, NULL) < 0)
3321 return RET_ERROR(ENOSPC);
3322 if (alloc_new_sample() < 0)
3323 return RET_ERROR(ENOSPC);
3324 if (alloc_new_info(1))
3325 return RET_ERROR(ENOSPC);
3327 free_sample = awe_free_sample();
3328 smp = &samples[free_sample].v;
3330 smp->sample = free_sample;
3332 smp->end = patch.len;
3333 smp->loopstart = patch.loop_start;
3334 smp->loopend = patch.loop_end;
3335 smp->size = patch.len;
3337 /* set up mode flags */
3338 smp->mode_flags = 0;
3339 if (!(patch.mode & WAVE_16_BITS))
3340 smp->mode_flags |= AWE_SAMPLE_8BITS;
3341 if (patch.mode & WAVE_UNSIGNED)
3342 smp->mode_flags |= AWE_SAMPLE_UNSIGNED;
3343 smp->mode_flags |= AWE_SAMPLE_NO_BLANK;
3344 if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
3345 smp->mode_flags |= AWE_SAMPLE_SINGLESHOT;
3346 if (patch.mode & WAVE_BIDIR_LOOP)
3347 smp->mode_flags |= AWE_SAMPLE_BIDIR_LOOP;
3348 if (patch.mode & WAVE_LOOP_BACK)
3349 smp->mode_flags |= AWE_SAMPLE_REVERSE_LOOP;
3351 AWE_DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, smp->mode_flags));
3352 if (patch.mode & WAVE_16_BITS) {
3353 /* convert to word offsets */
3356 smp->loopstart /= 2;
3359 smp->checksum_flag = 0;
3362 if ((rc = awe_write_wave_data(addr, sizeof_patch, smp, -1)) != 0)
3365 smp->sf_id = current_sf_id;
3366 add_sf_sample(free_sample);
3368 /* set up voice info */
3369 free_info = awe_free_info();
3370 rec = &infos[free_info].v;
3371 awe_init_voice_info(rec);
3372 rec->sample = free_sample; /* the last sample */
3373 rec->rate_offset = calc_rate_offset(patch.base_freq);
3374 note = freq_to_note(patch.base_note);
3375 rec->root = note / 100;
3376 rec->tune = -(note % 100);
3377 rec->low = freq_to_note(patch.low_note) / 100;
3378 rec->high = freq_to_note(patch.high_note) / 100;
3379 AWE_DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%lu-%lu)]\n",
3380 rec->rate_offset, note,
3381 rec->low, rec->high,
3382 patch.low_note, patch.high_note));
3383 /* panning position; -128 - 127 => 0-127 */
3384 rec->pan = (patch.panning + 128) / 2;
3386 /* detuning is ignored */
3387 /* 6points volume envelope */
3388 if (patch.mode & WAVE_ENVELOPES) {
3389 int attack, hold, decay, release;
3390 attack = calc_gus_envelope_time
3391 (patch.env_rate[0], 0, patch.env_offset[0]);
3392 hold = calc_gus_envelope_time
3393 (patch.env_rate[1], patch.env_offset[0],
3394 patch.env_offset[1]);
3395 decay = calc_gus_envelope_time
3396 (patch.env_rate[2], patch.env_offset[1],
3397 patch.env_offset[2]);
3398 release = calc_gus_envelope_time
3399 (patch.env_rate[3], patch.env_offset[1],
3400 patch.env_offset[4]);
3401 release += calc_gus_envelope_time
3402 (patch.env_rate[4], patch.env_offset[3],
3403 patch.env_offset[4]);
3404 release += calc_gus_envelope_time
3405 (patch.env_rate[5], patch.env_offset[4],
3406 patch.env_offset[5]);
3407 rec->parm.volatkhld = (calc_parm_attack(attack) << 8) |
3408 calc_parm_hold(hold);
3409 rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
3410 calc_parm_decay(decay);
3411 rec->parm.volrelease = 0x8000 | calc_parm_decay(release);
3412 AWE_DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release));
3413 rec->attenuation = calc_gus_attenuation(patch.env_offset[0]);
3416 /* tremolo effect */
3417 if (patch.mode & WAVE_TREMOLO) {
3418 int rate = (patch.tremolo_rate * 1000 / 38) / 42;
3419 rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
3420 AWE_DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n",
3421 patch.tremolo_rate, patch.tremolo_depth,
3422 rec->parm.tremfrq));
3424 /* vibrato effect */
3425 if (patch.mode & WAVE_VIBRATO) {
3426 int rate = (patch.vibrato_rate * 1000 / 38) / 42;
3427 rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
3428 AWE_DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n",
3429 patch.tremolo_rate, patch.tremolo_depth,
3430 rec->parm.tremfrq));
3433 /* scale_freq, scale_factor, volume, and fractions not implemented */
3435 /* append to the tail of the list */
3436 infos[free_info].bank = misc_modes[AWE_MD_GUS_BANK];
3437 infos[free_info].instr = patch.instr_no;
3438 infos[free_info].disabled = FALSE;
3439 infos[free_info].type = V_ST_NORMAL;
3440 infos[free_info].v.sf_id = current_sf_id;
3442 add_info_list(free_info);
3443 add_sf_info(free_info);
3445 /* set the voice index */
3446 awe_set_sample(rec);
3451 #endif /* AWE_HAS_GUS_COMPATIBILITY */
3453 /*----------------------------------------------------------------
3454 * sample and voice list handlers
3455 *----------------------------------------------------------------*/
3457 /* append this to the sf list */
3458 static void add_sf_info(int rec)
3460 int sf_id = infos[rec].v.sf_id;
3461 if (sf_id == 0) return;
3463 if (sflists[sf_id].infos < 0)
3464 sflists[sf_id].infos = rec;
3467 prev = sflists[sf_id].infos;
3468 while ((i = infos[prev].next) >= 0)
3470 infos[prev].next = rec;
3472 infos[rec].next = -1;
3473 sflists[sf_id].num_info++;
3476 /* prepend this sample to sf list */
3477 static void add_sf_sample(int rec)
3479 int sf_id = samples[rec].v.sf_id;
3480 if (sf_id == 0) return;
3482 samples[rec].next = sflists[sf_id].samples;
3483 sflists[sf_id].samples = rec;
3484 sflists[sf_id].num_sample++;
3487 /* purge the old records which don't belong with the same file id */
3488 static void purge_old_list(int rec, int next)
3490 infos[rec].next_instr = next;
3491 if (infos[rec].bank == AWE_DRUM_BANK) {
3492 /* remove samples with the same note range */
3493 int cur, *prevp = &infos[rec].next_instr;
3494 int low = infos[rec].v.low;
3495 int high = infos[rec].v.high;
3496 for (cur = next; cur >= 0; cur = infos[cur].next_instr) {
3497 if (infos[cur].v.low == low &&
3498 infos[cur].v.high == high &&
3499 infos[cur].v.sf_id != infos[rec].v.sf_id)
3500 *prevp = infos[cur].next_instr;
3501 prevp = &infos[cur].next_instr;
3504 if (infos[next].v.sf_id != infos[rec].v.sf_id)
3505 infos[rec].next_instr = -1;
3509 /* prepend to top of the preset table */
3510 static void add_info_list(int rec)
3513 int instr = infos[rec].instr;
3514 int bank = infos[rec].bank;
3516 if (infos[rec].disabled)
3519 prevp = &preset_table[instr];
3522 /* search the first record with the same bank number */
3523 if (infos[cur].bank == bank) {
3524 /* replace the list with the new record */
3525 infos[rec].next_bank = infos[cur].next_bank;
3527 purge_old_list(rec, cur);
3530 prevp = &infos[cur].next_bank;
3531 cur = infos[cur].next_bank;
3534 /* this is the first bank record.. just add this */
3535 infos[rec].next_instr = -1;
3536 infos[rec].next_bank = preset_table[instr];
3537 preset_table[instr] = rec;
3540 /* remove samples later than the specified sf_id */
3542 awe_remove_samples(int sf_id)
3545 awe_reset_samples();
3548 /* already removed? */
3549 if (current_sf_id <= sf_id)
3552 current_sf_id = sf_id;
3553 if (locked_sf_id > sf_id)
3554 locked_sf_id = sf_id;
3556 rebuild_preset_list();
3559 /* rebuild preset search list */
3560 static void rebuild_preset_list(void)
3564 for (i = 0; i < AWE_MAX_PRESETS; i++)
3565 preset_table[i] = -1;
3567 for (i = 0; i < current_sf_id; i++) {
3568 for (j = sflists[i].infos; j >= 0; j = infos[j].next)
3573 /* search the specified sample */
3575 awe_set_sample(awe_voice_info *vp)
3579 for (i = sflists[vp->sf_id-1].samples; i >= 0; i = samples[i].next) {
3580 if (samples[i].v.sample == vp->sample) {
3581 /* set the actual sample offsets */
3582 vp->start += samples[i].v.start;
3583 vp->end += samples[i].v.end;
3584 vp->loopstart += samples[i].v.loopstart;
3585 vp->loopend += samples[i].v.loopend;
3586 /* copy mode flags */
3587 vp->mode = samples[i].v.mode_flags;
3597 /*----------------------------------------------------------------
3599 *----------------------------------------------------------------*/
3601 /* look for all voices associated with the specified note & velocity */
3603 awe_search_multi_voices(int rec, int note, int velocity, awe_voice_info **vlist)
3608 for (; rec >= 0; rec = infos[rec].next_instr) {
3609 if (note >= infos[rec].v.low &&
3610 note <= infos[rec].v.high &&
3611 velocity >= infos[rec].v.vellow &&
3612 velocity <= infos[rec].v.velhigh) {
3613 vlist[nvoices] = &infos[rec].v;
3614 if (infos[rec].type == V_ST_MAPPED) /* mapper */
3617 if (nvoices >= AWE_MAX_VOICES)
3624 /* store the voice list from the specified note and velocity.
3625 if the preset is mapped, seek for the destination preset, and rewrite
3626 the note number if necessary.
3629 really_alloc_voices(int vrec, int def_vrec, int *note, int velocity, awe_voice_info **vlist, int level)
3633 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3635 nvoices = awe_search_multi_voices(def_vrec, *note, velocity, vlist);
3636 if (nvoices < 0) { /* mapping */
3637 int preset = vlist[0]->start;
3638 int bank = vlist[0]->end;
3639 int key = vlist[0]->fixkey;
3641 printk("AWE32: too deep mapping level\n");
3644 vrec = awe_search_instr(bank, preset);
3645 if (bank == AWE_DRUM_BANK)
3646 def_vrec = awe_search_instr(bank, 0);
3648 def_vrec = awe_search_instr(0, preset);
3651 return really_alloc_voices(vrec, def_vrec, note, velocity, vlist, level+1);
3657 /* allocate voices corresponding note and velocity; supports multiple insts. */
3659 awe_alloc_multi_voices(int ch, int note, int velocity, int key)
3662 awe_voice_info *vlist[AWE_MAX_VOICES];
3664 if (channels[ch].vrec < 0 && channels[ch].def_vrec < 0)
3665 awe_set_instr(0, ch, channels[ch].instr);
3667 /* check the possible voices; note may be changeable if mapped */
3668 nvoices = really_alloc_voices(channels[ch].vrec, channels[ch].def_vrec,
3669 ¬e, velocity, vlist, 0);
3671 /* set the voices */
3672 current_alloc_time++;
3673 for (i = 0; i < nvoices; i++) {
3674 v = awe_clear_voice();
3675 voices[v].key = key;
3677 voices[v].note = note;
3678 voices[v].velocity = velocity;
3679 voices[v].time = current_alloc_time;
3680 voices[v].cinfo = &channels[ch];
3681 voices[v].sample = vlist[i];
3682 voices[v].state = AWE_ST_MARK;
3683 voices[v].layer = nvoices - i - 1; /* in reverse order */
3686 /* clear the mark in allocated voices */
3687 for (i = 0; i < awe_max_voices; i++) {
3688 if (voices[i].state == AWE_ST_MARK)
3689 voices[i].state = AWE_ST_OFF;
3695 /* search the best voice from the specified status condition */
3697 search_best_voice(int condition)
3701 time = current_alloc_time + 1;
3702 for (i = 0; i < awe_max_voices; i++) {
3703 if ((voices[i].state & condition) &&
3704 (best < 0 || voices[i].time < time)) {
3706 time = voices[i].time;
3711 if (voices[best].state != AWE_ST_OFF)
3712 awe_terminate(best);
3713 awe_voice_init(best, TRUE);
3719 /* search an empty voice.
3720 if no empty voice is found, at least terminate a voice
3723 awe_clear_voice(void)
3727 /* looking for the oldest empty voice */
3728 if ((best = search_best_voice(AWE_ST_OFF)) >= 0)
3730 if ((best = search_best_voice(AWE_ST_RELEASED)) >= 0)
3732 /* looking for the oldest sustained voice */
3733 if ((best = search_best_voice(AWE_ST_SUSTAINED)) >= 0)
3736 #ifdef AWE_LOOKUP_MIDI_PRIORITY
3737 if (MULTI_LAYER_MODE() && misc_modes[AWE_MD_CHN_PRIOR]) {
3739 int time = current_alloc_time + 1;
3741 /* looking for the voices from high channel (except drum ch) */
3742 for (i = 0; i < awe_max_voices; i++) {
3743 if (IS_DRUM_CHANNEL(voices[i].ch)) continue;
3744 if (voices[i].ch < ch) continue;
3745 if (voices[i].state != AWE_ST_MARK &&
3746 (voices[i].ch > ch || voices[i].time < time)) {
3748 time = voices[i].time;
3755 best = search_best_voice(~AWE_ST_MARK);
3764 /* search sample for the specified note & velocity and set it on the voice;
3765 * note that voice is the voice index (not channel index)
3768 awe_alloc_one_voice(int voice, int note, int velocity)
3771 awe_voice_info *vlist[AWE_MAX_VOICES];
3773 ch = voices[voice].ch;
3774 if (channels[ch].vrec < 0 && channels[ch].def_vrec < 0)
3775 awe_set_instr(0, ch, channels[ch].instr);
3777 nvoices = really_alloc_voices(voices[voice].cinfo->vrec,
3778 voices[voice].cinfo->def_vrec,
3779 ¬e, velocity, vlist, 0);
3781 voices[voice].time = ++current_alloc_time;
3782 voices[voice].sample = vlist[0]; /* use the first one */
3783 voices[voice].layer = 0;
3784 voices[voice].note = note;
3785 voices[voice].velocity = velocity;
3790 /*----------------------------------------------------------------
3791 * sequencer2 functions
3792 *----------------------------------------------------------------*/
3794 /* search an empty voice; used by sequencer2 */
3796 awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
3798 playing_mode = AWE_PLAY_MULTI2;
3799 awe_info.nr_voices = AWE_MAX_CHANNELS;
3800 return awe_clear_voice();
3804 /* set up voice; used by sequencer2 */
3806 awe_setup_voice(int dev, int voice, int chn)
3808 struct channel_info *info;
3809 if (synth_devs[dev] == NULL ||
3810 (info = &synth_devs[dev]->chn_info[chn]) == NULL)
3813 if (voice < 0 || voice >= awe_max_voices)
3816 AWE_DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn));
3817 channels[chn].expression_vol = info->controllers[CTL_EXPRESSION];
3818 channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME];
3819 channels[chn].panning =
3820 info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */
3821 channels[chn].bender = info->bender_value; /* zero center */
3822 channels[chn].bank = info->controllers[CTL_BANK_SELECT];
3823 channels[chn].sustained = info->controllers[CTL_SUSTAIN];
3824 if (info->controllers[CTL_EXT_EFF_DEPTH]) {
3825 FX_SET(&channels[chn].fx, AWE_FX_REVERB,
3826 info->controllers[CTL_EXT_EFF_DEPTH] * 2);
3828 if (info->controllers[CTL_CHORUS_DEPTH]) {
3829 FX_SET(&channels[chn].fx, AWE_FX_CHORUS,
3830 info->controllers[CTL_CHORUS_DEPTH] * 2);
3832 awe_set_instr(dev, chn, info->pgm_num);
3836 #ifdef CONFIG_AWE32_MIXER
3837 /*================================================================
3838 * AWE32 mixer device control
3839 *================================================================*/
3842 awe_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
3846 if (((cmd >> 8) & 0xff) != 'M')
3847 return RET_ERROR(EINVAL);
3849 level = (int)IOCTL_IN(arg);
3850 level = ((level & 0xff) + (level >> 8)) / 2;
3851 AWE_DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
3853 if (IO_WRITE_CHECK(cmd)) {
3854 switch (cmd & 0xff) {
3855 case SOUND_MIXER_BASS:
3856 awe_bass_level = level * 12 / 100;
3857 if (awe_bass_level >= 12)
3858 awe_bass_level = 11;
3859 awe_equalizer(awe_bass_level, awe_treble_level);
3861 case SOUND_MIXER_TREBLE:
3862 awe_treble_level = level * 12 / 100;
3863 if (awe_treble_level >= 12)
3864 awe_treble_level = 11;
3865 awe_equalizer(awe_bass_level, awe_treble_level);
3867 case SOUND_MIXER_VOLUME:
3868 level = level * 127 / 100;
3869 if (level >= 128) level = 127;
3870 init_atten = vol_table[level];
3871 for (i = 0; i < awe_max_voices; i++)
3872 awe_set_voice_vol(i, TRUE);
3876 switch (cmd & 0xff) {
3877 case SOUND_MIXER_BASS:
3878 level = awe_bass_level * 100 / 24;
3879 level = (level << 8) | level;
3881 case SOUND_MIXER_TREBLE:
3882 level = awe_treble_level * 100 / 24;
3883 level = (level << 8) | level;
3885 case SOUND_MIXER_VOLUME:
3886 for (i = 127; i > 0; i--) {
3887 if (init_atten <= vol_table[i])
3890 level = i * 100 / 127;
3891 level = (level << 8) | level;
3893 case SOUND_MIXER_DEVMASK:
3894 level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME;
3900 return IOCTL_OUT(arg, level);
3902 #endif /* CONFIG_AWE32_MIXER */
3905 /*================================================================
3906 * initialization of AWE32
3907 *================================================================*/
3909 /* intiailize audio channels */
3911 awe_init_audio(void)
3915 /* turn off envelope engines */
3916 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
3917 awe_poke(AWE_DCYSUSV(ch), 0x80);
3920 /* reset all other parameters to zero */
3921 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
3922 awe_poke(AWE_ENVVOL(ch), 0);
3923 awe_poke(AWE_ENVVAL(ch), 0);
3924 awe_poke(AWE_DCYSUS(ch), 0);
3925 awe_poke(AWE_ATKHLDV(ch), 0);
3926 awe_poke(AWE_LFO1VAL(ch), 0);
3927 awe_poke(AWE_ATKHLD(ch), 0);
3928 awe_poke(AWE_LFO2VAL(ch), 0);
3929 awe_poke(AWE_IP(ch), 0);
3930 awe_poke(AWE_IFATN(ch), 0);
3931 awe_poke(AWE_PEFE(ch), 0);
3932 awe_poke(AWE_FMMOD(ch), 0);
3933 awe_poke(AWE_TREMFRQ(ch), 0);
3934 awe_poke(AWE_FM2FRQ2(ch), 0);
3935 awe_poke_dw(AWE_PTRX(ch), 0);
3936 awe_poke_dw(AWE_VTFT(ch), 0);
3937 awe_poke_dw(AWE_PSST(ch), 0);
3938 awe_poke_dw(AWE_CSL(ch), 0);
3939 awe_poke_dw(AWE_CCCA(ch), 0);
3942 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
3943 awe_poke_dw(AWE_CPF(ch), 0);
3944 awe_poke_dw(AWE_CVCF(ch), 0);
3949 /* initialize DMA address */
3953 awe_poke_dw(AWE_SMALR, 0);
3954 awe_poke_dw(AWE_SMARR, 0);
3955 awe_poke_dw(AWE_SMALW, 0);
3956 awe_poke_dw(AWE_SMARW, 0);
3960 /* initialization arrays; from ADIP */
3962 static unsigned short init1[128] = {
3963 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330,
3964 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730,
3965 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30,
3966 0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30,
3968 0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330,
3969 0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730,
3970 0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30,
3971 0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30,
3973 0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330,
3974 0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730,
3975 0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30,
3976 0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30,
3978 0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330,
3979 0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730,
3980 0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30,
3981 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30,
3984 static unsigned short init2[128] = {
3985 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
3986 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
3987 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
3988 0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
3990 0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
3991 0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
3992 0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
3993 0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
3995 0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
3996 0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
3997 0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
3998 0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
4000 0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
4001 0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
4002 0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
4003 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
4006 static unsigned short init3[128] = {
4007 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4008 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
4009 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
4010 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
4012 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
4013 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
4014 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
4015 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
4017 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
4018 0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
4019 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
4020 0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
4022 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
4023 0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
4024 0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
4025 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
4028 static unsigned short init4[128] = {
4029 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4030 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
4031 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
4032 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
4034 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
4035 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
4036 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
4037 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
4039 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
4040 0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
4041 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
4042 0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
4044 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
4045 0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
4046 0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
4047 0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
4051 /* send initialization arrays to start up */
4053 awe_init_array(void)
4055 awe_send_array(init1);
4057 awe_send_array(init2);
4058 awe_send_array(init3);
4059 awe_poke_dw(AWE_HWCF4, 0);
4060 awe_poke_dw(AWE_HWCF5, 0x83);
4061 awe_poke_dw(AWE_HWCF6, 0x8000);
4062 awe_send_array(init4);
4065 /* send an initialization array */
4067 awe_send_array(unsigned short *data)
4073 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4074 awe_poke(AWE_INIT1(i), *p);
4075 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4076 awe_poke(AWE_INIT2(i), *p);
4077 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4078 awe_poke(AWE_INIT3(i), *p);
4079 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4080 awe_poke(AWE_INIT4(i), *p);
4085 * set up awe32 channels to some known state.
4088 /* set the envelope & LFO parameters to the default values; see ADIP */
4090 awe_tweak_voice(int i)
4092 /* set all mod/vol envelope shape to minimum */
4093 awe_poke(AWE_ENVVOL(i), 0x8000);
4094 awe_poke(AWE_ENVVAL(i), 0x8000);
4095 awe_poke(AWE_DCYSUS(i), 0x7F7F);
4096 awe_poke(AWE_ATKHLDV(i), 0x7F7F);
4097 awe_poke(AWE_ATKHLD(i), 0x7F7F);
4098 awe_poke(AWE_PEFE(i), 0); /* mod envelope height to zero */
4099 awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */
4100 awe_poke(AWE_LFO2VAL(i), 0x8000);
4101 awe_poke(AWE_IP(i), 0xE000); /* no pitch shift */
4102 awe_poke(AWE_IFATN(i), 0xFF00); /* volume to minimum */
4103 awe_poke(AWE_FMMOD(i), 0);
4104 awe_poke(AWE_TREMFRQ(i), 0);
4105 awe_poke(AWE_FM2FRQ2(i), 0);
4112 /* reset all channels */
4113 for (i = 0; i < awe_max_voices; i++)
4119 * initializes the FM section of AWE32;
4120 * see Vince Vu's unofficial AWE32 programming guide
4126 #ifndef AWE_ALWAYS_INIT_FM
4127 /* if no extended memory is on board.. */
4128 if (awe_mem_size <= 0)
4131 AWE_DEBUG(3,printk("AWE32: initializing FM\n"));
4133 /* Initialize the last two channels for DRAM refresh and producing
4134 the reverb and chorus effects for Yamaha OPL-3 synthesizer */
4136 /* 31: FM left channel, 0xffffe0-0xffffe8 */
4137 awe_poke(AWE_DCYSUSV(30), 0x80);
4138 awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */
4139 awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 |
4140 (DEF_FM_CHORUS_DEPTH << 24));
4141 awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8));
4142 awe_poke_dw(AWE_CPF(30), 0);
4143 awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3);
4145 /* 32: FM right channel, 0xfffff0-0xfffff8 */
4146 awe_poke(AWE_DCYSUSV(31), 0x80);
4147 awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */
4148 awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 |
4149 (DEF_FM_CHORUS_DEPTH << 24));
4150 awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8));
4151 awe_poke_dw(AWE_CPF(31), 0x8000);
4152 awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3);
4154 /* skew volume & cutoff */
4155 awe_poke_dw(AWE_VTFT(30), 0x8000FFFF);
4156 awe_poke_dw(AWE_VTFT(31), 0x8000FFFF);
4158 voices[30].state = AWE_ST_FM;
4159 voices[31].state = AWE_ST_FM;
4161 /* change maximum channels to 30 */
4162 awe_max_voices = AWE_NORMAL_VOICES;
4163 if (playing_mode == AWE_PLAY_DIRECT)
4164 awe_info.nr_voices = awe_max_voices;
4166 awe_info.nr_voices = AWE_MAX_CHANNELS;
4167 voice_alloc->max_voice = awe_max_voices;
4171 * AWE32 DRAM access routines
4174 /* open DRAM write accessing mode */
4176 awe_open_dram_for_write(int offset, int channels)
4178 int vidx[AWE_NORMAL_VOICES];
4181 if (channels < 0 || channels >= AWE_NORMAL_VOICES) {
4182 channels = AWE_NORMAL_VOICES;
4183 for (i = 0; i < AWE_NORMAL_VOICES; i++)
4186 for (i = 0; i < channels; i++)
4187 vidx[i] = awe_clear_voice();
4190 /* use all channels for DMA transfer */
4191 for (i = 0; i < channels; i++) {
4192 if (vidx[i] < 0) continue;
4193 awe_poke(AWE_DCYSUSV(vidx[i]), 0x80);
4194 awe_poke_dw(AWE_VTFT(vidx[i]), 0);
4195 awe_poke_dw(AWE_CVCF(vidx[i]), 0);
4196 awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000);
4197 awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000);
4198 awe_poke_dw(AWE_PSST(vidx[i]), 0);
4199 awe_poke_dw(AWE_CSL(vidx[i]), 0);
4200 awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000);
4201 voices[vidx[i]].state = AWE_ST_DRAM;
4203 /* point channels 31 & 32 to ROM samples for DRAM refresh */
4204 awe_poke_dw(AWE_VTFT(30), 0);
4205 awe_poke_dw(AWE_PSST(30), 0x1d8);
4206 awe_poke_dw(AWE_CSL(30), 0x1e0);
4207 awe_poke_dw(AWE_CCCA(30), 0x1d8);
4208 awe_poke_dw(AWE_VTFT(31), 0);
4209 awe_poke_dw(AWE_PSST(31), 0x1d8);
4210 awe_poke_dw(AWE_CSL(31), 0x1e0);
4211 awe_poke_dw(AWE_CCCA(31), 0x1d8);
4212 voices[30].state = AWE_ST_FM;
4213 voices[31].state = AWE_ST_FM;
4215 /* if full bit is on, not ready to write on */
4216 if (awe_peek_dw(AWE_SMALW) & 0x80000000) {
4217 for (i = 0; i < channels; i++) {
4218 awe_poke_dw(AWE_CCCA(vidx[i]), 0);
4219 voices[i].state = AWE_ST_OFF;
4221 return RET_ERROR(ENOSPC);
4224 /* set address to write */
4225 awe_poke_dw(AWE_SMALW, offset);
4230 /* open DRAM for RAM size detection */
4232 awe_open_dram_for_check(void)
4235 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4236 awe_poke(AWE_DCYSUSV(i), 0x80);
4237 awe_poke_dw(AWE_VTFT(i), 0);
4238 awe_poke_dw(AWE_CVCF(i), 0);
4239 awe_poke_dw(AWE_PTRX(i), 0x40000000);
4240 awe_poke_dw(AWE_CPF(i), 0x40000000);
4241 awe_poke_dw(AWE_PSST(i), 0);
4242 awe_poke_dw(AWE_CSL(i), 0);
4243 if (i & 1) /* DMA write */
4244 awe_poke_dw(AWE_CCCA(i), 0x06000000);
4246 awe_poke_dw(AWE_CCCA(i), 0x04000000);
4247 voices[i].state = AWE_ST_DRAM;
4252 /* close dram access */
4254 awe_close_dram(void)
4257 /* wait until FULL bit in SMAxW register be false */
4258 for (i = 0; i < 10000; i++) {
4259 if (!(awe_peek_dw(AWE_SMALW) & 0x80000000))
4264 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4265 if (voices[i].state == AWE_ST_DRAM) {
4266 awe_poke_dw(AWE_CCCA(i), 0);
4267 awe_poke(AWE_DCYSUSV(i), 0x807F);
4268 voices[i].state = AWE_ST_OFF;
4274 /*================================================================
4275 * detect presence of AWE32 and check memory size
4276 *================================================================*/
4278 /* detect emu8000 chip on the specified address; from VV's guide */
4281 awe_detect_base(int addr)
4284 if ((awe_peek(AWE_U1) & 0x000F) != 0x000C)
4286 if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058)
4288 if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003)
4290 AWE_DEBUG(0,printk("AWE32 found at %x\n", awe_base));
4298 if (awe_base == 0) {
4299 for (base = 0x620; base <= 0x680; base += 0x20)
4300 if (awe_detect_base(base))
4302 AWE_DEBUG(0,printk("AWE32 not found\n"));
4309 /*================================================================
4310 * check dram size on AWE board
4311 *================================================================*/
4313 /* any three numbers you like */
4314 #define UNIQUE_ID1 0x1234
4315 #define UNIQUE_ID2 0x4321
4316 #define UNIQUE_ID3 0xFFFF
4319 awe_check_dram(void)
4321 if (awe_mem_size > 0) {
4322 awe_mem_size *= 1024; /* convert to Kbytes */
4323 return awe_mem_size;
4326 awe_open_dram_for_check();
4330 /* set up unique two id numbers */
4331 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET);
4332 awe_poke(AWE_SMLD, UNIQUE_ID1);
4333 awe_poke(AWE_SMLD, UNIQUE_ID2);
4335 while (awe_mem_size < AWE_MAX_DRAM_SIZE) {
4337 /* read a data on the DRAM start address */
4338 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET);
4339 awe_peek(AWE_SMLD); /* discard stale data */
4340 if (awe_peek(AWE_SMLD) != UNIQUE_ID1)
4342 if (awe_peek(AWE_SMLD) != UNIQUE_ID2)
4344 awe_mem_size += 32; /* increment 32 Kbytes */
4345 /* Write a unique data on the test address;
4346 * if the address is out of range, the data is written on
4347 * 0x200000(=AWE_DRAM_OFFSET). Then the two id words are
4348 * broken by this data.
4350 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + awe_mem_size*512L);
4351 awe_poke(AWE_SMLD, UNIQUE_ID3);
4353 /* read a data on the just written DRAM address */
4354 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + awe_mem_size*512L);
4355 awe_peek(AWE_SMLD); /* discard stale data */
4356 if (awe_peek(AWE_SMLD) != UNIQUE_ID3)
4361 AWE_DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", awe_mem_size));
4363 /* convert to Kbytes */
4364 awe_mem_size *= 1024;
4365 return awe_mem_size;
4369 /*================================================================
4370 * chorus and reverb controls; from VV's guide
4371 *================================================================*/
4373 /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
4374 static char chorus_defined[AWE_CHORUS_NUMBERS];
4375 static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = {
4376 {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
4377 {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
4378 {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
4379 {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
4380 {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
4381 {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
4382 {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */
4383 {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */
4387 awe_load_chorus_fx(awe_patch_info *patch, const char *addr, int count)
4389 if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) {
4390 printk("AWE32 Error: illegal chorus mode %d for uploading\n", patch->optarg);
4391 return RET_ERROR(EINVAL);
4393 if (count < sizeof(awe_chorus_fx_rec)) {
4394 printk("AWE32 Error: too short chorus fx parameters\n");
4395 return RET_ERROR(EINVAL);
4397 COPY_FROM_USER(&chorus_parm[patch->optarg], addr, AWE_PATCH_INFO_SIZE,
4398 sizeof(awe_chorus_fx_rec));
4399 chorus_defined[patch->optarg] = TRUE;
4404 awe_set_chorus_mode(int effect)
4406 if (effect < 0 || effect >= AWE_CHORUS_NUMBERS ||
4407 (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect]))
4409 awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback);
4410 awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset);
4411 awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth);
4412 awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay);
4413 awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq);
4414 awe_poke_dw(AWE_HWCF6, 0x8000);
4415 awe_poke_dw(AWE_HWCF7, 0x0000);
4416 chorus_mode = effect;
4419 /*----------------------------------------------------------------*/
4421 /* reverb mode settings; write the following 28 data of 16 bit length
4422 * on the corresponding ports in the reverb_cmds array
4424 static char reverb_defined[AWE_CHORUS_NUMBERS];
4425 static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = {
4427 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
4428 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
4429 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4430 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4433 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4434 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4435 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4436 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4439 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4440 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
4441 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
4442 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
4445 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4446 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4447 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
4448 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
4451 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
4452 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
4453 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4454 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4457 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
4458 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
4459 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4460 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4463 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
4464 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4465 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4466 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4468 {{ /* panning delay */
4469 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
4470 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4471 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4472 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4476 static struct ReverbCmdPair {
4477 unsigned short cmd, port;
4478 } reverb_cmds[28] = {
4479 {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
4480 {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
4481 {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
4482 {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
4483 {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
4484 {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
4485 {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
4489 awe_load_reverb_fx(awe_patch_info *patch, const char *addr, int count)
4491 if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) {
4492 printk("AWE32 Error: illegal reverb mode %d for uploading\n", patch->optarg);
4493 return RET_ERROR(EINVAL);
4495 if (count < sizeof(awe_reverb_fx_rec)) {
4496 printk("AWE32 Error: too short reverb fx parameters\n");
4497 return RET_ERROR(EINVAL);
4499 COPY_FROM_USER(&reverb_parm[patch->optarg], addr, AWE_PATCH_INFO_SIZE,
4500 sizeof(awe_reverb_fx_rec));
4501 reverb_defined[patch->optarg] = TRUE;
4506 awe_set_reverb_mode(int effect)
4509 if (effect < 0 || effect >= AWE_REVERB_NUMBERS ||
4510 (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect]))
4512 for (i = 0; i < 28; i++)
4513 awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port,
4514 reverb_parm[effect].parms[i]);
4515 reverb_mode = effect;
4518 /*================================================================
4519 * treble/bass equalizer control
4520 *================================================================*/
4522 static unsigned short bass_parm[12][3] = {
4523 {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
4524 {0xD25B, 0xD35B, 0x0000}, /* -8 */
4525 {0xD24C, 0xD34C, 0x0000}, /* -6 */
4526 {0xD23D, 0xD33D, 0x0000}, /* -4 */
4527 {0xD21F, 0xD31F, 0x0000}, /* -2 */
4528 {0xC208, 0xC308, 0x0001}, /* 0 (HW default) */
4529 {0xC219, 0xC319, 0x0001}, /* +2 */
4530 {0xC22A, 0xC32A, 0x0001}, /* +4 */
4531 {0xC24C, 0xC34C, 0x0001}, /* +6 */
4532 {0xC26E, 0xC36E, 0x0001}, /* +8 */
4533 {0xC248, 0xC348, 0x0002}, /* +10 */
4534 {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
4537 static unsigned short treble_parm[12][9] = {
4538 {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
4539 {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4540 {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4541 {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4542 {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4543 {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
4544 {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
4545 {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
4546 {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
4547 {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
4548 {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
4549 {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */
4554 * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
4557 awe_equalizer(int bass, int treble)
4561 if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
4563 awe_bass_level = bass;
4564 awe_treble_level = treble;
4565 awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]);
4566 awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]);
4567 awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]);
4568 awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]);
4569 awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]);
4570 awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]);
4571 awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]);
4572 awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]);
4573 awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]);
4574 awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]);
4575 w = bass_parm[bass][2] + treble_parm[treble][8];
4576 awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262));
4577 awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362));
4581 #endif /* CONFIG_AWE32_SYNTH */