4 * The low level driver for the AWE32/SB32/AWE64 wave table synth.
5 * version 0.4.4; Jan. 4, 2000
7 * Copyright (C) 1996-2000 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.
26 * Aug 18, 2003, Adam Belay <ambx1@neo.rr.com>
27 * - detection code rewrite
30 #include <linux/awe_voice.h>
31 #include <linux/init.h>
32 #include <linux/module.h>
33 #include <linux/string.h>
34 #include <linux/pnp.h>
36 #include "sound_config.h"
41 #ifdef AWE_HAS_GUS_COMPATIBILITY
43 #include <linux/ultrasound.h>
51 #define DEBUG(LVL,XXX) {if (ctrls[AWE_MD_DEBUG_MODE] > LVL) { XXX; }}
52 #define ERRMSG(XXX) {if (ctrls[AWE_MD_DEBUG_MODE]) { XXX; }}
53 #define FATALERR(XXX) XXX
55 #define DEBUG(LVL,XXX) /**/
56 #define ERRMSG(XXX) XXX
57 #define FATALERR(XXX) XXX
61 * bank and voice record
64 typedef struct _sf_list sf_list;
65 typedef struct _awe_voice_list awe_voice_list;
66 typedef struct _awe_sample_list awe_sample_list;
68 /* soundfont record */
70 unsigned short sf_id; /* id number */
71 unsigned short type; /* lock & shared flags */
72 int num_info; /* current info table index */
73 int num_sample; /* current sample table index */
74 int mem_ptr; /* current word byte pointer */
75 awe_voice_list *infos, *last_infos; /* instruments */
76 awe_sample_list *samples, *last_samples; /* samples */
77 #ifdef AWE_ALLOW_SAMPLE_SHARING
78 sf_list *shared; /* shared list */
79 unsigned char name[AWE_PATCH_NAME_LEN]; /* sharing id */
85 struct _awe_voice_list {
86 awe_voice_info v; /* instrument information */
87 sf_list *holder; /* parent sf_list of this record */
88 unsigned char bank, instr; /* preset number information */
89 char type, disabled; /* type=normal/mapped, disabled=boolean */
90 awe_voice_list *next; /* linked list with same sf_id */
91 awe_voice_list *next_instr; /* instrument list */
92 awe_voice_list *next_bank; /* hash table list */
100 struct _awe_sample_list {
101 awe_sample_info v; /* sample information */
102 sf_list *holder; /* parent sf_list of this record */
103 awe_sample_list *next; /* linked list with same sf_id */
106 /* sample and information table */
107 static int current_sf_id; /* current number of fonts */
108 static int locked_sf_id; /* locked position */
109 static sf_list *sfhead, *sftail; /* linked-lists */
111 #define awe_free_mem_ptr() (sftail ? sftail->mem_ptr : 0)
112 #define awe_free_info() (sftail ? sftail->num_info : 0)
113 #define awe_free_sample() (sftail ? sftail->num_sample : 0)
115 #define AWE_MAX_PRESETS 256
116 #define AWE_DEFAULT_PRESET 0
117 #define AWE_DEFAULT_BANK 0
118 #define AWE_DEFAULT_DRUM 0
119 #define AWE_DRUM_BANK 128
121 #define MAX_LAYERS AWE_MAX_VOICES
123 /* preset table index */
124 static awe_voice_list *preset_table[AWE_MAX_PRESETS];
131 typedef struct FX_Rec { /* channel effects */
132 unsigned char flags[AWE_FX_END];
133 short val[AWE_FX_END];
137 /* channel parameters */
138 typedef struct _awe_chan_info {
139 int channel; /* channel number */
140 int bank; /* current tone bank */
141 int instr; /* current program */
142 int bender; /* midi pitchbend (-8192 - 8192) */
143 int bender_range; /* midi bender range (x100) */
144 int panning; /* panning (0-127) */
145 int main_vol; /* channel volume (0-127) */
146 int expression_vol; /* midi expression (0-127) */
147 int chan_press; /* channel pressure */
148 int sustained; /* sustain status in MIDI */
149 FX_Rec fx; /* effects */
150 FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */
153 /* voice parameters */
154 typedef struct _voice_info {
156 #define AWE_ST_OFF (1<<0) /* no sound */
157 #define AWE_ST_ON (1<<1) /* playing */
158 #define AWE_ST_STANDBY (1<<2) /* stand by for playing */
159 #define AWE_ST_SUSTAINED (1<<3) /* sustained */
160 #define AWE_ST_MARK (1<<4) /* marked for allocation */
161 #define AWE_ST_DRAM (1<<5) /* DRAM read/write */
162 #define AWE_ST_FM (1<<6) /* reserved for FM */
163 #define AWE_ST_RELEASED (1<<7) /* released */
165 int ch; /* midi channel */
166 int key; /* internal key for search */
167 int layer; /* layer number (for channel mode only) */
168 int time; /* allocated time */
169 awe_chan_info *cinfo; /* channel info */
171 int note; /* midi key (0-127) */
172 int velocity; /* midi velocity (0-127) */
173 int sostenuto; /* sostenuto on/off */
174 awe_voice_info *sample; /* assigned voice */
176 /* EMU8000 parameters */
177 int apitch; /* pitch parameter */
178 int avol; /* volume parameter */
179 int apan; /* panning parameter */
180 int acutoff; /* cutoff parameter */
181 short aaux; /* aux word */
184 /* voice information */
185 static voice_info voices[AWE_MAX_VOICES];
187 #define IS_NO_SOUND(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED))
188 #define IS_NO_EFFECT(v) (voices[v].state != AWE_ST_ON)
189 #define IS_PLAYING(v) (voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED))
190 #define IS_EMPTY(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM))
193 /* MIDI channel effects information (for hw control) */
194 static awe_chan_info channels[AWE_MAX_CHANNELS];
201 #ifndef AWE_DEFAULT_BASE_ADDR
202 #define AWE_DEFAULT_BASE_ADDR 0 /* autodetect */
205 #ifndef AWE_DEFAULT_MEM_SIZE
206 #define AWE_DEFAULT_MEM_SIZE -1 /* autodetect */
209 static int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
210 static int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
212 static int isapnp = -1;
217 MODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>");
218 MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver");
219 MODULE_LICENSE("GPL");
221 module_param(io, int, 0);
222 MODULE_PARM_DESC(io, "base i/o port of Emu8000");
223 module_param(memsize, int, 0);
224 MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes");
225 module_param(isapnp, bool, 0);
226 MODULE_PARM_DESC(isapnp, "use ISAPnP detection");
228 /* DRAM start offset */
229 static int awe_mem_start = AWE_DRAM_OFFSET;
231 /* maximum channels for playing */
232 static int awe_max_voices = AWE_MAX_VOICES;
234 static int patch_opened; /* sample already loaded? */
236 static char atten_relative = FALSE;
237 static short atten_offset;
239 static int awe_present = FALSE; /* awe device present? */
240 static int awe_busy = FALSE; /* awe device opened? */
242 static int my_dev = -1;
244 #define DEFAULT_DRUM_FLAGS ((1 << 9) | (1 << 25))
245 #define IS_DRUM_CHANNEL(c) (drum_flags & (1 << (c)))
246 #define DRUM_CHANNEL_ON(c) (drum_flags |= (1 << (c)))
247 #define DRUM_CHANNEL_OFF(c) (drum_flags &= ~(1 << (c)))
248 static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */
250 static int playing_mode = AWE_PLAY_INDIRECT;
251 #define SINGLE_LAYER_MODE() (playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT)
252 #define MULTI_LAYER_MODE() (playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2)
254 static int current_alloc_time; /* voice allocation index for channel mode */
256 static struct synth_info awe_info = {
257 "AWE32 Synth", /* name */
259 SYNTH_TYPE_SAMPLE, /* synth_type */
260 SAMPLE_TYPE_AWE32, /* synth_subtype */
261 0, /* perc_mode (obsolete) */
262 AWE_MAX_VOICES, /* nr_voices */
263 0, /* nr_drums (obsolete) */
264 400 /* instr_bank_size */
268 static struct voice_alloc_info *voice_alloc; /* set at initialization */
272 * function prototypes
275 static int awe_request_region(void);
276 static void awe_release_region(void);
278 static void awe_reset_samples(void);
279 /* emu8000 chip i/o access */
280 static void setup_ports(int p1, int p2, int p3);
281 static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);
282 static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);
283 static unsigned short awe_peek(unsigned short cmd, unsigned short port);
284 static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);
285 static void awe_wait(unsigned short delay);
287 /* initialize emu8000 chip */
288 static void awe_initialize(void);
290 /* set voice parameters */
291 static void awe_init_ctrl_parms(int init_all);
292 static void awe_init_voice_info(awe_voice_info *vp);
293 static void awe_init_voice_parm(awe_voice_parm *pp);
294 #ifdef AWE_HAS_GUS_COMPATIBILITY
295 static int freq_to_note(int freq);
296 static int calc_rate_offset(int Hz);
297 /*static int calc_parm_delay(int msec);*/
298 static int calc_parm_hold(int msec);
299 static int calc_parm_attack(int msec);
300 static int calc_parm_decay(int msec);
301 static int calc_parm_search(int msec, short *table);
302 #endif /* gus compat */
304 /* turn on/off note */
305 static void awe_note_on(int voice);
306 static void awe_note_off(int voice);
307 static void awe_terminate(int voice);
308 static void awe_exclusive_off(int voice);
309 static void awe_note_off_all(int do_sustain);
311 /* calculate voice parameters */
312 typedef void (*fx_affect_func)(int voice, int forced);
313 static void awe_set_pitch(int voice, int forced);
314 static void awe_set_voice_pitch(int voice, int forced);
315 static void awe_set_volume(int voice, int forced);
316 static void awe_set_voice_vol(int voice, int forced);
317 static void awe_set_pan(int voice, int forced);
318 static void awe_fx_fmmod(int voice, int forced);
319 static void awe_fx_tremfrq(int voice, int forced);
320 static void awe_fx_fm2frq2(int voice, int forced);
321 static void awe_fx_filterQ(int voice, int forced);
322 static void awe_calc_pitch(int voice);
323 #ifdef AWE_HAS_GUS_COMPATIBILITY
324 static void awe_calc_pitch_from_freq(int voice, int freq);
326 static void awe_calc_volume(int voice);
327 static void awe_update_volume(void);
328 static void awe_change_master_volume(short val);
329 static void awe_voice_init(int voice, int init_all);
330 static void awe_channel_init(int ch, int init_all);
331 static void awe_fx_init(int ch);
332 static void awe_send_effect(int voice, int layer, int type, int val);
333 static void awe_modwheel_change(int voice, int value);
335 /* sequencer interface */
336 static int awe_open(int dev, int mode);
337 static void awe_close(int dev);
338 static int awe_ioctl(int dev, unsigned int cmd, void __user * arg);
339 static int awe_kill_note(int dev, int voice, int note, int velocity);
340 static int awe_start_note(int dev, int v, int note_num, int volume);
341 static int awe_set_instr(int dev, int voice, int instr_no);
342 static int awe_set_instr_2(int dev, int voice, int instr_no);
343 static void awe_reset(int dev);
344 static void awe_hw_control(int dev, unsigned char *event);
345 static int awe_load_patch(int dev, int format, const char __user *addr,
346 int offs, int count, int pmgr_flag);
347 static void awe_aftertouch(int dev, int voice, int pressure);
348 static void awe_controller(int dev, int voice, int ctrl_num, int value);
349 static void awe_panning(int dev, int voice, int value);
350 static void awe_volume_method(int dev, int mode);
351 static void awe_bender(int dev, int voice, int value);
352 static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc);
353 static void awe_setup_voice(int dev, int voice, int chn);
355 #define awe_key_pressure(dev,voice,key,press) awe_start_note(dev,voice,(key)+128,press)
357 /* hardware controls */
358 #ifdef AWE_HAS_GUS_COMPATIBILITY
359 static void awe_hw_gus_control(int dev, int cmd, unsigned char *event);
361 static void awe_hw_awe_control(int dev, int cmd, unsigned char *event);
362 static void awe_voice_change(int voice, fx_affect_func func);
363 static void awe_sostenuto_on(int voice, int forced);
364 static void awe_sustain_off(int voice, int forced);
365 static void awe_terminate_and_init(int voice, int forced);
368 static int awe_search_key(int bank, int preset, int note);
369 static awe_voice_list *awe_search_instr(int bank, int preset, int note);
370 static int awe_search_multi_voices(awe_voice_list *rec, int note, int velocity, awe_voice_info **vlist);
371 static void awe_alloc_multi_voices(int ch, int note, int velocity, int key);
372 static void awe_alloc_one_voice(int voice, int note, int velocity);
373 static int awe_clear_voice(void);
375 /* load / remove patches */
376 static int awe_open_patch(awe_patch_info *patch, const char __user *addr, int count);
377 static int awe_close_patch(awe_patch_info *patch, const char __user *addr, int count);
378 static int awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count);
379 static int awe_load_info(awe_patch_info *patch, const char __user *addr, int count);
380 static int awe_remove_info(awe_patch_info *patch, const char __user *addr, int count);
381 static int awe_load_data(awe_patch_info *patch, const char __user *addr, int count);
382 static int awe_replace_data(awe_patch_info *patch, const char __user *addr, int count);
383 static int awe_load_map(awe_patch_info *patch, const char __user *addr, int count);
384 #ifdef AWE_HAS_GUS_COMPATIBILITY
385 static int awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag);
387 /*static int awe_probe_info(awe_patch_info *patch, const char __user *addr, int count);*/
388 static int awe_probe_data(awe_patch_info *patch, const char __user *addr, int count);
389 static sf_list *check_patch_opened(int type, char *name);
390 static int awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *sp, int channels);
391 static int awe_create_sf(int type, char *name);
392 static void awe_free_sf(sf_list *sf);
393 static void add_sf_info(sf_list *sf, awe_voice_list *rec);
394 static void add_sf_sample(sf_list *sf, awe_sample_list *smp);
395 static void purge_old_list(awe_voice_list *rec, awe_voice_list *next);
396 static void add_info_list(awe_voice_list *rec);
397 static void awe_remove_samples(int sf_id);
398 static void rebuild_preset_list(void);
399 static short awe_set_sample(awe_voice_list *rec);
400 static awe_sample_list *search_sample_index(sf_list *sf, int sample);
402 static int is_identical_holder(sf_list *sf1, sf_list *sf2);
403 #ifdef AWE_ALLOW_SAMPLE_SHARING
404 static int is_identical_name(unsigned char *name, sf_list *p);
405 static int is_shared_sf(unsigned char *name);
406 static int info_duplicated(sf_list *sf, awe_voice_list *rec);
407 #endif /* allow sharing */
409 /* lowlevel functions */
410 static void awe_init_audio(void);
411 static void awe_init_dma(void);
412 static void awe_init_array(void);
413 static void awe_send_array(unsigned short *data);
414 static void awe_tweak_voice(int voice);
415 static void awe_tweak(void);
416 static void awe_init_fm(void);
417 static int awe_open_dram_for_write(int offset, int channels);
418 static void awe_open_dram_for_check(void);
419 static void awe_close_dram(void);
420 /*static void awe_write_dram(unsigned short c);*/
421 static int awe_detect_base(int addr);
422 static int awe_detect(void);
423 static void awe_check_dram(void);
424 static int awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count);
425 static void awe_set_chorus_mode(int mode);
426 static void awe_update_chorus_mode(void);
427 static int awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count);
428 static void awe_set_reverb_mode(int mode);
429 static void awe_update_reverb_mode(void);
430 static void awe_equalizer(int bass, int treble);
431 static void awe_update_equalizer(void);
433 #ifdef CONFIG_AWE32_MIXER
434 static void attach_mixer(void);
435 static void unload_mixer(void);
438 #ifdef CONFIG_AWE32_MIDIEMU
439 static void attach_midiemu(void);
440 static void unload_midiemu(void);
443 #define limitvalue(x, a, b) if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b)
450 #ifdef AWE_USE_NEW_VOLUME_CALC
451 #define DEF_VOLUME_CALC TRUE
453 #define DEF_VOLUME_CALC FALSE
454 #endif /* new volume */
456 #define DEF_ZERO_ATTEN 32 /* 12dB below */
457 #define DEF_MOD_SENSE 18
458 #define DEF_CHORUS_MODE 2
459 #define DEF_REVERB_MODE 4
460 #define DEF_BASS_LEVEL 5
461 #define DEF_TREBLE_LEVEL 9
463 static struct CtrlParmsDef {
466 void (*update)(void);
467 } ctrl_parms[AWE_MD_END] = {
468 {0,0, NULL}, {0,0, NULL}, /* <-- not used */
469 {AWE_VERSION_NUMBER, FALSE, NULL},
470 {TRUE, FALSE, NULL}, /* exclusive */
471 {TRUE, FALSE, NULL}, /* realpan */
472 {AWE_DEFAULT_BANK, FALSE, NULL}, /* gusbank */
473 {FALSE, TRUE, NULL}, /* keep effect */
474 {DEF_ZERO_ATTEN, FALSE, awe_update_volume}, /* zero_atten */
475 {FALSE, FALSE, NULL}, /* chn_prior */
476 {DEF_MOD_SENSE, FALSE, NULL}, /* modwheel sense */
477 {AWE_DEFAULT_PRESET, FALSE, NULL}, /* def_preset */
478 {AWE_DEFAULT_BANK, FALSE, NULL}, /* def_bank */
479 {AWE_DEFAULT_DRUM, FALSE, NULL}, /* def_drum */
480 {FALSE, FALSE, NULL}, /* toggle_drum_bank */
481 {DEF_VOLUME_CALC, FALSE, awe_update_volume}, /* new_volume_calc */
482 {DEF_CHORUS_MODE, FALSE, awe_update_chorus_mode}, /* chorus mode */
483 {DEF_REVERB_MODE, FALSE, awe_update_reverb_mode}, /* reverb mode */
484 {DEF_BASS_LEVEL, FALSE, awe_update_equalizer}, /* bass level */
485 {DEF_TREBLE_LEVEL, FALSE, awe_update_equalizer}, /* treble level */
486 {0, FALSE, NULL}, /* debug mode */
487 {FALSE, FALSE, NULL}, /* pan exchange */
490 static int ctrls[AWE_MD_END];
494 * synth operation table
497 static struct synth_operations awe_operations =
499 .owner = THIS_MODULE,
503 .synth_type = SYNTH_TYPE_SAMPLE,
504 .synth_subtype = SAMPLE_TYPE_AWE32,
508 .kill_note = awe_kill_note,
509 .start_note = awe_start_note,
510 .set_instr = awe_set_instr_2,
512 .hw_control = awe_hw_control,
513 .load_patch = awe_load_patch,
514 .aftertouch = awe_aftertouch,
515 .controller = awe_controller,
516 .panning = awe_panning,
517 .volume_method = awe_volume_method,
518 .bender = awe_bender,
519 .alloc_voice = awe_alloc,
520 .setup_voice = awe_setup_voice
523 static void free_tables(void)
527 for (p = sftail; p; p = prev) {
532 sfhead = sftail = NULL;
536 * clear sample tables
540 awe_reset_samples(void)
542 /* free all bank tables */
543 memset(preset_table, 0, sizeof(preset_table));
553 * EMU register access
556 /* select a given AWE32 pointer */
557 static int awe_ports[5];
558 static int port_setuped = FALSE;
559 static int awe_cur_cmd = -1;
560 #define awe_set_cmd(cmd) \
561 if (awe_cur_cmd != cmd) { outw(cmd, awe_ports[Pointer]); awe_cur_cmd = cmd; }
563 /* write 16bit data */
565 awe_poke(unsigned short cmd, unsigned short port, unsigned short data)
568 outw(data, awe_ports[port]);
571 /* write 32bit data */
573 awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data)
575 unsigned short addr = awe_ports[port];
577 outw(data, addr); /* write lower 16 bits */
578 outw(data >> 16, addr + 2); /* write higher 16 bits */
581 /* read 16bit data */
582 static unsigned short
583 awe_peek(unsigned short cmd, unsigned short port)
587 k = inw(awe_ports[port]);
591 /* read 32bit data */
593 awe_peek_dw(unsigned short cmd, unsigned short port)
596 unsigned short addr = awe_ports[port];
604 /* wait delay number of AWE32 44100Hz clocks */
605 #ifdef WAIT_BY_LOOP /* wait by loop -- that's not good.. */
607 awe_wait(unsigned short delay)
609 unsigned short clock, target;
610 unsigned short port = awe_ports[AWE_WC_Port];
614 awe_set_cmd(AWE_WC_Cmd);
615 clock = (unsigned short)inw(port);
616 target = clock + delay;
618 if (target < clock) {
619 for (; (unsigned short)inw(port) > target; counter++)
623 for (; (unsigned short)inw(port) < target; counter++)
629 static void awe_wait(unsigned short delay)
631 current->state = TASK_INTERRUPTIBLE;
632 schedule_timeout((HZ*(unsigned long)delay + 44099)/44100);
635 static void awe_wait(unsigned short delay)
637 udelay(((unsigned long)delay * 1000000L + 44099) / 44100);
640 #endif /* wait by loop */
642 /* write a word data */
643 #define awe_write_dram(c) awe_poke(AWE_SMLD, c)
646 * AWE32 voice parameters
649 /* initialize voice_info record */
651 awe_init_voice_info(awe_voice_info *vp)
673 vp->exclusiveClass = 0;
676 vp->scaleTuning = 100;
678 awe_init_voice_parm(&vp->parm);
681 /* initialize voice_parm record:
682 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
683 * Vibrato and Tremolo effects are zero.
685 * Chorus and Reverb effects are zero.
688 awe_init_voice_parm(awe_voice_parm *pp)
690 pp->moddelay = 0x8000;
691 pp->modatkhld = 0x7f7f;
692 pp->moddcysus = 0x7f7f;
693 pp->modrelease = 0x807f;
697 pp->voldelay = 0x8000;
698 pp->volatkhld = 0x7f7f;
699 pp->voldcysus = 0x7f7f;
700 pp->volrelease = 0x807f;
704 pp->lfo1delay = 0x8000;
705 pp->lfo2delay = 0x8000;
720 #ifdef AWE_HAS_GUS_COMPATIBILITY
722 /* convert frequency mHz to abstract cents (= midi key * 100) */
724 freq_to_note(int mHz)
726 /* abscents = log(mHz/8176) / log(2) * 1200 */
727 unsigned int max_val = (unsigned int)0xffffffff / 10000;
736 return 12799; /* maximum */
740 for (base = 8176 * 2; freq >= base; base *= 2) {
742 if (note >= 128) /* over maximum */
747 /* to avoid overflow... */
749 while (freq > max_val) {
755 freq = freq * times / base;
756 for (i = 0; i < 12; i++) {
757 if (freq < semitone_tuning[i+1])
763 freq = freq * 10000 / semitone_tuning[i];
764 for (i = 0; i < 100; i++) {
765 if (freq < cent_tuning[i+1])
770 return note * 100 + tune;
774 /* convert Hz to AWE32 rate offset:
775 * sample pitch offset for the specified sample rate
776 * rate=44100 is no offset, each 4096 is 1 octave (twice).
777 * eg, when rate is 22050, this offset becomes -4096.
780 calc_rate_offset(int Hz)
782 /* offset = log(Hz / 44100) / log(2) * 4096 */
785 /* maybe smaller than max (44100Hz) */
786 if (Hz <= 0 || Hz >= 44100) return 0;
789 for (freq = Hz * 2; freq < 44100; freq *= 2)
793 freq = 44100 * 10000 / (freq/2);
794 for (i = 0; i < 12; i++) {
795 if (freq < semitone_tuning[i+1])
799 freq = freq * 10000 / semitone_tuning[i];
800 for (i = 0; i < 100; i++) {
801 if (freq < cent_tuning[i+1])
805 return -base * 4096 / 1200;
810 * convert envelope time parameter to AWE32 raw parameter
813 /* attack & decay/release time table (msec) */
814 static short attack_time_tbl[128] = {
815 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
816 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
817 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
818 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
819 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
820 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
821 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
822 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
825 static short decay_time_tbl[128] = {
826 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
827 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
828 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
829 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
830 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
831 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
832 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
833 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
836 #define calc_parm_delay(msec) (0x8000 - (msec) * 1000 / 725);
838 /* delay time = 0x8000 - msec/92 */
840 calc_parm_hold(int msec)
842 int val = (0x7f * 92 - msec) / 92;
843 if (val < 1) val = 1;
844 if (val > 127) val = 127;
848 /* attack time: search from time table */
850 calc_parm_attack(int msec)
852 return calc_parm_search(msec, attack_time_tbl);
855 /* decay/release time: search from time table */
857 calc_parm_decay(int msec)
859 return calc_parm_search(msec, decay_time_tbl);
862 /* search an index for specified time from given time table */
864 calc_parm_search(int msec, short *table)
866 int left = 1, right = 127, mid;
867 while (left < right) {
868 mid = (left + right) / 2;
869 if (msec < (int)table[mid])
876 #endif /* AWE_HAS_GUS_COMPATIBILITY */
883 /* set an effect value */
884 #define FX_FLAG_OFF 0
885 #define FX_FLAG_SET 1
886 #define FX_FLAG_ADD 2
888 #define FX_SET(rec,type,value) \
889 ((rec)->flags[type] = FX_FLAG_SET, (rec)->val[type] = (value))
890 #define FX_ADD(rec,type,value) \
891 ((rec)->flags[type] = FX_FLAG_ADD, (rec)->val[type] = (value))
892 #define FX_UNSET(rec,type) \
893 ((rec)->flags[type] = FX_FLAG_OFF, (rec)->val[type] = 0)
895 /* check the effect value is set */
896 #define FX_ON(rec,type) ((rec)->flags[type])
902 static struct PARM_DEFS {
903 int type; /* byte or word */
904 int low, high; /* value range */
905 fx_affect_func realtime; /* realtime paramater change */
907 {PARM_WORD, 0, 0x8000, NULL}, /* env1 delay */
908 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 attack */
909 {PARM_BYTE, 0, 0x7e, NULL}, /* env1 hold */
910 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 decay */
911 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 release */
912 {PARM_BYTE, 0, 0x7f, NULL}, /* env1 sustain */
913 {PARM_BYTE, 0, 0xff, NULL}, /* env1 pitch */
914 {PARM_BYTE, 0, 0xff, NULL}, /* env1 cutoff */
916 {PARM_WORD, 0, 0x8000, NULL}, /* env2 delay */
917 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 attack */
918 {PARM_BYTE, 0, 0x7e, NULL}, /* env2 hold */
919 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 decay */
920 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 release */
921 {PARM_BYTE, 0, 0x7f, NULL}, /* env2 sustain */
923 {PARM_WORD, 0, 0x8000, NULL}, /* lfo1 delay */
924 {PARM_BYTE, 0, 0xff, awe_fx_tremfrq}, /* lfo1 freq */
925 {PARM_SIGN, -128, 127, awe_fx_tremfrq}, /* lfo1 volume */
926 {PARM_SIGN, -128, 127, awe_fx_fmmod}, /* lfo1 pitch */
927 {PARM_BYTE, 0, 0xff, awe_fx_fmmod}, /* lfo1 cutoff */
929 {PARM_WORD, 0, 0x8000, NULL}, /* lfo2 delay */
930 {PARM_BYTE, 0, 0xff, awe_fx_fm2frq2}, /* lfo2 freq */
931 {PARM_SIGN, -128, 127, awe_fx_fm2frq2}, /* lfo2 pitch */
933 {PARM_WORD, 0, 0xffff, awe_set_voice_pitch}, /* initial pitch */
934 {PARM_BYTE, 0, 0xff, NULL}, /* chorus */
935 {PARM_BYTE, 0, 0xff, NULL}, /* reverb */
936 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial cutoff */
937 {PARM_BYTE, 0, 15, awe_fx_filterQ}, /* initial resonance */
939 {PARM_WORD, 0, 0xffff, NULL}, /* sample start */
940 {PARM_WORD, 0, 0xffff, NULL}, /* loop start */
941 {PARM_WORD, 0, 0xffff, NULL}, /* loop end */
942 {PARM_WORD, 0, 0xffff, NULL}, /* coarse sample start */
943 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop start */
944 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop end */
945 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial attenuation */
950 FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value)
954 if (lay && (on = FX_ON(lay, type)) != 0)
955 effect = lay->val[type];
956 if (!on && (on = FX_ON(rec, type)) != 0)
957 effect = rec->val[type];
958 if (on == FX_FLAG_ADD) {
959 if (parm_defs[type].type == PARM_SIGN) {
961 effect += (int)value - 0x100;
963 effect += (int)value;
965 effect += (int)value;
969 if (effect < parm_defs[type].low)
970 effect = parm_defs[type].low;
971 else if (effect > parm_defs[type].high)
972 effect = parm_defs[type].high;
973 return (unsigned char)effect;
978 /* get word effect value */
979 static unsigned short
980 FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value)
984 if (lay && (on = FX_ON(lay, type)) != 0)
985 effect = lay->val[type];
986 if (!on && (on = FX_ON(rec, type)) != 0)
987 effect = rec->val[type];
988 if (on == FX_FLAG_ADD)
989 effect += (int)value;
991 if (effect < parm_defs[type].low)
992 effect = parm_defs[type].low;
993 else if (effect > parm_defs[type].high)
994 effect = parm_defs[type].high;
995 return (unsigned short)effect;
1000 /* get word (upper=type1/lower=type2) effect value */
1001 static unsigned short
1002 FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value)
1005 tmp = FX_BYTE(rec, lay, type1, (unsigned char)(value >> 8));
1007 tmp |= FX_BYTE(rec, lay, type2, (unsigned char)(value & 0xff));
1011 /* address offset */
1013 FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode)
1016 if (lay && FX_ON(lay, hi))
1017 addr = (short)lay->val[hi];
1018 else if (FX_ON(rec, hi))
1019 addr = (short)rec->val[hi];
1021 if (lay && FX_ON(lay, lo))
1022 addr += (short)lay->val[lo];
1023 else if (FX_ON(rec, lo))
1024 addr += (short)rec->val[lo];
1025 if (!(mode & AWE_SAMPLE_8BITS))
1032 * turn on/off sample
1035 /* table for volume target calculation */
1036 static unsigned short voltarget[16] = {
1037 0xEAC0, 0XE0C8, 0XD740, 0XCE20, 0XC560, 0XBD08, 0XB500, 0XAD58,
1038 0XA5F8, 0X9EF0, 0X9830, 0X91C0, 0X8B90, 0X85A8, 0X8000, 0X7A90
1042 awe_note_on(int voice)
1046 int vtarget, ftarget, ptarget, pitch;
1048 awe_voice_parm_block *parm;
1049 FX_Rec *fx = &voices[voice].cinfo->fx;
1050 FX_Rec *fx_lay = NULL;
1051 if (voices[voice].layer < MAX_LAYERS)
1052 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1054 /* A voice sample must assigned before calling */
1055 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1058 parm = (awe_voice_parm_block*)&vp->parm;
1060 /* channel to be silent and idle */
1061 awe_poke(AWE_DCYSUSV(voice), 0x0080);
1062 awe_poke(AWE_VTFT(voice), 0x0000FFFF);
1063 awe_poke(AWE_CVCF(voice), 0x0000FFFF);
1064 awe_poke(AWE_PTRX(voice), 0);
1065 awe_poke(AWE_CPF(voice), 0);
1067 /* set pitch offset */
1068 awe_set_pitch(voice, TRUE);
1070 /* modulation & volume envelope */
1071 if (parm->modatk >= 0x80 && parm->moddelay >= 0x8000) {
1072 awe_poke(AWE_ENVVAL(voice), 0xBFFF);
1073 pitch = (parm->env1pit<<4) + voices[voice].apitch;
1074 if (pitch > 0xffff) pitch = 0xffff;
1075 /* calculate filter target */
1076 ftarget = parm->cutoff + parm->env1fc;
1077 limitvalue(ftarget, 0, 255);
1080 awe_poke(AWE_ENVVAL(voice),
1081 FX_WORD(fx, fx_lay, AWE_FX_ENV1_DELAY, parm->moddelay));
1082 ftarget = parm->cutoff;
1084 pitch = voices[voice].apitch;
1087 /* calcualte pitch target */
1088 if (pitch != 0xffff) {
1089 ptarget = 1 << (pitch >> 12);
1090 if (pitch & 0x800) ptarget += (ptarget*0x102e)/0x2710;
1091 if (pitch & 0x400) ptarget += (ptarget*0x764)/0x2710;
1092 if (pitch & 0x200) ptarget += (ptarget*0x389)/0x2710;
1093 ptarget += (ptarget>>1);
1094 if (ptarget > 0xffff) ptarget = 0xffff;
1096 } else ptarget = 0xffff;
1097 if (parm->modatk >= 0x80)
1098 awe_poke(AWE_ATKHLD(voice),
1099 FX_BYTE(fx, fx_lay, AWE_FX_ENV1_HOLD, parm->modhld) << 8 | 0x7f);
1101 awe_poke(AWE_ATKHLD(voice),
1102 FX_COMB(fx, fx_lay, AWE_FX_ENV1_HOLD, AWE_FX_ENV1_ATTACK,
1103 vp->parm.modatkhld));
1104 awe_poke(AWE_DCYSUS(voice),
1105 FX_COMB(fx, fx_lay, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY,
1106 vp->parm.moddcysus));
1108 if (parm->volatk >= 0x80 && parm->voldelay >= 0x8000) {
1109 awe_poke(AWE_ENVVOL(voice), 0xBFFF);
1110 vtarget = voltarget[voices[voice].avol%0x10]>>(voices[voice].avol>>4);
1112 awe_poke(AWE_ENVVOL(voice),
1113 FX_WORD(fx, fx_lay, AWE_FX_ENV2_DELAY, vp->parm.voldelay));
1116 if (parm->volatk >= 0x80)
1117 awe_poke(AWE_ATKHLDV(voice),
1118 FX_BYTE(fx, fx_lay, AWE_FX_ENV2_HOLD, parm->volhld) << 8 | 0x7f);
1120 awe_poke(AWE_ATKHLDV(voice),
1121 FX_COMB(fx, fx_lay, AWE_FX_ENV2_HOLD, AWE_FX_ENV2_ATTACK,
1122 vp->parm.volatkhld));
1123 /* decay/sustain parameter for volume envelope must be set at last */
1125 /* cutoff and volume */
1126 awe_set_volume(voice, TRUE);
1128 /* modulation envelope heights */
1129 awe_poke(AWE_PEFE(voice),
1130 FX_COMB(fx, fx_lay, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF,
1134 awe_poke(AWE_LFO1VAL(voice),
1135 FX_WORD(fx, fx_lay, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay));
1136 awe_poke(AWE_LFO2VAL(voice),
1137 FX_WORD(fx, fx_lay, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay));
1139 /* lfo1 pitch & cutoff shift */
1140 awe_fx_fmmod(voice, TRUE);
1141 /* lfo1 volume & freq */
1142 awe_fx_tremfrq(voice, TRUE);
1143 /* lfo2 pitch & freq */
1144 awe_fx_fm2frq2(voice, TRUE);
1145 /* pan & loop start */
1146 awe_set_pan(voice, TRUE);
1148 /* chorus & loop end (chorus 8bit, MSB) */
1149 addr = vp->loopend - 1;
1150 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_END,
1151 AWE_FX_COARSE_LOOP_END, vp->mode);
1152 temp = FX_BYTE(fx, fx_lay, AWE_FX_CHORUS, vp->parm.chorus);
1153 temp = (temp <<24) | (unsigned int)addr;
1154 awe_poke_dw(AWE_CSL(voice), temp);
1155 DEBUG(4,printk("AWE32: [-- loopend=%x/%x]\n", vp->loopend, addr));
1157 /* Q & current address (Q 4bit value, MSB) */
1158 addr = vp->start - 1;
1159 addr += FX_OFFSET(fx, fx_lay, AWE_FX_SAMPLE_START,
1160 AWE_FX_COARSE_SAMPLE_START, vp->mode);
1161 temp = FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ);
1162 temp = (temp<<28) | (unsigned int)addr;
1163 awe_poke_dw(AWE_CCCA(voice), temp);
1164 DEBUG(4,printk("AWE32: [-- startaddr=%x/%x]\n", vp->start, addr));
1166 /* clear unknown registers */
1167 awe_poke_dw(AWE_00A0(voice), 0);
1168 awe_poke_dw(AWE_0080(voice), 0);
1171 awe_poke_dw(AWE_VTFT(voice), (vtarget<<16)|ftarget);
1172 awe_poke_dw(AWE_CVCF(voice), (vtarget<<16)|ftarget);
1175 temp = FX_BYTE(fx, fx_lay, AWE_FX_REVERB, vp->parm.reverb);
1176 temp = (temp << 8) | (ptarget << 16) | voices[voice].aaux;
1177 awe_poke_dw(AWE_PTRX(voice), temp);
1178 awe_poke_dw(AWE_CPF(voice), ptarget << 16);
1179 /* turn on envelope */
1180 awe_poke(AWE_DCYSUSV(voice),
1181 FX_COMB(fx, fx_lay, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY,
1182 vp->parm.voldcysus));
1184 voices[voice].state = AWE_ST_ON;
1186 /* clear voice position for the next note on this channel */
1187 if (SINGLE_LAYER_MODE()) {
1188 FX_UNSET(fx, AWE_FX_SAMPLE_START);
1189 FX_UNSET(fx, AWE_FX_COARSE_SAMPLE_START);
1194 /* turn off the voice */
1196 awe_note_off(int voice)
1200 FX_Rec *fx = &voices[voice].cinfo->fx;
1201 FX_Rec *fx_lay = NULL;
1202 if (voices[voice].layer < MAX_LAYERS)
1203 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1205 if ((vp = voices[voice].sample) == NULL) {
1206 voices[voice].state = AWE_ST_OFF;
1210 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_RELEASE,
1211 (unsigned char)vp->parm.modrelease);
1212 awe_poke(AWE_DCYSUS(voice), tmp);
1213 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_RELEASE,
1214 (unsigned char)vp->parm.volrelease);
1215 awe_poke(AWE_DCYSUSV(voice), tmp);
1216 voices[voice].state = AWE_ST_RELEASED;
1219 /* force to terminate the voice (no releasing echo) */
1221 awe_terminate(int voice)
1223 awe_poke(AWE_DCYSUSV(voice), 0x807F);
1224 awe_tweak_voice(voice);
1225 voices[voice].state = AWE_ST_OFF;
1228 /* turn off other voices with the same exclusive class (for drums) */
1230 awe_exclusive_off(int voice)
1234 if (voices[voice].sample == NULL)
1236 if ((exclass = voices[voice].sample->exclusiveClass) == 0)
1237 return; /* not exclusive */
1239 /* turn off voices with the same class */
1240 for (i = 0; i < awe_max_voices; i++) {
1241 if (i != voice && IS_PLAYING(i) &&
1242 voices[i].sample && voices[i].ch == voices[voice].ch &&
1243 voices[i].sample->exclusiveClass == exclass) {
1244 DEBUG(4,printk("AWE32: [exoff(%d)]\n", i));
1246 awe_voice_init(i, TRUE);
1253 * change the parameters of an audible voice
1258 awe_set_pitch(int voice, int forced)
1260 if (IS_NO_EFFECT(voice) && !forced) return;
1261 awe_poke(AWE_IP(voice), voices[voice].apitch);
1262 DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch));
1265 /* calculate & change pitch */
1267 awe_set_voice_pitch(int voice, int forced)
1269 awe_calc_pitch(voice);
1270 awe_set_pitch(voice, forced);
1273 /* change volume & cutoff */
1275 awe_set_volume(int voice, int forced)
1278 unsigned short tmp2;
1279 FX_Rec *fx = &voices[voice].cinfo->fx;
1280 FX_Rec *fx_lay = NULL;
1281 if (voices[voice].layer < MAX_LAYERS)
1282 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1284 if (!IS_PLAYING(voice) && !forced) return;
1285 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1288 tmp2 = FX_BYTE(fx, fx_lay, AWE_FX_CUTOFF,
1289 (unsigned char)voices[voice].acutoff);
1291 tmp2 |= FX_BYTE(fx, fx_lay, AWE_FX_ATTEN,
1292 (unsigned char)voices[voice].avol);
1293 awe_poke(AWE_IFATN(voice), tmp2);
1296 /* calculate & change volume */
1298 awe_set_voice_vol(int voice, int forced)
1300 if (IS_EMPTY(voice))
1302 awe_calc_volume(voice);
1303 awe_set_volume(voice, forced);
1307 /* change pan; this could make a click noise.. */
1309 awe_set_pan(int voice, int forced)
1314 FX_Rec *fx = &voices[voice].cinfo->fx;
1315 FX_Rec *fx_lay = NULL;
1316 if (voices[voice].layer < MAX_LAYERS)
1317 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1319 if (IS_NO_EFFECT(voice) && !forced) return;
1320 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1323 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
1324 if (vp->fixpan > 0) /* 0-127 */
1325 temp = 255 - (int)vp->fixpan * 2;
1328 if (vp->pan >= 0) /* 0-127 */
1329 pos = (int)vp->pan * 2 - 128;
1330 pos += voices[voice].cinfo->panning; /* -128 - 127 */
1333 limitvalue(temp, 0, 255);
1334 if (ctrls[AWE_MD_PAN_EXCHANGE]) {
1337 if (forced || temp != voices[voice].apan) {
1338 voices[voice].apan = temp;
1340 voices[voice].aaux = 0xff;
1342 voices[voice].aaux = (-temp) & 0xff;
1343 addr = vp->loopstart - 1;
1344 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START,
1345 AWE_FX_COARSE_LOOP_START, vp->mode);
1346 temp = (temp<<24) | (unsigned int)addr;
1347 awe_poke_dw(AWE_PSST(voice), temp);
1348 DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr));
1352 /* effects change during playing */
1354 awe_fx_fmmod(int voice, int forced)
1357 FX_Rec *fx = &voices[voice].cinfo->fx;
1358 FX_Rec *fx_lay = NULL;
1359 if (voices[voice].layer < MAX_LAYERS)
1360 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1362 if (IS_NO_EFFECT(voice) && !forced) return;
1363 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1365 awe_poke(AWE_FMMOD(voice),
1366 FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,
1370 /* set tremolo (lfo1) volume & frequency */
1372 awe_fx_tremfrq(int voice, int forced)
1375 FX_Rec *fx = &voices[voice].cinfo->fx;
1376 FX_Rec *fx_lay = NULL;
1377 if (voices[voice].layer < MAX_LAYERS)
1378 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1380 if (IS_NO_EFFECT(voice) && !forced) return;
1381 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1383 awe_poke(AWE_TREMFRQ(voice),
1384 FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,
1388 /* set lfo2 pitch & frequency */
1390 awe_fx_fm2frq2(int voice, int forced)
1393 FX_Rec *fx = &voices[voice].cinfo->fx;
1394 FX_Rec *fx_lay = NULL;
1395 if (voices[voice].layer < MAX_LAYERS)
1396 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1398 if (IS_NO_EFFECT(voice) && !forced) return;
1399 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1401 awe_poke(AWE_FM2FRQ2(voice),
1402 FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,
1407 /* Q & current address (Q 4bit value, MSB) */
1409 awe_fx_filterQ(int voice, int forced)
1413 FX_Rec *fx = &voices[voice].cinfo->fx;
1414 FX_Rec *fx_lay = NULL;
1415 if (voices[voice].layer < MAX_LAYERS)
1416 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1418 if (IS_NO_EFFECT(voice) && !forced) return;
1419 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1422 addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff;
1423 addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28);
1424 awe_poke_dw(AWE_CCCA(voice), addr);
1428 * calculate pitch offset
1430 * 0xE000 is no pitch offset at 44100Hz sample.
1431 * Every 4096 is one octave.
1435 awe_calc_pitch(int voice)
1437 voice_info *vp = &voices[voice];
1439 awe_chan_info *cp = voices[voice].cinfo;
1442 /* search voice information */
1443 if ((ap = vp->sample) == NULL)
1445 if (ap->index == 0) {
1446 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1447 if (awe_set_sample((awe_voice_list*)ap) == 0)
1451 /* calculate offset */
1452 if (ap->fixkey >= 0) {
1453 DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune));
1454 offset = (ap->fixkey - ap->root) * 4096 / 12;
1456 DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune));
1457 offset = (vp->note - ap->root) * 4096 / 12;
1458 DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset));
1460 offset = (offset * ap->scaleTuning) / 100;
1461 DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));
1462 offset += ap->tune * 4096 / 1200;
1463 DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));
1464 if (cp->bender != 0) {
1465 DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender));
1466 /* (819200: 1 semitone) ==> (4096: 12 semitones) */
1467 offset += cp->bender * cp->bender_range / 2400;
1470 /* add initial pitch correction */
1471 if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH))
1472 offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH];
1473 else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH))
1474 offset += cp->fx.val[AWE_FX_INIT_PITCH];
1476 /* 0xe000: root pitch */
1477 vp->apitch = 0xe000 + ap->rate_offset + offset;
1478 DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset));
1479 if (vp->apitch > 0xffff)
1480 vp->apitch = 0xffff;
1486 #ifdef AWE_HAS_GUS_COMPATIBILITY
1487 /* calculate MIDI key and semitone from the specified frequency */
1489 awe_calc_pitch_from_freq(int voice, int freq)
1491 voice_info *vp = &voices[voice];
1493 FX_Rec *fx = &voices[voice].cinfo->fx;
1494 FX_Rec *fx_lay = NULL;
1498 if (voices[voice].layer < MAX_LAYERS)
1499 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1501 /* search voice information */
1502 if ((ap = vp->sample) == NULL)
1504 if (ap->index == 0) {
1505 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1506 if (awe_set_sample((awe_voice_list*)ap) == 0)
1509 note = freq_to_note(freq);
1510 offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;
1511 offset = (offset * ap->scaleTuning) / 100;
1512 if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH))
1513 offset += fx_lay->val[AWE_FX_INIT_PITCH];
1514 else if (FX_ON(fx, AWE_FX_INIT_PITCH))
1515 offset += fx->val[AWE_FX_INIT_PITCH];
1516 vp->apitch = 0xe000 + ap->rate_offset + offset;
1517 if (vp->apitch > 0xffff)
1518 vp->apitch = 0xffff;
1522 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1526 * calculate volume attenuation
1528 * Voice volume is controlled by volume attenuation parameter.
1529 * So volume becomes maximum when avol is 0 (no attenuation), and
1530 * minimum when 255 (-96dB or silence).
1533 static int vol_table[128] = {
1534 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
1535 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
1536 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
1537 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
1538 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
1539 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
1540 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
1541 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
1544 /* tables for volume->attenuation calculation */
1545 static unsigned char voltab1[128] = {
1546 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1547 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
1548 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
1549 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
1550 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
1551 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
1552 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
1553 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
1554 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
1555 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
1556 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
1557 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
1558 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1561 static unsigned char voltab2[128] = {
1562 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
1563 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
1564 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
1565 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
1566 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
1567 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
1568 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
1569 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
1570 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
1571 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
1572 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
1573 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
1574 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
1577 static unsigned char expressiontab[128] = {
1578 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
1579 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
1580 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
1581 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
1582 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
1583 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
1584 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
1585 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
1586 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
1587 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
1588 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
1589 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
1590 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1594 awe_calc_volume(int voice)
1596 voice_info *vp = &voices[voice];
1598 awe_chan_info *cp = voices[voice].cinfo;
1601 /* search voice information */
1602 if ((ap = vp->sample) == NULL)
1606 if (ap->index == 0) {
1607 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1608 if (awe_set_sample((awe_voice_list*)ap) == 0)
1612 if (ctrls[AWE_MD_NEW_VOLUME_CALC]) {
1613 int main_vol = cp->main_vol * ap->amplitude / 127;
1614 limitvalue(vp->velocity, 0, 127);
1615 limitvalue(main_vol, 0, 127);
1616 limitvalue(cp->expression_vol, 0, 127);
1618 vol = voltab1[main_vol] + voltab2[vp->velocity];
1619 vol = (vol * 8) / 3;
1620 vol += ap->attenuation;
1621 if (cp->expression_vol < 127)
1622 vol += ((0x100 - vol) * expressiontab[cp->expression_vol])/128;
1623 vol += atten_offset;
1625 vol += ctrls[AWE_MD_ZERO_ATTEN];
1626 limitvalue(vol, 0, 255);
1631 vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127);
1632 vol = vol * ap->amplitude / 127;
1634 if (vol < 0) vol = 0;
1635 if (vol > 127) vol = 127;
1637 /* calc to attenuation */
1638 vol = vol_table[vol];
1639 vol += (int)ap->attenuation;
1640 vol += atten_offset;
1642 vol += ctrls[AWE_MD_ZERO_ATTEN];
1643 if (vol > 255) vol = 255;
1647 if (cp->bank != AWE_DRUM_BANK && ((awe_voice_parm_block*)(&ap->parm))->volatk < 0x7d) {
1649 if (vp->velocity < 70) atten = 70;
1650 else atten = vp->velocity;
1651 vp->acutoff = (atten * ap->parm.cutoff + 0xa0) >> 7;
1653 vp->acutoff = ap->parm.cutoff;
1655 DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));
1658 /* change master volume */
1660 awe_change_master_volume(short val)
1662 limitvalue(val, 0, 127);
1663 atten_offset = vol_table[val];
1664 atten_relative = TRUE;
1665 awe_update_volume();
1668 /* update volumes of all available channels */
1669 static void awe_update_volume(void)
1672 for (i = 0; i < awe_max_voices; i++)
1673 awe_set_voice_vol(i, TRUE);
1676 /* set sostenuto on */
1677 static void awe_sostenuto_on(int voice, int forced)
1679 if (IS_NO_EFFECT(voice) && !forced) return;
1680 voices[voice].sostenuto = 127;
1685 static void awe_sustain_off(int voice, int forced)
1687 if (voices[voice].state == AWE_ST_SUSTAINED) {
1688 awe_note_off(voice);
1689 awe_fx_init(voices[voice].ch);
1690 awe_voice_init(voice, FALSE);
1695 /* terminate and initialize voice */
1696 static void awe_terminate_and_init(int voice, int forced)
1698 awe_terminate(voice);
1699 awe_fx_init(voices[voice].ch);
1700 awe_voice_init(voice, TRUE);
1705 * synth operation routines
1708 #define AWE_VOICE_KEY(v) (0x8000 | (v))
1709 #define AWE_CHAN_KEY(c,n) (((c) << 8) | ((n) + 1))
1710 #define KEY_CHAN_MATCH(key,c) (((key) >> 8) == (c))
1712 /* initialize the voice */
1714 awe_voice_init(int voice, int init_all)
1716 voice_info *vp = &voices[voice];
1718 /* reset voice search key */
1719 if (playing_mode == AWE_PLAY_DIRECT)
1720 vp->key = AWE_VOICE_KEY(voice);
1724 /* clear voice mapping */
1725 voice_alloc->map[voice] = 0;
1727 /* touch the timing flag */
1728 vp->time = current_alloc_time;
1730 /* initialize other parameters if necessary */
1737 vp->cinfo = &channels[voice];
1739 vp->state = AWE_ST_OFF;
1741 /* emu8000 parameters */
1749 static void awe_fx_init(int ch)
1751 if (SINGLE_LAYER_MODE() && !ctrls[AWE_MD_KEEP_EFFECT]) {
1752 memset(&channels[ch].fx, 0, sizeof(channels[ch].fx));
1753 memset(&channels[ch].fx_layer, 0, sizeof(&channels[ch].fx_layer));
1757 /* initialize channel info */
1758 static void awe_channel_init(int ch, int init_all)
1760 awe_chan_info *cp = &channels[ch];
1763 cp->panning = 0; /* zero center */
1764 cp->bender_range = 200; /* sense * 100 */
1766 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) {
1767 cp->instr = ctrls[AWE_MD_DEF_DRUM];
1768 cp->bank = AWE_DRUM_BANK;
1770 cp->instr = ctrls[AWE_MD_DEF_PRESET];
1771 cp->bank = ctrls[AWE_MD_DEF_BANK];
1775 cp->bender = 0; /* zero tune skew */
1776 cp->expression_vol = 127;
1780 if (! ctrls[AWE_MD_KEEP_EFFECT]) {
1781 memset(&cp->fx, 0, sizeof(cp->fx));
1782 memset(&cp->fx_layer, 0, sizeof(cp->fx_layer));
1787 /* change the voice parameters; voice = channel */
1788 static void awe_voice_change(int voice, fx_affect_func func)
1791 switch (playing_mode) {
1792 case AWE_PLAY_DIRECT:
1795 case AWE_PLAY_INDIRECT:
1796 for (i = 0; i < awe_max_voices; i++)
1797 if (voices[i].key == AWE_VOICE_KEY(voice))
1801 for (i = 0; i < awe_max_voices; i++)
1802 if (KEY_CHAN_MATCH(voices[i].key, voice))
1810 * device open / close
1814 * reset status of all voices, and clear sample position flag
1817 awe_open(int dev, int mode)
1824 /* set default mode */
1825 awe_init_ctrl_parms(FALSE);
1826 atten_relative = TRUE;
1828 drum_flags = DEFAULT_DRUM_FLAGS;
1829 playing_mode = AWE_PLAY_INDIRECT;
1831 /* reset voices & channels */
1841 * reset all voices again (terminate sounds)
1851 /* set miscellaneous mode parameters
1854 awe_init_ctrl_parms(int init_all)
1857 for (i = 0; i < AWE_MD_END; i++) {
1858 if (init_all || ctrl_parms[i].init_each_time)
1859 ctrls[i] = ctrl_parms[i].value;
1864 /* sequencer I/O control:
1867 awe_ioctl(int dev, unsigned int cmd, void __user *arg)
1870 case SNDCTL_SYNTH_INFO:
1871 if (playing_mode == AWE_PLAY_DIRECT)
1872 awe_info.nr_voices = awe_max_voices;
1874 awe_info.nr_voices = AWE_MAX_CHANNELS;
1875 if (copy_to_user(arg, &awe_info, sizeof(awe_info)))
1880 case SNDCTL_SEQ_RESETSAMPLES:
1882 awe_reset_samples();
1886 case SNDCTL_SEQ_PERCMODE:
1891 case SNDCTL_SYNTH_MEMAVL:
1892 return memsize - awe_free_mem_ptr() * 2;
1896 printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd);
1903 static int voice_in_range(int voice)
1905 if (playing_mode == AWE_PLAY_DIRECT) {
1906 if (voice < 0 || voice >= awe_max_voices)
1909 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
1915 static void release_voice(int voice, int do_sustain)
1917 if (IS_NO_SOUND(voice))
1919 if (do_sustain && (voices[voice].cinfo->sustained == 127 ||
1920 voices[voice].sostenuto == 127))
1921 voices[voice].state = AWE_ST_SUSTAINED;
1923 awe_note_off(voice);
1924 awe_fx_init(voices[voice].ch);
1925 awe_voice_init(voice, FALSE);
1929 /* release all notes */
1930 static void awe_note_off_all(int do_sustain)
1933 for (i = 0; i < awe_max_voices; i++)
1934 release_voice(i, do_sustain);
1938 * not terminate, just release the voice.
1941 awe_kill_note(int dev, int voice, int note, int velocity)
1945 DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));
1946 if (! voice_in_range(voice))
1949 switch (playing_mode) {
1950 case AWE_PLAY_DIRECT:
1951 case AWE_PLAY_INDIRECT:
1952 key = AWE_VOICE_KEY(voice);
1955 case AWE_PLAY_MULTI2:
1956 v2 = voice_alloc->map[voice] >> 8;
1957 voice_alloc->map[voice] = 0;
1959 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
1961 /* continue to below */
1963 key = AWE_CHAN_KEY(voice, note);
1967 for (i = 0; i < awe_max_voices; i++) {
1968 if (voices[i].key == key)
1969 release_voice(i, TRUE);
1975 static void start_or_volume_change(int voice, int velocity)
1977 voices[voice].velocity = velocity;
1978 awe_calc_volume(voice);
1979 if (voices[voice].state == AWE_ST_STANDBY)
1981 else if (voices[voice].state == AWE_ST_ON)
1982 awe_set_volume(voice, FALSE);
1985 static void set_and_start_voice(int voice, int state)
1987 /* calculate pitch & volume parameters */
1988 voices[voice].state = state;
1989 awe_calc_pitch(voice);
1990 awe_calc_volume(voice);
1991 if (state == AWE_ST_ON)
1996 * if note is 255, identical with aftertouch function.
1997 * Otherwise, start a voice with specified not and volume.
2000 awe_start_note(int dev, int voice, int note, int velocity)
2002 int i, key, state, volonly;
2004 DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));
2005 if (! voice_in_range(voice))
2009 state = AWE_ST_STANDBY; /* stand by for playing */
2011 state = AWE_ST_ON; /* really play */
2014 switch (playing_mode) {
2015 case AWE_PLAY_DIRECT:
2016 case AWE_PLAY_INDIRECT:
2017 key = AWE_VOICE_KEY(voice);
2022 case AWE_PLAY_MULTI2:
2023 voice = voice_alloc->map[voice] >> 8;
2024 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2026 /* continue to below */
2028 if (note >= 128) { /* key volume mode */
2032 key = AWE_CHAN_KEY(voice, note);
2036 /* dynamic volume change */
2038 for (i = 0; i < awe_max_voices; i++) {
2039 if (voices[i].key == key)
2040 start_or_volume_change(i, velocity);
2045 /* if the same note still playing, stop it */
2046 if (playing_mode != AWE_PLAY_DIRECT || ctrls[AWE_MD_EXCLUSIVE_SOUND]) {
2047 for (i = 0; i < awe_max_voices; i++)
2048 if (voices[i].key == key) {
2049 if (voices[i].state == AWE_ST_ON) {
2051 awe_voice_init(i, FALSE);
2052 } else if (voices[i].state == AWE_ST_STANDBY)
2053 awe_voice_init(i, TRUE);
2057 /* allocate voices */
2058 if (playing_mode == AWE_PLAY_DIRECT)
2059 awe_alloc_one_voice(voice, note, velocity);
2061 awe_alloc_multi_voices(voice, note, velocity, key);
2063 /* turn off other voices exlusively (for drums) */
2064 for (i = 0; i < awe_max_voices; i++)
2065 if (voices[i].key == key)
2066 awe_exclusive_off(i);
2068 /* set up pitch and volume parameters */
2069 for (i = 0; i < awe_max_voices; i++) {
2070 if (voices[i].key == key && voices[i].state == AWE_ST_OFF)
2071 set_and_start_voice(i, state);
2078 /* calculate hash key */
2080 awe_search_key(int bank, int preset, int note)
2084 #if 1 /* new hash table */
2085 if (bank == AWE_DRUM_BANK)
2086 key = preset + note + 128;
2088 key = bank + preset;
2092 key %= AWE_MAX_PRESETS;
2098 /* search instrument from hash table */
2099 static awe_voice_list *
2100 awe_search_instr(int bank, int preset, int note)
2105 key = awe_search_key(bank, preset, note);
2106 for (p = preset_table[key]; p; p = p->next_bank) {
2107 if (p->instr == preset && p->bank == bank)
2110 key2 = awe_search_key(bank, preset, 0); /* search default */
2113 for (p = preset_table[key2]; p; p = p->next_bank) {
2114 if (p->instr == preset && p->bank == bank)
2121 /* assign the instrument to a voice */
2123 awe_set_instr_2(int dev, int voice, int instr_no)
2125 if (playing_mode == AWE_PLAY_MULTI2) {
2126 voice = voice_alloc->map[voice] >> 8;
2127 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2130 return awe_set_instr(dev, voice, instr_no);
2133 /* assign the instrument to a channel; voice is the channel number */
2135 awe_set_instr(int dev, int voice, int instr_no)
2137 awe_chan_info *cinfo;
2139 if (! voice_in_range(voice))
2142 if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)
2145 cinfo = &channels[voice];
2146 cinfo->instr = instr_no;
2147 DEBUG(2,printk("AWE32: [program(%d) %d]\n", voice, instr_no));
2153 /* reset all voices; terminate sounds and initialize parameters */
2158 current_alloc_time = 0;
2159 /* don't turn off voice 31 and 32. they are used also for FM voices */
2160 for (i = 0; i < awe_max_voices; i++) {
2162 awe_voice_init(i, TRUE);
2164 for (i = 0; i < AWE_MAX_CHANNELS; i++)
2165 awe_channel_init(i, TRUE);
2166 for (i = 0; i < 16; i++) {
2167 awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127;
2168 awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127;
2175 /* hardware specific control:
2176 * GUS specific and AWE32 specific controls are available.
2179 awe_hw_control(int dev, unsigned char *event)
2182 if (cmd & _AWE_MODE_FLAG)
2183 awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2184 #ifdef AWE_HAS_GUS_COMPATIBILITY
2186 awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2191 #ifdef AWE_HAS_GUS_COMPATIBILITY
2193 /* GUS compatible controls */
2195 awe_hw_gus_control(int dev, int cmd, unsigned char *event)
2202 if (MULTI_LAYER_MODE())
2204 if (cmd == _GUS_NUMVOICES)
2208 if (! voice_in_range(voice))
2211 p1 = *(unsigned short *) &event[4];
2212 p2 = *(short *) &event[6];
2213 plong = *(int*) &event[4];
2216 case _GUS_VOICESAMPLE:
2217 awe_set_instr(dev, voice, p1);
2220 case _GUS_VOICEBALA:
2221 /* 0 to 15 --> -128 to 127 */
2222 awe_panning(dev, voice, ((int)p1 << 4) - 128);
2226 case _GUS_VOICEVOL2:
2227 /* not supported yet */
2230 case _GUS_RAMPRANGE:
2235 /* volume ramping not supported */
2238 case _GUS_VOLUME_SCALE:
2241 case _GUS_VOICE_POS:
2242 FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START,
2243 (short)(plong & 0x7fff));
2244 FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START,
2245 (plong >> 15) & 0xffff);
2249 key = AWE_VOICE_KEY(voice);
2250 for (i = 0; i < awe_max_voices; i++) {
2251 if (voices[i].key == key) {
2259 awe_fx_init(voices[i].ch);
2260 awe_voice_init(i, TRUE);
2263 case _GUS_VOICEFADE:
2265 awe_fx_init(voices[i].ch);
2266 awe_voice_init(i, FALSE);
2269 case _GUS_VOICEFREQ:
2270 awe_calc_pitch_from_freq(i, plong);
2277 #endif /* gus_compat */
2280 /* AWE32 specific controls */
2282 awe_hw_awe_control(int dev, int cmd, unsigned char *event)
2290 if (! voice_in_range(voice))
2293 if (playing_mode == AWE_PLAY_MULTI2) {
2294 voice = voice_alloc->map[voice] >> 8;
2295 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2299 p1 = *(unsigned short *) &event[4];
2300 p2 = *(short *) &event[6];
2303 case _AWE_DEBUG_MODE:
2304 ctrls[AWE_MD_DEBUG_MODE] = p1;
2305 printk(KERN_DEBUG "AWE32: debug mode = %d\n", ctrls[AWE_MD_DEBUG_MODE]);
2307 case _AWE_REVERB_MODE:
2308 ctrls[AWE_MD_REVERB_MODE] = p1;
2309 awe_update_reverb_mode();
2312 case _AWE_CHORUS_MODE:
2313 ctrls[AWE_MD_CHORUS_MODE] = p1;
2314 awe_update_chorus_mode();
2317 case _AWE_REMOVE_LAST_SAMPLES:
2318 DEBUG(0,printk("AWE32: remove last samples\n"));
2320 if (locked_sf_id > 0)
2321 awe_remove_samples(locked_sf_id);
2324 case _AWE_INITIALIZE_CHIP:
2328 case _AWE_SEND_EFFECT:
2332 if (i < 0 || i >= MAX_LAYERS)
2335 awe_send_effect(voice, i, p1, p2);
2338 case _AWE_RESET_CHANNEL:
2339 awe_channel_init(voice, !p1);
2342 case _AWE_TERMINATE_ALL:
2346 case _AWE_TERMINATE_CHANNEL:
2347 awe_voice_change(voice, awe_terminate_and_init);
2350 case _AWE_RELEASE_ALL:
2351 awe_note_off_all(FALSE);
2353 case _AWE_NOTEOFF_ALL:
2354 awe_note_off_all(TRUE);
2357 case _AWE_INITIAL_VOLUME:
2358 DEBUG(0,printk("AWE32: init attenuation %d\n", p1));
2359 atten_relative = (char)p2;
2360 atten_offset = (short)p1;
2361 awe_update_volume();
2364 case _AWE_CHN_PRESSURE:
2365 channels[voice].chan_press = p1;
2366 awe_modwheel_change(voice, p1);
2369 case _AWE_CHANNEL_MODE:
2370 DEBUG(0,printk("AWE32: channel mode = %d\n", p1));
2375 case _AWE_DRUM_CHANNELS:
2376 DEBUG(0,printk("AWE32: drum flags = %x\n", p1));
2377 drum_flags = *(unsigned int*)&event[4];
2380 case _AWE_MISC_MODE:
2381 DEBUG(0,printk("AWE32: ctrl parms = %d %d\n", p1, p2));
2382 if (p1 > AWE_MD_VERSION && p1 < AWE_MD_END) {
2384 if (ctrl_parms[p1].update)
2385 ctrl_parms[p1].update();
2389 case _AWE_EQUALIZER:
2390 ctrls[AWE_MD_BASS_LEVEL] = p1;
2391 ctrls[AWE_MD_TREBLE_LEVEL] = p2;
2392 awe_update_equalizer();
2396 DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice));
2402 /* change effects */
2404 awe_send_effect(int voice, int layer, int type, int val)
2406 awe_chan_info *cinfo;
2410 cinfo = &channels[voice];
2411 if (layer >= 0 && layer < MAX_LAYERS)
2412 fx = &cinfo->fx_layer[layer];
2418 else if (type & 0x80)
2424 if (type >= 0 && type < AWE_FX_END) {
2425 DEBUG(2,printk("AWE32: effects (%d) %d %d\n", voice, type, val));
2426 if (mode == FX_FLAG_SET)
2427 FX_SET(fx, type, val);
2428 else if (mode == FX_FLAG_ADD)
2429 FX_ADD(fx, type, val);
2432 if (mode != FX_FLAG_OFF && parm_defs[type].realtime) {
2433 DEBUG(2,printk("AWE32: fx_realtime (%d)\n", voice));
2434 awe_voice_change(voice, parm_defs[type].realtime);
2440 /* change modulation wheel; voice is already mapped on multi2 mode */
2442 awe_modwheel_change(int voice, int value)
2445 awe_chan_info *cinfo;
2447 cinfo = &channels[voice];
2448 i = value * ctrls[AWE_MD_MOD_SENSE] / 1200;
2449 FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, i);
2450 awe_voice_change(voice, awe_fx_fmmod);
2451 FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, i);
2452 awe_voice_change(voice, awe_fx_fm2frq2);
2456 /* voice pressure change */
2458 awe_aftertouch(int dev, int voice, int pressure)
2462 DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure));
2463 if (! voice_in_range(voice))
2466 switch (playing_mode) {
2467 case AWE_PLAY_DIRECT:
2468 case AWE_PLAY_INDIRECT:
2469 awe_start_note(dev, voice, 255, pressure);
2471 case AWE_PLAY_MULTI2:
2472 note = (voice_alloc->map[voice] & 0xff) - 1;
2473 awe_key_pressure(dev, voice, note + 0x80, pressure);
2479 /* voice control change */
2481 awe_controller(int dev, int voice, int ctrl_num, int value)
2483 awe_chan_info *cinfo;
2485 if (! voice_in_range(voice))
2488 if (playing_mode == AWE_PLAY_MULTI2) {
2489 voice = voice_alloc->map[voice] >> 8;
2490 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2494 cinfo = &channels[voice];
2497 case CTL_BANK_SELECT: /* MIDI control #0 */
2498 DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value));
2499 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice) &&
2500 !ctrls[AWE_MD_TOGGLE_DRUM_BANK])
2502 if (value < 0 || value > 255)
2504 cinfo->bank = value;
2505 if (cinfo->bank == AWE_DRUM_BANK)
2506 DRUM_CHANNEL_ON(cinfo->channel);
2508 DRUM_CHANNEL_OFF(cinfo->channel);
2509 awe_set_instr(dev, voice, cinfo->instr);
2512 case CTL_MODWHEEL: /* MIDI control #1 */
2513 DEBUG(2,printk("AWE32: [modwheel(%d) %d]\n", voice, value));
2514 awe_modwheel_change(voice, value);
2517 case CTRL_PITCH_BENDER: /* SEQ1 V2 contorl */
2518 DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value));
2520 cinfo->bender = value;
2521 awe_voice_change(voice, awe_set_voice_pitch);
2524 case CTRL_PITCH_BENDER_RANGE: /* SEQ1 V2 control */
2525 DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value));
2526 /* value = sense x 100 */
2527 cinfo->bender_range = value;
2528 /* no audible pitch change yet.. */
2531 case CTL_EXPRESSION: /* MIDI control #11 */
2532 if (SINGLE_LAYER_MODE())
2534 case CTRL_EXPRESSION: /* SEQ1 V2 control */
2535 DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value));
2537 cinfo->expression_vol = value;
2538 awe_voice_change(voice, awe_set_voice_vol);
2541 case CTL_PAN: /* MIDI control #10 */
2542 DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value));
2543 /* (0-127) -> signed 8bit */
2544 cinfo->panning = value * 2 - 128;
2545 if (ctrls[AWE_MD_REALTIME_PAN])
2546 awe_voice_change(voice, awe_set_pan);
2549 case CTL_MAIN_VOLUME: /* MIDI control #7 */
2550 if (SINGLE_LAYER_MODE())
2551 value = (value * 100) / 16383;
2552 case CTRL_MAIN_VOLUME: /* SEQ1 V2 control */
2553 DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value));
2555 cinfo->main_vol = value;
2556 awe_voice_change(voice, awe_set_voice_vol);
2559 case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */
2560 DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value));
2561 FX_SET(&cinfo->fx, AWE_FX_REVERB, value * 2);
2564 case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */
2565 DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value));
2566 FX_SET(&cinfo->fx, AWE_FX_CHORUS, value * 2);
2569 case 120: /* all sounds off */
2570 awe_note_off_all(FALSE);
2572 case 123: /* all notes off */
2573 awe_note_off_all(TRUE);
2576 case CTL_SUSTAIN: /* MIDI control #64 */
2577 cinfo->sustained = value;
2579 awe_voice_change(voice, awe_sustain_off);
2582 case CTL_SOSTENUTO: /* MIDI control #66 */
2584 awe_voice_change(voice, awe_sostenuto_on);
2586 awe_voice_change(voice, awe_sustain_off);
2590 DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n",
2591 voice, ctrl_num, value));
2597 /* voice pan change (value = -128 - 127) */
2599 awe_panning(int dev, int voice, int value)
2601 awe_chan_info *cinfo;
2603 if (! voice_in_range(voice))
2606 if (playing_mode == AWE_PLAY_MULTI2) {
2607 voice = voice_alloc->map[voice] >> 8;
2608 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2612 cinfo = &channels[voice];
2613 cinfo->panning = value;
2614 DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, cinfo->panning));
2615 if (ctrls[AWE_MD_REALTIME_PAN])
2616 awe_voice_change(voice, awe_set_pan);
2620 /* volume mode change */
2622 awe_volume_method(int dev, int mode)
2624 /* not impremented */
2625 DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode));
2629 /* pitch wheel change: 0-16384 */
2631 awe_bender(int dev, int voice, int value)
2633 awe_chan_info *cinfo;
2635 if (! voice_in_range(voice))
2638 if (playing_mode == AWE_PLAY_MULTI2) {
2639 voice = voice_alloc->map[voice] >> 8;
2640 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2644 /* convert to zero centered value */
2645 cinfo = &channels[voice];
2646 cinfo->bender = value - 8192;
2647 DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, cinfo->bender));
2648 awe_voice_change(voice, awe_set_voice_pitch);
2653 * load a sound patch:
2654 * three types of patches are accepted: AWE, GUS, and SYSEX.
2658 awe_load_patch(int dev, int format, const char __user *addr,
2659 int offs, int count, int pmgr_flag)
2661 awe_patch_info patch;
2664 #ifdef AWE_HAS_GUS_COMPATIBILITY
2665 if (format == GUS_PATCH) {
2666 return awe_load_guspatch(addr, offs, count, pmgr_flag);
2669 if (format == SYSEX_PATCH) {
2670 /* no system exclusive message supported yet */
2672 } else if (format != AWE_PATCH) {
2673 printk(KERN_WARNING "AWE32 Error: Invalid patch format (key) 0x%x\n", format);
2677 if (count < AWE_PATCH_INFO_SIZE) {
2678 printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
2681 if (copy_from_user(((char*)&patch) + offs, addr + offs,
2682 AWE_PATCH_INFO_SIZE - offs))
2685 count -= AWE_PATCH_INFO_SIZE;
2686 if (count < patch.len) {
2687 printk(KERN_WARNING "AWE32: sample: Patch record too short (%d<%d)\n",
2692 switch (patch.type) {
2694 rc = awe_load_info(&patch, addr, count);
2697 rc = awe_load_data(&patch, addr, count);
2699 case AWE_OPEN_PATCH:
2700 rc = awe_open_patch(&patch, addr, count);
2702 case AWE_CLOSE_PATCH:
2703 rc = awe_close_patch(&patch, addr, count);
2705 case AWE_UNLOAD_PATCH:
2706 rc = awe_unload_patch(&patch, addr, count);
2708 case AWE_REPLACE_DATA:
2709 rc = awe_replace_data(&patch, addr, count);
2711 case AWE_MAP_PRESET:
2712 rc = awe_load_map(&patch, addr, count);
2714 /* case AWE_PROBE_INFO:
2715 rc = awe_probe_info(&patch, addr, count);
2717 case AWE_PROBE_DATA:
2718 rc = awe_probe_data(&patch, addr, count);
2720 case AWE_REMOVE_INFO:
2721 rc = awe_remove_info(&patch, addr, count);
2723 case AWE_LOAD_CHORUS_FX:
2724 rc = awe_load_chorus_fx(&patch, addr, count);
2726 case AWE_LOAD_REVERB_FX:
2727 rc = awe_load_reverb_fx(&patch, addr, count);
2731 printk(KERN_WARNING "AWE32 Error: unknown patch format type %d\n",
2740 /* create an sf list record */
2742 awe_create_sf(int type, char *name)
2746 /* terminate sounds */
2748 rec = (sf_list *)kmalloc(sizeof(*rec), GFP_KERNEL);
2750 return 1; /* no memory */
2751 rec->sf_id = current_sf_id + 1;
2753 if (/*current_sf_id == 0 ||*/ (type & AWE_PAT_LOCKED) != 0)
2754 locked_sf_id = current_sf_id + 1;
2755 rec->num_info = awe_free_info();
2756 rec->num_sample = awe_free_sample();
2757 rec->mem_ptr = awe_free_mem_ptr();
2758 rec->infos = rec->last_infos = NULL;
2759 rec->samples = rec->last_samples = NULL;
2761 /* add to linked-list */
2771 #ifdef AWE_ALLOW_SAMPLE_SHARING
2774 memcpy(rec->name, name, AWE_PATCH_NAME_LEN);
2776 strcpy(rec->name, "*TEMPORARY*");
2777 if (current_sf_id > 1 && name && (type & AWE_PAT_SHARED) != 0) {
2778 /* is the current font really a shared font? */
2779 if (is_shared_sf(rec->name)) {
2780 /* check if the shared font is already installed */
2782 for (p = rec->prev; p; p = p->prev) {
2783 if (is_identical_name(rec->name, p)) {
2790 #endif /* allow sharing */
2796 #ifdef AWE_ALLOW_SAMPLE_SHARING
2798 /* check if the given name is a valid shared name */
2799 #define ASC_TO_KEY(c) ((c) - 'A' + 1)
2800 static int is_shared_sf(unsigned char *name)
2802 static unsigned char id_head[4] = {
2803 ASC_TO_KEY('A'), ASC_TO_KEY('W'), ASC_TO_KEY('E'),
2806 if (memcmp(name, id_head, 4) == 0)
2811 /* check if the given name matches to the existing list */
2812 static int is_identical_name(unsigned char *name, sf_list *p)
2815 if (is_shared_sf(id) && memcmp(id, name, AWE_PATCH_NAME_LEN) == 0)
2820 /* check if the given voice info exists */
2821 static int info_duplicated(sf_list *sf, awe_voice_list *rec)
2823 /* search for all sharing lists */
2824 for (; sf; sf = sf->shared) {
2826 for (p = sf->infos; p; p = p->next) {
2827 if (p->type == V_ST_NORMAL &&
2828 p->bank == rec->bank &&
2829 p->instr == rec->instr &&
2830 p->v.low == rec->v.low &&
2831 p->v.high == rec->v.high &&
2832 p->v.sample == rec->v.sample)
2839 #endif /* AWE_ALLOW_SAMPLE_SHARING */
2842 /* free sf_list record */
2843 /* linked-list in this function is not cared */
2845 awe_free_sf(sf_list *sf)
2848 awe_voice_list *p, *next;
2849 for (p = sf->infos; p; p = next) {
2855 awe_sample_list *p, *next;
2856 for (p = sf->samples; p; p = next) {
2865 /* open patch; create sf list and set opened flag */
2867 awe_open_patch(awe_patch_info *patch, const char __user *addr, int count)
2872 if (copy_from_user(&parm, addr + AWE_PATCH_INFO_SIZE, sizeof(parm)))
2876 #ifdef AWE_ALLOW_SAMPLE_SHARING
2877 if (sftail && (parm.type & AWE_PAT_SHARED) != 0) {
2878 /* is the previous font the same font? */
2879 if (is_identical_name(parm.name, sftail)) {
2880 /* then append to the previous */
2883 if (parm.type & AWE_PAT_LOCKED)
2884 locked_sf_id = current_sf_id;
2887 #endif /* allow sharing */
2889 if (awe_create_sf(parm.type, parm.name)) {
2890 printk(KERN_ERR "AWE32: can't open: failed to alloc new list\n");
2894 patch_opened = TRUE;
2895 return current_sf_id;
2898 /* check if the patch is already opened */
2900 check_patch_opened(int type, char *name)
2902 if (! patch_opened) {
2903 if (awe_create_sf(type, name)) {
2904 printk(KERN_ERR "AWE32: failed to alloc new list\n");
2907 patch_opened = TRUE;
2913 /* close the patch; if no voice is loaded, remove the patch */
2915 awe_close_patch(awe_patch_info *patch, const char __user *addr, int count)
2917 if (patch_opened && sftail) {
2918 /* if no voice is loaded, release the current patch */
2919 if (sftail->infos == NULL) {
2921 awe_remove_samples(current_sf_id - 1);
2929 /* remove the latest patch */
2931 awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count)
2933 if (current_sf_id > 0 && current_sf_id > locked_sf_id) {
2935 awe_remove_samples(current_sf_id - 1);
2940 /* allocate voice info list records */
2941 static awe_voice_list *
2942 alloc_new_info(void)
2944 awe_voice_list *newlist;
2946 newlist = kmalloc(sizeof(*newlist), GFP_KERNEL);
2947 if (newlist == NULL) {
2948 printk(KERN_ERR "AWE32: can't alloc info table\n");
2954 /* allocate sample info list records */
2955 static awe_sample_list *
2956 alloc_new_sample(void)
2958 awe_sample_list *newlist;
2960 newlist = (awe_sample_list *)kmalloc(sizeof(*newlist), GFP_KERNEL);
2961 if (newlist == NULL) {
2962 printk(KERN_ERR "AWE32: can't alloc sample table\n");
2968 /* load voice map */
2970 awe_load_map(awe_patch_info *patch, const char __user *addr, int count)
2973 awe_voice_list *rec, *p;
2976 /* get the link info */
2977 if (count < sizeof(map)) {
2978 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
2981 if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
2984 /* check if the identical mapping already exists */
2985 p = awe_search_instr(map.map_bank, map.map_instr, map.map_key);
2986 for (; p; p = p->next_instr) {
2987 if (p->type == V_ST_MAPPED &&
2988 p->v.start == map.src_instr &&
2989 p->v.end == map.src_bank &&
2990 p->v.fixkey == map.src_key)
2991 return 0; /* already present! */
2994 if ((sf = check_patch_opened(AWE_PAT_TYPE_MAP, NULL)) == NULL)
2997 if ((rec = alloc_new_info()) == NULL)
3000 rec->bank = map.map_bank;
3001 rec->instr = map.map_instr;
3002 rec->type = V_ST_MAPPED;
3003 rec->disabled = FALSE;
3004 awe_init_voice_info(&rec->v);
3005 if (map.map_key >= 0) {
3006 rec->v.low = map.map_key;
3007 rec->v.high = map.map_key;
3009 rec->v.start = map.src_instr;
3010 rec->v.end = map.src_bank;
3011 rec->v.fixkey = map.src_key;
3012 add_sf_info(sf, rec);
3019 /* probe preset in the current list -- nothing to be loaded */
3021 awe_probe_info(awe_patch_info *patch, const char __user *addr, int count)
3023 #ifdef AWE_ALLOW_SAMPLE_SHARING
3030 /* get the link info */
3031 if (count < sizeof(map)) {
3032 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3035 if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
3038 /* check if the identical mapping already exists */
3041 p = awe_search_instr(map.src_bank, map.src_instr, map.src_key);
3042 for (; p; p = p->next_instr) {
3043 if (p->type == V_ST_NORMAL &&
3044 is_identical_holder(p->holder, sftail) &&
3045 p->v.low <= map.src_key &&
3046 p->v.high >= map.src_key)
3047 return 0; /* already present! */
3049 #endif /* allow sharing */
3054 /* probe sample in the current list -- nothing to be loaded */
3056 awe_probe_data(awe_patch_info *patch, const char __user *addr, int count)
3058 #ifdef AWE_ALLOW_SAMPLE_SHARING
3062 /* search the specified sample by optarg */
3063 if (search_sample_index(sftail, patch->optarg) != NULL)
3065 #endif /* allow sharing */
3070 /* remove the present instrument layers */
3072 remove_info(sf_list *sf, int bank, int instr)
3074 awe_voice_list *prev, *next, *p;
3078 for (p = sf->infos; p; p = next) {
3080 if (p->type == V_ST_NORMAL &&
3081 p->bank == bank && p->instr == instr) {
3082 /* remove this layer */
3087 if (p == sf->last_infos)
3088 sf->last_infos = prev;
3096 rebuild_preset_list();
3100 /* load voice information data */
3102 awe_load_info(awe_patch_info *patch, const char __user *addr, int count)
3105 awe_voice_rec_hdr hdr;
3109 awe_voice_list *rec;
3111 if (count < AWE_VOICE_REC_SIZE) {
3112 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3116 offset = AWE_PATCH_INFO_SIZE;
3117 if (copy_from_user((char*)&hdr, addr + offset, AWE_VOICE_REC_SIZE))
3119 offset += AWE_VOICE_REC_SIZE;
3121 if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
3122 printk(KERN_WARNING "AWE32 Error: Invalid voice number %d\n", hdr.nvoices);
3125 total_size = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE * hdr.nvoices;
3126 if (count < total_size) {
3127 printk(KERN_WARNING "AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n",
3128 count, hdr.nvoices);
3132 if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
3135 switch (hdr.write_mode) {
3136 case AWE_WR_EXCLUSIVE:
3137 /* exclusive mode - if the instrument already exists,
3139 for (rec = sf->infos; rec; rec = rec->next) {
3140 if (rec->type == V_ST_NORMAL &&
3141 rec->bank == hdr.bank &&
3142 rec->instr == hdr.instr)
3146 case AWE_WR_REPLACE:
3147 /* replace mode - remove the instrument if it already exists */
3148 remove_info(sf, hdr.bank, hdr.instr);
3152 /* append new layers */
3153 for (i = 0; i < hdr.nvoices; i++) {
3154 rec = alloc_new_info();
3158 rec->bank = hdr.bank;
3159 rec->instr = hdr.instr;
3160 rec->type = V_ST_NORMAL;
3161 rec->disabled = FALSE;
3163 /* copy awe_voice_info parameters */
3164 if (copy_from_user(&rec->v, addr + offset, AWE_VOICE_INFO_SIZE)) {
3168 offset += AWE_VOICE_INFO_SIZE;
3169 #ifdef AWE_ALLOW_SAMPLE_SHARING
3170 if (sf && sf->shared) {
3171 if (info_duplicated(sf, rec)) {
3176 #endif /* allow sharing */
3177 if (rec->v.mode & AWE_MODE_INIT_PARM)
3178 awe_init_voice_parm(&rec->v.parm);
3179 add_sf_info(sf, rec);
3180 awe_set_sample(rec);
3188 /* remove instrument layers */
3190 awe_remove_info(awe_patch_info *patch, const char __user *addr, int count)
3192 unsigned char bank, instr;
3195 if (! patch_opened || (sf = sftail) == NULL) {
3196 printk(KERN_WARNING "AWE32: remove_info: patch not opened\n");
3200 bank = ((unsigned short)patch->optarg >> 8) & 0xff;
3201 instr = (unsigned short)patch->optarg & 0xff;
3202 if (! remove_info(sf, bank, instr))
3208 /* load wave sample data */
3210 awe_load_data(awe_patch_info *patch, const char __user *addr, int count)
3214 awe_sample_info tmprec;
3215 awe_sample_list *rec;
3218 if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
3221 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3222 offset = AWE_PATCH_INFO_SIZE;
3223 if (copy_from_user(&tmprec, addr + offset, AWE_SAMPLE_INFO_SIZE))
3225 offset += AWE_SAMPLE_INFO_SIZE;
3226 if (size != tmprec.size) {
3227 printk(KERN_WARNING "AWE32: load: sample size differed (%d != %d)\n",
3232 if (search_sample_index(sf, tmprec.sample) != NULL) {
3233 #ifdef AWE_ALLOW_SAMPLE_SHARING
3234 /* if shared sample, skip this data */
3235 if (sf->type & AWE_PAT_SHARED)
3237 #endif /* allow sharing */
3238 DEBUG(1,printk("AWE32: sample data %d already present\n", tmprec.sample));
3242 if ((rec = alloc_new_sample()) == NULL)
3245 memcpy(&rec->v, &tmprec, sizeof(tmprec));
3247 if (rec->v.size > 0) {
3248 if ((rc = awe_write_wave_data(addr, offset, rec, -1)) < 0) {
3255 add_sf_sample(sf, rec);
3260 /* replace wave sample data */
3262 awe_replace_data(awe_patch_info *patch, const char __user *addr, int count)
3268 awe_sample_info cursmp;
3271 awe_sample_list *rec;
3273 if (! patch_opened || (sf = sftail) == NULL) {
3274 printk(KERN_WARNING "AWE32: replace: patch not opened\n");
3278 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3279 offset = AWE_PATCH_INFO_SIZE;
3280 if (copy_from_user(&cursmp, addr + offset, AWE_SAMPLE_INFO_SIZE))
3282 offset += AWE_SAMPLE_INFO_SIZE;
3283 if (cursmp.size == 0 || size != cursmp.size) {
3284 printk(KERN_WARNING "AWE32: replace: invalid sample size (%d!=%d)\n",
3288 channels = patch->optarg;
3289 if (channels <= 0 || channels > AWE_NORMAL_VOICES) {
3290 printk(KERN_WARNING "AWE32: replace: invalid channels %d\n", channels);
3294 for (rec = sf->samples; rec; rec = rec->next) {
3295 if (rec->v.sample == cursmp.sample)
3299 printk(KERN_WARNING "AWE32: replace: cannot find existing sample data %d\n",
3304 if (rec->v.size != cursmp.size) {
3305 printk(KERN_WARNING "AWE32: replace: exiting size differed (%d!=%d)\n",
3306 rec->v.size, cursmp.size);
3310 save_mem_ptr = awe_free_mem_ptr();
3311 sftail->mem_ptr = rec->v.start - awe_mem_start;
3312 memcpy(&rec->v, &cursmp, sizeof(cursmp));
3313 rec->v.sf_id = current_sf_id;
3314 if ((rc = awe_write_wave_data(addr, offset, rec, channels)) < 0)
3316 sftail->mem_ptr = save_mem_ptr;
3322 /*----------------------------------------------------------------*/
3324 static const char __user *readbuf_addr;
3325 static int readbuf_offs;
3326 static int readbuf_flags;
3328 /* initialize read buffer */
3330 readbuf_init(const char __user *addr, int offset, awe_sample_info *sp)
3332 readbuf_addr = addr;
3333 readbuf_offs = offset;
3334 readbuf_flags = sp->mode_flags;
3338 /* read directly from user buffer */
3339 static unsigned short
3340 readbuf_word(int pos)
3343 /* read from user buffer */
3344 if (readbuf_flags & AWE_SAMPLE_8BITS) {
3346 get_user(cc, (unsigned char __user *)(readbuf_addr + readbuf_offs + pos));
3347 c = (unsigned short)cc << 8; /* convert 8bit -> 16bit */
3349 get_user(c, (unsigned short __user *)(readbuf_addr + readbuf_offs + pos * 2));
3351 if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
3352 c ^= 0x8000; /* unsigned -> signed */
3356 #define readbuf_word_cache readbuf_word
3357 #define readbuf_end() /**/
3359 /*----------------------------------------------------------------*/
3361 #define BLANK_LOOP_START 8
3362 #define BLANK_LOOP_END 40
3363 #define BLANK_LOOP_SIZE 48
3365 /* loading onto memory - return the actual written size */
3367 awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *list, int channels)
3369 int i, truesize, dram_offset;
3370 awe_sample_info *sp = &list->v;
3373 /* be sure loop points start < end */
3374 if (sp->loopstart > sp->loopend) {
3375 int tmp = sp->loopstart;
3376 sp->loopstart = sp->loopend;
3380 /* compute true data size to be loaded */
3381 truesize = sp->size;
3382 if (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))
3383 truesize += sp->loopend - sp->loopstart;
3384 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK)
3385 truesize += BLANK_LOOP_SIZE;
3386 if (awe_free_mem_ptr() + truesize >= memsize/2) {
3387 DEBUG(-1,printk("AWE32 Error: Sample memory full\n"));
3391 /* recalculate address offset */
3392 sp->end -= sp->start;
3393 sp->loopstart -= sp->start;
3394 sp->loopend -= sp->start;
3396 dram_offset = awe_free_mem_ptr() + awe_mem_start;
3397 sp->start = dram_offset;
3398 sp->end += dram_offset;
3399 sp->loopstart += dram_offset;
3400 sp->loopend += dram_offset;
3402 /* set the total size (store onto obsolete checksum value) */
3406 sp->checksum = truesize;
3408 if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0)
3411 if (readbuf_init(addr, offset, sp) < 0)
3414 for (i = 0; i < sp->size; i++) {
3416 c = readbuf_word(i);
3418 if (i == sp->loopend &&
3419 (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))) {
3420 int looplen = sp->loopend - sp->loopstart;
3421 /* copy reverse loop */
3423 for (k = 1; k <= looplen; k++) {
3424 c = readbuf_word_cache(i - k);
3427 if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) {
3430 sp->start += looplen;
3437 /* if no blank loop is attached in the sample, add it */
3438 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) {
3439 for (i = 0; i < BLANK_LOOP_SIZE; i++)
3441 if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) {
3442 sp->loopstart = sp->end + BLANK_LOOP_START;
3443 sp->loopend = sp->end + BLANK_LOOP_END;
3456 /*----------------------------------------------------------------*/
3458 #ifdef AWE_HAS_GUS_COMPATIBILITY
3460 /* calculate GUS envelope time:
3461 * is this correct? i have no idea..
3464 calc_gus_envelope_time(int rate, int start, int end)
3467 r = (3 - ((rate >> 6) & 3)) * 3;
3475 return (t * 10) / (p * 441);
3478 #define calc_gus_sustain(val) (0x7f - vol_table[(val)/2])
3479 #define calc_gus_attenuation(val) vol_table[(val)/2]
3481 /* load GUS patch */
3483 awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag)
3485 struct patch_info patch;
3486 awe_voice_info *rec;
3487 awe_sample_info *smp;
3488 awe_voice_list *vrec;
3489 awe_sample_list *smprec;
3494 sizeof_patch = (int)((long)&patch.data[0] - (long)&patch); /* header size */
3495 if (size < sizeof_patch) {
3496 printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
3499 if (copy_from_user(((char*)&patch) + offs, addr + offs, sizeof_patch - offs))
3501 size -= sizeof_patch;
3502 if (size < patch.len) {
3503 printk(KERN_WARNING "AWE32 Error: Patch record too short (%d<%d)\n",
3507 if ((sf = check_patch_opened(AWE_PAT_TYPE_GUS, NULL)) == NULL)
3509 if ((smprec = alloc_new_sample()) == NULL)
3511 if ((vrec = alloc_new_info()) == NULL) {
3517 smp->sample = sf->num_sample;
3519 smp->end = patch.len;
3520 smp->loopstart = patch.loop_start;
3521 smp->loopend = patch.loop_end;
3522 smp->size = patch.len;
3524 /* set up mode flags */
3525 smp->mode_flags = 0;
3526 if (!(patch.mode & WAVE_16_BITS))
3527 smp->mode_flags |= AWE_SAMPLE_8BITS;
3528 if (patch.mode & WAVE_UNSIGNED)
3529 smp->mode_flags |= AWE_SAMPLE_UNSIGNED;
3530 smp->mode_flags |= AWE_SAMPLE_NO_BLANK;
3531 if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
3532 smp->mode_flags |= AWE_SAMPLE_SINGLESHOT;
3533 if (patch.mode & WAVE_BIDIR_LOOP)
3534 smp->mode_flags |= AWE_SAMPLE_BIDIR_LOOP;
3535 if (patch.mode & WAVE_LOOP_BACK)
3536 smp->mode_flags |= AWE_SAMPLE_REVERSE_LOOP;
3538 DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, smp->mode_flags));
3539 if (patch.mode & WAVE_16_BITS) {
3540 /* convert to word offsets */
3543 smp->loopstart /= 2;
3546 smp->checksum_flag = 0;
3549 if ((rc = awe_write_wave_data(addr, sizeof_patch, smprec, -1)) < 0) {
3554 add_sf_sample(sf, smprec);
3556 /* set up voice info */
3558 awe_init_voice_info(rec);
3559 rec->sample = sf->num_info; /* the last sample */
3560 rec->rate_offset = calc_rate_offset(patch.base_freq);
3561 note = freq_to_note(patch.base_note);
3562 rec->root = note / 100;
3563 rec->tune = -(note % 100);
3564 rec->low = freq_to_note(patch.low_note) / 100;
3565 rec->high = freq_to_note(patch.high_note) / 100;
3566 DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%d-%d)]\n",
3567 rec->rate_offset, note,
3568 rec->low, rec->high,
3569 patch.low_note, patch.high_note));
3570 /* panning position; -128 - 127 => 0-127 */
3571 rec->pan = (patch.panning + 128) / 2;
3573 /* detuning is ignored */
3574 /* 6points volume envelope */
3575 if (patch.mode & WAVE_ENVELOPES) {
3576 int attack, hold, decay, release;
3577 attack = calc_gus_envelope_time
3578 (patch.env_rate[0], 0, patch.env_offset[0]);
3579 hold = calc_gus_envelope_time
3580 (patch.env_rate[1], patch.env_offset[0],
3581 patch.env_offset[1]);
3582 decay = calc_gus_envelope_time
3583 (patch.env_rate[2], patch.env_offset[1],
3584 patch.env_offset[2]);
3585 release = calc_gus_envelope_time
3586 (patch.env_rate[3], patch.env_offset[1],
3587 patch.env_offset[4]);
3588 release += calc_gus_envelope_time
3589 (patch.env_rate[4], patch.env_offset[3],
3590 patch.env_offset[4]);
3591 release += calc_gus_envelope_time
3592 (patch.env_rate[5], patch.env_offset[4],
3593 patch.env_offset[5]);
3594 rec->parm.volatkhld = (calc_parm_hold(hold) << 8) |
3595 calc_parm_attack(attack);
3596 rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
3597 calc_parm_decay(decay);
3598 rec->parm.volrelease = 0x8000 | calc_parm_decay(release);
3599 DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release));
3600 rec->attenuation = calc_gus_attenuation(patch.env_offset[0]);
3603 /* tremolo effect */
3604 if (patch.mode & WAVE_TREMOLO) {
3605 int rate = (patch.tremolo_rate * 1000 / 38) / 42;
3606 rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
3607 DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n",
3608 patch.tremolo_rate, patch.tremolo_depth,
3609 rec->parm.tremfrq));
3611 /* vibrato effect */
3612 if (patch.mode & WAVE_VIBRATO) {
3613 int rate = (patch.vibrato_rate * 1000 / 38) / 42;
3614 rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
3615 DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n",
3616 patch.tremolo_rate, patch.tremolo_depth,
3617 rec->parm.tremfrq));
3620 /* scale_freq, scale_factor, volume, and fractions not implemented */
3622 /* append to the tail of the list */
3623 vrec->bank = ctrls[AWE_MD_GUS_BANK];
3624 vrec->instr = patch.instr_no;
3625 vrec->disabled = FALSE;
3626 vrec->type = V_ST_NORMAL;
3628 add_sf_info(sf, vrec);
3629 add_info_list(vrec);
3631 /* set the voice index */
3632 awe_set_sample(vrec);
3637 #endif /* AWE_HAS_GUS_COMPATIBILITY */
3640 * sample and voice list handlers
3643 /* append this to the current sf list */
3644 static void add_sf_info(sf_list *sf, awe_voice_list *rec)
3649 rec->v.sf_id = sf->sf_id;
3651 sf->last_infos->next = rec;
3654 sf->last_infos = rec;
3659 /* prepend this sample to sf list */
3660 static void add_sf_sample(sf_list *sf, awe_sample_list *rec)
3665 rec->v.sf_id = sf->sf_id;
3666 if (sf->last_samples)
3667 sf->last_samples->next = rec;
3670 sf->last_samples = rec;
3675 /* purge the old records which don't belong with the same file id */
3676 static void purge_old_list(awe_voice_list *rec, awe_voice_list *next)
3678 rec->next_instr = next;
3679 if (rec->bank == AWE_DRUM_BANK) {
3680 /* remove samples with the same note range */
3681 awe_voice_list *cur, *prev = rec;
3682 int low = rec->v.low;
3683 int high = rec->v.high;
3684 for (cur = next; cur; cur = cur->next_instr) {
3685 if (cur->v.low == low &&
3686 cur->v.high == high &&
3687 ! is_identical_holder(cur->holder, rec->holder))
3688 prev->next_instr = cur->next_instr;
3693 if (! is_identical_holder(next->holder, rec->holder))
3694 /* remove all samples */
3695 rec->next_instr = NULL;
3699 /* prepend to top of the preset table */
3700 static void add_info_list(awe_voice_list *rec)
3702 awe_voice_list *prev, *cur;
3708 key = awe_search_key(rec->bank, rec->instr, rec->v.low);
3710 for (cur = preset_table[key]; cur; cur = cur->next_bank) {
3711 /* search the first record with the same bank number */
3712 if (cur->instr == rec->instr && cur->bank == rec->bank) {
3713 /* replace the list with the new record */
3714 rec->next_bank = cur->next_bank;
3716 prev->next_bank = rec;
3718 preset_table[key] = rec;
3719 purge_old_list(rec, cur);
3725 /* this is the first bank record.. just add this */
3726 rec->next_instr = NULL;
3727 rec->next_bank = preset_table[key];
3728 preset_table[key] = rec;
3731 /* remove samples later than the specified sf_id */
3733 awe_remove_samples(int sf_id)
3738 awe_reset_samples();
3741 /* already removed? */
3742 if (current_sf_id <= sf_id)
3745 for (p = sftail; p; p = prev) {
3746 if (p->sf_id <= sf_id)
3753 sf_id = sftail->sf_id;
3754 sftail->next = NULL;
3759 current_sf_id = sf_id;
3760 if (locked_sf_id > sf_id)
3761 locked_sf_id = sf_id;
3763 rebuild_preset_list();
3766 /* rebuild preset search list */
3767 static void rebuild_preset_list(void)
3770 awe_voice_list *rec;
3772 memset(preset_table, 0, sizeof(preset_table));
3774 for (p = sfhead; p; p = p->next) {
3775 for (rec = p->infos; rec; rec = rec->next)
3780 /* compare the given sf_id pair */
3781 static int is_identical_holder(sf_list *sf1, sf_list *sf2)
3783 if (sf1 == NULL || sf2 == NULL)
3787 #ifdef AWE_ALLOW_SAMPLE_SHARING
3789 /* compare with the sharing id */
3792 if (sf1->sf_id < sf2->sf_id) { /* make sure id1 > id2 */
3793 sf_list *tmp; tmp = sf1; sf1 = sf2; sf2 = tmp;
3795 for (p = sf1->shared; p; p = p->shared) {
3796 if (counter++ > current_sf_id)
3797 break; /* strange sharing loop.. quit */
3802 #endif /* allow sharing */
3806 /* search the sample index matching with the given sample id */
3807 static awe_sample_list *
3808 search_sample_index(sf_list *sf, int sample)
3811 #ifdef AWE_ALLOW_SAMPLE_SHARING
3814 for (p = sf->samples; p; p = p->next) {
3815 if (p->v.sample == sample)
3819 if (counter++ > current_sf_id)
3820 break; /* strange sharing loop.. quit */
3824 for (p = sf->samples; p; p = p->next) {
3825 if (p->v.sample == sample)
3833 /* search the specified sample */
3834 /* non-zero = found */
3836 awe_set_sample(awe_voice_list *rec)
3838 awe_sample_list *smp;
3839 awe_voice_info *vp = &rec->v;
3842 if ((smp = search_sample_index(rec->holder, vp->sample)) == NULL)
3845 /* set the actual sample offsets */
3846 vp->start += smp->v.start;
3847 vp->end += smp->v.end;
3848 vp->loopstart += smp->v.loopstart;
3849 vp->loopend += smp->v.loopend;
3850 /* copy mode flags */
3851 vp->mode = smp->v.mode_flags;
3863 /* look for all voices associated with the specified note & velocity */
3865 awe_search_multi_voices(awe_voice_list *rec, int note, int velocity,
3866 awe_voice_info **vlist)
3871 for (; rec; rec = rec->next_instr) {
3872 if (note >= rec->v.low &&
3873 note <= rec->v.high &&
3874 velocity >= rec->v.vellow &&
3875 velocity <= rec->v.velhigh) {
3876 if (rec->type == V_ST_MAPPED) {
3881 vlist[nvoices++] = &rec->v;
3882 if (nvoices >= AWE_MAX_VOICES)
3889 /* store the voice list from the specified note and velocity.
3890 if the preset is mapped, seek for the destination preset, and rewrite
3891 the note number if necessary.
3894 really_alloc_voices(int bank, int instr, int *note, int velocity, awe_voice_info **vlist)
3897 awe_voice_list *vrec;
3901 vrec = awe_search_instr(bank, instr, *note);
3902 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3904 if (bank == AWE_DRUM_BANK)
3905 /* search default drumset */
3906 vrec = awe_search_instr(bank, ctrls[AWE_MD_DEF_DRUM], *note);
3908 /* search default preset */
3909 vrec = awe_search_instr(ctrls[AWE_MD_DEF_BANK], instr, *note);
3910 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3913 if (bank == AWE_DRUM_BANK && ctrls[AWE_MD_DEF_DRUM] != 0)
3914 /* search default drumset */
3915 vrec = awe_search_instr(bank, 0, *note);
3916 else if (bank != AWE_DRUM_BANK && ctrls[AWE_MD_DEF_BANK] != 0)
3917 /* search default preset */
3918 vrec = awe_search_instr(0, instr, *note);
3919 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3921 if (nvoices < 0) { /* mapping */
3922 int key = vlist[0]->fixkey;
3923 instr = vlist[0]->start;
3924 bank = vlist[0]->end;
3926 printk(KERN_ERR "AWE32: too deep mapping level\n");
3938 /* allocate voices corresponding note and velocity; supports multiple insts. */
3940 awe_alloc_multi_voices(int ch, int note, int velocity, int key)
3942 int i, v, nvoices, bank;
3943 awe_voice_info *vlist[AWE_MAX_VOICES];
3945 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch))
3946 bank = AWE_DRUM_BANK; /* always search drumset */
3948 bank = channels[ch].bank;
3950 /* check the possible voices; note may be changeable if mapped */
3951 nvoices = really_alloc_voices(bank, channels[ch].instr,
3952 ¬e, velocity, vlist);
3954 /* set the voices */
3955 current_alloc_time++;
3956 for (i = 0; i < nvoices; i++) {
3957 v = awe_clear_voice();
3958 voices[v].key = key;
3960 voices[v].note = note;
3961 voices[v].velocity = velocity;
3962 voices[v].time = current_alloc_time;
3963 voices[v].cinfo = &channels[ch];
3964 voices[v].sample = vlist[i];
3965 voices[v].state = AWE_ST_MARK;
3966 voices[v].layer = nvoices - i - 1; /* in reverse order */
3969 /* clear the mark in allocated voices */
3970 for (i = 0; i < awe_max_voices; i++) {
3971 if (voices[i].state == AWE_ST_MARK)
3972 voices[i].state = AWE_ST_OFF;
3978 /* search an empty voice.
3979 if no empty voice is found, at least terminate a voice
3982 awe_clear_voice(void)
3985 OFF=0, RELEASED, SUSTAINED, PLAYING, END
3987 struct voice_candidate_t {
3992 int i, type, vtarget;
3995 for (type = OFF; type < END; type++) {
3996 candidate[type].best = -1;
3997 candidate[type].time = current_alloc_time + 1;
3998 candidate[type].vtarget = vtarget;
4001 for (i = 0; i < awe_max_voices; i++) {
4002 if (voices[i].state & AWE_ST_OFF)
4004 else if (voices[i].state & AWE_ST_RELEASED)
4006 else if (voices[i].state & AWE_ST_SUSTAINED)
4008 else if (voices[i].state & ~AWE_ST_MARK)
4012 #ifdef AWE_CHECK_VTARGET
4013 /* get current volume */
4014 vtarget = (awe_peek_dw(AWE_VTFT(i)) >> 16) & 0xffff;
4016 if (candidate[type].best < 0 ||
4017 vtarget < candidate[type].vtarget ||
4018 (vtarget == candidate[type].vtarget &&
4019 voices[i].time < candidate[type].time)) {
4020 candidate[type].best = i;
4021 candidate[type].time = voices[i].time;
4022 candidate[type].vtarget = vtarget;
4026 for (type = OFF; type < END; type++) {
4027 if ((i = candidate[type].best) >= 0) {
4028 if (voices[i].state != AWE_ST_OFF)
4030 awe_voice_init(i, TRUE);
4038 /* search sample for the specified note & velocity and set it on the voice;
4039 * note that voice is the voice index (not channel index)
4042 awe_alloc_one_voice(int voice, int note, int velocity)
4044 int ch, nvoices, bank;
4045 awe_voice_info *vlist[AWE_MAX_VOICES];
4047 ch = voices[voice].ch;
4048 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice))
4049 bank = AWE_DRUM_BANK; /* always search drumset */
4051 bank = voices[voice].cinfo->bank;
4053 nvoices = really_alloc_voices(bank, voices[voice].cinfo->instr,
4054 ¬e, velocity, vlist);
4056 voices[voice].time = ++current_alloc_time;
4057 voices[voice].sample = vlist[0]; /* use the first one */
4058 voices[voice].layer = 0;
4059 voices[voice].note = note;
4060 voices[voice].velocity = velocity;
4066 * sequencer2 functions
4069 /* search an empty voice; used by sequencer2 */
4071 awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
4073 playing_mode = AWE_PLAY_MULTI2;
4074 awe_info.nr_voices = AWE_MAX_CHANNELS;
4075 return awe_clear_voice();
4079 /* set up voice; used by sequencer2 */
4081 awe_setup_voice(int dev, int voice, int chn)
4083 struct channel_info *info;
4084 if (synth_devs[dev] == NULL ||
4085 (info = &synth_devs[dev]->chn_info[chn]) == NULL)
4088 if (voice < 0 || voice >= awe_max_voices)
4091 DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn));
4092 channels[chn].expression_vol = info->controllers[CTL_EXPRESSION];
4093 channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME];
4094 channels[chn].panning =
4095 info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */
4096 channels[chn].bender = info->bender_value; /* zero center */
4097 channels[chn].bank = info->controllers[CTL_BANK_SELECT];
4098 channels[chn].sustained = info->controllers[CTL_SUSTAIN];
4099 if (info->controllers[CTL_EXT_EFF_DEPTH]) {
4100 FX_SET(&channels[chn].fx, AWE_FX_REVERB,
4101 info->controllers[CTL_EXT_EFF_DEPTH] * 2);
4103 if (info->controllers[CTL_CHORUS_DEPTH]) {
4104 FX_SET(&channels[chn].fx, AWE_FX_CHORUS,
4105 info->controllers[CTL_CHORUS_DEPTH] * 2);
4107 awe_set_instr(dev, chn, info->pgm_num);
4111 #ifdef CONFIG_AWE32_MIXER
4113 * AWE32 mixer device control
4116 static int awe_mixer_ioctl(int dev, unsigned int cmd, void __user *arg);
4118 static int my_mixerdev = -1;
4120 static struct mixer_operations awe_mixer_operations = {
4121 .owner = THIS_MODULE,
4123 .name = "AWE32 Equalizer",
4124 .ioctl = awe_mixer_ioctl,
4127 static void __init attach_mixer(void)
4129 if ((my_mixerdev = sound_alloc_mixerdev()) >= 0) {
4130 mixer_devs[my_mixerdev] = &awe_mixer_operations;
4134 static void unload_mixer(void)
4136 if (my_mixerdev >= 0)
4137 sound_unload_mixerdev(my_mixerdev);
4141 awe_mixer_ioctl(int dev, unsigned int cmd, void __user * arg)
4143 int i, level, value;
4145 if (((cmd >> 8) & 0xff) != 'M')
4148 if (get_user(level, (int __user *)arg))
4150 level = ((level & 0xff) + (level >> 8)) / 2;
4151 DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
4153 if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
4154 switch (cmd & 0xff) {
4155 case SOUND_MIXER_BASS:
4156 value = level * 12 / 100;
4159 ctrls[AWE_MD_BASS_LEVEL] = value;
4160 awe_update_equalizer();
4162 case SOUND_MIXER_TREBLE:
4163 value = level * 12 / 100;
4166 ctrls[AWE_MD_TREBLE_LEVEL] = value;
4167 awe_update_equalizer();
4169 case SOUND_MIXER_VOLUME:
4170 level = level * 127 / 100;
4171 if (level >= 128) level = 127;
4172 atten_relative = FALSE;
4173 atten_offset = vol_table[level];
4174 awe_update_volume();
4178 switch (cmd & 0xff) {
4179 case SOUND_MIXER_BASS:
4180 level = ctrls[AWE_MD_BASS_LEVEL] * 100 / 24;
4181 level = (level << 8) | level;
4183 case SOUND_MIXER_TREBLE:
4184 level = ctrls[AWE_MD_TREBLE_LEVEL] * 100 / 24;
4185 level = (level << 8) | level;
4187 case SOUND_MIXER_VOLUME:
4188 value = atten_offset;
4190 value += ctrls[AWE_MD_ZERO_ATTEN];
4191 for (i = 127; i > 0; i--) {
4192 if (value <= vol_table[i])
4195 level = i * 100 / 127;
4196 level = (level << 8) | level;
4198 case SOUND_MIXER_DEVMASK:
4199 level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME;
4205 if (put_user(level, (int __user *)arg))
4209 #endif /* CONFIG_AWE32_MIXER */
4213 * initialization of Emu8000
4216 /* intiailize audio channels */
4218 awe_init_audio(void)
4222 /* turn off envelope engines */
4223 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4224 awe_poke(AWE_DCYSUSV(ch), 0x80);
4227 /* reset all other parameters to zero */
4228 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4229 awe_poke(AWE_ENVVOL(ch), 0);
4230 awe_poke(AWE_ENVVAL(ch), 0);
4231 awe_poke(AWE_DCYSUS(ch), 0);
4232 awe_poke(AWE_ATKHLDV(ch), 0);
4233 awe_poke(AWE_LFO1VAL(ch), 0);
4234 awe_poke(AWE_ATKHLD(ch), 0);
4235 awe_poke(AWE_LFO2VAL(ch), 0);
4236 awe_poke(AWE_IP(ch), 0);
4237 awe_poke(AWE_IFATN(ch), 0);
4238 awe_poke(AWE_PEFE(ch), 0);
4239 awe_poke(AWE_FMMOD(ch), 0);
4240 awe_poke(AWE_TREMFRQ(ch), 0);
4241 awe_poke(AWE_FM2FRQ2(ch), 0);
4242 awe_poke_dw(AWE_PTRX(ch), 0);
4243 awe_poke_dw(AWE_VTFT(ch), 0);
4244 awe_poke_dw(AWE_PSST(ch), 0);
4245 awe_poke_dw(AWE_CSL(ch), 0);
4246 awe_poke_dw(AWE_CCCA(ch), 0);
4249 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4250 awe_poke_dw(AWE_CPF(ch), 0);
4251 awe_poke_dw(AWE_CVCF(ch), 0);
4256 /* initialize DMA address */
4260 awe_poke_dw(AWE_SMALR, 0);
4261 awe_poke_dw(AWE_SMARR, 0);
4262 awe_poke_dw(AWE_SMALW, 0);
4263 awe_poke_dw(AWE_SMARW, 0);
4267 /* initialization arrays; from ADIP */
4269 static unsigned short init1[128] = {
4270 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330,
4271 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730,
4272 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30,
4273 0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30,
4275 0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330,
4276 0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730,
4277 0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30,
4278 0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30,
4280 0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330,
4281 0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730,
4282 0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30,
4283 0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30,
4285 0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330,
4286 0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730,
4287 0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30,
4288 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30,
4291 static unsigned short init2[128] = {
4292 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
4293 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
4294 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
4295 0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
4297 0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
4298 0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
4299 0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
4300 0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
4302 0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
4303 0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
4304 0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
4305 0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
4307 0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
4308 0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
4309 0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
4310 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
4313 static unsigned short init3[128] = {
4314 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4315 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
4316 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
4317 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
4319 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
4320 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
4321 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
4322 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
4324 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
4325 0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
4326 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
4327 0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
4329 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
4330 0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
4331 0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
4332 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
4335 static unsigned short init4[128] = {
4336 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4337 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
4338 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
4339 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
4341 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
4342 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
4343 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
4344 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
4346 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
4347 0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
4348 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
4349 0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
4351 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
4352 0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
4353 0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
4354 0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
4358 /* send initialization arrays to start up */
4360 awe_init_array(void)
4362 awe_send_array(init1);
4364 awe_send_array(init2);
4365 awe_send_array(init3);
4366 awe_poke_dw(AWE_HWCF4, 0);
4367 awe_poke_dw(AWE_HWCF5, 0x83);
4368 awe_poke_dw(AWE_HWCF6, 0x8000);
4369 awe_send_array(init4);
4372 /* send an initialization array */
4374 awe_send_array(unsigned short *data)
4380 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4381 awe_poke(AWE_INIT1(i), *p);
4382 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4383 awe_poke(AWE_INIT2(i), *p);
4384 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4385 awe_poke(AWE_INIT3(i), *p);
4386 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4387 awe_poke(AWE_INIT4(i), *p);
4392 * set up awe32 channels to some known state.
4395 /* set the envelope & LFO parameters to the default values; see ADIP */
4397 awe_tweak_voice(int i)
4399 /* set all mod/vol envelope shape to minimum */
4400 awe_poke(AWE_ENVVOL(i), 0x8000);
4401 awe_poke(AWE_ENVVAL(i), 0x8000);
4402 awe_poke(AWE_DCYSUS(i), 0x7F7F);
4403 awe_poke(AWE_ATKHLDV(i), 0x7F7F);
4404 awe_poke(AWE_ATKHLD(i), 0x7F7F);
4405 awe_poke(AWE_PEFE(i), 0); /* mod envelope height to zero */
4406 awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */
4407 awe_poke(AWE_LFO2VAL(i), 0x8000);
4408 awe_poke(AWE_IP(i), 0xE000); /* no pitch shift */
4409 awe_poke(AWE_IFATN(i), 0xFF00); /* volume to minimum */
4410 awe_poke(AWE_FMMOD(i), 0);
4411 awe_poke(AWE_TREMFRQ(i), 0);
4412 awe_poke(AWE_FM2FRQ2(i), 0);
4419 /* reset all channels */
4420 for (i = 0; i < awe_max_voices; i++)
4426 * initializes the FM section of AWE32;
4427 * see Vince Vu's unofficial AWE32 programming guide
4433 #ifndef AWE_ALWAYS_INIT_FM
4434 /* if no extended memory is on board.. */
4438 DEBUG(3,printk("AWE32: initializing FM\n"));
4440 /* Initialize the last two channels for DRAM refresh and producing
4441 the reverb and chorus effects for Yamaha OPL-3 synthesizer */
4443 /* 31: FM left channel, 0xffffe0-0xffffe8 */
4444 awe_poke(AWE_DCYSUSV(30), 0x80);
4445 awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */
4446 awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 |
4447 (DEF_FM_CHORUS_DEPTH << 24));
4448 awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8));
4449 awe_poke_dw(AWE_CPF(30), 0);
4450 awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3);
4452 /* 32: FM right channel, 0xfffff0-0xfffff8 */
4453 awe_poke(AWE_DCYSUSV(31), 0x80);
4454 awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */
4455 awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 |
4456 (DEF_FM_CHORUS_DEPTH << 24));
4457 awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8));
4458 awe_poke_dw(AWE_CPF(31), 0x8000);
4459 awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3);
4461 /* skew volume & cutoff */
4462 awe_poke_dw(AWE_VTFT(30), 0x8000FFFF);
4463 awe_poke_dw(AWE_VTFT(31), 0x8000FFFF);
4465 voices[30].state = AWE_ST_FM;
4466 voices[31].state = AWE_ST_FM;
4468 /* change maximum channels to 30 */
4469 awe_max_voices = AWE_NORMAL_VOICES;
4470 if (playing_mode == AWE_PLAY_DIRECT)
4471 awe_info.nr_voices = awe_max_voices;
4473 awe_info.nr_voices = AWE_MAX_CHANNELS;
4474 voice_alloc->max_voice = awe_max_voices;
4478 * AWE32 DRAM access routines
4481 /* open DRAM write accessing mode */
4483 awe_open_dram_for_write(int offset, int channels)
4485 int vidx[AWE_NORMAL_VOICES];
4488 if (channels < 0 || channels >= AWE_NORMAL_VOICES) {
4489 channels = AWE_NORMAL_VOICES;
4490 for (i = 0; i < AWE_NORMAL_VOICES; i++)
4493 for (i = 0; i < channels; i++) {
4494 vidx[i] = awe_clear_voice();
4495 voices[vidx[i]].state = AWE_ST_MARK;
4499 /* use all channels for DMA transfer */
4500 for (i = 0; i < channels; i++) {
4501 if (vidx[i] < 0) continue;
4502 awe_poke(AWE_DCYSUSV(vidx[i]), 0x80);
4503 awe_poke_dw(AWE_VTFT(vidx[i]), 0);
4504 awe_poke_dw(AWE_CVCF(vidx[i]), 0);
4505 awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000);
4506 awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000);
4507 awe_poke_dw(AWE_PSST(vidx[i]), 0);
4508 awe_poke_dw(AWE_CSL(vidx[i]), 0);
4509 awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000);
4510 voices[vidx[i]].state = AWE_ST_DRAM;
4512 /* point channels 31 & 32 to ROM samples for DRAM refresh */
4513 awe_poke_dw(AWE_VTFT(30), 0);
4514 awe_poke_dw(AWE_PSST(30), 0x1d8);
4515 awe_poke_dw(AWE_CSL(30), 0x1e0);
4516 awe_poke_dw(AWE_CCCA(30), 0x1d8);
4517 awe_poke_dw(AWE_VTFT(31), 0);
4518 awe_poke_dw(AWE_PSST(31), 0x1d8);
4519 awe_poke_dw(AWE_CSL(31), 0x1e0);
4520 awe_poke_dw(AWE_CCCA(31), 0x1d8);
4521 voices[30].state = AWE_ST_FM;
4522 voices[31].state = AWE_ST_FM;
4524 /* if full bit is on, not ready to write on */
4525 if (awe_peek_dw(AWE_SMALW) & 0x80000000) {
4526 for (i = 0; i < channels; i++) {
4527 awe_poke_dw(AWE_CCCA(vidx[i]), 0);
4528 voices[vidx[i]].state = AWE_ST_OFF;
4530 printk("awe: not ready to write..\n");
4534 /* set address to write */
4535 awe_poke_dw(AWE_SMALW, offset);
4540 /* open DRAM for RAM size detection */
4542 awe_open_dram_for_check(void)
4545 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4546 awe_poke(AWE_DCYSUSV(i), 0x80);
4547 awe_poke_dw(AWE_VTFT(i), 0);
4548 awe_poke_dw(AWE_CVCF(i), 0);
4549 awe_poke_dw(AWE_PTRX(i), 0x40000000);
4550 awe_poke_dw(AWE_CPF(i), 0x40000000);
4551 awe_poke_dw(AWE_PSST(i), 0);
4552 awe_poke_dw(AWE_CSL(i), 0);
4553 if (i & 1) /* DMA write */
4554 awe_poke_dw(AWE_CCCA(i), 0x06000000);
4556 awe_poke_dw(AWE_CCCA(i), 0x04000000);
4557 voices[i].state = AWE_ST_DRAM;
4562 /* close dram access */
4564 awe_close_dram(void)
4567 /* wait until FULL bit in SMAxW register be false */
4568 for (i = 0; i < 10000; i++) {
4569 if (!(awe_peek_dw(AWE_SMALW) & 0x80000000))
4574 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4575 if (voices[i].state == AWE_ST_DRAM) {
4576 awe_poke_dw(AWE_CCCA(i), 0);
4577 awe_poke(AWE_DCYSUSV(i), 0x807F);
4578 voices[i].state = AWE_ST_OFF;
4585 * check dram size on AWE board
4588 /* any three numbers you like */
4589 #define UNIQUE_ID1 0x1234
4590 #define UNIQUE_ID2 0x4321
4591 #define UNIQUE_ID3 0xABCD
4594 awe_check_dram(void)
4596 if (awe_present) /* already initialized */
4599 if (memsize >= 0) { /* given by config file or module option */
4600 memsize *= 1024; /* convert to Kbytes */
4604 awe_open_dram_for_check();
4608 /* set up unique two id numbers */
4609 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET);
4610 awe_poke(AWE_SMLD, UNIQUE_ID1);
4611 awe_poke(AWE_SMLD, UNIQUE_ID2);
4613 while (memsize < AWE_MAX_DRAM_SIZE) {
4615 /* read a data on the DRAM start address */
4616 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET);
4617 awe_peek(AWE_SMLD); /* discard stale data */
4618 if (awe_peek(AWE_SMLD) != UNIQUE_ID1)
4620 if (awe_peek(AWE_SMLD) != UNIQUE_ID2)
4622 memsize += 512; /* increment 512kbytes */
4623 /* Write a unique data on the test address;
4624 * if the address is out of range, the data is written on
4625 * 0x200000(=AWE_DRAM_OFFSET). Then the two id words are
4626 * broken by this data.
4628 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + memsize*512L);
4629 awe_poke(AWE_SMLD, UNIQUE_ID3);
4631 /* read a data on the just written DRAM address */
4632 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + memsize*512L);
4633 awe_peek(AWE_SMLD); /* discard stale data */
4634 if (awe_peek(AWE_SMLD) != UNIQUE_ID3)
4639 DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", memsize));
4641 /* convert to Kbytes */
4646 /*----------------------------------------------------------------*/
4649 * chorus and reverb controls; from VV's guide
4652 /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
4653 static char chorus_defined[AWE_CHORUS_NUMBERS];
4654 static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = {
4655 {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
4656 {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
4657 {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
4658 {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
4659 {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
4660 {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
4661 {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */
4662 {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */
4666 awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count)
4668 if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) {
4669 printk(KERN_WARNING "AWE32 Error: invalid chorus mode %d for uploading\n", patch->optarg);
4672 if (count < sizeof(awe_chorus_fx_rec)) {
4673 printk(KERN_WARNING "AWE32 Error: too short chorus fx parameters\n");
4676 if (copy_from_user(&chorus_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
4677 sizeof(awe_chorus_fx_rec)))
4679 chorus_defined[patch->optarg] = TRUE;
4684 awe_set_chorus_mode(int effect)
4686 if (effect < 0 || effect >= AWE_CHORUS_NUMBERS ||
4687 (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect]))
4689 awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback);
4690 awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset);
4691 awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth);
4692 awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay);
4693 awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq);
4694 awe_poke_dw(AWE_HWCF6, 0x8000);
4695 awe_poke_dw(AWE_HWCF7, 0x0000);
4699 awe_update_chorus_mode(void)
4701 awe_set_chorus_mode(ctrls[AWE_MD_CHORUS_MODE]);
4704 /*----------------------------------------------------------------*/
4706 /* reverb mode settings; write the following 28 data of 16 bit length
4707 * on the corresponding ports in the reverb_cmds array
4709 static char reverb_defined[AWE_CHORUS_NUMBERS];
4710 static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = {
4712 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
4713 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
4714 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4715 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4718 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4719 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4720 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4721 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4724 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4725 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
4726 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
4727 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
4730 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4731 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4732 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
4733 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
4736 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
4737 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
4738 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4739 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4742 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
4743 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
4744 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4745 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4748 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
4749 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4750 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4751 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4753 {{ /* panning delay */
4754 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
4755 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4756 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4757 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4761 static struct ReverbCmdPair {
4762 unsigned short cmd, port;
4763 } reverb_cmds[28] = {
4764 {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
4765 {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
4766 {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
4767 {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
4768 {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
4769 {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
4770 {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
4774 awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count)
4776 if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) {
4777 printk(KERN_WARNING "AWE32 Error: invalid reverb mode %d for uploading\n", patch->optarg);
4780 if (count < sizeof(awe_reverb_fx_rec)) {
4781 printk(KERN_WARNING "AWE32 Error: too short reverb fx parameters\n");
4784 if (copy_from_user(&reverb_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
4785 sizeof(awe_reverb_fx_rec)))
4787 reverb_defined[patch->optarg] = TRUE;
4792 awe_set_reverb_mode(int effect)
4795 if (effect < 0 || effect >= AWE_REVERB_NUMBERS ||
4796 (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect]))
4798 for (i = 0; i < 28; i++)
4799 awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port,
4800 reverb_parm[effect].parms[i]);
4804 awe_update_reverb_mode(void)
4806 awe_set_reverb_mode(ctrls[AWE_MD_REVERB_MODE]);
4810 * treble/bass equalizer control
4813 static unsigned short bass_parm[12][3] = {
4814 {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
4815 {0xD25B, 0xD35B, 0x0000}, /* -8 */
4816 {0xD24C, 0xD34C, 0x0000}, /* -6 */
4817 {0xD23D, 0xD33D, 0x0000}, /* -4 */
4818 {0xD21F, 0xD31F, 0x0000}, /* -2 */
4819 {0xC208, 0xC308, 0x0001}, /* 0 (HW default) */
4820 {0xC219, 0xC319, 0x0001}, /* +2 */
4821 {0xC22A, 0xC32A, 0x0001}, /* +4 */
4822 {0xC24C, 0xC34C, 0x0001}, /* +6 */
4823 {0xC26E, 0xC36E, 0x0001}, /* +8 */
4824 {0xC248, 0xC348, 0x0002}, /* +10 */
4825 {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
4828 static unsigned short treble_parm[12][9] = {
4829 {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
4830 {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4831 {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4832 {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4833 {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4834 {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
4835 {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
4836 {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
4837 {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
4838 {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
4839 {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
4840 {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */
4845 * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
4848 awe_equalizer(int bass, int treble)
4852 if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
4854 awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]);
4855 awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]);
4856 awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]);
4857 awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]);
4858 awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]);
4859 awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]);
4860 awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]);
4861 awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]);
4862 awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]);
4863 awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]);
4864 w = bass_parm[bass][2] + treble_parm[treble][8];
4865 awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262));
4866 awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362));
4869 static void awe_update_equalizer(void)
4871 awe_equalizer(ctrls[AWE_MD_BASS_LEVEL], ctrls[AWE_MD_TREBLE_LEVEL]);
4875 /*----------------------------------------------------------------*/
4877 #ifdef CONFIG_AWE32_MIDIEMU
4880 * Emu8000 MIDI Emulation
4888 enum { Q_NONE, Q_VARLEN, Q_READ, Q_SYSEX, };
4890 #define MAX_MIDIBUF 64
4893 typedef struct MidiStatus {
4894 int queue; /* queue type */
4895 int qlen; /* queue length */
4896 int read; /* chars read */
4897 int status; /* current status */
4898 int chan; /* current channel */
4899 unsigned char buf[MAX_MIDIBUF];
4902 /* MIDI mode type */
4903 enum { MODE_GM, MODE_GS, MODE_XG, };
4905 /* NRPN / CC -> Emu8000 parameter converter */
4909 unsigned short (*convert)(int val);
4917 static int awe_midi_open(int dev, int mode, void (*input)(int,unsigned char), void (*output)(int));
4918 static void awe_midi_close(int dev);
4919 static int awe_midi_ioctl(int dev, unsigned cmd, void __user * arg);
4920 static int awe_midi_outputc(int dev, unsigned char midi_byte);
4922 static void init_midi_status(MidiStatus *st);
4923 static void clear_rpn(void);
4924 static void get_midi_char(MidiStatus *st, int c);
4925 /*static void queue_varlen(MidiStatus *st, int c);*/
4926 static void special_event(MidiStatus *st, int c);
4927 static void queue_read(MidiStatus *st, int c);
4928 static void midi_note_on(MidiStatus *st);
4929 static void midi_note_off(MidiStatus *st);
4930 static void midi_key_pressure(MidiStatus *st);
4931 static void midi_channel_pressure(MidiStatus *st);
4932 static void midi_pitch_wheel(MidiStatus *st);
4933 static void midi_program_change(MidiStatus *st);
4934 static void midi_control_change(MidiStatus *st);
4935 static void midi_select_bank(MidiStatus *st, int val);
4936 static void midi_nrpn_event(MidiStatus *st);
4937 static void midi_rpn_event(MidiStatus *st);
4938 static void midi_detune(int chan, int coarse, int fine);
4939 static void midi_system_exclusive(MidiStatus *st);
4940 static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
4941 static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
4942 static int xg_control_change(MidiStatus *st, int cmd, int val);
4944 #define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
4948 * OSS Midi device record
4951 static struct midi_operations awe_midi_operations =
4953 .owner = THIS_MODULE,
4954 .info = {"AWE Midi Emu", 0, 0, SNDCARD_SB},
4956 .open = awe_midi_open, /*open*/
4957 .close = awe_midi_close, /*close*/
4958 .ioctl = awe_midi_ioctl, /*ioctl*/
4959 .outputc = awe_midi_outputc, /*outputc*/
4962 static int my_mididev = -1;
4964 static void __init attach_midiemu(void)
4966 if ((my_mididev = sound_alloc_mididev()) < 0)
4967 printk ("Sound: Too many midi devices detected\n");
4969 midi_devs[my_mididev] = &awe_midi_operations;
4972 static void unload_midiemu(void)
4974 if (my_mididev >= 0)
4975 sound_unload_mididev(my_mididev);
4980 * open/close midi device
4983 static int midi_opened = FALSE;
4985 static int midi_mode;
4986 static int coarsetune, finetune;
4988 static int xg_mapping = TRUE;
4989 static int xg_bankmode;
4991 /* effect sensitivity */
4994 #define FX_RESONANCE 1
4996 #define FX_RELEASE 3
4997 #define FX_VIBRATE 4
4998 #define FX_VIBDEPTH 5
4999 #define FX_VIBDELAY 6
5002 #define DEF_FX_CUTOFF 170
5003 #define DEF_FX_RESONANCE 6
5004 #define DEF_FX_ATTACK 50
5005 #define DEF_FX_RELEASE 50
5006 #define DEF_FX_VIBRATE 30
5007 #define DEF_FX_VIBDEPTH 4
5008 #define DEF_FX_VIBDELAY 1500
5011 static int gs_sense[] =
5013 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
5014 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
5016 static int xg_sense[] =
5018 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
5019 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
5023 /* current status */
5024 static MidiStatus curst;
5028 awe_midi_open (int dev, int mode,
5029 void (*input)(int,unsigned char),
5030 void (*output)(int))
5037 midi_mode = MODE_GM;
5039 curst.queue = Q_NONE;
5044 memset(curst.buf, 0, sizeof(curst.buf));
5046 init_midi_status(&curst);
5052 awe_midi_close (int dev)
5054 midi_opened = FALSE;
5059 awe_midi_ioctl (int dev, unsigned cmd, void __user *arg)
5065 awe_midi_outputc (int dev, unsigned char midi_byte)
5070 /* force to change playing mode */
5071 playing_mode = AWE_PLAY_MULTI;
5073 get_midi_char(&curst, midi_byte);
5082 static void init_midi_status(MidiStatus *st)
5094 #define MAX_MIDI_CHANNELS 16
5097 static unsigned char nrpn[MAX_MIDI_CHANNELS]; /* current event is NRPN? */
5098 static int msb_bit; /* current event is msb for RPN/NRPN */
5099 /* RPN & NRPN indeces */
5100 static unsigned char rpn_msb[MAX_MIDI_CHANNELS], rpn_lsb[MAX_MIDI_CHANNELS];
5101 /* RPN & NRPN values */
5102 static int rpn_val[MAX_MIDI_CHANNELS];
5104 static void clear_rpn(void)
5107 for (i = 0; i < MAX_MIDI_CHANNELS; i++) {
5118 * process midi queue
5121 /* status event types */
5122 typedef void (*StatusEvent)(MidiStatus *st);
5123 static struct StatusEventList {
5124 StatusEvent process;
5126 } status_event[8] = {
5129 {midi_key_pressure, 2},
5130 {midi_control_change, 2},
5131 {midi_program_change, 1},
5132 {midi_channel_pressure, 1},
5133 {midi_pitch_wheel, 2},
5138 /* read a char from fifo and process it */
5139 static void get_midi_char(MidiStatus *st, int c)
5142 /* ignore active sense */
5147 switch (st->queue) {
5148 /* case Q_VARLEN: queue_varlen(st, c); break;*/
5155 if ((c & 0xf0) == 0xf0) {
5156 special_event(st, c);
5157 } else if (c & 0x80) { /* status change */
5158 st->status = (c >> 4) & 0x07;
5159 st->chan = c & 0x0f;
5161 st->qlen = status_event[st->status].qlen;
5170 static void special_event(MidiStatus *st, int c)
5173 case 0xf0: /* system exclusive */
5174 st->queue = Q_SYSEX;
5177 case 0xf1: /* MTC quarter frame */
5178 case 0xf3: /* song select */
5182 case 0xf2: /* song position */
5190 /* read variable length value */
5191 static void queue_varlen(MidiStatus *st, int c)
5193 st->qlen += (c & 0x7f);
5198 if (st->qlen <= 0) {
5209 static void queue_read(MidiStatus *st, int c)
5211 if (st->read < MAX_MIDIBUF) {
5212 if (st->queue != Q_SYSEX)
5214 st->buf[st->read] = (unsigned char)c;
5217 if (st->queue == Q_SYSEX && c == 0xf7) {
5218 midi_system_exclusive(st);
5220 } else if (st->queue == Q_READ && st->read >= st->qlen) {
5221 if (status_event[st->status].process)
5222 status_event[st->status].process(st);
5233 static void midi_note_on(MidiStatus *st)
5235 DEBUG(2,printk("midi: note_on (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
5236 if (st->buf[1] == 0)
5239 awe_start_note(0, st->chan, st->buf[0], st->buf[1]);
5243 static void midi_note_off(MidiStatus *st)
5245 DEBUG(2,printk("midi: note_off (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
5246 awe_kill_note(0, st->chan, st->buf[0], st->buf[1]);
5249 /* key pressure change */
5250 static void midi_key_pressure(MidiStatus *st)
5252 awe_key_pressure(0, st->chan, st->buf[0], st->buf[1]);
5255 /* channel pressure change */
5256 static void midi_channel_pressure(MidiStatus *st)
5258 channels[st->chan].chan_press = st->buf[0];
5259 awe_modwheel_change(st->chan, st->buf[0]);
5262 /* pitch wheel change */
5263 static void midi_pitch_wheel(MidiStatus *st)
5265 int val = (int)st->buf[1] * 128 + st->buf[0];
5266 awe_bender(0, st->chan, val);
5269 /* program change */
5270 static void midi_program_change(MidiStatus *st)
5273 preset = st->buf[0];
5274 if (midi_mode == MODE_GS && IS_DRUM_CHANNEL(st->chan) && preset == 127)
5276 else if (midi_mode == MODE_XG && xg_mapping && IS_DRUM_CHANNEL(st->chan))
5279 awe_set_instr(0, st->chan, preset);
5282 #define send_effect(chan,type,val) awe_send_effect(chan,-1,type,val)
5283 #define add_effect(chan,type,val) awe_send_effect(chan,-1,(type)|0x80,val)
5284 #define unset_effect(chan,type) awe_send_effect(chan,-1,(type)|0x40,0)
5286 /* midi control change */
5287 static void midi_control_change(MidiStatus *st)
5289 int cmd = st->buf[0];
5290 int val = st->buf[1];
5292 DEBUG(2,printk("midi: control (%d) %d %d\n", st->chan, cmd, val));
5293 if (midi_mode == MODE_XG) {
5294 if (xg_control_change(st, cmd, val))
5298 /* controls #31 - #64 are LSB of #0 - #31 */
5300 if (cmd >= 0x20 && cmd < 0x40) {
5306 case CTL_SOFT_PEDAL:
5308 add_effect(st->chan, AWE_FX_CUTOFF, -160);
5310 unset_effect(st->chan, AWE_FX_CUTOFF);
5313 case CTL_BANK_SELECT:
5314 midi_select_bank(st, val);
5317 /* set RPN/NRPN parameter */
5318 case CTL_REGIST_PARM_NUM_MSB:
5319 nrpn[st->chan]=0; rpn_msb[st->chan]=val;
5321 case CTL_REGIST_PARM_NUM_LSB:
5322 nrpn[st->chan]=0; rpn_lsb[st->chan]=val;
5324 case CTL_NONREG_PARM_NUM_MSB:
5325 nrpn[st->chan]=1; rpn_msb[st->chan]=val;
5327 case CTL_NONREG_PARM_NUM_LSB:
5328 nrpn[st->chan]=1; rpn_lsb[st->chan]=val;
5331 /* send RPN/NRPN entry */
5332 case CTL_DATA_ENTRY:
5334 rpn_val[st->chan] = val * 128;
5336 rpn_val[st->chan] |= val;
5338 midi_nrpn_event(st);
5343 /* increase/decrease data entry */
5344 case CTL_DATA_INCREMENT:
5345 rpn_val[st->chan]++;
5348 case CTL_DATA_DECREMENT:
5349 rpn_val[st->chan]--;
5355 awe_controller(0, st->chan, cmd, val);
5360 /* tone bank change */
5361 static void midi_select_bank(MidiStatus *st, int val)
5363 if (midi_mode == MODE_XG && msb_bit) {
5365 /* XG MSB value; not normal bank selection */
5367 case 127: /* remap to drum channel */
5368 awe_controller(0, st->chan, CTL_BANK_SELECT, 128);
5370 default: /* remap to normal channel */
5371 awe_controller(0, st->chan, CTL_BANK_SELECT, val);
5375 } else if (midi_mode == MODE_GS && !msb_bit)
5376 /* ignore LSB bank in GS mode (used for mapping) */
5379 /* normal bank controls; accept both MSB and LSB */
5380 if (! IS_DRUM_CHANNEL(st->chan)) {
5381 if (midi_mode == MODE_XG) {
5382 if (xg_bankmode) return;
5383 if (val == 64 || val == 126)
5385 } else if (midi_mode == MODE_GS && val == 127)
5387 awe_controller(0, st->chan, CTL_BANK_SELECT, val);
5396 static void midi_rpn_event(MidiStatus *st)
5399 type = (rpn_msb[st->chan]<<8) | rpn_lsb[st->chan];
5401 case 0x0000: /* Pitch bend sensitivity */
5402 /* MSB only / 1 semitone per 128 */
5404 channels[st->chan].bender_range =
5405 rpn_val[st->chan] * 100 / 128;
5409 case 0x0001: /* fine tuning: */
5410 /* MSB/LSB, 8192=center, 100/8192 cent step */
5411 finetune = rpn_val[st->chan] - 8192;
5412 midi_detune(st->chan, coarsetune, finetune);
5415 case 0x0002: /* coarse tuning */
5416 /* MSB only / 8192=center, 1 semitone per 128 */
5418 coarsetune = rpn_val[st->chan] - 8192;
5419 midi_detune(st->chan, coarsetune, finetune);
5423 case 0x7F7F: /* "lock-in" RPN */
5430 * coarse = -8192 to 8192 (100 cent per 128)
5431 * fine = -8192 to 8192 (max=100cent)
5433 static void midi_detune(int chan, int coarse, int fine)
5435 /* 4096 = 1200 cents in AWE parameter */
5437 val = coarse * 4096 / (12 * 128);
5440 send_effect(chan, AWE_FX_INIT_PITCH, val);
5442 unset_effect(chan, AWE_FX_INIT_PITCH);
5447 * system exclusive message
5448 * GM/GS/XG macros are accepted
5451 static void midi_system_exclusive(MidiStatus *st)
5454 static unsigned char gm_on_macro[] = {
5455 0x7e,0x7f,0x09,0x01,
5458 static unsigned char xg_on_macro[] = {
5459 0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,
5462 * drum channel: XX=0x1?(channel), YY=0x15, ZZ=on/off
5463 * reverb mode: XX=0x01, YY=0x30, ZZ=0-7
5464 * chorus mode: XX=0x01, YY=0x38, ZZ=0-7
5466 static unsigned char gs_pfx_macro[] = {
5467 0x41,0x10,0x42,0x12,0x40,/*XX,YY,ZZ*/
5471 /* SC88 system mode set
5472 * single module mode: XX=1
5473 * double module mode: XX=0
5475 static unsigned char gs_mode_macro[] = {
5476 0x41,0x10,0x42,0x12,0x00,0x00,0x7F,/*ZZ*/
5478 /* SC88 display macro: XX=01:bitmap, 00:text
5480 static unsigned char gs_disp_macro[] = {
5481 0x41,0x10,0x45,0x12,0x10,/*XX,00*/
5486 if (memcmp(st->buf, gm_on_macro, sizeof(gm_on_macro)) == 0) {
5487 if (midi_mode != MODE_GS && midi_mode != MODE_XG)
5488 midi_mode = MODE_GM;
5489 init_midi_status(st);
5493 else if (memcmp(st->buf, gs_pfx_macro, sizeof(gs_pfx_macro)) == 0) {
5494 if (midi_mode != MODE_GS && midi_mode != MODE_XG)
5495 midi_mode = MODE_GS;
5497 if (st->buf[5] == 0x00 && st->buf[6] == 0x7f && st->buf[7] == 0x00) {
5499 init_midi_status(st);
5502 else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x15) {
5504 int p = st->buf[5] & 0x0f;
5506 else if (p < 10) p--;
5507 if (st->buf[7] == 0)
5508 DRUM_CHANNEL_OFF(p);
5512 } else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x21) {
5514 int p = st->buf[5] & 0x0f;
5516 else if (p < 10) p--;
5517 if (! IS_DRUM_CHANNEL(p))
5518 awe_set_instr(0, p, st->buf[7]);
5520 } else if (st->buf[5] == 0x01 && st->buf[6] == 0x30) {
5522 awe_set_reverb_mode(st->buf[7]);
5524 } else if (st->buf[5] == 0x01 && st->buf[6] == 0x38) {
5526 awe_set_chorus_mode(st->buf[7]);
5528 } else if (st->buf[5] == 0x00 && st->buf[6] == 0x04) {
5530 awe_change_master_volume(st->buf[7]);
5536 else if (memcmp(st->buf, xg_on_macro, sizeof(xg_on_macro)) == 0) {
5537 midi_mode = MODE_XG;
5544 /*----------------------------------------------------------------*/
5547 * convert NRPN/control values
5550 static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
5553 for (i = 0; i < num_tables; i++) {
5554 if (table[i].control == type) {
5555 cval = table[i].convert(val);
5556 send_effect(st->chan, table[i].awe_effect, cval);
5563 static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
5566 for (i = 0; i < num_tables; i++) {
5567 if (table[i].control == type) {
5568 cval = table[i].convert(val);
5569 add_effect(st->chan, table[i].awe_effect|0x80, cval);
5578 * AWE32 NRPN effects
5581 static unsigned short fx_delay(int val);
5582 static unsigned short fx_attack(int val);
5583 static unsigned short fx_hold(int val);
5584 static unsigned short fx_decay(int val);
5585 static unsigned short fx_the_value(int val);
5586 static unsigned short fx_twice_value(int val);
5587 static unsigned short fx_conv_pitch(int val);
5588 static unsigned short fx_conv_Q(int val);
5590 /* function for each NRPN */ /* [range] units */
5591 #define fx_env1_delay fx_delay /* [0,5900] 4msec */
5592 #define fx_env1_attack fx_attack /* [0,5940] 1msec */
5593 #define fx_env1_hold fx_hold /* [0,8191] 1msec */
5594 #define fx_env1_decay fx_decay /* [0,5940] 4msec */
5595 #define fx_env1_release fx_decay /* [0,5940] 4msec */
5596 #define fx_env1_sustain fx_the_value /* [0,127] 0.75dB */
5597 #define fx_env1_pitch fx_the_value /* [-127,127] 9.375cents */
5598 #define fx_env1_cutoff fx_the_value /* [-127,127] 56.25cents */
5600 #define fx_env2_delay fx_delay /* [0,5900] 4msec */
5601 #define fx_env2_attack fx_attack /* [0,5940] 1msec */
5602 #define fx_env2_hold fx_hold /* [0,8191] 1msec */
5603 #define fx_env2_decay fx_decay /* [0,5940] 4msec */
5604 #define fx_env2_release fx_decay /* [0,5940] 4msec */
5605 #define fx_env2_sustain fx_the_value /* [0,127] 0.75dB */
5607 #define fx_lfo1_delay fx_delay /* [0,5900] 4msec */
5608 #define fx_lfo1_freq fx_twice_value /* [0,127] 84mHz */
5609 #define fx_lfo1_volume fx_twice_value /* [0,127] 0.1875dB */
5610 #define fx_lfo1_pitch fx_the_value /* [-127,127] 9.375cents */
5611 #define fx_lfo1_cutoff fx_twice_value /* [-64,63] 56.25cents */
5613 #define fx_lfo2_delay fx_delay /* [0,5900] 4msec */
5614 #define fx_lfo2_freq fx_twice_value /* [0,127] 84mHz */
5615 #define fx_lfo2_pitch fx_the_value /* [-127,127] 9.375cents */
5617 #define fx_init_pitch fx_conv_pitch /* [-8192,8192] cents */
5618 #define fx_chorus fx_the_value /* [0,255] -- */
5619 #define fx_reverb fx_the_value /* [0,255] -- */
5620 #define fx_cutoff fx_twice_value /* [0,127] 62Hz */
5621 #define fx_filterQ fx_conv_Q /* [0,127] -- */
5623 static unsigned short fx_delay(int val)
5625 return (unsigned short)calc_parm_delay(val);
5628 static unsigned short fx_attack(int val)
5630 return (unsigned short)calc_parm_attack(val);
5633 static unsigned short fx_hold(int val)
5635 return (unsigned short)calc_parm_hold(val);
5638 static unsigned short fx_decay(int val)
5640 return (unsigned short)calc_parm_decay(val);
5643 static unsigned short fx_the_value(int val)
5645 return (unsigned short)(val & 0xff);
5648 static unsigned short fx_twice_value(int val)
5650 return (unsigned short)((val * 2) & 0xff);
5653 static unsigned short fx_conv_pitch(int val)
5655 return (short)(val * 4096 / 1200);
5658 static unsigned short fx_conv_Q(int val)
5660 return (unsigned short)((val / 8) & 0xff);
5664 static ConvTable awe_effects[] =
5666 { 0, AWE_FX_LFO1_DELAY, fx_lfo1_delay},
5667 { 1, AWE_FX_LFO1_FREQ, fx_lfo1_freq},
5668 { 2, AWE_FX_LFO2_DELAY, fx_lfo2_delay},
5669 { 3, AWE_FX_LFO2_FREQ, fx_lfo2_freq},
5671 { 4, AWE_FX_ENV1_DELAY, fx_env1_delay},
5672 { 5, AWE_FX_ENV1_ATTACK,fx_env1_attack},
5673 { 6, AWE_FX_ENV1_HOLD, fx_env1_hold},
5674 { 7, AWE_FX_ENV1_DECAY, fx_env1_decay},
5675 { 8, AWE_FX_ENV1_SUSTAIN, fx_env1_sustain},
5676 { 9, AWE_FX_ENV1_RELEASE, fx_env1_release},
5678 {10, AWE_FX_ENV2_DELAY, fx_env2_delay},
5679 {11, AWE_FX_ENV2_ATTACK, fx_env2_attack},
5680 {12, AWE_FX_ENV2_HOLD, fx_env2_hold},
5681 {13, AWE_FX_ENV2_DECAY, fx_env2_decay},
5682 {14, AWE_FX_ENV2_SUSTAIN, fx_env2_sustain},
5683 {15, AWE_FX_ENV2_RELEASE, fx_env2_release},
5685 {16, AWE_FX_INIT_PITCH, fx_init_pitch},
5686 {17, AWE_FX_LFO1_PITCH, fx_lfo1_pitch},
5687 {18, AWE_FX_LFO2_PITCH, fx_lfo2_pitch},
5688 {19, AWE_FX_ENV1_PITCH, fx_env1_pitch},
5689 {20, AWE_FX_LFO1_VOLUME, fx_lfo1_volume},
5690 {21, AWE_FX_CUTOFF, fx_cutoff},
5691 {22, AWE_FX_FILTERQ, fx_filterQ},
5692 {23, AWE_FX_LFO1_CUTOFF, fx_lfo1_cutoff},
5693 {24, AWE_FX_ENV1_CUTOFF, fx_env1_cutoff},
5694 {25, AWE_FX_CHORUS, fx_chorus},
5695 {26, AWE_FX_REVERB, fx_reverb},
5698 static int num_awe_effects = numberof(awe_effects);
5702 * GS(SC88) NRPN effects; still experimental
5705 /* cutoff: quarter semitone step, max=255 */
5706 static unsigned short gs_cutoff(int val)
5708 return (val - 64) * gs_sense[FX_CUTOFF] / 50;
5711 /* resonance: 0 to 15(max) */
5712 static unsigned short gs_filterQ(int val)
5714 return (val - 64) * gs_sense[FX_RESONANCE] / 50;
5718 static unsigned short gs_attack(int val)
5720 return -(val - 64) * gs_sense[FX_ATTACK] / 50;
5724 static unsigned short gs_decay(int val)
5726 return -(val - 64) * gs_sense[FX_RELEASE] / 50;
5730 static unsigned short gs_release(int val)
5732 return -(val - 64) * gs_sense[FX_RELEASE] / 50;
5735 /* vibrato freq: 0.042Hz step, max=255 */
5736 static unsigned short gs_vib_rate(int val)
5738 return (val - 64) * gs_sense[FX_VIBRATE] / 50;
5741 /* vibrato depth: max=127, 1 octave */
5742 static unsigned short gs_vib_depth(int val)
5744 return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
5747 /* vibrato delay: -0.725msec step */
5748 static unsigned short gs_vib_delay(int val)
5750 return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
5753 static ConvTable gs_effects[] =
5755 {32, AWE_FX_CUTOFF, gs_cutoff},
5756 {33, AWE_FX_FILTERQ, gs_filterQ},
5757 {99, AWE_FX_ENV2_ATTACK, gs_attack},
5758 {100, AWE_FX_ENV2_DECAY, gs_decay},
5759 {102, AWE_FX_ENV2_RELEASE, gs_release},
5760 {8, AWE_FX_LFO1_FREQ, gs_vib_rate},
5761 {9, AWE_FX_LFO1_VOLUME, gs_vib_depth},
5762 {10, AWE_FX_LFO1_DELAY, gs_vib_delay},
5765 static int num_gs_effects = numberof(gs_effects);
5769 * NRPN events: accept as AWE32/SC88 specific controls
5772 static void midi_nrpn_event(MidiStatus *st)
5774 if (rpn_msb[st->chan] == 127 && rpn_lsb[st->chan] <= 26) {
5775 if (! msb_bit) /* both MSB/LSB necessary */
5776 send_converted_effect(awe_effects, num_awe_effects,
5777 st, rpn_lsb[st->chan],
5778 rpn_val[st->chan] - 8192);
5779 } else if (rpn_msb[st->chan] == 1) {
5780 if (msb_bit) /* only MSB is valid */
5781 add_converted_effect(gs_effects, num_gs_effects,
5782 st, rpn_lsb[st->chan],
5783 rpn_val[st->chan] / 128);
5789 * XG control effects; still experimental
5792 /* cutoff: quarter semitone step, max=255 */
5793 static unsigned short xg_cutoff(int val)
5795 return (val - 64) * xg_sense[FX_CUTOFF] / 64;
5798 /* resonance: 0(open) to 15(most nasal) */
5799 static unsigned short xg_filterQ(int val)
5801 return (val - 64) * xg_sense[FX_RESONANCE] / 64;
5805 static unsigned short xg_attack(int val)
5807 return -(val - 64) * xg_sense[FX_ATTACK] / 64;
5811 static unsigned short xg_release(int val)
5813 return -(val - 64) * xg_sense[FX_RELEASE] / 64;
5816 static ConvTable xg_effects[] =
5818 {71, AWE_FX_CUTOFF, xg_cutoff},
5819 {74, AWE_FX_FILTERQ, xg_filterQ},
5820 {72, AWE_FX_ENV2_RELEASE, xg_release},
5821 {73, AWE_FX_ENV2_ATTACK, xg_attack},
5824 static int num_xg_effects = numberof(xg_effects);
5826 static int xg_control_change(MidiStatus *st, int cmd, int val)
5828 return add_converted_effect(xg_effects, num_xg_effects, st, cmd, val);
5831 #endif /* CONFIG_AWE32_MIDIEMU */
5834 /*----------------------------------------------------------------*/
5838 * initialization of AWE driver
5842 awe_initialize(void)
5844 DEBUG(0,printk("AWE32: initializing..\n"));
5846 /* initialize hardware configuration */
5847 awe_poke(AWE_HWCF1, 0x0059);
5848 awe_poke(AWE_HWCF2, 0x0020);
5850 /* disable audio; this seems to reduce a clicking noise a bit.. */
5851 awe_poke(AWE_HWCF3, 0);
5853 /* initialize audio channels */
5856 /* initialize DMA */
5859 /* initialize init array */
5862 /* check DRAM memory size */
5865 /* initialize the FM section of the AWE32 */
5868 /* set up voice envelopes */
5872 awe_poke(AWE_HWCF3, 0x0004);
5874 /* set default values */
5875 awe_init_ctrl_parms(TRUE);
5878 awe_update_equalizer();
5880 /* set reverb & chorus modes */
5881 awe_update_reverb_mode();
5882 awe_update_chorus_mode();
5887 * Core Device Management Functions
5890 /* store values to i/o port array */
5891 static void setup_ports(int port1, int port2, int port3)
5893 awe_ports[0] = port1;
5895 port2 = port1 + 0x400;
5896 awe_ports[1] = port2;
5897 awe_ports[2] = port2 + 2;
5899 port3 = port1 + 0x800;
5900 awe_ports[3] = port3;
5901 awe_ports[4] = port3 + 2;
5903 port_setuped = TRUE;
5908 * 0x620-623, 0xA20-A23, 0xE20-E23
5912 awe_request_region(void)
5916 if (! request_region(awe_ports[0], 4, "sound driver (AWE32)"))
5918 if (! request_region(awe_ports[1], 4, "sound driver (AWE32)"))
5920 if (! request_region(awe_ports[3], 4, "sound driver (AWE32)"))
5924 release_region(awe_ports[1], 4);
5926 release_region(awe_ports[0], 4);
5931 awe_release_region(void)
5933 if (! port_setuped) return;
5934 release_region(awe_ports[0], 4);
5935 release_region(awe_ports[1], 4);
5936 release_region(awe_ports[3], 4);
5939 static int awe_attach_device(void)
5941 if (awe_present) return 0; /* for OSS38.. called twice? */
5943 /* reserve I/O ports for awedrv */
5944 if (! awe_request_region()) {
5945 printk(KERN_ERR "AWE32: I/O area already used.\n");
5949 /* set buffers to NULL */
5950 sfhead = sftail = NULL;
5952 my_dev = sound_alloc_synthdev();
5954 printk(KERN_ERR "AWE32 Error: too many synthesizers\n");
5955 awe_release_region();
5959 voice_alloc = &awe_operations.alloc;
5960 voice_alloc->max_voice = awe_max_voices;
5961 synth_devs[my_dev] = &awe_operations;
5963 #ifdef CONFIG_AWE32_MIXER
5966 #ifdef CONFIG_AWE32_MIDIEMU
5970 /* clear all samples */
5971 awe_reset_samples();
5973 /* initialize AWE32 hardware */
5976 sprintf(awe_info.name, "AWE32-%s (RAM%dk)",
5977 AWEDRV_VERSION, memsize/1024);
5978 printk(KERN_INFO "<SoundBlaster EMU8000 (RAM%dk)>\n", memsize/1024);
5985 static void awe_dettach_device(void)
5988 awe_reset_samples();
5989 awe_release_region();
5991 #ifdef CONFIG_AWE32_MIXER
5994 #ifdef CONFIG_AWE32_MIDIEMU
5997 sound_unload_synthdev(my_dev);
5998 awe_present = FALSE;
6004 * Legacy device Probing
6007 /* detect emu8000 chip on the specified address; from VV's guide */
6010 awe_detect_base(int addr)
6012 setup_ports(addr, 0, 0);
6013 if ((awe_peek(AWE_U1) & 0x000F) != 0x000C)
6015 if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058)
6017 if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003)
6019 DEBUG(0,printk("AWE32 found at %x\n", addr));
6023 static int __init awe_detect_legacy_devices(void)
6026 for (base = 0x620; base <= 0x680; base += 0x20)
6027 if (awe_detect_base(base)) {
6028 awe_attach_device();
6031 DEBUG(0,printk("AWE32 Legacy detection failed\n"));
6037 * PnP device Probing
6040 static struct pnp_device_id awe_pnp_ids[] = {
6041 {.id = "CTL0021", .driver_data = 0}, /* AWE32 WaveTable */
6042 {.id = "CTL0022", .driver_data = 0}, /* AWE64 WaveTable */
6043 {.id = "CTL0023", .driver_data = 0}, /* AWE64 Gold WaveTable */
6044 { } /* terminator */
6047 MODULE_DEVICE_TABLE(pnp, awe_pnp_ids);
6049 static int awe_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
6054 printk(KERN_ERR "AWE32: This driver only supports one AWE32 device, skipping.\n");
6057 if (!pnp_port_valid(dev,0) ||
6058 !pnp_port_valid(dev,1) ||
6059 !pnp_port_valid(dev,2)) {
6060 printk(KERN_ERR "AWE32: The PnP device does not have the required resources.\n");
6063 io1 = pnp_port_start(dev,0);
6064 io2 = pnp_port_start(dev,1);
6065 io3 = pnp_port_start(dev,2);
6066 printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x.\n",
6068 setup_ports(io1, io2, io3);
6070 awe_attach_device();
6074 static void awe_pnp_remove(struct pnp_dev *dev)
6076 awe_dettach_device();
6079 static struct pnp_driver awe_pnp_driver = {
6081 .id_table = awe_pnp_ids,
6082 .probe = awe_pnp_probe,
6083 .remove = awe_pnp_remove,
6086 static int __init awe_detect_pnp_devices(void)
6090 ret = pnp_register_driver(&awe_pnp_driver);
6092 printk(KERN_ERR "AWE32: PnP support is unavailable.\n");
6098 * device / lowlevel (module) interface
6104 printk(KERN_INFO "AWE32: Probing for WaveTable...\n");
6106 if (awe_detect_pnp_devices()>=0)
6109 printk(KERN_INFO "AWE32: Skipping PnP detection.\n");
6111 if (awe_detect_legacy_devices())
6117 static int __init attach_awe(void)
6119 return awe_detect() ? 0 : -ENODEV;
6122 static void __exit unload_awe(void)
6124 pnp_unregister_driver(&awe_pnp_driver);
6125 awe_dettach_device();
6129 module_init(attach_awe);
6130 module_exit(unload_awe);
6133 static int __init setup_awe(char *str)
6135 /* io, memsize, isapnp */
6138 str = get_options(str, ARRAY_SIZE(ints), ints);
6147 __setup("awe=", setup_awe);