Merge with 2.4.0-test3-pre4.
[linux-2.6/linux-mips.git] / drivers / sound / awe_wave.c
blob4fee7b72f5b1dfd125a4455b3de27df952590222
1 /*
2 * sound/awe_wave.c
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.
24 #include <linux/awe_voice.h>
25 #include <linux/config.h>
26 #include <linux/init.h>
27 #include <linux/module.h>
28 #include <linux/string.h>
29 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
30 #include <linux/isapnp.h>
31 #endif
33 #include "sound_config.h"
34 #include "soundmodule.h"
36 #include "awe_wave.h"
37 #include "awe_hw.h"
39 #ifdef AWE_HAS_GUS_COMPATIBILITY
40 #include "tuning.h"
41 #include <linux/ultrasound.h>
42 #endif
45 * debug message
48 #ifdef AWE_DEBUG_ON
49 #define DEBUG(LVL,XXX) {if (ctrls[AWE_MD_DEBUG_MODE] > LVL) { XXX; }}
50 #define ERRMSG(XXX) {if (ctrls[AWE_MD_DEBUG_MODE]) { XXX; }}
51 #define FATALERR(XXX) XXX
52 #else
53 #define DEBUG(LVL,XXX) /**/
54 #define ERRMSG(XXX) XXX
55 #define FATALERR(XXX) XXX
56 #endif
59 * bank and voice record
62 typedef struct _sf_list sf_list;
63 typedef struct _awe_voice_list awe_voice_list;
64 typedef struct _awe_sample_list awe_sample_list;
66 /* soundfont record */
67 struct _sf_list {
68 unsigned short sf_id; /* id number */
69 unsigned short type; /* lock & shared flags */
70 int num_info; /* current info table index */
71 int num_sample; /* current sample table index */
72 int mem_ptr; /* current word byte pointer */
73 awe_voice_list *infos, *last_infos; /* instruments */
74 awe_sample_list *samples, *last_samples; /* samples */
75 #ifdef AWE_ALLOW_SAMPLE_SHARING
76 sf_list *shared; /* shared list */
77 unsigned char name[AWE_PATCH_NAME_LEN]; /* sharing id */
78 #endif
79 sf_list *next, *prev;
82 /* instrument list */
83 struct _awe_voice_list {
84 awe_voice_info v; /* instrument information */
85 sf_list *holder; /* parent sf_list of this record */
86 unsigned char bank, instr; /* preset number information */
87 char type, disabled; /* type=normal/mapped, disabled=boolean */
88 awe_voice_list *next; /* linked list with same sf_id */
89 awe_voice_list *next_instr; /* instrument list */
90 awe_voice_list *next_bank; /* hash table list */
93 /* voice list type */
94 #define V_ST_NORMAL 0
95 #define V_ST_MAPPED 1
97 /* sample list */
98 struct _awe_sample_list {
99 awe_sample_info v; /* sample information */
100 sf_list *holder; /* parent sf_list of this record */
101 awe_sample_list *next; /* linked list with same sf_id */
104 /* sample and information table */
105 static int current_sf_id = 0; /* current number of fonts */
106 static int locked_sf_id = 0; /* locked position */
107 static sf_list *sfhead = NULL, *sftail = NULL; /* linked-lists */
109 #define awe_free_mem_ptr() (sftail ? sftail->mem_ptr : 0)
110 #define awe_free_info() (sftail ? sftail->num_info : 0)
111 #define awe_free_sample() (sftail ? sftail->num_sample : 0)
113 #define AWE_MAX_PRESETS 256
114 #define AWE_DEFAULT_PRESET 0
115 #define AWE_DEFAULT_BANK 0
116 #define AWE_DEFAULT_DRUM 0
117 #define AWE_DRUM_BANK 128
119 #define MAX_LAYERS AWE_MAX_VOICES
121 /* preset table index */
122 static awe_voice_list *preset_table[AWE_MAX_PRESETS];
125 * voice table
128 /* effects table */
129 typedef struct FX_Rec { /* channel effects */
130 unsigned char flags[AWE_FX_END];
131 short val[AWE_FX_END];
132 } FX_Rec;
135 /* channel parameters */
136 typedef struct _awe_chan_info {
137 int channel; /* channel number */
138 int bank; /* current tone bank */
139 int instr; /* current program */
140 int bender; /* midi pitchbend (-8192 - 8192) */
141 int bender_range; /* midi bender range (x100) */
142 int panning; /* panning (0-127) */
143 int main_vol; /* channel volume (0-127) */
144 int expression_vol; /* midi expression (0-127) */
145 int chan_press; /* channel pressure */
146 int sustained; /* sustain status in MIDI */
147 FX_Rec fx; /* effects */
148 FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */
149 } awe_chan_info;
151 /* voice parameters */
152 typedef struct _voice_info {
153 int state;
154 #define AWE_ST_OFF (1<<0) /* no sound */
155 #define AWE_ST_ON (1<<1) /* playing */
156 #define AWE_ST_STANDBY (1<<2) /* stand by for playing */
157 #define AWE_ST_SUSTAINED (1<<3) /* sustained */
158 #define AWE_ST_MARK (1<<4) /* marked for allocation */
159 #define AWE_ST_DRAM (1<<5) /* DRAM read/write */
160 #define AWE_ST_FM (1<<6) /* reserved for FM */
161 #define AWE_ST_RELEASED (1<<7) /* released */
163 int ch; /* midi channel */
164 int key; /* internal key for search */
165 int layer; /* layer number (for channel mode only) */
166 int time; /* allocated time */
167 awe_chan_info *cinfo; /* channel info */
169 int note; /* midi key (0-127) */
170 int velocity; /* midi velocity (0-127) */
171 int sostenuto; /* sostenuto on/off */
172 awe_voice_info *sample; /* assigned voice */
174 /* EMU8000 parameters */
175 int apitch; /* pitch parameter */
176 int avol; /* volume parameter */
177 int apan; /* panning parameter */
178 int acutoff; /* cutoff parameter */
179 short aaux; /* aux word */
180 } voice_info;
182 /* voice information */
183 static voice_info voices[AWE_MAX_VOICES];
185 #define IS_NO_SOUND(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED))
186 #define IS_NO_EFFECT(v) (voices[v].state != AWE_ST_ON)
187 #define IS_PLAYING(v) (voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED))
188 #define IS_EMPTY(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM))
191 /* MIDI channel effects information (for hw control) */
192 static awe_chan_info channels[AWE_MAX_CHANNELS];
196 * global variables
199 #ifndef AWE_DEFAULT_BASE_ADDR
200 #define AWE_DEFAULT_BASE_ADDR 0 /* autodetect */
201 #endif
203 #ifndef AWE_DEFAULT_MEM_SIZE
204 #define AWE_DEFAULT_MEM_SIZE -1 /* autodetect */
205 #endif
207 int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
208 int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
209 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
210 static int isapnp = 1;
211 #else
212 static int isapnp = 0;
213 #endif
215 MODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>");
216 MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver");
217 MODULE_PARM(io, "i");
218 MODULE_PARM_DESC(io, "base i/o port of Emu8000");
219 MODULE_PARM(memsize, "i");
220 MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes");
221 MODULE_PARM(isapnp, "i");
222 MODULE_PARM_DESC(isapnp, "use ISAPnP detection");
223 EXPORT_NO_SYMBOLS;
225 /* DRAM start offset */
226 static int awe_mem_start = AWE_DRAM_OFFSET;
228 /* maximum channels for playing */
229 static int awe_max_voices = AWE_MAX_VOICES;
231 static int patch_opened = 0; /* sample already loaded? */
233 static char atten_relative = FALSE;
234 static short atten_offset = 0;
236 static int awe_present = FALSE; /* awe device present? */
237 static int awe_busy = FALSE; /* awe device opened? */
239 static int my_dev = -1;
241 #define DEFAULT_DRUM_FLAGS ((1 << 9) | (1 << 25))
242 #define IS_DRUM_CHANNEL(c) (drum_flags & (1 << (c)))
243 #define DRUM_CHANNEL_ON(c) (drum_flags |= (1 << (c)))
244 #define DRUM_CHANNEL_OFF(c) (drum_flags &= ~(1 << (c)))
245 static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */
247 static int playing_mode = AWE_PLAY_INDIRECT;
248 #define SINGLE_LAYER_MODE() (playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT)
249 #define MULTI_LAYER_MODE() (playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2)
251 static int current_alloc_time = 0; /* voice allocation index for channel mode */
253 static struct synth_info awe_info = {
254 "AWE32 Synth", /* name */
255 0, /* device */
256 SYNTH_TYPE_SAMPLE, /* synth_type */
257 SAMPLE_TYPE_AWE32, /* synth_subtype */
258 0, /* perc_mode (obsolete) */
259 AWE_MAX_VOICES, /* nr_voices */
260 0, /* nr_drums (obsolete) */
261 400 /* instr_bank_size */
265 static struct voice_alloc_info *voice_alloc; /* set at initialization */
269 * function prototypes
272 static int awe_check_port(void);
273 static void awe_request_region(void);
274 static void awe_release_region(void);
276 static void awe_reset_samples(void);
277 /* emu8000 chip i/o access */
278 static void setup_ports(int p1, int p2, int p3);
279 static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);
280 static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);
281 static unsigned short awe_peek(unsigned short cmd, unsigned short port);
282 static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);
283 static void awe_wait(unsigned short delay);
285 /* initialize emu8000 chip */
286 static int _attach_awe(void);
287 static void _unload_awe(void);
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);
325 #endif
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, caddr_t 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 *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);
360 #endif
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);
367 /* voice search */
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 *addr, int count);
377 static int awe_close_patch(awe_patch_info *patch, const char *addr, int count);
378 static int awe_unload_patch(awe_patch_info *patch, const char *addr, int count);
379 static int awe_load_info(awe_patch_info *patch, const char *addr, int count);
380 static int awe_remove_info(awe_patch_info *patch, const char *addr, int count);
381 static int awe_load_data(awe_patch_info *patch, const char *addr, int count);
382 static int awe_replace_data(awe_patch_info *patch, const char *addr, int count);
383 static int awe_load_map(awe_patch_info *patch, const char *addr, int count);
384 #ifdef AWE_HAS_GUS_COMPATIBILITY
385 static int awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag);
386 #endif
387 /*static int awe_probe_info(awe_patch_info *patch, const char *addr, int count);*/
388 static int awe_probe_data(awe_patch_info *patch, const char *addr, int count);
389 static sf_list *check_patch_opened(int type, char *name);
390 static int awe_write_wave_data(const char *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 *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 *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);
436 #endif
438 #ifdef CONFIG_AWE32_MIDIEMU
439 static void attach_midiemu(void);
440 static void unload_midiemu(void);
441 #endif
443 #define limitvalue(x, a, b) if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b)
446 * control parameters
450 #ifdef AWE_USE_NEW_VOLUME_CALC
451 #define DEF_VOLUME_CALC TRUE
452 #else
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 {
464 int value;
465 int init_each_time;
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 "EMU8K",
500 &awe_info,
502 SYNTH_TYPE_SAMPLE,
503 SAMPLE_TYPE_AWE32,
504 awe_open,
505 awe_close,
506 awe_ioctl,
507 awe_kill_note,
508 awe_start_note,
509 awe_set_instr_2,
510 awe_reset,
511 awe_hw_control,
512 awe_load_patch,
513 awe_aftertouch,
514 awe_controller,
515 awe_panning,
516 awe_volume_method,
517 awe_bender,
518 awe_alloc,
519 awe_setup_voice
524 * General attach / unload interface
527 static int __init _attach_awe(void)
529 if (awe_present) return 0; /* for OSS38.. called twice? */
531 /* check presence of AWE32 card */
532 if (! awe_detect()) {
533 printk(KERN_ERR "AWE32: not detected\n");
534 return 0;
537 /* check AWE32 ports are available */
538 if (awe_check_port()) {
539 printk(KERN_ERR "AWE32: I/O area already used.\n");
540 return 0;
543 /* set buffers to NULL */
544 sfhead = sftail = NULL;
546 my_dev = sound_alloc_synthdev();
547 if (my_dev == -1) {
548 printk(KERN_ERR "AWE32 Error: too many synthesizers\n");
549 return 0;
552 voice_alloc = &awe_operations.alloc;
553 voice_alloc->max_voice = awe_max_voices;
554 synth_devs[my_dev] = &awe_operations;
556 #ifdef CONFIG_AWE32_MIXER
557 attach_mixer();
558 #endif
559 #ifdef CONFIG_AWE32_MIDIEMU
560 attach_midiemu();
561 #endif
563 /* reserve I/O ports for awedrv */
564 awe_request_region();
566 /* clear all samples */
567 awe_reset_samples();
569 /* intialize AWE32 hardware */
570 awe_initialize();
572 sprintf(awe_info.name, "AWE32-%s (RAM%dk)",
573 AWEDRV_VERSION, memsize/1024);
574 printk(KERN_INFO "<SoundBlaster EMU8000 (RAM%dk)>\n", memsize/1024);
576 awe_present = TRUE;
578 SOUND_LOCK;
580 return 1;
584 static void free_tables(void)
586 if (sftail) {
587 sf_list *p, *prev;
588 for (p = sftail; p; p = prev) {
589 prev = p->prev;
590 awe_free_sf(p);
593 sfhead = sftail = NULL;
597 static void __exit _unload_awe(void)
599 if (awe_present) {
600 awe_reset_samples();
601 awe_release_region();
602 free_tables();
603 #ifdef CONFIG_AWE32_MIXER
604 unload_mixer();
605 #endif
606 #ifdef CONFIG_AWE32_MIDIEMU
607 unload_midiemu();
608 #endif
609 sound_unload_synthdev(my_dev);
610 awe_present = FALSE;
611 SOUND_LOCK_END;
617 * clear sample tables
620 static void
621 awe_reset_samples(void)
623 /* free all bank tables */
624 memset(preset_table, 0, sizeof(preset_table));
625 free_tables();
627 current_sf_id = 0;
628 locked_sf_id = 0;
629 patch_opened = 0;
634 * EMU register access
637 /* select a given AWE32 pointer */
638 static int awe_ports[5];
639 static int port_setuped = FALSE;
640 static int awe_cur_cmd = -1;
641 #define awe_set_cmd(cmd) \
642 if (awe_cur_cmd != cmd) { outw(cmd, awe_ports[Pointer]); awe_cur_cmd = cmd; }
644 /* store values to i/o port array */
645 static void setup_ports(int port1, int port2, int port3)
647 awe_ports[0] = port1;
648 if (port2 == 0)
649 port2 = port1 + 0x400;
650 awe_ports[1] = port2;
651 awe_ports[2] = port2 + 2;
652 if (port3 == 0)
653 port3 = port1 + 0x800;
654 awe_ports[3] = port3;
655 awe_ports[4] = port3 + 2;
657 port_setuped = TRUE;
660 /* write 16bit data */
661 static void
662 awe_poke(unsigned short cmd, unsigned short port, unsigned short data)
664 awe_set_cmd(cmd);
665 outw(data, awe_ports[port]);
668 /* write 32bit data */
669 static void
670 awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data)
672 unsigned short addr = awe_ports[port];
673 awe_set_cmd(cmd);
674 outw(data, addr); /* write lower 16 bits */
675 outw(data >> 16, addr + 2); /* write higher 16 bits */
678 /* read 16bit data */
679 static unsigned short
680 awe_peek(unsigned short cmd, unsigned short port)
682 unsigned short k;
683 awe_set_cmd(cmd);
684 k = inw(awe_ports[port]);
685 return k;
688 /* read 32bit data */
689 static unsigned int
690 awe_peek_dw(unsigned short cmd, unsigned short port)
692 unsigned int k1, k2;
693 unsigned short addr = awe_ports[port];
694 awe_set_cmd(cmd);
695 k1 = inw(addr);
696 k2 = inw(addr + 2);
697 k1 |= k2 << 16;
698 return k1;
701 /* wait delay number of AWE32 44100Hz clocks */
702 #ifdef WAIT_BY_LOOP /* wait by loop -- that's not good.. */
703 static void
704 awe_wait(unsigned short delay)
706 unsigned short clock, target;
707 unsigned short port = awe_ports[AWE_WC_Port];
708 int counter;
710 /* sample counter */
711 awe_set_cmd(AWE_WC_Cmd);
712 clock = (unsigned short)inw(port);
713 target = clock + delay;
714 counter = 0;
715 if (target < clock) {
716 for (; (unsigned short)inw(port) > target; counter++)
717 if (counter > 65536)
718 break;
720 for (; (unsigned short)inw(port) < target; counter++)
721 if (counter > 65536)
722 break;
724 #else
726 static void awe_wait(unsigned short delay)
728 current->state = TASK_INTERRUPTIBLE;
729 schedule_timeout((HZ*(unsigned long)delay + 44099)/44100);
732 static void awe_wait(unsigned short delay)
734 udelay(((unsigned long)delay * 1000000L + 44099) / 44100);
737 #endif /* wait by loop */
739 /* write a word data */
740 #define awe_write_dram(c) awe_poke(AWE_SMLD, c)
744 * port check / request
745 * 0x620-623, 0xA20-A23, 0xE20-E23
748 static int __init
749 awe_check_port(void)
751 if (! port_setuped) return 0;
752 return (check_region(awe_ports[0], 4) ||
753 check_region(awe_ports[1], 4) ||
754 check_region(awe_ports[3], 4));
757 static void __init
758 awe_request_region(void)
760 if (! port_setuped) return;
761 request_region(awe_ports[0], 4, "sound driver (AWE32)");
762 request_region(awe_ports[1], 4, "sound driver (AWE32)");
763 request_region(awe_ports[3], 4, "sound driver (AWE32)");
766 static void __exit
767 awe_release_region(void)
769 if (! port_setuped) return;
770 release_region(awe_ports[0], 4);
771 release_region(awe_ports[1], 4);
772 release_region(awe_ports[3], 4);
777 * initialization of AWE driver
780 static void
781 awe_initialize(void)
783 DEBUG(0,printk("AWE32: initializing..\n"));
785 /* initialize hardware configuration */
786 awe_poke(AWE_HWCF1, 0x0059);
787 awe_poke(AWE_HWCF2, 0x0020);
789 /* disable audio; this seems to reduce a clicking noise a bit.. */
790 awe_poke(AWE_HWCF3, 0);
792 /* initialize audio channels */
793 awe_init_audio();
795 /* initialize DMA */
796 awe_init_dma();
798 /* initialize init array */
799 awe_init_array();
801 /* check DRAM memory size */
802 awe_check_dram();
804 /* initialize the FM section of the AWE32 */
805 awe_init_fm();
807 /* set up voice envelopes */
808 awe_tweak();
810 /* enable audio */
811 awe_poke(AWE_HWCF3, 0x0004);
813 /* set default values */
814 awe_init_ctrl_parms(TRUE);
816 /* set equalizer */
817 awe_update_equalizer();
819 /* set reverb & chorus modes */
820 awe_update_reverb_mode();
821 awe_update_chorus_mode();
826 * AWE32 voice parameters
829 /* initialize voice_info record */
830 static void
831 awe_init_voice_info(awe_voice_info *vp)
833 vp->sample = 0;
834 vp->rate_offset = 0;
836 vp->start = 0;
837 vp->end = 0;
838 vp->loopstart = 0;
839 vp->loopend = 0;
840 vp->mode = 0;
841 vp->root = 60;
842 vp->tune = 0;
843 vp->low = 0;
844 vp->high = 127;
845 vp->vellow = 0;
846 vp->velhigh = 127;
848 vp->fixkey = -1;
849 vp->fixvel = -1;
850 vp->fixpan = -1;
851 vp->pan = -1;
853 vp->exclusiveClass = 0;
854 vp->amplitude = 127;
855 vp->attenuation = 0;
856 vp->scaleTuning = 100;
858 awe_init_voice_parm(&vp->parm);
861 /* initialize voice_parm record:
862 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
863 * Vibrato and Tremolo effects are zero.
864 * Cutoff is maximum.
865 * Chorus and Reverb effects are zero.
867 static void
868 awe_init_voice_parm(awe_voice_parm *pp)
870 pp->moddelay = 0x8000;
871 pp->modatkhld = 0x7f7f;
872 pp->moddcysus = 0x7f7f;
873 pp->modrelease = 0x807f;
874 pp->modkeyhold = 0;
875 pp->modkeydecay = 0;
877 pp->voldelay = 0x8000;
878 pp->volatkhld = 0x7f7f;
879 pp->voldcysus = 0x7f7f;
880 pp->volrelease = 0x807f;
881 pp->volkeyhold = 0;
882 pp->volkeydecay = 0;
884 pp->lfo1delay = 0x8000;
885 pp->lfo2delay = 0x8000;
886 pp->pefe = 0;
888 pp->fmmod = 0;
889 pp->tremfrq = 0;
890 pp->fm2frq2 = 0;
892 pp->cutoff = 0xff;
893 pp->filterQ = 0;
895 pp->chorus = 0;
896 pp->reverb = 0;
900 #ifdef AWE_HAS_GUS_COMPATIBILITY
902 /* convert frequency mHz to abstract cents (= midi key * 100) */
903 static int
904 freq_to_note(int mHz)
906 /* abscents = log(mHz/8176) / log(2) * 1200 */
907 unsigned int max_val = (unsigned int)0xffffffff / 10000;
908 int i, times;
909 unsigned int base;
910 unsigned int freq;
911 int note, tune;
913 if (mHz == 0)
914 return 0;
915 if (mHz < 0)
916 return 12799; /* maximum */
918 freq = mHz;
919 note = 0;
920 for (base = 8176 * 2; freq >= base; base *= 2) {
921 note += 12;
922 if (note >= 128) /* over maximum */
923 return 12799;
925 base /= 2;
927 /* to avoid overflow... */
928 times = 10000;
929 while (freq > max_val) {
930 max_val *= 10;
931 times /= 10;
932 base /= 10;
935 freq = freq * times / base;
936 for (i = 0; i < 12; i++) {
937 if (freq < semitone_tuning[i+1])
938 break;
939 note++;
942 tune = 0;
943 freq = freq * 10000 / semitone_tuning[i];
944 for (i = 0; i < 100; i++) {
945 if (freq < cent_tuning[i+1])
946 break;
947 tune++;
950 return note * 100 + tune;
954 /* convert Hz to AWE32 rate offset:
955 * sample pitch offset for the specified sample rate
956 * rate=44100 is no offset, each 4096 is 1 octave (twice).
957 * eg, when rate is 22050, this offset becomes -4096.
959 static int
960 calc_rate_offset(int Hz)
962 /* offset = log(Hz / 44100) / log(2) * 4096 */
963 int freq, base, i;
965 /* maybe smaller than max (44100Hz) */
966 if (Hz <= 0 || Hz >= 44100) return 0;
968 base = 0;
969 for (freq = Hz * 2; freq < 44100; freq *= 2)
970 base++;
971 base *= 1200;
973 freq = 44100 * 10000 / (freq/2);
974 for (i = 0; i < 12; i++) {
975 if (freq < semitone_tuning[i+1])
976 break;
977 base += 100;
979 freq = freq * 10000 / semitone_tuning[i];
980 for (i = 0; i < 100; i++) {
981 if (freq < cent_tuning[i+1])
982 break;
983 base++;
985 return -base * 4096 / 1200;
990 * convert envelope time parameter to AWE32 raw parameter
993 /* attack & decay/release time table (msec) */
994 static short attack_time_tbl[128] = {
995 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
996 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
997 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
998 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
999 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
1000 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
1001 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
1002 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
1005 static short decay_time_tbl[128] = {
1006 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
1007 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
1008 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
1009 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
1010 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
1011 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
1012 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
1013 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
1016 #define calc_parm_delay(msec) (0x8000 - (msec) * 1000 / 725);
1018 /* delay time = 0x8000 - msec/92 */
1019 static int
1020 calc_parm_hold(int msec)
1022 int val = (0x7f * 92 - msec) / 92;
1023 if (val < 1) val = 1;
1024 if (val > 127) val = 127;
1025 return val;
1028 /* attack time: search from time table */
1029 static int
1030 calc_parm_attack(int msec)
1032 return calc_parm_search(msec, attack_time_tbl);
1035 /* decay/release time: search from time table */
1036 static int
1037 calc_parm_decay(int msec)
1039 return calc_parm_search(msec, decay_time_tbl);
1042 /* search an index for specified time from given time table */
1043 static int
1044 calc_parm_search(int msec, short *table)
1046 int left = 1, right = 127, mid;
1047 while (left < right) {
1048 mid = (left + right) / 2;
1049 if (msec < (int)table[mid])
1050 left = mid + 1;
1051 else
1052 right = mid;
1054 return left;
1056 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1060 * effects table
1063 /* set an effect value */
1064 #define FX_FLAG_OFF 0
1065 #define FX_FLAG_SET 1
1066 #define FX_FLAG_ADD 2
1068 #define FX_SET(rec,type,value) \
1069 ((rec)->flags[type] = FX_FLAG_SET, (rec)->val[type] = (value))
1070 #define FX_ADD(rec,type,value) \
1071 ((rec)->flags[type] = FX_FLAG_ADD, (rec)->val[type] = (value))
1072 #define FX_UNSET(rec,type) \
1073 ((rec)->flags[type] = FX_FLAG_OFF, (rec)->val[type] = 0)
1075 /* check the effect value is set */
1076 #define FX_ON(rec,type) ((rec)->flags[type])
1078 #define PARM_BYTE 0
1079 #define PARM_WORD 1
1080 #define PARM_SIGN 2
1082 static struct PARM_DEFS {
1083 int type; /* byte or word */
1084 int low, high; /* value range */
1085 fx_affect_func realtime; /* realtime paramater change */
1086 } parm_defs[] = {
1087 {PARM_WORD, 0, 0x8000, NULL}, /* env1 delay */
1088 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 attack */
1089 {PARM_BYTE, 0, 0x7e, NULL}, /* env1 hold */
1090 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 decay */
1091 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 release */
1092 {PARM_BYTE, 0, 0x7f, NULL}, /* env1 sustain */
1093 {PARM_BYTE, 0, 0xff, NULL}, /* env1 pitch */
1094 {PARM_BYTE, 0, 0xff, NULL}, /* env1 cutoff */
1096 {PARM_WORD, 0, 0x8000, NULL}, /* env2 delay */
1097 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 attack */
1098 {PARM_BYTE, 0, 0x7e, NULL}, /* env2 hold */
1099 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 decay */
1100 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 release */
1101 {PARM_BYTE, 0, 0x7f, NULL}, /* env2 sustain */
1103 {PARM_WORD, 0, 0x8000, NULL}, /* lfo1 delay */
1104 {PARM_BYTE, 0, 0xff, awe_fx_tremfrq}, /* lfo1 freq */
1105 {PARM_SIGN, -128, 127, awe_fx_tremfrq}, /* lfo1 volume */
1106 {PARM_SIGN, -128, 127, awe_fx_fmmod}, /* lfo1 pitch */
1107 {PARM_BYTE, 0, 0xff, awe_fx_fmmod}, /* lfo1 cutoff */
1109 {PARM_WORD, 0, 0x8000, NULL}, /* lfo2 delay */
1110 {PARM_BYTE, 0, 0xff, awe_fx_fm2frq2}, /* lfo2 freq */
1111 {PARM_SIGN, -128, 127, awe_fx_fm2frq2}, /* lfo2 pitch */
1113 {PARM_WORD, 0, 0xffff, awe_set_voice_pitch}, /* initial pitch */
1114 {PARM_BYTE, 0, 0xff, NULL}, /* chorus */
1115 {PARM_BYTE, 0, 0xff, NULL}, /* reverb */
1116 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial cutoff */
1117 {PARM_BYTE, 0, 15, awe_fx_filterQ}, /* initial resonance */
1119 {PARM_WORD, 0, 0xffff, NULL}, /* sample start */
1120 {PARM_WORD, 0, 0xffff, NULL}, /* loop start */
1121 {PARM_WORD, 0, 0xffff, NULL}, /* loop end */
1122 {PARM_WORD, 0, 0xffff, NULL}, /* coarse sample start */
1123 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop start */
1124 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop end */
1125 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial attenuation */
1129 static unsigned char
1130 FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value)
1132 int effect = 0;
1133 int on = 0;
1134 if (lay && (on = FX_ON(lay, type)) != 0)
1135 effect = lay->val[type];
1136 if (!on && (on = FX_ON(rec, type)) != 0)
1137 effect = rec->val[type];
1138 if (on == FX_FLAG_ADD) {
1139 if (parm_defs[type].type == PARM_SIGN) {
1140 if (value > 0x7f)
1141 effect += (int)value - 0x100;
1142 else
1143 effect += (int)value;
1144 } else {
1145 effect += (int)value;
1148 if (on) {
1149 if (effect < parm_defs[type].low)
1150 effect = parm_defs[type].low;
1151 else if (effect > parm_defs[type].high)
1152 effect = parm_defs[type].high;
1153 return (unsigned char)effect;
1155 return value;
1158 /* get word effect value */
1159 static unsigned short
1160 FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value)
1162 int effect = 0;
1163 int on = 0;
1164 if (lay && (on = FX_ON(lay, type)) != 0)
1165 effect = lay->val[type];
1166 if (!on && (on = FX_ON(rec, type)) != 0)
1167 effect = rec->val[type];
1168 if (on == FX_FLAG_ADD)
1169 effect += (int)value;
1170 if (on) {
1171 if (effect < parm_defs[type].low)
1172 effect = parm_defs[type].low;
1173 else if (effect > parm_defs[type].high)
1174 effect = parm_defs[type].high;
1175 return (unsigned short)effect;
1177 return value;
1180 /* get word (upper=type1/lower=type2) effect value */
1181 static unsigned short
1182 FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value)
1184 unsigned short tmp;
1185 tmp = FX_BYTE(rec, lay, type1, (unsigned char)(value >> 8));
1186 tmp <<= 8;
1187 tmp |= FX_BYTE(rec, lay, type2, (unsigned char)(value & 0xff));
1188 return tmp;
1191 /* address offset */
1192 static int
1193 FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode)
1195 int addr = 0;
1196 if (lay && FX_ON(lay, hi))
1197 addr = (short)lay->val[hi];
1198 else if (FX_ON(rec, hi))
1199 addr = (short)rec->val[hi];
1200 addr = addr << 15;
1201 if (lay && FX_ON(lay, lo))
1202 addr += (short)lay->val[lo];
1203 else if (FX_ON(rec, lo))
1204 addr += (short)rec->val[lo];
1205 if (!(mode & AWE_SAMPLE_8BITS))
1206 addr /= 2;
1207 return addr;
1212 * turn on/off sample
1215 /* table for volume target calculation */
1216 static unsigned short voltarget[16] = {
1217 0xEAC0, 0XE0C8, 0XD740, 0XCE20, 0XC560, 0XBD08, 0XB500, 0XAD58,
1218 0XA5F8, 0X9EF0, 0X9830, 0X91C0, 0X8B90, 0X85A8, 0X8000, 0X7A90
1221 static void
1222 awe_note_on(int voice)
1224 unsigned int temp;
1225 int addr;
1226 int vtarget, ftarget, ptarget, pitch;
1227 awe_voice_info *vp;
1228 awe_voice_parm_block *parm;
1229 FX_Rec *fx = &voices[voice].cinfo->fx;
1230 FX_Rec *fx_lay = NULL;
1231 if (voices[voice].layer < MAX_LAYERS)
1232 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1234 /* A voice sample must assigned before calling */
1235 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1236 return;
1238 parm = (awe_voice_parm_block*)&vp->parm;
1240 /* channel to be silent and idle */
1241 awe_poke(AWE_DCYSUSV(voice), 0x0080);
1242 awe_poke(AWE_VTFT(voice), 0x0000FFFF);
1243 awe_poke(AWE_CVCF(voice), 0x0000FFFF);
1244 awe_poke(AWE_PTRX(voice), 0);
1245 awe_poke(AWE_CPF(voice), 0);
1247 /* set pitch offset */
1248 awe_set_pitch(voice, TRUE);
1250 /* modulation & volume envelope */
1251 if (parm->modatk >= 0x80 && parm->moddelay >= 0x8000) {
1252 awe_poke(AWE_ENVVAL(voice), 0xBFFF);
1253 pitch = (parm->env1pit<<4) + voices[voice].apitch;
1254 if (pitch > 0xffff) pitch = 0xffff;
1255 /* calculate filter target */
1256 ftarget = parm->cutoff + parm->env1fc;
1257 limitvalue(ftarget, 0, 255);
1258 ftarget <<= 8;
1259 } else {
1260 awe_poke(AWE_ENVVAL(voice),
1261 FX_WORD(fx, fx_lay, AWE_FX_ENV1_DELAY, parm->moddelay));
1262 ftarget = parm->cutoff;
1263 ftarget <<= 8;
1264 pitch = voices[voice].apitch;
1267 /* calcualte pitch target */
1268 if (pitch != 0xffff) {
1269 ptarget = 1 << (pitch >> 12);
1270 if (pitch & 0x800) ptarget += (ptarget*0x102e)/0x2710;
1271 if (pitch & 0x400) ptarget += (ptarget*0x764)/0x2710;
1272 if (pitch & 0x200) ptarget += (ptarget*0x389)/0x2710;
1273 ptarget += (ptarget>>1);
1274 if (ptarget > 0xffff) ptarget = 0xffff;
1276 } else ptarget = 0xffff;
1277 if (parm->modatk >= 0x80)
1278 awe_poke(AWE_ATKHLD(voice),
1279 FX_BYTE(fx, fx_lay, AWE_FX_ENV1_HOLD, parm->modhld) << 8 | 0x7f);
1280 else
1281 awe_poke(AWE_ATKHLD(voice),
1282 FX_COMB(fx, fx_lay, AWE_FX_ENV1_HOLD, AWE_FX_ENV1_ATTACK,
1283 vp->parm.modatkhld));
1284 awe_poke(AWE_DCYSUS(voice),
1285 FX_COMB(fx, fx_lay, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY,
1286 vp->parm.moddcysus));
1288 if (parm->volatk >= 0x80 && parm->voldelay >= 0x8000) {
1289 awe_poke(AWE_ENVVOL(voice), 0xBFFF);
1290 vtarget = voltarget[voices[voice].avol%0x10]>>(voices[voice].avol>>4);
1291 } else {
1292 awe_poke(AWE_ENVVOL(voice),
1293 FX_WORD(fx, fx_lay, AWE_FX_ENV2_DELAY, vp->parm.voldelay));
1294 vtarget = 0;
1296 if (parm->volatk >= 0x80)
1297 awe_poke(AWE_ATKHLDV(voice),
1298 FX_BYTE(fx, fx_lay, AWE_FX_ENV2_HOLD, parm->volhld) << 8 | 0x7f);
1299 else
1300 awe_poke(AWE_ATKHLDV(voice),
1301 FX_COMB(fx, fx_lay, AWE_FX_ENV2_HOLD, AWE_FX_ENV2_ATTACK,
1302 vp->parm.volatkhld));
1303 /* decay/sustain parameter for volume envelope must be set at last */
1305 /* cutoff and volume */
1306 awe_set_volume(voice, TRUE);
1308 /* modulation envelope heights */
1309 awe_poke(AWE_PEFE(voice),
1310 FX_COMB(fx, fx_lay, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF,
1311 vp->parm.pefe));
1313 /* lfo1/2 delay */
1314 awe_poke(AWE_LFO1VAL(voice),
1315 FX_WORD(fx, fx_lay, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay));
1316 awe_poke(AWE_LFO2VAL(voice),
1317 FX_WORD(fx, fx_lay, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay));
1319 /* lfo1 pitch & cutoff shift */
1320 awe_fx_fmmod(voice, TRUE);
1321 /* lfo1 volume & freq */
1322 awe_fx_tremfrq(voice, TRUE);
1323 /* lfo2 pitch & freq */
1324 awe_fx_fm2frq2(voice, TRUE);
1325 /* pan & loop start */
1326 awe_set_pan(voice, TRUE);
1328 /* chorus & loop end (chorus 8bit, MSB) */
1329 addr = vp->loopend - 1;
1330 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_END,
1331 AWE_FX_COARSE_LOOP_END, vp->mode);
1332 temp = FX_BYTE(fx, fx_lay, AWE_FX_CHORUS, vp->parm.chorus);
1333 temp = (temp <<24) | (unsigned int)addr;
1334 awe_poke_dw(AWE_CSL(voice), temp);
1335 DEBUG(4,printk("AWE32: [-- loopend=%x/%x]\n", vp->loopend, addr));
1337 /* Q & current address (Q 4bit value, MSB) */
1338 addr = vp->start - 1;
1339 addr += FX_OFFSET(fx, fx_lay, AWE_FX_SAMPLE_START,
1340 AWE_FX_COARSE_SAMPLE_START, vp->mode);
1341 temp = FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ);
1342 temp = (temp<<28) | (unsigned int)addr;
1343 awe_poke_dw(AWE_CCCA(voice), temp);
1344 DEBUG(4,printk("AWE32: [-- startaddr=%x/%x]\n", vp->start, addr));
1346 /* clear unknown registers */
1347 awe_poke_dw(AWE_00A0(voice), 0);
1348 awe_poke_dw(AWE_0080(voice), 0);
1350 /* reset volume */
1351 awe_poke_dw(AWE_VTFT(voice), (vtarget<<16)|ftarget);
1352 awe_poke_dw(AWE_CVCF(voice), (vtarget<<16)|ftarget);
1354 /* set reverb */
1355 temp = FX_BYTE(fx, fx_lay, AWE_FX_REVERB, vp->parm.reverb);
1356 temp = (temp << 8) | (ptarget << 16) | voices[voice].aaux;
1357 awe_poke_dw(AWE_PTRX(voice), temp);
1358 awe_poke_dw(AWE_CPF(voice), ptarget << 16);
1359 /* turn on envelope */
1360 awe_poke(AWE_DCYSUSV(voice),
1361 FX_COMB(fx, fx_lay, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY,
1362 vp->parm.voldcysus));
1364 voices[voice].state = AWE_ST_ON;
1366 /* clear voice position for the next note on this channel */
1367 if (SINGLE_LAYER_MODE()) {
1368 FX_UNSET(fx, AWE_FX_SAMPLE_START);
1369 FX_UNSET(fx, AWE_FX_COARSE_SAMPLE_START);
1374 /* turn off the voice */
1375 static void
1376 awe_note_off(int voice)
1378 awe_voice_info *vp;
1379 unsigned short tmp;
1380 FX_Rec *fx = &voices[voice].cinfo->fx;
1381 FX_Rec *fx_lay = NULL;
1382 if (voices[voice].layer < MAX_LAYERS)
1383 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1385 if ((vp = voices[voice].sample) == NULL) {
1386 voices[voice].state = AWE_ST_OFF;
1387 return;
1390 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_RELEASE,
1391 (unsigned char)vp->parm.modrelease);
1392 awe_poke(AWE_DCYSUS(voice), tmp);
1393 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_RELEASE,
1394 (unsigned char)vp->parm.volrelease);
1395 awe_poke(AWE_DCYSUSV(voice), tmp);
1396 voices[voice].state = AWE_ST_RELEASED;
1399 /* force to terminate the voice (no releasing echo) */
1400 static void
1401 awe_terminate(int voice)
1403 awe_poke(AWE_DCYSUSV(voice), 0x807F);
1404 awe_tweak_voice(voice);
1405 voices[voice].state = AWE_ST_OFF;
1408 /* turn off other voices with the same exclusive class (for drums) */
1409 static void
1410 awe_exclusive_off(int voice)
1412 int i, exclass;
1414 if (voices[voice].sample == NULL)
1415 return;
1416 if ((exclass = voices[voice].sample->exclusiveClass) == 0)
1417 return; /* not exclusive */
1419 /* turn off voices with the same class */
1420 for (i = 0; i < awe_max_voices; i++) {
1421 if (i != voice && IS_PLAYING(i) &&
1422 voices[i].sample && voices[i].ch == voices[voice].ch &&
1423 voices[i].sample->exclusiveClass == exclass) {
1424 DEBUG(4,printk("AWE32: [exoff(%d)]\n", i));
1425 awe_terminate(i);
1426 awe_voice_init(i, TRUE);
1433 * change the parameters of an audible voice
1436 /* change pitch */
1437 static void
1438 awe_set_pitch(int voice, int forced)
1440 if (IS_NO_EFFECT(voice) && !forced) return;
1441 awe_poke(AWE_IP(voice), voices[voice].apitch);
1442 DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch));
1445 /* calculate & change pitch */
1446 static void
1447 awe_set_voice_pitch(int voice, int forced)
1449 awe_calc_pitch(voice);
1450 awe_set_pitch(voice, forced);
1453 /* change volume & cutoff */
1454 static void
1455 awe_set_volume(int voice, int forced)
1457 awe_voice_info *vp;
1458 unsigned short tmp2;
1459 FX_Rec *fx = &voices[voice].cinfo->fx;
1460 FX_Rec *fx_lay = NULL;
1461 if (voices[voice].layer < MAX_LAYERS)
1462 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1464 if (!IS_PLAYING(voice) && !forced) return;
1465 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1466 return;
1468 tmp2 = FX_BYTE(fx, fx_lay, AWE_FX_CUTOFF,
1469 (unsigned char)voices[voice].acutoff);
1470 tmp2 = (tmp2 << 8);
1471 tmp2 |= FX_BYTE(fx, fx_lay, AWE_FX_ATTEN,
1472 (unsigned char)voices[voice].avol);
1473 awe_poke(AWE_IFATN(voice), tmp2);
1476 /* calculate & change volume */
1477 static void
1478 awe_set_voice_vol(int voice, int forced)
1480 if (IS_EMPTY(voice))
1481 return;
1482 awe_calc_volume(voice);
1483 awe_set_volume(voice, forced);
1487 /* change pan; this could make a click noise.. */
1488 static void
1489 awe_set_pan(int voice, int forced)
1491 unsigned int temp;
1492 int addr;
1493 awe_voice_info *vp;
1494 FX_Rec *fx = &voices[voice].cinfo->fx;
1495 FX_Rec *fx_lay = NULL;
1496 if (voices[voice].layer < MAX_LAYERS)
1497 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1499 if (IS_NO_EFFECT(voice) && !forced) return;
1500 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1501 return;
1503 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
1504 if (vp->fixpan > 0) /* 0-127 */
1505 temp = 255 - (int)vp->fixpan * 2;
1506 else {
1507 int pos = 0;
1508 if (vp->pan >= 0) /* 0-127 */
1509 pos = (int)vp->pan * 2 - 128;
1510 pos += voices[voice].cinfo->panning; /* -128 - 127 */
1511 temp = 127 - pos;
1513 limitvalue(temp, 0, 255);
1514 if (ctrls[AWE_MD_PAN_EXCHANGE]) {
1515 temp = 255 - temp;
1517 if (forced || temp != voices[voice].apan) {
1518 voices[voice].apan = temp;
1519 if (temp == 0)
1520 voices[voice].aaux = 0xff;
1521 else
1522 voices[voice].aaux = (-temp) & 0xff;
1523 addr = vp->loopstart - 1;
1524 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START,
1525 AWE_FX_COARSE_LOOP_START, vp->mode);
1526 temp = (temp<<24) | (unsigned int)addr;
1527 awe_poke_dw(AWE_PSST(voice), temp);
1528 DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr));
1532 /* effects change during playing */
1533 static void
1534 awe_fx_fmmod(int voice, int forced)
1536 awe_voice_info *vp;
1537 FX_Rec *fx = &voices[voice].cinfo->fx;
1538 FX_Rec *fx_lay = NULL;
1539 if (voices[voice].layer < MAX_LAYERS)
1540 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1542 if (IS_NO_EFFECT(voice) && !forced) return;
1543 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1544 return;
1545 awe_poke(AWE_FMMOD(voice),
1546 FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,
1547 vp->parm.fmmod));
1550 /* set tremolo (lfo1) volume & frequency */
1551 static void
1552 awe_fx_tremfrq(int voice, int forced)
1554 awe_voice_info *vp;
1555 FX_Rec *fx = &voices[voice].cinfo->fx;
1556 FX_Rec *fx_lay = NULL;
1557 if (voices[voice].layer < MAX_LAYERS)
1558 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1560 if (IS_NO_EFFECT(voice) && !forced) return;
1561 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1562 return;
1563 awe_poke(AWE_TREMFRQ(voice),
1564 FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,
1565 vp->parm.tremfrq));
1568 /* set lfo2 pitch & frequency */
1569 static void
1570 awe_fx_fm2frq2(int voice, int forced)
1572 awe_voice_info *vp;
1573 FX_Rec *fx = &voices[voice].cinfo->fx;
1574 FX_Rec *fx_lay = NULL;
1575 if (voices[voice].layer < MAX_LAYERS)
1576 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1578 if (IS_NO_EFFECT(voice) && !forced) return;
1579 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1580 return;
1581 awe_poke(AWE_FM2FRQ2(voice),
1582 FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,
1583 vp->parm.fm2frq2));
1587 /* Q & current address (Q 4bit value, MSB) */
1588 static void
1589 awe_fx_filterQ(int voice, int forced)
1591 unsigned int addr;
1592 awe_voice_info *vp;
1593 FX_Rec *fx = &voices[voice].cinfo->fx;
1594 FX_Rec *fx_lay = NULL;
1595 if (voices[voice].layer < MAX_LAYERS)
1596 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1598 if (IS_NO_EFFECT(voice) && !forced) return;
1599 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1600 return;
1602 addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff;
1603 addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28);
1604 awe_poke_dw(AWE_CCCA(voice), addr);
1608 * calculate pitch offset
1610 * 0xE000 is no pitch offset at 44100Hz sample.
1611 * Every 4096 is one octave.
1614 static void
1615 awe_calc_pitch(int voice)
1617 voice_info *vp = &voices[voice];
1618 awe_voice_info *ap;
1619 awe_chan_info *cp = voices[voice].cinfo;
1620 int offset;
1622 /* search voice information */
1623 if ((ap = vp->sample) == NULL)
1624 return;
1625 if (ap->index == 0) {
1626 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1627 if (awe_set_sample((awe_voice_list*)ap) == 0)
1628 return;
1631 /* calculate offset */
1632 if (ap->fixkey >= 0) {
1633 DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune));
1634 offset = (ap->fixkey - ap->root) * 4096 / 12;
1635 } else {
1636 DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune));
1637 offset = (vp->note - ap->root) * 4096 / 12;
1638 DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset));
1640 offset = (offset * ap->scaleTuning) / 100;
1641 DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));
1642 offset += ap->tune * 4096 / 1200;
1643 DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));
1644 if (cp->bender != 0) {
1645 DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender));
1646 /* (819200: 1 semitone) ==> (4096: 12 semitones) */
1647 offset += cp->bender * cp->bender_range / 2400;
1650 /* add initial pitch correction */
1651 if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH))
1652 offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH];
1653 else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH))
1654 offset += cp->fx.val[AWE_FX_INIT_PITCH];
1656 /* 0xe000: root pitch */
1657 vp->apitch = 0xe000 + ap->rate_offset + offset;
1658 DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset));
1659 if (vp->apitch > 0xffff)
1660 vp->apitch = 0xffff;
1661 if (vp->apitch < 0)
1662 vp->apitch = 0;
1666 #ifdef AWE_HAS_GUS_COMPATIBILITY
1667 /* calculate MIDI key and semitone from the specified frequency */
1668 static void
1669 awe_calc_pitch_from_freq(int voice, int freq)
1671 voice_info *vp = &voices[voice];
1672 awe_voice_info *ap;
1673 FX_Rec *fx = &voices[voice].cinfo->fx;
1674 FX_Rec *fx_lay = NULL;
1675 int offset;
1676 int note;
1678 if (voices[voice].layer < MAX_LAYERS)
1679 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1681 /* search voice information */
1682 if ((ap = vp->sample) == NULL)
1683 return;
1684 if (ap->index == 0) {
1685 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1686 if (awe_set_sample((awe_voice_list*)ap) == 0)
1687 return;
1689 note = freq_to_note(freq);
1690 offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;
1691 offset = (offset * ap->scaleTuning) / 100;
1692 if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH))
1693 offset += fx_lay->val[AWE_FX_INIT_PITCH];
1694 else if (FX_ON(fx, AWE_FX_INIT_PITCH))
1695 offset += fx->val[AWE_FX_INIT_PITCH];
1696 vp->apitch = 0xe000 + ap->rate_offset + offset;
1697 if (vp->apitch > 0xffff)
1698 vp->apitch = 0xffff;
1699 if (vp->apitch < 0)
1700 vp->apitch = 0;
1702 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1706 * calculate volume attenuation
1708 * Voice volume is controlled by volume attenuation parameter.
1709 * So volume becomes maximum when avol is 0 (no attenuation), and
1710 * minimum when 255 (-96dB or silence).
1713 static int vol_table[128] = {
1714 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
1715 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
1716 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
1717 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
1718 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
1719 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
1720 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
1721 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
1724 /* tables for volume->attenuation calculation */
1725 static unsigned char voltab1[128] = {
1726 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1727 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
1728 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
1729 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
1730 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
1731 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
1732 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
1733 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
1734 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
1735 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
1736 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
1737 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
1738 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1741 static unsigned char voltab2[128] = {
1742 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
1743 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
1744 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
1745 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
1746 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
1747 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
1748 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
1749 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
1750 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
1751 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
1752 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
1753 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
1754 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
1757 static unsigned char expressiontab[128] = {
1758 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
1759 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
1760 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
1761 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
1762 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
1763 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
1764 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
1765 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
1766 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
1767 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
1768 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
1769 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
1770 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1773 static void
1774 awe_calc_volume(int voice)
1776 voice_info *vp = &voices[voice];
1777 awe_voice_info *ap;
1778 awe_chan_info *cp = voices[voice].cinfo;
1779 int vol;
1781 /* search voice information */
1782 if ((ap = vp->sample) == NULL)
1783 return;
1785 ap = vp->sample;
1786 if (ap->index == 0) {
1787 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1788 if (awe_set_sample((awe_voice_list*)ap) == 0)
1789 return;
1792 if (ctrls[AWE_MD_NEW_VOLUME_CALC]) {
1793 int main_vol = cp->main_vol * ap->amplitude / 127;
1794 limitvalue(vp->velocity, 0, 127);
1795 limitvalue(main_vol, 0, 127);
1796 limitvalue(cp->expression_vol, 0, 127);
1798 vol = voltab1[main_vol] + voltab2[vp->velocity];
1799 vol = (vol * 8) / 3;
1800 vol += ap->attenuation;
1801 if (cp->expression_vol < 127)
1802 vol += ((0x100 - vol) * expressiontab[cp->expression_vol])/128;
1803 vol += atten_offset;
1804 if (atten_relative)
1805 vol += ctrls[AWE_MD_ZERO_ATTEN];
1806 limitvalue(vol, 0, 255);
1807 vp->avol = vol;
1809 } else {
1810 /* 0 - 127 */
1811 vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127);
1812 vol = vol * ap->amplitude / 127;
1814 if (vol < 0) vol = 0;
1815 if (vol > 127) vol = 127;
1817 /* calc to attenuation */
1818 vol = vol_table[vol];
1819 vol += (int)ap->attenuation;
1820 vol += atten_offset;
1821 if (atten_relative)
1822 vol += ctrls[AWE_MD_ZERO_ATTEN];
1823 if (vol > 255) vol = 255;
1825 vp->avol = vol;
1827 if (cp->bank != AWE_DRUM_BANK && ((awe_voice_parm_block*)(&ap->parm))->volatk < 0x7d) {
1828 int atten;
1829 if (vp->velocity < 70) atten = 70;
1830 else atten = vp->velocity;
1831 vp->acutoff = (atten * ap->parm.cutoff + 0xa0) >> 7;
1832 } else {
1833 vp->acutoff = ap->parm.cutoff;
1835 DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));
1838 /* change master volume */
1839 static void
1840 awe_change_master_volume(short val)
1842 limitvalue(val, 0, 127);
1843 atten_offset = vol_table[val];
1844 atten_relative = TRUE;
1845 awe_update_volume();
1848 /* update volumes of all available channels */
1849 static void awe_update_volume(void)
1851 int i;
1852 for (i = 0; i < awe_max_voices; i++)
1853 awe_set_voice_vol(i, TRUE);
1856 /* set sostenuto on */
1857 static void awe_sostenuto_on(int voice, int forced)
1859 if (IS_NO_EFFECT(voice) && !forced) return;
1860 voices[voice].sostenuto = 127;
1864 /* drop sustain */
1865 static void awe_sustain_off(int voice, int forced)
1867 if (voices[voice].state == AWE_ST_SUSTAINED) {
1868 awe_note_off(voice);
1869 awe_fx_init(voices[voice].ch);
1870 awe_voice_init(voice, FALSE);
1875 /* terminate and initialize voice */
1876 static void awe_terminate_and_init(int voice, int forced)
1878 awe_terminate(voice);
1879 awe_fx_init(voices[voice].ch);
1880 awe_voice_init(voice, TRUE);
1885 * synth operation routines
1888 #define AWE_VOICE_KEY(v) (0x8000 | (v))
1889 #define AWE_CHAN_KEY(c,n) (((c) << 8) | ((n) + 1))
1890 #define KEY_CHAN_MATCH(key,c) (((key) >> 8) == (c))
1892 /* initialize the voice */
1893 static void
1894 awe_voice_init(int voice, int init_all)
1896 voice_info *vp = &voices[voice];
1898 /* reset voice search key */
1899 if (playing_mode == AWE_PLAY_DIRECT)
1900 vp->key = AWE_VOICE_KEY(voice);
1901 else
1902 vp->key = 0;
1904 /* clear voice mapping */
1905 voice_alloc->map[voice] = 0;
1907 /* touch the timing flag */
1908 vp->time = current_alloc_time;
1910 /* initialize other parameters if necessary */
1911 if (init_all) {
1912 vp->note = -1;
1913 vp->velocity = 0;
1914 vp->sostenuto = 0;
1916 vp->sample = NULL;
1917 vp->cinfo = &channels[voice];
1918 vp->ch = voice;
1919 vp->state = AWE_ST_OFF;
1921 /* emu8000 parameters */
1922 vp->apitch = 0;
1923 vp->avol = 255;
1924 vp->apan = -1;
1928 /* clear effects */
1929 static void awe_fx_init(int ch)
1931 if (SINGLE_LAYER_MODE() && !ctrls[AWE_MD_KEEP_EFFECT]) {
1932 memset(&channels[ch].fx, 0, sizeof(channels[ch].fx));
1933 memset(&channels[ch].fx_layer, 0, sizeof(&channels[ch].fx_layer));
1937 /* initialize channel info */
1938 static void awe_channel_init(int ch, int init_all)
1940 awe_chan_info *cp = &channels[ch];
1941 cp->channel = ch;
1942 if (init_all) {
1943 cp->panning = 0; /* zero center */
1944 cp->bender_range = 200; /* sense * 100 */
1945 cp->main_vol = 127;
1946 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) {
1947 cp->instr = ctrls[AWE_MD_DEF_DRUM];
1948 cp->bank = AWE_DRUM_BANK;
1949 } else {
1950 cp->instr = ctrls[AWE_MD_DEF_PRESET];
1951 cp->bank = ctrls[AWE_MD_DEF_BANK];
1955 cp->bender = 0; /* zero tune skew */
1956 cp->expression_vol = 127;
1957 cp->chan_press = 0;
1958 cp->sustained = 0;
1960 if (! ctrls[AWE_MD_KEEP_EFFECT]) {
1961 memset(&cp->fx, 0, sizeof(cp->fx));
1962 memset(&cp->fx_layer, 0, sizeof(cp->fx_layer));
1967 /* change the voice parameters; voice = channel */
1968 static void awe_voice_change(int voice, fx_affect_func func)
1970 int i;
1971 switch (playing_mode) {
1972 case AWE_PLAY_DIRECT:
1973 func(voice, FALSE);
1974 break;
1975 case AWE_PLAY_INDIRECT:
1976 for (i = 0; i < awe_max_voices; i++)
1977 if (voices[i].key == AWE_VOICE_KEY(voice))
1978 func(i, FALSE);
1979 break;
1980 default:
1981 for (i = 0; i < awe_max_voices; i++)
1982 if (KEY_CHAN_MATCH(voices[i].key, voice))
1983 func(i, FALSE);
1984 break;
1990 * device open / close
1993 /* open device:
1994 * reset status of all voices, and clear sample position flag
1996 static int
1997 awe_open(int dev, int mode)
1999 if (awe_busy)
2000 return -EBUSY;
2002 awe_busy = TRUE;
2004 /* set default mode */
2005 awe_init_ctrl_parms(FALSE);
2006 atten_relative = TRUE;
2007 atten_offset = 0;
2008 drum_flags = DEFAULT_DRUM_FLAGS;
2009 playing_mode = AWE_PLAY_INDIRECT;
2011 /* reset voices & channels */
2012 awe_reset(dev);
2014 patch_opened = 0;
2016 return 0;
2020 /* close device:
2021 * reset all voices again (terminate sounds)
2023 static void
2024 awe_close(int dev)
2026 awe_reset(dev);
2027 awe_busy = FALSE;
2031 /* set miscellaneous mode parameters
2033 static void
2034 awe_init_ctrl_parms(int init_all)
2036 int i;
2037 for (i = 0; i < AWE_MD_END; i++) {
2038 if (init_all || ctrl_parms[i].init_each_time)
2039 ctrls[i] = ctrl_parms[i].value;
2044 /* sequencer I/O control:
2046 static int
2047 awe_ioctl(int dev, unsigned int cmd, caddr_t arg)
2049 switch (cmd) {
2050 case SNDCTL_SYNTH_INFO:
2051 if (playing_mode == AWE_PLAY_DIRECT)
2052 awe_info.nr_voices = awe_max_voices;
2053 else
2054 awe_info.nr_voices = AWE_MAX_CHANNELS;
2055 memcpy((char*)arg, &awe_info, sizeof(awe_info));
2056 return 0;
2057 break;
2059 case SNDCTL_SEQ_RESETSAMPLES:
2060 awe_reset(dev);
2061 awe_reset_samples();
2062 return 0;
2063 break;
2065 case SNDCTL_SEQ_PERCMODE:
2066 /* what's this? */
2067 return 0;
2068 break;
2070 case SNDCTL_SYNTH_MEMAVL:
2071 return memsize - awe_free_mem_ptr() * 2;
2073 default:
2074 printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd);
2075 return -EINVAL;
2080 static int voice_in_range(int voice)
2082 if (playing_mode == AWE_PLAY_DIRECT) {
2083 if (voice < 0 || voice >= awe_max_voices)
2084 return FALSE;
2085 } else {
2086 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2087 return FALSE;
2089 return TRUE;
2092 static void release_voice(int voice, int do_sustain)
2094 if (IS_NO_SOUND(voice))
2095 return;
2096 if (do_sustain && (voices[voice].cinfo->sustained == 127 ||
2097 voices[voice].sostenuto == 127))
2098 voices[voice].state = AWE_ST_SUSTAINED;
2099 else {
2100 awe_note_off(voice);
2101 awe_fx_init(voices[voice].ch);
2102 awe_voice_init(voice, FALSE);
2106 /* release all notes */
2107 static void awe_note_off_all(int do_sustain)
2109 int i;
2110 for (i = 0; i < awe_max_voices; i++)
2111 release_voice(i, do_sustain);
2114 /* kill a voice:
2115 * not terminate, just release the voice.
2117 static int
2118 awe_kill_note(int dev, int voice, int note, int velocity)
2120 int i, v2, key;
2122 DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));
2123 if (! voice_in_range(voice))
2124 return -EINVAL;
2126 switch (playing_mode) {
2127 case AWE_PLAY_DIRECT:
2128 case AWE_PLAY_INDIRECT:
2129 key = AWE_VOICE_KEY(voice);
2130 break;
2132 case AWE_PLAY_MULTI2:
2133 v2 = voice_alloc->map[voice] >> 8;
2134 voice_alloc->map[voice] = 0;
2135 voice = v2;
2136 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2137 return -EINVAL;
2138 /* continue to below */
2139 default:
2140 key = AWE_CHAN_KEY(voice, note);
2141 break;
2144 for (i = 0; i < awe_max_voices; i++) {
2145 if (voices[i].key == key)
2146 release_voice(i, TRUE);
2148 return 0;
2152 static void start_or_volume_change(int voice, int velocity)
2154 voices[voice].velocity = velocity;
2155 awe_calc_volume(voice);
2156 if (voices[voice].state == AWE_ST_STANDBY)
2157 awe_note_on(voice);
2158 else if (voices[voice].state == AWE_ST_ON)
2159 awe_set_volume(voice, FALSE);
2162 static void set_and_start_voice(int voice, int state)
2164 /* calculate pitch & volume parameters */
2165 voices[voice].state = state;
2166 awe_calc_pitch(voice);
2167 awe_calc_volume(voice);
2168 if (state == AWE_ST_ON)
2169 awe_note_on(voice);
2172 /* start a voice:
2173 * if note is 255, identical with aftertouch function.
2174 * Otherwise, start a voice with specified not and volume.
2176 static int
2177 awe_start_note(int dev, int voice, int note, int velocity)
2179 int i, key, state, volonly;
2181 DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));
2182 if (! voice_in_range(voice))
2183 return -EINVAL;
2185 if (velocity == 0)
2186 state = AWE_ST_STANDBY; /* stand by for playing */
2187 else
2188 state = AWE_ST_ON; /* really play */
2189 volonly = FALSE;
2191 switch (playing_mode) {
2192 case AWE_PLAY_DIRECT:
2193 case AWE_PLAY_INDIRECT:
2194 key = AWE_VOICE_KEY(voice);
2195 if (note == 255)
2196 volonly = TRUE;
2197 break;
2199 case AWE_PLAY_MULTI2:
2200 voice = voice_alloc->map[voice] >> 8;
2201 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2202 return -EINVAL;
2203 /* continue to below */
2204 default:
2205 if (note >= 128) { /* key volume mode */
2206 note -= 128;
2207 volonly = TRUE;
2209 key = AWE_CHAN_KEY(voice, note);
2210 break;
2213 /* dynamic volume change */
2214 if (volonly) {
2215 for (i = 0; i < awe_max_voices; i++) {
2216 if (voices[i].key == key)
2217 start_or_volume_change(i, velocity);
2219 return 0;
2222 /* if the same note still playing, stop it */
2223 if (playing_mode != AWE_PLAY_DIRECT || ctrls[AWE_MD_EXCLUSIVE_SOUND]) {
2224 for (i = 0; i < awe_max_voices; i++)
2225 if (voices[i].key == key) {
2226 if (voices[i].state == AWE_ST_ON) {
2227 awe_note_off(i);
2228 awe_voice_init(i, FALSE);
2229 } else if (voices[i].state == AWE_ST_STANDBY)
2230 awe_voice_init(i, TRUE);
2234 /* allocate voices */
2235 if (playing_mode == AWE_PLAY_DIRECT)
2236 awe_alloc_one_voice(voice, note, velocity);
2237 else
2238 awe_alloc_multi_voices(voice, note, velocity, key);
2240 /* turn off other voices exlusively (for drums) */
2241 for (i = 0; i < awe_max_voices; i++)
2242 if (voices[i].key == key)
2243 awe_exclusive_off(i);
2245 /* set up pitch and volume parameters */
2246 for (i = 0; i < awe_max_voices; i++) {
2247 if (voices[i].key == key && voices[i].state == AWE_ST_OFF)
2248 set_and_start_voice(i, state);
2251 return 0;
2255 /* calculate hash key */
2256 static int
2257 awe_search_key(int bank, int preset, int note)
2259 unsigned int key;
2261 #if 1 /* new hash table */
2262 if (bank == AWE_DRUM_BANK)
2263 key = preset + note + 128;
2264 else
2265 key = bank + preset;
2266 #else
2267 key = preset;
2268 #endif
2269 key %= AWE_MAX_PRESETS;
2271 return (int)key;
2275 /* search instrument from hash table */
2276 static awe_voice_list *
2277 awe_search_instr(int bank, int preset, int note)
2279 awe_voice_list *p;
2280 int key, key2;
2282 key = awe_search_key(bank, preset, note);
2283 for (p = preset_table[key]; p; p = p->next_bank) {
2284 if (p->instr == preset && p->bank == bank)
2285 return p;
2287 key2 = awe_search_key(bank, preset, 0); /* search default */
2288 if (key == key2)
2289 return NULL;
2290 for (p = preset_table[key2]; p; p = p->next_bank) {
2291 if (p->instr == preset && p->bank == bank)
2292 return p;
2294 return NULL;
2298 /* assign the instrument to a voice */
2299 static int
2300 awe_set_instr_2(int dev, int voice, int instr_no)
2302 if (playing_mode == AWE_PLAY_MULTI2) {
2303 voice = voice_alloc->map[voice] >> 8;
2304 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2305 return -EINVAL;
2307 return awe_set_instr(dev, voice, instr_no);
2310 /* assign the instrument to a channel; voice is the channel number */
2311 static int
2312 awe_set_instr(int dev, int voice, int instr_no)
2314 awe_chan_info *cinfo;
2316 if (! voice_in_range(voice))
2317 return -EINVAL;
2319 if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)
2320 return -EINVAL;
2322 cinfo = &channels[voice];
2323 cinfo->instr = instr_no;
2324 DEBUG(2,printk("AWE32: [program(%d) %d]\n", voice, instr_no));
2326 return 0;
2330 /* reset all voices; terminate sounds and initialize parameters */
2331 static void
2332 awe_reset(int dev)
2334 int i;
2335 current_alloc_time = 0;
2336 /* don't turn off voice 31 and 32. they are used also for FM voices */
2337 for (i = 0; i < awe_max_voices; i++) {
2338 awe_terminate(i);
2339 awe_voice_init(i, TRUE);
2341 for (i = 0; i < AWE_MAX_CHANNELS; i++)
2342 awe_channel_init(i, TRUE);
2343 for (i = 0; i < 16; i++) {
2344 awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127;
2345 awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127;
2347 awe_init_fm();
2348 awe_tweak();
2352 /* hardware specific control:
2353 * GUS specific and AWE32 specific controls are available.
2355 static void
2356 awe_hw_control(int dev, unsigned char *event)
2358 int cmd = event[2];
2359 if (cmd & _AWE_MODE_FLAG)
2360 awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2361 #ifdef AWE_HAS_GUS_COMPATIBILITY
2362 else
2363 awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2364 #endif
2368 #ifdef AWE_HAS_GUS_COMPATIBILITY
2370 /* GUS compatible controls */
2371 static void
2372 awe_hw_gus_control(int dev, int cmd, unsigned char *event)
2374 int voice, i, key;
2375 unsigned short p1;
2376 short p2;
2377 int plong;
2379 if (MULTI_LAYER_MODE())
2380 return;
2381 if (cmd == _GUS_NUMVOICES)
2382 return;
2384 voice = event[3];
2385 if (! voice_in_range(voice))
2386 return;
2388 p1 = *(unsigned short *) &event[4];
2389 p2 = *(short *) &event[6];
2390 plong = *(int*) &event[4];
2392 switch (cmd) {
2393 case _GUS_VOICESAMPLE:
2394 awe_set_instr(dev, voice, p1);
2395 return;
2397 case _GUS_VOICEBALA:
2398 /* 0 to 15 --> -128 to 127 */
2399 awe_panning(dev, voice, ((int)p1 << 4) - 128);
2400 return;
2402 case _GUS_VOICEVOL:
2403 case _GUS_VOICEVOL2:
2404 /* not supported yet */
2405 return;
2407 case _GUS_RAMPRANGE:
2408 case _GUS_RAMPRATE:
2409 case _GUS_RAMPMODE:
2410 case _GUS_RAMPON:
2411 case _GUS_RAMPOFF:
2412 /* volume ramping not supported */
2413 return;
2415 case _GUS_VOLUME_SCALE:
2416 return;
2418 case _GUS_VOICE_POS:
2419 FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START,
2420 (short)(plong & 0x7fff));
2421 FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START,
2422 (plong >> 15) & 0xffff);
2423 return;
2426 key = AWE_VOICE_KEY(voice);
2427 for (i = 0; i < awe_max_voices; i++) {
2428 if (voices[i].key == key) {
2429 switch (cmd) {
2430 case _GUS_VOICEON:
2431 awe_note_on(i);
2432 break;
2434 case _GUS_VOICEOFF:
2435 awe_terminate(i);
2436 awe_fx_init(voices[i].ch);
2437 awe_voice_init(i, TRUE);
2438 break;
2440 case _GUS_VOICEFADE:
2441 awe_note_off(i);
2442 awe_fx_init(voices[i].ch);
2443 awe_voice_init(i, FALSE);
2444 break;
2446 case _GUS_VOICEFREQ:
2447 awe_calc_pitch_from_freq(i, plong);
2448 break;
2454 #endif /* gus_compat */
2457 /* AWE32 specific controls */
2458 static void
2459 awe_hw_awe_control(int dev, int cmd, unsigned char *event)
2461 int voice;
2462 unsigned short p1;
2463 short p2;
2464 int i;
2466 voice = event[3];
2467 if (! voice_in_range(voice))
2468 return;
2470 if (playing_mode == AWE_PLAY_MULTI2) {
2471 voice = voice_alloc->map[voice] >> 8;
2472 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2473 return;
2476 p1 = *(unsigned short *) &event[4];
2477 p2 = *(short *) &event[6];
2479 switch (cmd) {
2480 case _AWE_DEBUG_MODE:
2481 ctrls[AWE_MD_DEBUG_MODE] = p1;
2482 printk(KERN_DEBUG "AWE32: debug mode = %d\n", ctrls[AWE_MD_DEBUG_MODE]);
2483 break;
2484 case _AWE_REVERB_MODE:
2485 ctrls[AWE_MD_REVERB_MODE] = p1;
2486 awe_update_reverb_mode();
2487 break;
2489 case _AWE_CHORUS_MODE:
2490 ctrls[AWE_MD_CHORUS_MODE] = p1;
2491 awe_update_chorus_mode();
2492 break;
2494 case _AWE_REMOVE_LAST_SAMPLES:
2495 DEBUG(0,printk("AWE32: remove last samples\n"));
2496 awe_reset(0);
2497 if (locked_sf_id > 0)
2498 awe_remove_samples(locked_sf_id);
2499 break;
2501 case _AWE_INITIALIZE_CHIP:
2502 awe_initialize();
2503 break;
2505 case _AWE_SEND_EFFECT:
2506 i = -1;
2507 if (p1 >= 0x100) {
2508 i = (p1 >> 8);
2509 if (i < 0 || i >= MAX_LAYERS)
2510 break;
2512 awe_send_effect(voice, i, p1, p2);
2513 break;
2515 case _AWE_RESET_CHANNEL:
2516 awe_channel_init(voice, !p1);
2517 break;
2519 case _AWE_TERMINATE_ALL:
2520 awe_reset(0);
2521 break;
2523 case _AWE_TERMINATE_CHANNEL:
2524 awe_voice_change(voice, awe_terminate_and_init);
2525 break;
2527 case _AWE_RELEASE_ALL:
2528 awe_note_off_all(FALSE);
2529 break;
2530 case _AWE_NOTEOFF_ALL:
2531 awe_note_off_all(TRUE);
2532 break;
2534 case _AWE_INITIAL_VOLUME:
2535 DEBUG(0,printk("AWE32: init attenuation %d\n", p1));
2536 atten_relative = (char)p2;
2537 atten_offset = (short)p1;
2538 awe_update_volume();
2539 break;
2541 case _AWE_CHN_PRESSURE:
2542 channels[voice].chan_press = p1;
2543 awe_modwheel_change(voice, p1);
2544 break;
2546 case _AWE_CHANNEL_MODE:
2547 DEBUG(0,printk("AWE32: channel mode = %d\n", p1));
2548 playing_mode = p1;
2549 awe_reset(0);
2550 break;
2552 case _AWE_DRUM_CHANNELS:
2553 DEBUG(0,printk("AWE32: drum flags = %x\n", p1));
2554 drum_flags = *(unsigned int*)&event[4];
2555 break;
2557 case _AWE_MISC_MODE:
2558 DEBUG(0,printk("AWE32: ctrl parms = %d %d\n", p1, p2));
2559 if (p1 > AWE_MD_VERSION && p1 < AWE_MD_END) {
2560 ctrls[p1] = p2;
2561 if (ctrl_parms[p1].update)
2562 ctrl_parms[p1].update();
2564 break;
2566 case _AWE_EQUALIZER:
2567 ctrls[AWE_MD_BASS_LEVEL] = p1;
2568 ctrls[AWE_MD_TREBLE_LEVEL] = p2;
2569 awe_update_equalizer();
2570 break;
2572 default:
2573 DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice));
2574 break;
2579 /* change effects */
2580 static void
2581 awe_send_effect(int voice, int layer, int type, int val)
2583 awe_chan_info *cinfo;
2584 FX_Rec *fx;
2585 int mode;
2587 cinfo = &channels[voice];
2588 if (layer >= 0 && layer < MAX_LAYERS)
2589 fx = &cinfo->fx_layer[layer];
2590 else
2591 fx = &cinfo->fx;
2593 if (type & 0x40)
2594 mode = FX_FLAG_OFF;
2595 else if (type & 0x80)
2596 mode = FX_FLAG_ADD;
2597 else
2598 mode = FX_FLAG_SET;
2599 type &= 0x3f;
2601 if (type >= 0 && type < AWE_FX_END) {
2602 DEBUG(2,printk("AWE32: effects (%d) %d %d\n", voice, type, val));
2603 if (mode == FX_FLAG_SET)
2604 FX_SET(fx, type, val);
2605 else if (mode == FX_FLAG_ADD)
2606 FX_ADD(fx, type, val);
2607 else
2608 FX_UNSET(fx, type);
2609 if (mode != FX_FLAG_OFF && parm_defs[type].realtime) {
2610 DEBUG(2,printk("AWE32: fx_realtime (%d)\n", voice));
2611 awe_voice_change(voice, parm_defs[type].realtime);
2617 /* change modulation wheel; voice is already mapped on multi2 mode */
2618 static void
2619 awe_modwheel_change(int voice, int value)
2621 int i;
2622 awe_chan_info *cinfo;
2624 cinfo = &channels[voice];
2625 i = value * ctrls[AWE_MD_MOD_SENSE] / 1200;
2626 FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, i);
2627 awe_voice_change(voice, awe_fx_fmmod);
2628 FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, i);
2629 awe_voice_change(voice, awe_fx_fm2frq2);
2633 /* voice pressure change */
2634 static void
2635 awe_aftertouch(int dev, int voice, int pressure)
2637 int note;
2639 DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure));
2640 if (! voice_in_range(voice))
2641 return;
2643 switch (playing_mode) {
2644 case AWE_PLAY_DIRECT:
2645 case AWE_PLAY_INDIRECT:
2646 awe_start_note(dev, voice, 255, pressure);
2647 break;
2648 case AWE_PLAY_MULTI2:
2649 note = (voice_alloc->map[voice] & 0xff) - 1;
2650 awe_key_pressure(dev, voice, note + 0x80, pressure);
2651 break;
2656 /* voice control change */
2657 static void
2658 awe_controller(int dev, int voice, int ctrl_num, int value)
2660 awe_chan_info *cinfo;
2662 if (! voice_in_range(voice))
2663 return;
2665 if (playing_mode == AWE_PLAY_MULTI2) {
2666 voice = voice_alloc->map[voice] >> 8;
2667 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2668 return;
2671 cinfo = &channels[voice];
2673 switch (ctrl_num) {
2674 case CTL_BANK_SELECT: /* MIDI control #0 */
2675 DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value));
2676 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice) &&
2677 !ctrls[AWE_MD_TOGGLE_DRUM_BANK])
2678 break;
2679 if (value < 0 || value > 255)
2680 break;
2681 cinfo->bank = value;
2682 if (cinfo->bank == AWE_DRUM_BANK)
2683 DRUM_CHANNEL_ON(cinfo->channel);
2684 else
2685 DRUM_CHANNEL_OFF(cinfo->channel);
2686 awe_set_instr(dev, voice, cinfo->instr);
2687 break;
2689 case CTL_MODWHEEL: /* MIDI control #1 */
2690 DEBUG(2,printk("AWE32: [modwheel(%d) %d]\n", voice, value));
2691 awe_modwheel_change(voice, value);
2692 break;
2694 case CTRL_PITCH_BENDER: /* SEQ1 V2 contorl */
2695 DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value));
2696 /* zero centered */
2697 cinfo->bender = value;
2698 awe_voice_change(voice, awe_set_voice_pitch);
2699 break;
2701 case CTRL_PITCH_BENDER_RANGE: /* SEQ1 V2 control */
2702 DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value));
2703 /* value = sense x 100 */
2704 cinfo->bender_range = value;
2705 /* no audible pitch change yet.. */
2706 break;
2708 case CTL_EXPRESSION: /* MIDI control #11 */
2709 if (SINGLE_LAYER_MODE())
2710 value /= 128;
2711 case CTRL_EXPRESSION: /* SEQ1 V2 control */
2712 DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value));
2713 /* 0 - 127 */
2714 cinfo->expression_vol = value;
2715 awe_voice_change(voice, awe_set_voice_vol);
2716 break;
2718 case CTL_PAN: /* MIDI control #10 */
2719 DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value));
2720 /* (0-127) -> signed 8bit */
2721 cinfo->panning = value * 2 - 128;
2722 if (ctrls[AWE_MD_REALTIME_PAN])
2723 awe_voice_change(voice, awe_set_pan);
2724 break;
2726 case CTL_MAIN_VOLUME: /* MIDI control #7 */
2727 if (SINGLE_LAYER_MODE())
2728 value = (value * 100) / 16383;
2729 case CTRL_MAIN_VOLUME: /* SEQ1 V2 control */
2730 DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value));
2731 /* 0 - 127 */
2732 cinfo->main_vol = value;
2733 awe_voice_change(voice, awe_set_voice_vol);
2734 break;
2736 case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */
2737 DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value));
2738 FX_SET(&cinfo->fx, AWE_FX_REVERB, value * 2);
2739 break;
2741 case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */
2742 DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value));
2743 FX_SET(&cinfo->fx, AWE_FX_CHORUS, value * 2);
2744 break;
2746 case 120: /* all sounds off */
2747 awe_note_off_all(FALSE);
2748 break;
2749 case 123: /* all notes off */
2750 awe_note_off_all(TRUE);
2751 break;
2753 case CTL_SUSTAIN: /* MIDI control #64 */
2754 cinfo->sustained = value;
2755 if (value != 127)
2756 awe_voice_change(voice, awe_sustain_off);
2757 break;
2759 case CTL_SOSTENUTO: /* MIDI control #66 */
2760 if (value == 127)
2761 awe_voice_change(voice, awe_sostenuto_on);
2762 else
2763 awe_voice_change(voice, awe_sustain_off);
2764 break;
2766 default:
2767 DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n",
2768 voice, ctrl_num, value));
2769 break;
2774 /* voice pan change (value = -128 - 127) */
2775 static void
2776 awe_panning(int dev, int voice, int value)
2778 awe_chan_info *cinfo;
2780 if (! voice_in_range(voice))
2781 return;
2783 if (playing_mode == AWE_PLAY_MULTI2) {
2784 voice = voice_alloc->map[voice] >> 8;
2785 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2786 return;
2789 cinfo = &channels[voice];
2790 cinfo->panning = value;
2791 DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, cinfo->panning));
2792 if (ctrls[AWE_MD_REALTIME_PAN])
2793 awe_voice_change(voice, awe_set_pan);
2797 /* volume mode change */
2798 static void
2799 awe_volume_method(int dev, int mode)
2801 /* not impremented */
2802 DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode));
2806 /* pitch wheel change: 0-16384 */
2807 static void
2808 awe_bender(int dev, int voice, int value)
2810 awe_chan_info *cinfo;
2812 if (! voice_in_range(voice))
2813 return;
2815 if (playing_mode == AWE_PLAY_MULTI2) {
2816 voice = voice_alloc->map[voice] >> 8;
2817 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2818 return;
2821 /* convert to zero centered value */
2822 cinfo = &channels[voice];
2823 cinfo->bender = value - 8192;
2824 DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, cinfo->bender));
2825 awe_voice_change(voice, awe_set_voice_pitch);
2830 * load a sound patch:
2831 * three types of patches are accepted: AWE, GUS, and SYSEX.
2834 static int
2835 awe_load_patch(int dev, int format, const char *addr,
2836 int offs, int count, int pmgr_flag)
2838 awe_patch_info patch;
2839 int rc = 0;
2841 #ifdef AWE_HAS_GUS_COMPATIBILITY
2842 if (format == GUS_PATCH) {
2843 return awe_load_guspatch(addr, offs, count, pmgr_flag);
2844 } else
2845 #endif
2846 if (format == SYSEX_PATCH) {
2847 /* no system exclusive message supported yet */
2848 return 0;
2849 } else if (format != AWE_PATCH) {
2850 printk(KERN_WARNING "AWE32 Error: Invalid patch format (key) 0x%x\n", format);
2851 return -EINVAL;
2854 if (count < AWE_PATCH_INFO_SIZE) {
2855 printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
2856 return -EINVAL;
2858 if (copy_from_user(((char*)&patch) + offs, addr + offs,
2859 AWE_PATCH_INFO_SIZE - offs))
2860 return -EFAULT;
2862 count -= AWE_PATCH_INFO_SIZE;
2863 if (count < patch.len) {
2864 printk(KERN_WARNING "AWE32: sample: Patch record too short (%d<%d)\n",
2865 count, patch.len);
2866 return -EINVAL;
2869 switch (patch.type) {
2870 case AWE_LOAD_INFO:
2871 rc = awe_load_info(&patch, addr, count);
2872 break;
2873 case AWE_LOAD_DATA:
2874 rc = awe_load_data(&patch, addr, count);
2875 break;
2876 case AWE_OPEN_PATCH:
2877 rc = awe_open_patch(&patch, addr, count);
2878 break;
2879 case AWE_CLOSE_PATCH:
2880 rc = awe_close_patch(&patch, addr, count);
2881 break;
2882 case AWE_UNLOAD_PATCH:
2883 rc = awe_unload_patch(&patch, addr, count);
2884 break;
2885 case AWE_REPLACE_DATA:
2886 rc = awe_replace_data(&patch, addr, count);
2887 break;
2888 case AWE_MAP_PRESET:
2889 rc = awe_load_map(&patch, addr, count);
2890 break;
2891 /* case AWE_PROBE_INFO:
2892 rc = awe_probe_info(&patch, addr, count);
2893 break;*/
2894 case AWE_PROBE_DATA:
2895 rc = awe_probe_data(&patch, addr, count);
2896 break;
2897 case AWE_REMOVE_INFO:
2898 rc = awe_remove_info(&patch, addr, count);
2899 break;
2900 case AWE_LOAD_CHORUS_FX:
2901 rc = awe_load_chorus_fx(&patch, addr, count);
2902 break;
2903 case AWE_LOAD_REVERB_FX:
2904 rc = awe_load_reverb_fx(&patch, addr, count);
2905 break;
2907 default:
2908 printk(KERN_WARNING "AWE32 Error: unknown patch format type %d\n",
2909 patch.type);
2910 rc = -EINVAL;
2913 return rc;
2917 /* create an sf list record */
2918 static int
2919 awe_create_sf(int type, char *name)
2921 sf_list *rec;
2923 /* terminate sounds */
2924 awe_reset(0);
2925 rec = (sf_list *)kmalloc(sizeof(*rec), GFP_KERNEL);
2926 if (rec == NULL)
2927 return 1; /* no memory */
2928 rec->sf_id = current_sf_id + 1;
2929 rec->type = type;
2930 if (/*current_sf_id == 0 ||*/ (type & AWE_PAT_LOCKED) != 0)
2931 locked_sf_id = current_sf_id + 1;
2932 rec->num_info = awe_free_info();
2933 rec->num_sample = awe_free_sample();
2934 rec->mem_ptr = awe_free_mem_ptr();
2935 rec->infos = rec->last_infos = NULL;
2936 rec->samples = rec->last_samples = NULL;
2938 /* add to linked-list */
2939 rec->next = NULL;
2940 rec->prev = sftail;
2941 if (sftail)
2942 sftail->next = rec;
2943 else
2944 sfhead = rec;
2945 sftail = rec;
2946 current_sf_id++;
2948 #ifdef AWE_ALLOW_SAMPLE_SHARING
2949 rec->shared = NULL;
2950 if (name)
2951 memcpy(rec->name, name, AWE_PATCH_NAME_LEN);
2952 else
2953 strcpy(rec->name, "*TEMPORARY*");
2954 if (current_sf_id > 1 && name && (type & AWE_PAT_SHARED) != 0) {
2955 /* is the current font really a shared font? */
2956 if (is_shared_sf(rec->name)) {
2957 /* check if the shared font is already installed */
2958 sf_list *p;
2959 for (p = rec->prev; p; p = p->prev) {
2960 if (is_identical_name(rec->name, p)) {
2961 rec->shared = p;
2962 break;
2967 #endif /* allow sharing */
2969 return 0;
2973 #ifdef AWE_ALLOW_SAMPLE_SHARING
2975 /* check if the given name is a valid shared name */
2976 #define ASC_TO_KEY(c) ((c) - 'A' + 1)
2977 static int is_shared_sf(unsigned char *name)
2979 static unsigned char id_head[4] = {
2980 ASC_TO_KEY('A'), ASC_TO_KEY('W'), ASC_TO_KEY('E'),
2981 AWE_MAJOR_VERSION,
2983 if (memcmp(name, id_head, 4) == 0)
2984 return TRUE;
2985 return FALSE;
2988 /* check if the given name matches to the existing list */
2989 static int is_identical_name(unsigned char *name, sf_list *p)
2991 char *id = p->name;
2992 if (is_shared_sf(id) && memcmp(id, name, AWE_PATCH_NAME_LEN) == 0)
2993 return TRUE;
2994 return FALSE;
2997 /* check if the given voice info exists */
2998 static int info_duplicated(sf_list *sf, awe_voice_list *rec)
3000 /* search for all sharing lists */
3001 for (; sf; sf = sf->shared) {
3002 awe_voice_list *p;
3003 for (p = sf->infos; p; p = p->next) {
3004 if (p->type == V_ST_NORMAL &&
3005 p->bank == rec->bank &&
3006 p->instr == rec->instr &&
3007 p->v.low == rec->v.low &&
3008 p->v.high == rec->v.high &&
3009 p->v.sample == rec->v.sample)
3010 return TRUE;
3013 return FALSE;
3016 #endif /* AWE_ALLOW_SAMPLE_SHARING */
3019 /* free sf_list record */
3020 /* linked-list in this function is not cared */
3021 static void
3022 awe_free_sf(sf_list *sf)
3024 if (sf->infos) {
3025 awe_voice_list *p, *next;
3026 for (p = sf->infos; p; p = next) {
3027 next = p->next;
3028 kfree(p);
3031 if (sf->samples) {
3032 awe_sample_list *p, *next;
3033 for (p = sf->samples; p; p = next) {
3034 next = p->next;
3035 kfree(p);
3038 kfree(sf);
3042 /* open patch; create sf list and set opened flag */
3043 static int
3044 awe_open_patch(awe_patch_info *patch, const char *addr, int count)
3046 awe_open_parm parm;
3047 int shared;
3049 if (copy_from_user(&parm, addr + AWE_PATCH_INFO_SIZE, sizeof(parm)))
3050 return -EFAULT;
3051 shared = FALSE;
3053 #ifdef AWE_ALLOW_SAMPLE_SHARING
3054 if (sftail && (parm.type & AWE_PAT_SHARED) != 0) {
3055 /* is the previous font the same font? */
3056 if (is_identical_name(parm.name, sftail)) {
3057 /* then append to the previous */
3058 shared = TRUE;
3059 awe_reset(0);
3060 if (parm.type & AWE_PAT_LOCKED)
3061 locked_sf_id = current_sf_id;
3064 #endif /* allow sharing */
3065 if (! shared) {
3066 if (awe_create_sf(parm.type, parm.name)) {
3067 printk(KERN_ERR "AWE32: can't open: failed to alloc new list\n");
3068 return -ENOMEM;
3071 patch_opened = TRUE;
3072 return current_sf_id;
3075 /* check if the patch is already opened */
3076 static sf_list *
3077 check_patch_opened(int type, char *name)
3079 if (! patch_opened) {
3080 if (awe_create_sf(type, name)) {
3081 printk(KERN_ERR "AWE32: failed to alloc new list\n");
3082 return NULL;
3084 patch_opened = TRUE;
3085 return sftail;
3087 return sftail;
3090 /* close the patch; if no voice is loaded, remove the patch */
3091 static int
3092 awe_close_patch(awe_patch_info *patch, const char *addr, int count)
3094 if (patch_opened && sftail) {
3095 /* if no voice is loaded, release the current patch */
3096 if (sftail->infos == NULL) {
3097 awe_reset(0);
3098 awe_remove_samples(current_sf_id - 1);
3101 patch_opened = 0;
3102 return 0;
3106 /* remove the latest patch */
3107 static int
3108 awe_unload_patch(awe_patch_info *patch, const char *addr, int count)
3110 if (current_sf_id > 0 && current_sf_id > locked_sf_id) {
3111 awe_reset(0);
3112 awe_remove_samples(current_sf_id - 1);
3114 return 0;
3117 /* allocate voice info list records */
3118 static awe_voice_list *
3119 alloc_new_info(void)
3121 awe_voice_list *newlist;
3123 newlist = (awe_voice_list *)kmalloc(sizeof(*newlist), GFP_KERNEL);
3124 if (newlist == NULL) {
3125 printk(KERN_ERR "AWE32: can't alloc info table\n");
3126 return NULL;
3128 return newlist;
3131 /* allocate sample info list records */
3132 static awe_sample_list *
3133 alloc_new_sample(void)
3135 awe_sample_list *newlist;
3137 newlist = (awe_sample_list *)kmalloc(sizeof(*newlist), GFP_KERNEL);
3138 if (newlist == NULL) {
3139 printk(KERN_ERR "AWE32: can't alloc sample table\n");
3140 return NULL;
3142 return newlist;
3145 /* load voice map */
3146 static int
3147 awe_load_map(awe_patch_info *patch, const char *addr, int count)
3149 awe_voice_map map;
3150 awe_voice_list *rec, *p;
3151 sf_list *sf;
3153 /* get the link info */
3154 if (count < sizeof(map)) {
3155 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3156 return -EINVAL;
3158 if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
3159 return -EFAULT;
3161 /* check if the identical mapping already exists */
3162 p = awe_search_instr(map.map_bank, map.map_instr, map.map_key);
3163 for (; p; p = p->next_instr) {
3164 if (p->type == V_ST_MAPPED &&
3165 p->v.start == map.src_instr &&
3166 p->v.end == map.src_bank &&
3167 p->v.fixkey == map.src_key)
3168 return 0; /* already present! */
3171 if ((sf = check_patch_opened(AWE_PAT_TYPE_MAP, NULL)) == NULL)
3172 return -ENOMEM;
3174 if ((rec = alloc_new_info()) == NULL)
3175 return -ENOMEM;
3177 rec->bank = map.map_bank;
3178 rec->instr = map.map_instr;
3179 rec->type = V_ST_MAPPED;
3180 rec->disabled = FALSE;
3181 awe_init_voice_info(&rec->v);
3182 if (map.map_key >= 0) {
3183 rec->v.low = map.map_key;
3184 rec->v.high = map.map_key;
3186 rec->v.start = map.src_instr;
3187 rec->v.end = map.src_bank;
3188 rec->v.fixkey = map.src_key;
3189 add_sf_info(sf, rec);
3190 add_info_list(rec);
3192 return 0;
3195 #if 0
3196 /* probe preset in the current list -- nothing to be loaded */
3197 static int
3198 awe_probe_info(awe_patch_info *patch, const char *addr, int count)
3200 #ifdef AWE_ALLOW_SAMPLE_SHARING
3201 awe_voice_map map;
3202 awe_voice_list *p;
3204 if (! patch_opened)
3205 return -EINVAL;
3207 /* get the link info */
3208 if (count < sizeof(map)) {
3209 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3210 return -EINVAL;
3212 if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
3213 return -EFAULT;
3215 /* check if the identical mapping already exists */
3216 if (sftail == NULL)
3217 return -EINVAL;
3218 p = awe_search_instr(map.src_bank, map.src_instr, map.src_key);
3219 for (; p; p = p->next_instr) {
3220 if (p->type == V_ST_NORMAL &&
3221 is_identical_holder(p->holder, sftail) &&
3222 p->v.low <= map.src_key &&
3223 p->v.high >= map.src_key)
3224 return 0; /* already present! */
3226 #endif /* allow sharing */
3227 return -EINVAL;
3229 #endif
3231 /* probe sample in the current list -- nothing to be loaded */
3232 static int
3233 awe_probe_data(awe_patch_info *patch, const char *addr, int count)
3235 #ifdef AWE_ALLOW_SAMPLE_SHARING
3236 if (! patch_opened)
3237 return -EINVAL;
3239 /* search the specified sample by optarg */
3240 if (search_sample_index(sftail, patch->optarg) != NULL)
3241 return 0;
3242 #endif /* allow sharing */
3243 return -EINVAL;
3247 /* remove the present instrument layers */
3248 static int
3249 remove_info(sf_list *sf, int bank, int instr)
3251 awe_voice_list *prev, *next, *p;
3252 int removed = 0;
3254 prev = NULL;
3255 for (p = sf->infos; p; p = next) {
3256 next = p->next;
3257 if (p->type == V_ST_NORMAL &&
3258 p->bank == bank && p->instr == instr) {
3259 /* remove this layer */
3260 if (prev)
3261 prev->next = next;
3262 else
3263 sf->infos = next;
3264 if (p == sf->last_infos)
3265 sf->last_infos = prev;
3266 sf->num_info--;
3267 removed++;
3268 kfree(p);
3269 } else
3270 prev = p;
3272 if (removed)
3273 rebuild_preset_list();
3274 return removed;
3277 /* load voice information data */
3278 static int
3279 awe_load_info(awe_patch_info *patch, const char *addr, int count)
3281 int offset;
3282 awe_voice_rec_hdr hdr;
3283 int i;
3284 int total_size;
3285 sf_list *sf;
3286 awe_voice_list *rec;
3288 if (count < AWE_VOICE_REC_SIZE) {
3289 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3290 return -EINVAL;
3293 offset = AWE_PATCH_INFO_SIZE;
3294 if (copy_from_user((char*)&hdr, addr + offset, AWE_VOICE_REC_SIZE))
3295 return -EFAULT;
3296 offset += AWE_VOICE_REC_SIZE;
3298 if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
3299 printk(KERN_WARNING "AWE32 Error: Invalid voice number %d\n", hdr.nvoices);
3300 return -EINVAL;
3302 total_size = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE * hdr.nvoices;
3303 if (count < total_size) {
3304 printk(KERN_WARNING "AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n",
3305 count, hdr.nvoices);
3306 return -EINVAL;
3309 if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
3310 return -ENOMEM;
3312 switch (hdr.write_mode) {
3313 case AWE_WR_EXCLUSIVE:
3314 /* exclusive mode - if the instrument already exists,
3315 return error */
3316 for (rec = sf->infos; rec; rec = rec->next) {
3317 if (rec->type == V_ST_NORMAL &&
3318 rec->bank == hdr.bank &&
3319 rec->instr == hdr.instr)
3320 return -EINVAL;
3322 break;
3323 case AWE_WR_REPLACE:
3324 /* replace mode - remove the instrument if it already exists */
3325 remove_info(sf, hdr.bank, hdr.instr);
3326 break;
3329 /* append new layers */
3330 for (i = 0; i < hdr.nvoices; i++) {
3331 rec = alloc_new_info();
3332 if (rec == NULL)
3333 return -ENOMEM;
3335 rec->bank = hdr.bank;
3336 rec->instr = hdr.instr;
3337 rec->type = V_ST_NORMAL;
3338 rec->disabled = FALSE;
3340 /* copy awe_voice_info parameters */
3341 if (copy_from_user(&rec->v, addr + offset, AWE_VOICE_INFO_SIZE)) {
3342 kfree(rec);
3343 return -EFAULT;
3345 offset += AWE_VOICE_INFO_SIZE;
3346 #ifdef AWE_ALLOW_SAMPLE_SHARING
3347 if (sf && sf->shared) {
3348 if (info_duplicated(sf, rec)) {
3349 kfree(rec);
3350 continue;
3353 #endif /* allow sharing */
3354 if (rec->v.mode & AWE_MODE_INIT_PARM)
3355 awe_init_voice_parm(&rec->v.parm);
3356 add_sf_info(sf, rec);
3357 awe_set_sample(rec);
3358 add_info_list(rec);
3361 return 0;
3365 /* remove instrument layers */
3366 static int
3367 awe_remove_info(awe_patch_info *patch, const char *addr, int count)
3369 unsigned char bank, instr;
3370 sf_list *sf;
3372 if (! patch_opened || (sf = sftail) == NULL) {
3373 printk(KERN_WARNING "AWE32: remove_info: patch not opened\n");
3374 return -EINVAL;
3377 bank = ((unsigned short)patch->optarg >> 8) & 0xff;
3378 instr = (unsigned short)patch->optarg & 0xff;
3379 if (! remove_info(sf, bank, instr))
3380 return -EINVAL;
3381 return 0;
3385 /* load wave sample data */
3386 static int
3387 awe_load_data(awe_patch_info *patch, const char *addr, int count)
3389 int offset, size;
3390 int rc;
3391 awe_sample_info tmprec;
3392 awe_sample_list *rec;
3393 sf_list *sf;
3395 if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
3396 return -ENOMEM;
3398 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3399 offset = AWE_PATCH_INFO_SIZE;
3400 if (copy_from_user(&tmprec, addr + offset, AWE_SAMPLE_INFO_SIZE))
3401 return -EFAULT;
3402 offset += AWE_SAMPLE_INFO_SIZE;
3403 if (size != tmprec.size) {
3404 printk(KERN_WARNING "AWE32: load: sample size differed (%d != %d)\n",
3405 tmprec.size, size);
3406 return -EINVAL;
3409 if (search_sample_index(sf, tmprec.sample) != NULL) {
3410 #ifdef AWE_ALLOW_SAMPLE_SHARING
3411 /* if shared sample, skip this data */
3412 if (sf->type & AWE_PAT_SHARED)
3413 return 0;
3414 #endif /* allow sharing */
3415 DEBUG(1,printk("AWE32: sample data %d already present\n", tmprec.sample));
3416 return -EINVAL;
3419 if ((rec = alloc_new_sample()) == NULL)
3420 return -ENOMEM;
3422 memcpy(&rec->v, &tmprec, sizeof(tmprec));
3424 if (rec->v.size > 0) {
3425 if ((rc = awe_write_wave_data(addr, offset, rec, -1)) < 0) {
3426 kfree(rec);
3427 return rc;
3429 sf->mem_ptr += rc;
3432 add_sf_sample(sf, rec);
3433 return 0;
3437 /* replace wave sample data */
3438 static int
3439 awe_replace_data(awe_patch_info *patch, const char *addr, int count)
3441 int offset;
3442 int size;
3443 int rc;
3444 int channels;
3445 awe_sample_info cursmp;
3446 int save_mem_ptr;
3447 sf_list *sf;
3448 awe_sample_list *rec;
3450 if (! patch_opened || (sf = sftail) == NULL) {
3451 printk(KERN_WARNING "AWE32: replace: patch not opened\n");
3452 return -EINVAL;
3455 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3456 offset = AWE_PATCH_INFO_SIZE;
3457 if (copy_from_user(&cursmp, addr + offset, AWE_SAMPLE_INFO_SIZE))
3458 return -EFAULT;
3459 offset += AWE_SAMPLE_INFO_SIZE;
3460 if (cursmp.size == 0 || size != cursmp.size) {
3461 printk(KERN_WARNING "AWE32: replace: invalid sample size (%d!=%d)\n",
3462 cursmp.size, size);
3463 return -EINVAL;
3465 channels = patch->optarg;
3466 if (channels <= 0 || channels > AWE_NORMAL_VOICES) {
3467 printk(KERN_WARNING "AWE32: replace: invalid channels %d\n", channels);
3468 return -EINVAL;
3471 for (rec = sf->samples; rec; rec = rec->next) {
3472 if (rec->v.sample == cursmp.sample)
3473 break;
3475 if (rec == NULL) {
3476 printk(KERN_WARNING "AWE32: replace: cannot find existing sample data %d\n",
3477 cursmp.sample);
3478 return -EINVAL;
3481 if (rec->v.size != cursmp.size) {
3482 printk(KERN_WARNING "AWE32: replace: exiting size differed (%d!=%d)\n",
3483 rec->v.size, cursmp.size);
3484 return -EINVAL;
3487 save_mem_ptr = awe_free_mem_ptr();
3488 sftail->mem_ptr = rec->v.start - awe_mem_start;
3489 memcpy(&rec->v, &cursmp, sizeof(cursmp));
3490 rec->v.sf_id = current_sf_id;
3491 if ((rc = awe_write_wave_data(addr, offset, rec, channels)) < 0)
3492 return rc;
3493 sftail->mem_ptr = save_mem_ptr;
3495 return 0;
3499 /*----------------------------------------------------------------*/
3501 static const char *readbuf_addr;
3502 static int readbuf_offs;
3503 static int readbuf_flags;
3505 /* initialize read buffer */
3506 static int
3507 readbuf_init(const char *addr, int offset, awe_sample_info *sp)
3509 readbuf_addr = addr;
3510 readbuf_offs = offset;
3511 readbuf_flags = sp->mode_flags;
3512 return 0;
3515 /* read directly from user buffer */
3516 static unsigned short
3517 readbuf_word(int pos)
3519 unsigned short c;
3520 /* read from user buffer */
3521 if (readbuf_flags & AWE_SAMPLE_8BITS) {
3522 unsigned char cc;
3523 get_user(cc, (unsigned char*)(readbuf_addr + readbuf_offs + pos));
3524 c = (unsigned short)cc << 8; /* convert 8bit -> 16bit */
3525 } else {
3526 get_user(c, (unsigned short*)(readbuf_addr + readbuf_offs + pos * 2));
3528 if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
3529 c ^= 0x8000; /* unsigned -> signed */
3530 return c;
3533 #define readbuf_word_cache readbuf_word
3534 #define readbuf_end() /**/
3536 /*----------------------------------------------------------------*/
3538 #define BLANK_LOOP_START 8
3539 #define BLANK_LOOP_END 40
3540 #define BLANK_LOOP_SIZE 48
3542 /* loading onto memory - return the actual written size */
3543 static int
3544 awe_write_wave_data(const char *addr, int offset, awe_sample_list *list, int channels)
3546 int i, truesize, dram_offset;
3547 awe_sample_info *sp = &list->v;
3548 int rc;
3550 /* be sure loop points start < end */
3551 if (sp->loopstart > sp->loopend) {
3552 int tmp = sp->loopstart;
3553 sp->loopstart = sp->loopend;
3554 sp->loopend = tmp;
3557 /* compute true data size to be loaded */
3558 truesize = sp->size;
3559 if (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))
3560 truesize += sp->loopend - sp->loopstart;
3561 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK)
3562 truesize += BLANK_LOOP_SIZE;
3563 if (awe_free_mem_ptr() + truesize >= memsize/2) {
3564 DEBUG(-1,printk("AWE32 Error: Sample memory full\n"));
3565 return -ENOSPC;
3568 /* recalculate address offset */
3569 sp->end -= sp->start;
3570 sp->loopstart -= sp->start;
3571 sp->loopend -= sp->start;
3573 dram_offset = awe_free_mem_ptr() + awe_mem_start;
3574 sp->start = dram_offset;
3575 sp->end += dram_offset;
3576 sp->loopstart += dram_offset;
3577 sp->loopend += dram_offset;
3579 /* set the total size (store onto obsolete checksum value) */
3580 if (sp->size == 0)
3581 sp->checksum = 0;
3582 else
3583 sp->checksum = truesize;
3585 if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0)
3586 return rc;
3588 if (readbuf_init(addr, offset, sp) < 0)
3589 return -ENOSPC;
3591 for (i = 0; i < sp->size; i++) {
3592 unsigned short c;
3593 c = readbuf_word(i);
3594 awe_write_dram(c);
3595 if (i == sp->loopend &&
3596 (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))) {
3597 int looplen = sp->loopend - sp->loopstart;
3598 /* copy reverse loop */
3599 int k;
3600 for (k = 1; k <= looplen; k++) {
3601 c = readbuf_word_cache(i - k);
3602 awe_write_dram(c);
3604 if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) {
3605 sp->end += looplen;
3606 } else {
3607 sp->start += looplen;
3608 sp->end += looplen;
3612 readbuf_end();
3614 /* if no blank loop is attached in the sample, add it */
3615 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) {
3616 for (i = 0; i < BLANK_LOOP_SIZE; i++)
3617 awe_write_dram(0);
3618 if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) {
3619 sp->loopstart = sp->end + BLANK_LOOP_START;
3620 sp->loopend = sp->end + BLANK_LOOP_END;
3624 awe_close_dram();
3626 /* initialize FM */
3627 awe_init_fm();
3629 return truesize;
3633 /*----------------------------------------------------------------*/
3635 #ifdef AWE_HAS_GUS_COMPATIBILITY
3637 /* calculate GUS envelope time:
3638 * is this correct? i have no idea..
3640 static int
3641 calc_gus_envelope_time(int rate, int start, int end)
3643 int r, p, t;
3644 r = (3 - ((rate >> 6) & 3)) * 3;
3645 p = rate & 0x3f;
3646 t = end - start;
3647 if (t < 0) t = -t;
3648 if (13 > r)
3649 t = t << (13 - r);
3650 else
3651 t = t >> (r - 13);
3652 return (t * 10) / (p * 441);
3655 #define calc_gus_sustain(val) (0x7f - vol_table[(val)/2])
3656 #define calc_gus_attenuation(val) vol_table[(val)/2]
3658 /* load GUS patch */
3659 static int
3660 awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag)
3662 struct patch_info patch;
3663 awe_voice_info *rec;
3664 awe_sample_info *smp;
3665 awe_voice_list *vrec;
3666 awe_sample_list *smprec;
3667 int sizeof_patch;
3668 int note, rc;
3669 sf_list *sf;
3671 sizeof_patch = (int)((long)&patch.data[0] - (long)&patch); /* header size */
3672 if (size < sizeof_patch) {
3673 printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
3674 return -EINVAL;
3676 if (copy_from_user(((char*)&patch) + offs, addr + offs, sizeof_patch - offs))
3677 return -EFAULT;
3678 size -= sizeof_patch;
3679 if (size < patch.len) {
3680 printk(KERN_WARNING "AWE32 Error: Patch record too short (%d<%d)\n",
3681 size, patch.len);
3682 return -EINVAL;
3684 if ((sf = check_patch_opened(AWE_PAT_TYPE_GUS, NULL)) == NULL)
3685 return -ENOMEM;
3686 if ((smprec = alloc_new_sample()) == NULL)
3687 return -ENOMEM;
3688 if ((vrec = alloc_new_info()) == NULL) {
3689 kfree(smprec);
3690 return -ENOMEM;
3693 smp = &smprec->v;
3694 smp->sample = sf->num_sample;
3695 smp->start = 0;
3696 smp->end = patch.len;
3697 smp->loopstart = patch.loop_start;
3698 smp->loopend = patch.loop_end;
3699 smp->size = patch.len;
3701 /* set up mode flags */
3702 smp->mode_flags = 0;
3703 if (!(patch.mode & WAVE_16_BITS))
3704 smp->mode_flags |= AWE_SAMPLE_8BITS;
3705 if (patch.mode & WAVE_UNSIGNED)
3706 smp->mode_flags |= AWE_SAMPLE_UNSIGNED;
3707 smp->mode_flags |= AWE_SAMPLE_NO_BLANK;
3708 if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
3709 smp->mode_flags |= AWE_SAMPLE_SINGLESHOT;
3710 if (patch.mode & WAVE_BIDIR_LOOP)
3711 smp->mode_flags |= AWE_SAMPLE_BIDIR_LOOP;
3712 if (patch.mode & WAVE_LOOP_BACK)
3713 smp->mode_flags |= AWE_SAMPLE_REVERSE_LOOP;
3715 DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, smp->mode_flags));
3716 if (patch.mode & WAVE_16_BITS) {
3717 /* convert to word offsets */
3718 smp->size /= 2;
3719 smp->end /= 2;
3720 smp->loopstart /= 2;
3721 smp->loopend /= 2;
3723 smp->checksum_flag = 0;
3724 smp->checksum = 0;
3726 if ((rc = awe_write_wave_data(addr, sizeof_patch, smprec, -1)) < 0)
3727 return rc;
3728 sf->mem_ptr += rc;
3729 add_sf_sample(sf, smprec);
3731 /* set up voice info */
3732 rec = &vrec->v;
3733 awe_init_voice_info(rec);
3734 rec->sample = sf->num_info; /* the last sample */
3735 rec->rate_offset = calc_rate_offset(patch.base_freq);
3736 note = freq_to_note(patch.base_note);
3737 rec->root = note / 100;
3738 rec->tune = -(note % 100);
3739 rec->low = freq_to_note(patch.low_note) / 100;
3740 rec->high = freq_to_note(patch.high_note) / 100;
3741 DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%d-%d)]\n",
3742 rec->rate_offset, note,
3743 rec->low, rec->high,
3744 patch.low_note, patch.high_note));
3745 /* panning position; -128 - 127 => 0-127 */
3746 rec->pan = (patch.panning + 128) / 2;
3748 /* detuning is ignored */
3749 /* 6points volume envelope */
3750 if (patch.mode & WAVE_ENVELOPES) {
3751 int attack, hold, decay, release;
3752 attack = calc_gus_envelope_time
3753 (patch.env_rate[0], 0, patch.env_offset[0]);
3754 hold = calc_gus_envelope_time
3755 (patch.env_rate[1], patch.env_offset[0],
3756 patch.env_offset[1]);
3757 decay = calc_gus_envelope_time
3758 (patch.env_rate[2], patch.env_offset[1],
3759 patch.env_offset[2]);
3760 release = calc_gus_envelope_time
3761 (patch.env_rate[3], patch.env_offset[1],
3762 patch.env_offset[4]);
3763 release += calc_gus_envelope_time
3764 (patch.env_rate[4], patch.env_offset[3],
3765 patch.env_offset[4]);
3766 release += calc_gus_envelope_time
3767 (patch.env_rate[5], patch.env_offset[4],
3768 patch.env_offset[5]);
3769 rec->parm.volatkhld = (calc_parm_hold(hold) << 8) |
3770 calc_parm_attack(attack);
3771 rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
3772 calc_parm_decay(decay);
3773 rec->parm.volrelease = 0x8000 | calc_parm_decay(release);
3774 DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release));
3775 rec->attenuation = calc_gus_attenuation(patch.env_offset[0]);
3778 /* tremolo effect */
3779 if (patch.mode & WAVE_TREMOLO) {
3780 int rate = (patch.tremolo_rate * 1000 / 38) / 42;
3781 rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
3782 DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n",
3783 patch.tremolo_rate, patch.tremolo_depth,
3784 rec->parm.tremfrq));
3786 /* vibrato effect */
3787 if (patch.mode & WAVE_VIBRATO) {
3788 int rate = (patch.vibrato_rate * 1000 / 38) / 42;
3789 rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
3790 DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n",
3791 patch.tremolo_rate, patch.tremolo_depth,
3792 rec->parm.tremfrq));
3795 /* scale_freq, scale_factor, volume, and fractions not implemented */
3797 /* append to the tail of the list */
3798 vrec->bank = ctrls[AWE_MD_GUS_BANK];
3799 vrec->instr = patch.instr_no;
3800 vrec->disabled = FALSE;
3801 vrec->type = V_ST_NORMAL;
3803 add_sf_info(sf, vrec);
3804 add_info_list(vrec);
3806 /* set the voice index */
3807 awe_set_sample(vrec);
3809 return 0;
3812 #endif /* AWE_HAS_GUS_COMPATIBILITY */
3815 * sample and voice list handlers
3818 /* append this to the current sf list */
3819 static void add_sf_info(sf_list *sf, awe_voice_list *rec)
3821 if (sf == NULL)
3822 return;
3823 rec->holder = sf;
3824 rec->v.sf_id = sf->sf_id;
3825 if (sf->last_infos)
3826 sf->last_infos->next = rec;
3827 else
3828 sf->infos = rec;
3829 sf->last_infos = rec;
3830 rec->next = NULL;
3831 sf->num_info++;
3834 /* prepend this sample to sf list */
3835 static void add_sf_sample(sf_list *sf, awe_sample_list *rec)
3837 if (sf == NULL)
3838 return;
3839 rec->holder = sf;
3840 rec->v.sf_id = sf->sf_id;
3841 if (sf->last_samples)
3842 sf->last_samples->next = rec;
3843 else
3844 sf->samples = rec;
3845 sf->last_samples = rec;
3846 rec->next = NULL;
3847 sf->num_sample++;
3850 /* purge the old records which don't belong with the same file id */
3851 static void purge_old_list(awe_voice_list *rec, awe_voice_list *next)
3853 rec->next_instr = next;
3854 if (rec->bank == AWE_DRUM_BANK) {
3855 /* remove samples with the same note range */
3856 awe_voice_list *cur, *prev = rec;
3857 int low = rec->v.low;
3858 int high = rec->v.high;
3859 for (cur = next; cur; cur = cur->next_instr) {
3860 if (cur->v.low == low &&
3861 cur->v.high == high &&
3862 ! is_identical_holder(cur->holder, rec->holder))
3863 prev->next_instr = cur->next_instr;
3864 else
3865 prev = cur;
3867 } else {
3868 if (! is_identical_holder(next->holder, rec->holder))
3869 /* remove all samples */
3870 rec->next_instr = NULL;
3874 /* prepend to top of the preset table */
3875 static void add_info_list(awe_voice_list *rec)
3877 awe_voice_list *prev, *cur;
3878 int key;
3880 if (rec->disabled)
3881 return;
3883 key = awe_search_key(rec->bank, rec->instr, rec->v.low);
3884 prev = NULL;
3885 for (cur = preset_table[key]; cur; cur = cur->next_bank) {
3886 /* search the first record with the same bank number */
3887 if (cur->instr == rec->instr && cur->bank == rec->bank) {
3888 /* replace the list with the new record */
3889 rec->next_bank = cur->next_bank;
3890 if (prev)
3891 prev->next_bank = rec;
3892 else
3893 preset_table[key] = rec;
3894 purge_old_list(rec, cur);
3895 return;
3897 prev = cur;
3900 /* this is the first bank record.. just add this */
3901 rec->next_instr = NULL;
3902 rec->next_bank = preset_table[key];
3903 preset_table[key] = rec;
3906 /* remove samples later than the specified sf_id */
3907 static void
3908 awe_remove_samples(int sf_id)
3910 sf_list *p, *prev;
3912 if (sf_id <= 0) {
3913 awe_reset_samples();
3914 return;
3916 /* already removed? */
3917 if (current_sf_id <= sf_id)
3918 return;
3920 for (p = sftail; p; p = prev) {
3921 if (p->sf_id <= sf_id)
3922 break;
3923 prev = p->prev;
3924 awe_free_sf(p);
3926 sftail = p;
3927 if (sftail) {
3928 sf_id = sftail->sf_id;
3929 sftail->next = NULL;
3930 } else {
3931 sf_id = 0;
3932 sfhead = NULL;
3934 current_sf_id = sf_id;
3935 if (locked_sf_id > sf_id)
3936 locked_sf_id = sf_id;
3938 rebuild_preset_list();
3941 /* rebuild preset search list */
3942 static void rebuild_preset_list(void)
3944 sf_list *p;
3945 awe_voice_list *rec;
3947 memset(preset_table, 0, sizeof(preset_table));
3949 for (p = sfhead; p; p = p->next) {
3950 for (rec = p->infos; rec; rec = rec->next)
3951 add_info_list(rec);
3955 /* compare the given sf_id pair */
3956 static int is_identical_holder(sf_list *sf1, sf_list *sf2)
3958 if (sf1 == NULL || sf2 == NULL)
3959 return FALSE;
3960 if (sf1 == sf2)
3961 return TRUE;
3962 #ifdef AWE_ALLOW_SAMPLE_SHARING
3964 /* compare with the sharing id */
3965 sf_list *p;
3966 int counter = 0;
3967 if (sf1->sf_id < sf2->sf_id) { /* make sure id1 > id2 */
3968 sf_list *tmp; tmp = sf1; sf1 = sf2; sf2 = tmp;
3970 for (p = sf1->shared; p; p = p->shared) {
3971 if (counter++ > current_sf_id)
3972 break; /* strange sharing loop.. quit */
3973 if (p == sf2)
3974 return TRUE;
3977 #endif /* allow sharing */
3978 return FALSE;
3981 /* search the sample index matching with the given sample id */
3982 static awe_sample_list *
3983 search_sample_index(sf_list *sf, int sample)
3985 awe_sample_list *p;
3986 #ifdef AWE_ALLOW_SAMPLE_SHARING
3987 int counter = 0;
3988 while (sf) {
3989 for (p = sf->samples; p; p = p->next) {
3990 if (p->v.sample == sample)
3991 return p;
3993 sf = sf->shared;
3994 if (counter++ > current_sf_id)
3995 break; /* strange sharing loop.. quit */
3997 #else
3998 if (sf) {
3999 for (p = sf->samples; p; p = p->next) {
4000 if (p->v.sample == sample)
4001 return p;
4004 #endif
4005 return NULL;
4008 /* search the specified sample */
4009 /* non-zero = found */
4010 static short
4011 awe_set_sample(awe_voice_list *rec)
4013 awe_sample_list *smp;
4014 awe_voice_info *vp = &rec->v;
4016 vp->index = 0;
4017 if ((smp = search_sample_index(rec->holder, vp->sample)) == NULL)
4018 return 0;
4020 /* set the actual sample offsets */
4021 vp->start += smp->v.start;
4022 vp->end += smp->v.end;
4023 vp->loopstart += smp->v.loopstart;
4024 vp->loopend += smp->v.loopend;
4025 /* copy mode flags */
4026 vp->mode = smp->v.mode_flags;
4027 /* set flag */
4028 vp->index = 1;
4030 return 1;
4035 * voice allocation
4038 /* look for all voices associated with the specified note & velocity */
4039 static int
4040 awe_search_multi_voices(awe_voice_list *rec, int note, int velocity,
4041 awe_voice_info **vlist)
4043 int nvoices;
4045 nvoices = 0;
4046 for (; rec; rec = rec->next_instr) {
4047 if (note >= rec->v.low &&
4048 note <= rec->v.high &&
4049 velocity >= rec->v.vellow &&
4050 velocity <= rec->v.velhigh) {
4051 if (rec->type == V_ST_MAPPED) {
4052 /* mapper */
4053 vlist[0] = &rec->v;
4054 return -1;
4056 vlist[nvoices++] = &rec->v;
4057 if (nvoices >= AWE_MAX_VOICES)
4058 break;
4061 return nvoices;
4064 /* store the voice list from the specified note and velocity.
4065 if the preset is mapped, seek for the destination preset, and rewrite
4066 the note number if necessary.
4068 static int
4069 really_alloc_voices(int bank, int instr, int *note, int velocity, awe_voice_info **vlist)
4071 int nvoices;
4072 awe_voice_list *vrec;
4073 int level = 0;
4075 for (;;) {
4076 vrec = awe_search_instr(bank, instr, *note);
4077 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
4078 if (nvoices == 0) {
4079 if (bank == AWE_DRUM_BANK)
4080 /* search default drumset */
4081 vrec = awe_search_instr(bank, ctrls[AWE_MD_DEF_DRUM], *note);
4082 else
4083 /* search default preset */
4084 vrec = awe_search_instr(ctrls[AWE_MD_DEF_BANK], instr, *note);
4085 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
4087 if (nvoices == 0) {
4088 if (bank == AWE_DRUM_BANK && ctrls[AWE_MD_DEF_DRUM] != 0)
4089 /* search default drumset */
4090 vrec = awe_search_instr(bank, 0, *note);
4091 else if (bank != AWE_DRUM_BANK && ctrls[AWE_MD_DEF_BANK] != 0)
4092 /* search default preset */
4093 vrec = awe_search_instr(0, instr, *note);
4094 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
4096 if (nvoices < 0) { /* mapping */
4097 int key = vlist[0]->fixkey;
4098 instr = vlist[0]->start;
4099 bank = vlist[0]->end;
4100 if (level++ > 5) {
4101 printk(KERN_ERR "AWE32: too deep mapping level\n");
4102 return 0;
4104 if (key >= 0)
4105 *note = key;
4106 } else
4107 break;
4110 return nvoices;
4113 /* allocate voices corresponding note and velocity; supports multiple insts. */
4114 static void
4115 awe_alloc_multi_voices(int ch, int note, int velocity, int key)
4117 int i, v, nvoices, bank;
4118 awe_voice_info *vlist[AWE_MAX_VOICES];
4120 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch))
4121 bank = AWE_DRUM_BANK; /* always search drumset */
4122 else
4123 bank = channels[ch].bank;
4125 /* check the possible voices; note may be changeable if mapped */
4126 nvoices = really_alloc_voices(bank, channels[ch].instr,
4127 &note, velocity, vlist);
4129 /* set the voices */
4130 current_alloc_time++;
4131 for (i = 0; i < nvoices; i++) {
4132 v = awe_clear_voice();
4133 voices[v].key = key;
4134 voices[v].ch = ch;
4135 voices[v].note = note;
4136 voices[v].velocity = velocity;
4137 voices[v].time = current_alloc_time;
4138 voices[v].cinfo = &channels[ch];
4139 voices[v].sample = vlist[i];
4140 voices[v].state = AWE_ST_MARK;
4141 voices[v].layer = nvoices - i - 1; /* in reverse order */
4144 /* clear the mark in allocated voices */
4145 for (i = 0; i < awe_max_voices; i++) {
4146 if (voices[i].state == AWE_ST_MARK)
4147 voices[i].state = AWE_ST_OFF;
4153 /* search an empty voice.
4154 if no empty voice is found, at least terminate a voice
4156 static int
4157 awe_clear_voice(void)
4159 enum {
4160 OFF=0, RELEASED, SUSTAINED, PLAYING, END
4162 struct voice_candidate_t {
4163 int best;
4164 int time;
4165 int vtarget;
4166 } candidate[END];
4167 int i, type, vtarget;
4169 vtarget = 0xffff;
4170 for (type = OFF; type < END; type++) {
4171 candidate[type].best = -1;
4172 candidate[type].time = current_alloc_time + 1;
4173 candidate[type].vtarget = vtarget;
4176 for (i = 0; i < awe_max_voices; i++) {
4177 if (voices[i].state & AWE_ST_OFF)
4178 type = OFF;
4179 else if (voices[i].state & AWE_ST_RELEASED)
4180 type = RELEASED;
4181 else if (voices[i].state & AWE_ST_SUSTAINED)
4182 type = SUSTAINED;
4183 else if (voices[i].state & ~AWE_ST_MARK)
4184 type = PLAYING;
4185 else
4186 continue;
4187 #ifdef AWE_CHECK_VTARGET
4188 /* get current volume */
4189 vtarget = (awe_peek_dw(AWE_VTFT(i)) >> 16) & 0xffff;
4190 #endif
4191 if (candidate[type].best < 0 ||
4192 vtarget < candidate[type].vtarget ||
4193 (vtarget == candidate[type].vtarget &&
4194 voices[i].time < candidate[type].time)) {
4195 candidate[type].best = i;
4196 candidate[type].time = voices[i].time;
4197 candidate[type].vtarget = vtarget;
4201 for (type = OFF; type < END; type++) {
4202 if ((i = candidate[type].best) >= 0) {
4203 if (voices[i].state != AWE_ST_OFF)
4204 awe_terminate(i);
4205 awe_voice_init(i, TRUE);
4206 return i;
4209 return 0;
4213 /* search sample for the specified note & velocity and set it on the voice;
4214 * note that voice is the voice index (not channel index)
4216 static void
4217 awe_alloc_one_voice(int voice, int note, int velocity)
4219 int ch, nvoices, bank;
4220 awe_voice_info *vlist[AWE_MAX_VOICES];
4222 ch = voices[voice].ch;
4223 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice))
4224 bank = AWE_DRUM_BANK; /* always search drumset */
4225 else
4226 bank = voices[voice].cinfo->bank;
4228 nvoices = really_alloc_voices(bank, voices[voice].cinfo->instr,
4229 &note, velocity, vlist);
4230 if (nvoices > 0) {
4231 voices[voice].time = ++current_alloc_time;
4232 voices[voice].sample = vlist[0]; /* use the first one */
4233 voices[voice].layer = 0;
4234 voices[voice].note = note;
4235 voices[voice].velocity = velocity;
4241 * sequencer2 functions
4244 /* search an empty voice; used by sequencer2 */
4245 static int
4246 awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
4248 playing_mode = AWE_PLAY_MULTI2;
4249 awe_info.nr_voices = AWE_MAX_CHANNELS;
4250 return awe_clear_voice();
4254 /* set up voice; used by sequencer2 */
4255 static void
4256 awe_setup_voice(int dev, int voice, int chn)
4258 struct channel_info *info;
4259 if (synth_devs[dev] == NULL ||
4260 (info = &synth_devs[dev]->chn_info[chn]) == NULL)
4261 return;
4263 if (voice < 0 || voice >= awe_max_voices)
4264 return;
4266 DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn));
4267 channels[chn].expression_vol = info->controllers[CTL_EXPRESSION];
4268 channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME];
4269 channels[chn].panning =
4270 info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */
4271 channels[chn].bender = info->bender_value; /* zero center */
4272 channels[chn].bank = info->controllers[CTL_BANK_SELECT];
4273 channels[chn].sustained = info->controllers[CTL_SUSTAIN];
4274 if (info->controllers[CTL_EXT_EFF_DEPTH]) {
4275 FX_SET(&channels[chn].fx, AWE_FX_REVERB,
4276 info->controllers[CTL_EXT_EFF_DEPTH] * 2);
4278 if (info->controllers[CTL_CHORUS_DEPTH]) {
4279 FX_SET(&channels[chn].fx, AWE_FX_CHORUS,
4280 info->controllers[CTL_CHORUS_DEPTH] * 2);
4282 awe_set_instr(dev, chn, info->pgm_num);
4286 #ifdef CONFIG_AWE32_MIXER
4288 * AWE32 mixer device control
4291 static int awe_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg);
4293 static int my_mixerdev = -1;
4295 static struct mixer_operations awe_mixer_operations = {
4296 "AWE32 Equalizer",
4297 awe_mixer_ioctl,
4300 static void __init attach_mixer(void)
4302 if ((my_mixerdev = sound_alloc_mixerdev()) >= 0) {
4303 mixer_devs[my_mixerdev] = &awe_mixer_operations;
4307 static void __exit unload_mixer(void)
4309 if (my_mixerdev >= 0)
4310 sound_unload_mixerdev(my_mixerdev);
4313 static int
4314 awe_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
4316 int i, level, value;
4318 if (((cmd >> 8) & 0xff) != 'M')
4319 return -EINVAL;
4321 level = *(int*)arg;
4322 level = ((level & 0xff) + (level >> 8)) / 2;
4323 DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
4325 if (_SIOC_DIR(cmd) & _IOC_WRITE) {
4326 switch (cmd & 0xff) {
4327 case SOUND_MIXER_BASS:
4328 value = level * 12 / 100;
4329 if (value >= 12)
4330 value = 11;
4331 ctrls[AWE_MD_BASS_LEVEL] = value;
4332 awe_update_equalizer();
4333 break;
4334 case SOUND_MIXER_TREBLE:
4335 value = level * 12 / 100;
4336 if (value >= 12)
4337 value = 11;
4338 ctrls[AWE_MD_TREBLE_LEVEL] = value;
4339 awe_update_equalizer();
4340 break;
4341 case SOUND_MIXER_VOLUME:
4342 level = level * 127 / 100;
4343 if (level >= 128) level = 127;
4344 atten_relative = FALSE;
4345 atten_offset = vol_table[level];
4346 awe_update_volume();
4347 break;
4350 switch (cmd & 0xff) {
4351 case SOUND_MIXER_BASS:
4352 level = ctrls[AWE_MD_BASS_LEVEL] * 100 / 24;
4353 level = (level << 8) | level;
4354 break;
4355 case SOUND_MIXER_TREBLE:
4356 level = ctrls[AWE_MD_TREBLE_LEVEL] * 100 / 24;
4357 level = (level << 8) | level;
4358 break;
4359 case SOUND_MIXER_VOLUME:
4360 value = atten_offset;
4361 if (atten_relative)
4362 value += ctrls[AWE_MD_ZERO_ATTEN];
4363 for (i = 127; i > 0; i--) {
4364 if (value <= vol_table[i])
4365 break;
4367 level = i * 100 / 127;
4368 level = (level << 8) | level;
4369 break;
4370 case SOUND_MIXER_DEVMASK:
4371 level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME;
4372 break;
4373 default:
4374 level = 0;
4375 break;
4377 return *(int*)arg = level;
4379 #endif /* CONFIG_AWE32_MIXER */
4383 * initialization of Emu8000
4386 /* intiailize audio channels */
4387 static void
4388 awe_init_audio(void)
4390 int ch;
4392 /* turn off envelope engines */
4393 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4394 awe_poke(AWE_DCYSUSV(ch), 0x80);
4397 /* reset all other parameters to zero */
4398 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4399 awe_poke(AWE_ENVVOL(ch), 0);
4400 awe_poke(AWE_ENVVAL(ch), 0);
4401 awe_poke(AWE_DCYSUS(ch), 0);
4402 awe_poke(AWE_ATKHLDV(ch), 0);
4403 awe_poke(AWE_LFO1VAL(ch), 0);
4404 awe_poke(AWE_ATKHLD(ch), 0);
4405 awe_poke(AWE_LFO2VAL(ch), 0);
4406 awe_poke(AWE_IP(ch), 0);
4407 awe_poke(AWE_IFATN(ch), 0);
4408 awe_poke(AWE_PEFE(ch), 0);
4409 awe_poke(AWE_FMMOD(ch), 0);
4410 awe_poke(AWE_TREMFRQ(ch), 0);
4411 awe_poke(AWE_FM2FRQ2(ch), 0);
4412 awe_poke_dw(AWE_PTRX(ch), 0);
4413 awe_poke_dw(AWE_VTFT(ch), 0);
4414 awe_poke_dw(AWE_PSST(ch), 0);
4415 awe_poke_dw(AWE_CSL(ch), 0);
4416 awe_poke_dw(AWE_CCCA(ch), 0);
4419 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4420 awe_poke_dw(AWE_CPF(ch), 0);
4421 awe_poke_dw(AWE_CVCF(ch), 0);
4426 /* initialize DMA address */
4427 static void
4428 awe_init_dma(void)
4430 awe_poke_dw(AWE_SMALR, 0);
4431 awe_poke_dw(AWE_SMARR, 0);
4432 awe_poke_dw(AWE_SMALW, 0);
4433 awe_poke_dw(AWE_SMARW, 0);
4437 /* initialization arrays; from ADIP */
4439 static unsigned short init1[128] = {
4440 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330,
4441 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730,
4442 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30,
4443 0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30,
4445 0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330,
4446 0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730,
4447 0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30,
4448 0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30,
4450 0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330,
4451 0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730,
4452 0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30,
4453 0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30,
4455 0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330,
4456 0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730,
4457 0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30,
4458 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30,
4461 static unsigned short init2[128] = {
4462 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
4463 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
4464 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
4465 0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
4467 0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
4468 0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
4469 0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
4470 0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
4472 0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
4473 0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
4474 0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
4475 0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
4477 0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
4478 0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
4479 0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
4480 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
4483 static unsigned short init3[128] = {
4484 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4485 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
4486 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
4487 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
4489 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
4490 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
4491 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
4492 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
4494 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
4495 0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
4496 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
4497 0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
4499 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
4500 0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
4501 0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
4502 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
4505 static unsigned short init4[128] = {
4506 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4507 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
4508 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
4509 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
4511 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
4512 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
4513 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
4514 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
4516 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
4517 0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
4518 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
4519 0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
4521 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
4522 0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
4523 0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
4524 0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
4528 /* send initialization arrays to start up */
4529 static void
4530 awe_init_array(void)
4532 awe_send_array(init1);
4533 awe_wait(1024);
4534 awe_send_array(init2);
4535 awe_send_array(init3);
4536 awe_poke_dw(AWE_HWCF4, 0);
4537 awe_poke_dw(AWE_HWCF5, 0x83);
4538 awe_poke_dw(AWE_HWCF6, 0x8000);
4539 awe_send_array(init4);
4542 /* send an initialization array */
4543 static void
4544 awe_send_array(unsigned short *data)
4546 int i;
4547 unsigned short *p;
4549 p = data;
4550 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4551 awe_poke(AWE_INIT1(i), *p);
4552 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4553 awe_poke(AWE_INIT2(i), *p);
4554 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4555 awe_poke(AWE_INIT3(i), *p);
4556 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4557 awe_poke(AWE_INIT4(i), *p);
4562 * set up awe32 channels to some known state.
4565 /* set the envelope & LFO parameters to the default values; see ADIP */
4566 static void
4567 awe_tweak_voice(int i)
4569 /* set all mod/vol envelope shape to minimum */
4570 awe_poke(AWE_ENVVOL(i), 0x8000);
4571 awe_poke(AWE_ENVVAL(i), 0x8000);
4572 awe_poke(AWE_DCYSUS(i), 0x7F7F);
4573 awe_poke(AWE_ATKHLDV(i), 0x7F7F);
4574 awe_poke(AWE_ATKHLD(i), 0x7F7F);
4575 awe_poke(AWE_PEFE(i), 0); /* mod envelope height to zero */
4576 awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */
4577 awe_poke(AWE_LFO2VAL(i), 0x8000);
4578 awe_poke(AWE_IP(i), 0xE000); /* no pitch shift */
4579 awe_poke(AWE_IFATN(i), 0xFF00); /* volume to minimum */
4580 awe_poke(AWE_FMMOD(i), 0);
4581 awe_poke(AWE_TREMFRQ(i), 0);
4582 awe_poke(AWE_FM2FRQ2(i), 0);
4585 static void
4586 awe_tweak(void)
4588 int i;
4589 /* reset all channels */
4590 for (i = 0; i < awe_max_voices; i++)
4591 awe_tweak_voice(i);
4596 * initializes the FM section of AWE32;
4597 * see Vince Vu's unofficial AWE32 programming guide
4600 static void
4601 awe_init_fm(void)
4603 #ifndef AWE_ALWAYS_INIT_FM
4604 /* if no extended memory is on board.. */
4605 if (memsize <= 0)
4606 return;
4607 #endif
4608 DEBUG(3,printk("AWE32: initializing FM\n"));
4610 /* Initialize the last two channels for DRAM refresh and producing
4611 the reverb and chorus effects for Yamaha OPL-3 synthesizer */
4613 /* 31: FM left channel, 0xffffe0-0xffffe8 */
4614 awe_poke(AWE_DCYSUSV(30), 0x80);
4615 awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */
4616 awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 |
4617 (DEF_FM_CHORUS_DEPTH << 24));
4618 awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8));
4619 awe_poke_dw(AWE_CPF(30), 0);
4620 awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3);
4622 /* 32: FM right channel, 0xfffff0-0xfffff8 */
4623 awe_poke(AWE_DCYSUSV(31), 0x80);
4624 awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */
4625 awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 |
4626 (DEF_FM_CHORUS_DEPTH << 24));
4627 awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8));
4628 awe_poke_dw(AWE_CPF(31), 0x8000);
4629 awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3);
4631 /* skew volume & cutoff */
4632 awe_poke_dw(AWE_VTFT(30), 0x8000FFFF);
4633 awe_poke_dw(AWE_VTFT(31), 0x8000FFFF);
4635 voices[30].state = AWE_ST_FM;
4636 voices[31].state = AWE_ST_FM;
4638 /* change maximum channels to 30 */
4639 awe_max_voices = AWE_NORMAL_VOICES;
4640 if (playing_mode == AWE_PLAY_DIRECT)
4641 awe_info.nr_voices = awe_max_voices;
4642 else
4643 awe_info.nr_voices = AWE_MAX_CHANNELS;
4644 voice_alloc->max_voice = awe_max_voices;
4648 * AWE32 DRAM access routines
4651 /* open DRAM write accessing mode */
4652 static int
4653 awe_open_dram_for_write(int offset, int channels)
4655 int vidx[AWE_NORMAL_VOICES];
4656 int i;
4658 if (channels < 0 || channels >= AWE_NORMAL_VOICES) {
4659 channels = AWE_NORMAL_VOICES;
4660 for (i = 0; i < AWE_NORMAL_VOICES; i++)
4661 vidx[i] = i;
4662 } else {
4663 for (i = 0; i < channels; i++) {
4664 vidx[i] = awe_clear_voice();
4665 voices[vidx[i]].state = AWE_ST_MARK;
4669 /* use all channels for DMA transfer */
4670 for (i = 0; i < channels; i++) {
4671 if (vidx[i] < 0) continue;
4672 awe_poke(AWE_DCYSUSV(vidx[i]), 0x80);
4673 awe_poke_dw(AWE_VTFT(vidx[i]), 0);
4674 awe_poke_dw(AWE_CVCF(vidx[i]), 0);
4675 awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000);
4676 awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000);
4677 awe_poke_dw(AWE_PSST(vidx[i]), 0);
4678 awe_poke_dw(AWE_CSL(vidx[i]), 0);
4679 awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000);
4680 voices[vidx[i]].state = AWE_ST_DRAM;
4682 /* point channels 31 & 32 to ROM samples for DRAM refresh */
4683 awe_poke_dw(AWE_VTFT(30), 0);
4684 awe_poke_dw(AWE_PSST(30), 0x1d8);
4685 awe_poke_dw(AWE_CSL(30), 0x1e0);
4686 awe_poke_dw(AWE_CCCA(30), 0x1d8);
4687 awe_poke_dw(AWE_VTFT(31), 0);
4688 awe_poke_dw(AWE_PSST(31), 0x1d8);
4689 awe_poke_dw(AWE_CSL(31), 0x1e0);
4690 awe_poke_dw(AWE_CCCA(31), 0x1d8);
4691 voices[30].state = AWE_ST_FM;
4692 voices[31].state = AWE_ST_FM;
4694 /* if full bit is on, not ready to write on */
4695 if (awe_peek_dw(AWE_SMALW) & 0x80000000) {
4696 for (i = 0; i < channels; i++) {
4697 awe_poke_dw(AWE_CCCA(vidx[i]), 0);
4698 voices[vidx[i]].state = AWE_ST_OFF;
4700 printk("awe: not ready to write..\n");
4701 return -EPERM;
4704 /* set address to write */
4705 awe_poke_dw(AWE_SMALW, offset);
4707 return 0;
4710 /* open DRAM for RAM size detection */
4711 static void
4712 awe_open_dram_for_check(void)
4714 int i;
4715 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4716 awe_poke(AWE_DCYSUSV(i), 0x80);
4717 awe_poke_dw(AWE_VTFT(i), 0);
4718 awe_poke_dw(AWE_CVCF(i), 0);
4719 awe_poke_dw(AWE_PTRX(i), 0x40000000);
4720 awe_poke_dw(AWE_CPF(i), 0x40000000);
4721 awe_poke_dw(AWE_PSST(i), 0);
4722 awe_poke_dw(AWE_CSL(i), 0);
4723 if (i & 1) /* DMA write */
4724 awe_poke_dw(AWE_CCCA(i), 0x06000000);
4725 else /* DMA read */
4726 awe_poke_dw(AWE_CCCA(i), 0x04000000);
4727 voices[i].state = AWE_ST_DRAM;
4732 /* close dram access */
4733 static void
4734 awe_close_dram(void)
4736 int i;
4737 /* wait until FULL bit in SMAxW register be false */
4738 for (i = 0; i < 10000; i++) {
4739 if (!(awe_peek_dw(AWE_SMALW) & 0x80000000))
4740 break;
4741 awe_wait(10);
4744 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4745 if (voices[i].state == AWE_ST_DRAM) {
4746 awe_poke_dw(AWE_CCCA(i), 0);
4747 awe_poke(AWE_DCYSUSV(i), 0x807F);
4748 voices[i].state = AWE_ST_OFF;
4755 * detect presence of AWE32 and check memory size
4758 /* detect emu8000 chip on the specified address; from VV's guide */
4760 static int __init
4761 awe_detect_base(int addr)
4763 setup_ports(addr, 0, 0);
4764 if ((awe_peek(AWE_U1) & 0x000F) != 0x000C)
4765 return 0;
4766 if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058)
4767 return 0;
4768 if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003)
4769 return 0;
4770 DEBUG(0,printk("AWE32 found at %x\n", addr));
4771 return 1;
4774 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
4775 static struct {
4776 unsigned short vendor;
4777 unsigned short function;
4778 char *name;
4779 } isapnp_awe_list[] __initdata = {
4780 {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0021), "AWE32 WaveTable"},
4781 {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0022), "AWE64 WaveTable"},
4782 {ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0023), "AWE64 Gold WaveTable"},
4783 {0,}
4786 static struct pci_dev *idev = NULL;
4788 static int __init awe_probe_isapnp(int *port)
4790 int i;
4792 for (i = 0; isapnp_awe_list[i].vendor != 0; i++) {
4793 while ((idev = isapnp_find_dev(NULL,
4794 isapnp_awe_list[i].vendor,
4795 isapnp_awe_list[i].function,
4796 idev))) {
4797 if (idev->prepare(idev) < 0)
4798 continue;
4799 if (idev->activate(idev) < 0 ||
4800 !idev->resource[0].start) {
4801 idev->deactivate(idev);
4802 idev->deactivate(idev);
4803 continue;
4805 *port = idev->resource[0].start;
4806 break;
4808 if (!idev)
4809 continue;
4810 printk(KERN_INFO "ISAPnP reports %s at i/o %#x\n",
4811 isapnp_awe_list[i].name, *port);
4812 return 0;
4814 return -ENODEV;
4817 static void __exit awe_deactivate_isapnp(void)
4819 #if 1
4820 if (idev) {
4821 idev->deactivate(idev);
4822 idev = NULL;
4824 #endif
4827 #endif
4829 static int __init
4830 awe_detect(void)
4832 int base;
4834 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
4835 if (isapnp) {
4836 if (awe_probe_isapnp(&io) < 0) {
4837 printk(KERN_ERR "AWE32: No ISAPnP cards found\n");
4838 return 0;
4840 setup_ports(io, 0, 0);
4841 return 1;
4843 #endif /* isapnp */
4845 if (io) /* use default i/o port value */
4846 setup_ports(io, 0, 0);
4847 else { /* probe it */
4848 for (base = 0x620; base <= 0x680; base += 0x20)
4849 if (awe_detect_base(base))
4850 return 1;
4851 DEBUG(0,printk("AWE32 not found\n"));
4852 return 0;
4855 return 1;
4860 * check dram size on AWE board
4863 /* any three numbers you like */
4864 #define UNIQUE_ID1 0x1234
4865 #define UNIQUE_ID2 0x4321
4866 #define UNIQUE_ID3 0xFFFF
4868 static void __init
4869 awe_check_dram(void)
4871 if (awe_present) /* already initialized */
4872 return;
4874 if (memsize >= 0) { /* given by config file or module option */
4875 memsize *= 1024; /* convert to Kbytes */
4876 return;
4879 awe_open_dram_for_check();
4881 memsize = 0;
4883 /* set up unique two id numbers */
4884 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET);
4885 awe_poke(AWE_SMLD, UNIQUE_ID1);
4886 awe_poke(AWE_SMLD, UNIQUE_ID2);
4888 while (memsize < AWE_MAX_DRAM_SIZE) {
4889 awe_wait(5);
4890 /* read a data on the DRAM start address */
4891 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET);
4892 awe_peek(AWE_SMLD); /* discard stale data */
4893 if (awe_peek(AWE_SMLD) != UNIQUE_ID1)
4894 break;
4895 if (awe_peek(AWE_SMLD) != UNIQUE_ID2)
4896 break;
4897 memsize += 512; /* increment 512kbytes */
4898 /* Write a unique data on the test address;
4899 * if the address is out of range, the data is written on
4900 * 0x200000(=AWE_DRAM_OFFSET). Then the two id words are
4901 * broken by this data.
4903 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + memsize*512L);
4904 awe_poke(AWE_SMLD, UNIQUE_ID3);
4905 awe_wait(5);
4906 /* read a data on the just written DRAM address */
4907 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + memsize*512L);
4908 awe_peek(AWE_SMLD); /* discard stale data */
4909 if (awe_peek(AWE_SMLD) != UNIQUE_ID3)
4910 break;
4912 awe_close_dram();
4914 DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", memsize));
4916 /* convert to Kbytes */
4917 memsize *= 1024;
4921 /*----------------------------------------------------------------*/
4924 * chorus and reverb controls; from VV's guide
4927 /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
4928 static char chorus_defined[AWE_CHORUS_NUMBERS];
4929 static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = {
4930 {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
4931 {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
4932 {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
4933 {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
4934 {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
4935 {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
4936 {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */
4937 {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */
4940 static int
4941 awe_load_chorus_fx(awe_patch_info *patch, const char *addr, int count)
4943 if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) {
4944 printk(KERN_WARNING "AWE32 Error: invalid chorus mode %d for uploading\n", patch->optarg);
4945 return -EINVAL;
4947 if (count < sizeof(awe_chorus_fx_rec)) {
4948 printk(KERN_WARNING "AWE32 Error: too short chorus fx parameters\n");
4949 return -EINVAL;
4951 if (copy_from_user(&chorus_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
4952 sizeof(awe_chorus_fx_rec)))
4953 return -EFAULT;
4954 chorus_defined[patch->optarg] = TRUE;
4955 return 0;
4958 static void
4959 awe_set_chorus_mode(int effect)
4961 if (effect < 0 || effect >= AWE_CHORUS_NUMBERS ||
4962 (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect]))
4963 return;
4964 awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback);
4965 awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset);
4966 awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth);
4967 awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay);
4968 awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq);
4969 awe_poke_dw(AWE_HWCF6, 0x8000);
4970 awe_poke_dw(AWE_HWCF7, 0x0000);
4973 static void
4974 awe_update_chorus_mode(void)
4976 awe_set_chorus_mode(ctrls[AWE_MD_CHORUS_MODE]);
4979 /*----------------------------------------------------------------*/
4981 /* reverb mode settings; write the following 28 data of 16 bit length
4982 * on the corresponding ports in the reverb_cmds array
4984 static char reverb_defined[AWE_CHORUS_NUMBERS];
4985 static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = {
4986 {{ /* room 1 */
4987 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
4988 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
4989 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4990 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4992 {{ /* room 2 */
4993 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4994 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4995 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4996 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4998 {{ /* room 3 */
4999 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
5000 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
5001 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
5002 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
5004 {{ /* hall 1 */
5005 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
5006 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
5007 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
5008 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
5010 {{ /* hall 2 */
5011 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
5012 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
5013 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
5014 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
5016 {{ /* plate */
5017 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
5018 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
5019 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
5020 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
5022 {{ /* delay */
5023 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
5024 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
5025 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
5026 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
5028 {{ /* panning delay */
5029 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
5030 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
5031 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
5032 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
5036 static struct ReverbCmdPair {
5037 unsigned short cmd, port;
5038 } reverb_cmds[28] = {
5039 {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
5040 {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
5041 {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
5042 {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
5043 {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
5044 {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
5045 {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
5048 static int
5049 awe_load_reverb_fx(awe_patch_info *patch, const char *addr, int count)
5051 if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) {
5052 printk(KERN_WARNING "AWE32 Error: invalid reverb mode %d for uploading\n", patch->optarg);
5053 return -EINVAL;
5055 if (count < sizeof(awe_reverb_fx_rec)) {
5056 printk(KERN_WARNING "AWE32 Error: too short reverb fx parameters\n");
5057 return -EINVAL;
5059 if (copy_from_user(&reverb_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
5060 sizeof(awe_reverb_fx_rec)))
5061 return -EFAULT;
5062 reverb_defined[patch->optarg] = TRUE;
5063 return 0;
5066 static void
5067 awe_set_reverb_mode(int effect)
5069 int i;
5070 if (effect < 0 || effect >= AWE_REVERB_NUMBERS ||
5071 (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect]))
5072 return;
5073 for (i = 0; i < 28; i++)
5074 awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port,
5075 reverb_parm[effect].parms[i]);
5078 static void
5079 awe_update_reverb_mode(void)
5081 awe_set_reverb_mode(ctrls[AWE_MD_REVERB_MODE]);
5085 * treble/bass equalizer control
5088 static unsigned short bass_parm[12][3] = {
5089 {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
5090 {0xD25B, 0xD35B, 0x0000}, /* -8 */
5091 {0xD24C, 0xD34C, 0x0000}, /* -6 */
5092 {0xD23D, 0xD33D, 0x0000}, /* -4 */
5093 {0xD21F, 0xD31F, 0x0000}, /* -2 */
5094 {0xC208, 0xC308, 0x0001}, /* 0 (HW default) */
5095 {0xC219, 0xC319, 0x0001}, /* +2 */
5096 {0xC22A, 0xC32A, 0x0001}, /* +4 */
5097 {0xC24C, 0xC34C, 0x0001}, /* +6 */
5098 {0xC26E, 0xC36E, 0x0001}, /* +8 */
5099 {0xC248, 0xC348, 0x0002}, /* +10 */
5100 {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
5103 static unsigned short treble_parm[12][9] = {
5104 {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
5105 {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
5106 {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
5107 {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
5108 {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
5109 {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
5110 {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
5111 {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
5112 {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
5113 {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
5114 {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
5115 {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */
5120 * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
5122 static void
5123 awe_equalizer(int bass, int treble)
5125 unsigned short w;
5127 if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
5128 return;
5129 awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]);
5130 awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]);
5131 awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]);
5132 awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]);
5133 awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]);
5134 awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]);
5135 awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]);
5136 awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]);
5137 awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]);
5138 awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]);
5139 w = bass_parm[bass][2] + treble_parm[treble][8];
5140 awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262));
5141 awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362));
5144 static void awe_update_equalizer(void)
5146 awe_equalizer(ctrls[AWE_MD_BASS_LEVEL], ctrls[AWE_MD_TREBLE_LEVEL]);
5150 /*----------------------------------------------------------------*/
5152 #ifdef CONFIG_AWE32_MIDIEMU
5155 * Emu8000 MIDI Emulation
5159 * midi queue record
5162 /* queue type */
5163 enum { Q_NONE, Q_VARLEN, Q_READ, Q_SYSEX, };
5165 #define MAX_MIDIBUF 64
5167 /* midi status */
5168 typedef struct MidiStatus {
5169 int queue; /* queue type */
5170 int qlen; /* queue length */
5171 int read; /* chars read */
5172 int status; /* current status */
5173 int chan; /* current channel */
5174 unsigned char buf[MAX_MIDIBUF];
5175 } MidiStatus;
5177 /* MIDI mode type */
5178 enum { MODE_GM, MODE_GS, MODE_XG, };
5180 /* NRPN / CC -> Emu8000 parameter converter */
5181 typedef struct {
5182 int control;
5183 int awe_effect;
5184 unsigned short (*convert)(int val);
5185 } ConvTable;
5189 * prototypes
5192 static int awe_midi_open(int dev, int mode, void (*input)(int,unsigned char), void (*output)(int));
5193 static void awe_midi_close(int dev);
5194 static int awe_midi_ioctl(int dev, unsigned cmd, caddr_t arg);
5195 static int awe_midi_outputc(int dev, unsigned char midi_byte);
5197 static void init_midi_status(MidiStatus *st);
5198 static void clear_rpn(void);
5199 static void get_midi_char(MidiStatus *st, int c);
5200 /*static void queue_varlen(MidiStatus *st, int c);*/
5201 static void special_event(MidiStatus *st, int c);
5202 static void queue_read(MidiStatus *st, int c);
5203 static void midi_note_on(MidiStatus *st);
5204 static void midi_note_off(MidiStatus *st);
5205 static void midi_key_pressure(MidiStatus *st);
5206 static void midi_channel_pressure(MidiStatus *st);
5207 static void midi_pitch_wheel(MidiStatus *st);
5208 static void midi_program_change(MidiStatus *st);
5209 static void midi_control_change(MidiStatus *st);
5210 static void midi_select_bank(MidiStatus *st, int val);
5211 static void midi_nrpn_event(MidiStatus *st);
5212 static void midi_rpn_event(MidiStatus *st);
5213 static void midi_detune(int chan, int coarse, int fine);
5214 static void midi_system_exclusive(MidiStatus *st);
5215 static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
5216 static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
5217 static int xg_control_change(MidiStatus *st, int cmd, int val);
5219 #define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
5223 * OSS Midi device record
5226 static struct midi_operations awe_midi_operations =
5228 {"AWE Midi Emu", 0, 0, SNDCARD_SB},
5229 NULL /*&std_midi_synth*/,
5230 {0}, /* input_info */
5231 awe_midi_open, /*open*/
5232 awe_midi_close, /*close*/
5233 awe_midi_ioctl, /*ioctl*/
5234 awe_midi_outputc, /*outputc*/
5235 NULL /*start_read*/,
5236 NULL /*end_read*/,
5237 NULL, /* kick */
5238 NULL, /* command */
5241 static int my_mididev = -1;
5243 static void __init attach_midiemu(void)
5245 if ((my_mididev = sound_alloc_mididev()) < 0)
5246 printk ("Sound: Too many midi devices detected\n");
5247 else
5248 midi_devs[my_mididev] = &awe_midi_operations;
5251 static void __exit unload_midiemu(void)
5253 if (my_mididev >= 0)
5254 sound_unload_mididev(my_mididev);
5259 * open/close midi device
5262 static int midi_opened = FALSE;
5264 static int midi_mode;
5265 static int coarsetune = 0, finetune = 0;
5267 static int xg_mapping = TRUE;
5268 static int xg_bankmode = 0;
5270 /* effect sensitivity */
5272 #define FX_CUTOFF 0
5273 #define FX_RESONANCE 1
5274 #define FX_ATTACK 2
5275 #define FX_RELEASE 3
5276 #define FX_VIBRATE 4
5277 #define FX_VIBDEPTH 5
5278 #define FX_VIBDELAY 6
5279 #define FX_NUMS 7
5281 #define DEF_FX_CUTOFF 170
5282 #define DEF_FX_RESONANCE 6
5283 #define DEF_FX_ATTACK 50
5284 #define DEF_FX_RELEASE 50
5285 #define DEF_FX_VIBRATE 30
5286 #define DEF_FX_VIBDEPTH 4
5287 #define DEF_FX_VIBDELAY 1500
5289 /* effect sense: */
5290 static int gs_sense[] =
5292 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
5293 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
5295 static int xg_sense[] =
5297 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
5298 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
5302 /* current status */
5303 static MidiStatus curst;
5306 static int
5307 awe_midi_open (int dev, int mode,
5308 void (*input)(int,unsigned char),
5309 void (*output)(int))
5311 if (midi_opened)
5312 return -EBUSY;
5314 midi_opened = TRUE;
5316 midi_mode = MODE_GM;
5318 curst.queue = Q_NONE;
5319 curst.qlen = 0;
5320 curst.read = 0;
5321 curst.status = 0;
5322 curst.chan = 0;
5323 memset(curst.buf, 0, sizeof(curst.buf));
5325 init_midi_status(&curst);
5327 return 0;
5330 static void
5331 awe_midi_close (int dev)
5333 midi_opened = FALSE;
5337 static int
5338 awe_midi_ioctl (int dev, unsigned cmd, caddr_t arg)
5340 return -EPERM;
5343 static int
5344 awe_midi_outputc (int dev, unsigned char midi_byte)
5346 if (! midi_opened)
5347 return 1;
5349 /* force to change playing mode */
5350 playing_mode = AWE_PLAY_MULTI;
5352 get_midi_char(&curst, midi_byte);
5353 return 1;
5358 * initialize
5361 static void init_midi_status(MidiStatus *st)
5363 clear_rpn();
5364 coarsetune = 0;
5365 finetune = 0;
5370 * RPN & NRPN
5373 #define MAX_MIDI_CHANNELS 16
5375 /* RPN & NRPN */
5376 static unsigned char nrpn[MAX_MIDI_CHANNELS]; /* current event is NRPN? */
5377 static int msb_bit; /* current event is msb for RPN/NRPN */
5378 /* RPN & NRPN indeces */
5379 static unsigned char rpn_msb[MAX_MIDI_CHANNELS], rpn_lsb[MAX_MIDI_CHANNELS];
5380 /* RPN & NRPN values */
5381 static int rpn_val[MAX_MIDI_CHANNELS];
5383 static void clear_rpn(void)
5385 int i;
5386 for (i = 0; i < MAX_MIDI_CHANNELS; i++) {
5387 nrpn[i] = 0;
5388 rpn_msb[i] = 127;
5389 rpn_lsb[i] = 127;
5390 rpn_val[i] = 0;
5392 msb_bit = 0;
5397 * process midi queue
5400 /* status event types */
5401 typedef void (*StatusEvent)(MidiStatus *st);
5402 static struct StatusEventList {
5403 StatusEvent process;
5404 int qlen;
5405 } status_event[8] = {
5406 {midi_note_off, 2},
5407 {midi_note_on, 2},
5408 {midi_key_pressure, 2},
5409 {midi_control_change, 2},
5410 {midi_program_change, 1},
5411 {midi_channel_pressure, 1},
5412 {midi_pitch_wheel, 2},
5413 {NULL, 0},
5417 /* read a char from fifo and process it */
5418 static void get_midi_char(MidiStatus *st, int c)
5420 if (c == 0xfe) {
5421 /* ignore active sense */
5422 st->queue = Q_NONE;
5423 return;
5426 switch (st->queue) {
5427 /* case Q_VARLEN: queue_varlen(st, c); break;*/
5428 case Q_READ:
5429 case Q_SYSEX:
5430 queue_read(st, c);
5431 break;
5432 case Q_NONE:
5433 st->read = 0;
5434 if ((c & 0xf0) == 0xf0) {
5435 special_event(st, c);
5436 } else if (c & 0x80) { /* status change */
5437 st->status = (c >> 4) & 0x07;
5438 st->chan = c & 0x0f;
5439 st->queue = Q_READ;
5440 st->qlen = status_event[st->status].qlen;
5441 if (st->qlen == 0)
5442 st->queue = Q_NONE;
5444 break;
5448 /* 0xfx events */
5449 static void special_event(MidiStatus *st, int c)
5451 switch (c) {
5452 case 0xf0: /* system exclusive */
5453 st->queue = Q_SYSEX;
5454 st->qlen = 0;
5455 break;
5456 case 0xf1: /* MTC quarter frame */
5457 case 0xf3: /* song select */
5458 st->queue = Q_READ;
5459 st->qlen = 1;
5460 break;
5461 case 0xf2: /* song position */
5462 st->queue = Q_READ;
5463 st->qlen = 2;
5464 break;
5468 #if 0
5469 /* read variable length value */
5470 static void queue_varlen(MidiStatus *st, int c)
5472 st->qlen += (c & 0x7f);
5473 if (c & 0x80) {
5474 st->qlen <<= 7;
5475 return;
5477 if (st->qlen <= 0) {
5478 st->qlen = 0;
5479 st->queue = Q_NONE;
5481 st->queue = Q_READ;
5482 st->read = 0;
5484 #endif
5487 /* read a char */
5488 static void queue_read(MidiStatus *st, int c)
5490 if (st->read < MAX_MIDIBUF) {
5491 if (st->queue != Q_SYSEX)
5492 c &= 0x7f;
5493 st->buf[st->read] = (unsigned char)c;
5495 st->read++;
5496 if (st->queue == Q_SYSEX && c == 0xf7) {
5497 midi_system_exclusive(st);
5498 st->queue = Q_NONE;
5499 } else if (st->queue == Q_READ && st->read >= st->qlen) {
5500 if (status_event[st->status].process)
5501 status_event[st->status].process(st);
5502 st->queue = Q_NONE;
5508 * status events
5511 /* note on */
5512 static void midi_note_on(MidiStatus *st)
5514 DEBUG(2,printk("midi: note_on (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
5515 if (st->buf[1] == 0)
5516 midi_note_off(st);
5517 else
5518 awe_start_note(0, st->chan, st->buf[0], st->buf[1]);
5521 /* note off */
5522 static void midi_note_off(MidiStatus *st)
5524 DEBUG(2,printk("midi: note_off (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
5525 awe_kill_note(0, st->chan, st->buf[0], st->buf[1]);
5528 /* key pressure change */
5529 static void midi_key_pressure(MidiStatus *st)
5531 awe_key_pressure(0, st->chan, st->buf[0], st->buf[1]);
5534 /* channel pressure change */
5535 static void midi_channel_pressure(MidiStatus *st)
5537 channels[st->chan].chan_press = st->buf[0];
5538 awe_modwheel_change(st->chan, st->buf[0]);
5541 /* pitch wheel change */
5542 static void midi_pitch_wheel(MidiStatus *st)
5544 int val = (int)st->buf[1] * 128 + st->buf[0];
5545 awe_bender(0, st->chan, val);
5548 /* program change */
5549 static void midi_program_change(MidiStatus *st)
5551 int preset;
5552 preset = st->buf[0];
5553 if (midi_mode == MODE_GS && IS_DRUM_CHANNEL(st->chan) && preset == 127)
5554 preset = 0;
5555 else if (midi_mode == MODE_XG && xg_mapping && IS_DRUM_CHANNEL(st->chan))
5556 preset += 64;
5558 awe_set_instr(0, st->chan, preset);
5561 #define send_effect(chan,type,val) awe_send_effect(chan,-1,type,val)
5562 #define add_effect(chan,type,val) awe_send_effect(chan,-1,(type)|0x80,val)
5563 #define unset_effect(chan,type) awe_send_effect(chan,-1,(type)|0x40,0)
5565 /* midi control change */
5566 static void midi_control_change(MidiStatus *st)
5568 int cmd = st->buf[0];
5569 int val = st->buf[1];
5571 DEBUG(2,printk("midi: control (%d) %d %d\n", st->chan, cmd, val));
5572 if (midi_mode == MODE_XG) {
5573 if (xg_control_change(st, cmd, val))
5574 return;
5577 /* controls #31 - #64 are LSB of #0 - #31 */
5578 msb_bit = 1;
5579 if (cmd >= 0x20 && cmd < 0x40) {
5580 msb_bit = 0;
5581 cmd -= 0x20;
5584 switch (cmd) {
5585 case CTL_SOFT_PEDAL:
5586 if (val == 127)
5587 add_effect(st->chan, AWE_FX_CUTOFF, -160);
5588 else
5589 unset_effect(st->chan, AWE_FX_CUTOFF);
5590 break;
5592 case CTL_BANK_SELECT:
5593 midi_select_bank(st, val);
5594 break;
5596 /* set RPN/NRPN parameter */
5597 case CTL_REGIST_PARM_NUM_MSB:
5598 nrpn[st->chan]=0; rpn_msb[st->chan]=val;
5599 break;
5600 case CTL_REGIST_PARM_NUM_LSB:
5601 nrpn[st->chan]=0; rpn_lsb[st->chan]=val;
5602 break;
5603 case CTL_NONREG_PARM_NUM_MSB:
5604 nrpn[st->chan]=1; rpn_msb[st->chan]=val;
5605 break;
5606 case CTL_NONREG_PARM_NUM_LSB:
5607 nrpn[st->chan]=1; rpn_lsb[st->chan]=val;
5608 break;
5610 /* send RPN/NRPN entry */
5611 case CTL_DATA_ENTRY:
5612 if (msb_bit)
5613 rpn_val[st->chan] = val * 128;
5614 else
5615 rpn_val[st->chan] |= val;
5616 if (nrpn[st->chan])
5617 midi_nrpn_event(st);
5618 else
5619 midi_rpn_event(st);
5620 break;
5622 /* increase/decrease data entry */
5623 case CTL_DATA_INCREMENT:
5624 rpn_val[st->chan]++;
5625 midi_rpn_event(st);
5626 break;
5627 case CTL_DATA_DECREMENT:
5628 rpn_val[st->chan]--;
5629 midi_rpn_event(st);
5630 break;
5632 /* default */
5633 default:
5634 awe_controller(0, st->chan, cmd, val);
5635 break;
5639 /* tone bank change */
5640 static void midi_select_bank(MidiStatus *st, int val)
5642 if (midi_mode == MODE_XG && msb_bit) {
5643 xg_bankmode = val;
5644 /* XG MSB value; not normal bank selection */
5645 switch (val) {
5646 case 127: /* remap to drum channel */
5647 awe_controller(0, st->chan, CTL_BANK_SELECT, 128);
5648 break;
5649 default: /* remap to normal channel */
5650 awe_controller(0, st->chan, CTL_BANK_SELECT, val);
5651 break;
5653 return;
5654 } else if (midi_mode == MODE_GS && !msb_bit)
5655 /* ignore LSB bank in GS mode (used for mapping) */
5656 return;
5658 /* normal bank controls; accept both MSB and LSB */
5659 if (! IS_DRUM_CHANNEL(st->chan)) {
5660 if (midi_mode == MODE_XG) {
5661 if (xg_bankmode) return;
5662 if (val == 64 || val == 126)
5663 val = 0;
5664 } else if (midi_mode == MODE_GS && val == 127)
5665 val = 0;
5666 awe_controller(0, st->chan, CTL_BANK_SELECT, val);
5672 * RPN events
5675 static void midi_rpn_event(MidiStatus *st)
5677 int type;
5678 type = (rpn_msb[st->chan]<<8) | rpn_lsb[st->chan];
5679 switch (type) {
5680 case 0x0000: /* Pitch bend sensitivity */
5681 /* MSB only / 1 semitone per 128 */
5682 if (msb_bit) {
5683 channels[st->chan].bender_range =
5684 rpn_val[st->chan] * 100 / 128;
5686 break;
5688 case 0x0001: /* fine tuning: */
5689 /* MSB/LSB, 8192=center, 100/8192 cent step */
5690 finetune = rpn_val[st->chan] - 8192;
5691 midi_detune(st->chan, coarsetune, finetune);
5692 break;
5694 case 0x0002: /* coarse tuning */
5695 /* MSB only / 8192=center, 1 semitone per 128 */
5696 if (msb_bit) {
5697 coarsetune = rpn_val[st->chan] - 8192;
5698 midi_detune(st->chan, coarsetune, finetune);
5700 break;
5702 case 0x7F7F: /* "lock-in" RPN */
5703 break;
5708 /* tuning:
5709 * coarse = -8192 to 8192 (100 cent per 128)
5710 * fine = -8192 to 8192 (max=100cent)
5712 static void midi_detune(int chan, int coarse, int fine)
5714 /* 4096 = 1200 cents in AWE parameter */
5715 int val;
5716 val = coarse * 4096 / (12 * 128);
5717 val += fine / 24;
5718 if (val)
5719 send_effect(chan, AWE_FX_INIT_PITCH, val);
5720 else
5721 unset_effect(chan, AWE_FX_INIT_PITCH);
5726 * system exclusive message
5727 * GM/GS/XG macros are accepted
5730 static void midi_system_exclusive(MidiStatus *st)
5732 /* GM on */
5733 static unsigned char gm_on_macro[] = {
5734 0x7e,0x7f,0x09,0x01,
5736 /* XG on */
5737 static unsigned char xg_on_macro[] = {
5738 0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,
5740 /* GS prefix
5741 * drum channel: XX=0x1?(channel), YY=0x15, ZZ=on/off
5742 * reverb mode: XX=0x01, YY=0x30, ZZ=0-7
5743 * chorus mode: XX=0x01, YY=0x38, ZZ=0-7
5745 static unsigned char gs_pfx_macro[] = {
5746 0x41,0x10,0x42,0x12,0x40,/*XX,YY,ZZ*/
5749 #if 0
5750 /* SC88 system mode set
5751 * single module mode: XX=1
5752 * double module mode: XX=0
5754 static unsigned char gs_mode_macro[] = {
5755 0x41,0x10,0x42,0x12,0x00,0x00,0x7F,/*ZZ*/
5757 /* SC88 display macro: XX=01:bitmap, 00:text
5759 static unsigned char gs_disp_macro[] = {
5760 0x41,0x10,0x45,0x12,0x10,/*XX,00*/
5762 #endif
5764 /* GM on */
5765 if (memcmp(st->buf, gm_on_macro, sizeof(gm_on_macro)) == 0) {
5766 if (midi_mode != MODE_GS && midi_mode != MODE_XG)
5767 midi_mode = MODE_GM;
5768 init_midi_status(st);
5771 /* GS macros */
5772 else if (memcmp(st->buf, gs_pfx_macro, sizeof(gs_pfx_macro)) == 0) {
5773 if (midi_mode != MODE_GS && midi_mode != MODE_XG)
5774 midi_mode = MODE_GS;
5776 if (st->buf[5] == 0x00 && st->buf[6] == 0x7f && st->buf[7] == 0x00) {
5777 /* GS reset */
5778 init_midi_status(st);
5781 else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x15) {
5782 /* drum pattern */
5783 int p = st->buf[5] & 0x0f;
5784 if (p == 0) p = 9;
5785 else if (p < 10) p--;
5786 if (st->buf[7] == 0)
5787 DRUM_CHANNEL_OFF(p);
5788 else
5789 DRUM_CHANNEL_ON(p);
5791 } else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x21) {
5792 /* program */
5793 int p = st->buf[5] & 0x0f;
5794 if (p == 0) p = 9;
5795 else if (p < 10) p--;
5796 if (! IS_DRUM_CHANNEL(p))
5797 awe_set_instr(0, p, st->buf[7]);
5799 } else if (st->buf[5] == 0x01 && st->buf[6] == 0x30) {
5800 /* reverb mode */
5801 awe_set_reverb_mode(st->buf[7]);
5803 } else if (st->buf[5] == 0x01 && st->buf[6] == 0x38) {
5804 /* chorus mode */
5805 awe_set_chorus_mode(st->buf[7]);
5807 } else if (st->buf[5] == 0x00 && st->buf[6] == 0x04) {
5808 /* master volume */
5809 awe_change_master_volume(st->buf[7]);
5814 /* XG on */
5815 else if (memcmp(st->buf, xg_on_macro, sizeof(xg_on_macro)) == 0) {
5816 midi_mode = MODE_XG;
5817 xg_mapping = TRUE;
5818 xg_bankmode = 0;
5823 /*----------------------------------------------------------------*/
5826 * convert NRPN/control values
5829 static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
5831 int i, cval;
5832 for (i = 0; i < num_tables; i++) {
5833 if (table[i].control == type) {
5834 cval = table[i].convert(val);
5835 send_effect(st->chan, table[i].awe_effect, cval);
5836 return TRUE;
5839 return FALSE;
5842 static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
5844 int i, cval;
5845 for (i = 0; i < num_tables; i++) {
5846 if (table[i].control == type) {
5847 cval = table[i].convert(val);
5848 add_effect(st->chan, table[i].awe_effect|0x80, cval);
5849 return TRUE;
5852 return FALSE;
5857 * AWE32 NRPN effects
5860 static unsigned short fx_delay(int val);
5861 static unsigned short fx_attack(int val);
5862 static unsigned short fx_hold(int val);
5863 static unsigned short fx_decay(int val);
5864 static unsigned short fx_the_value(int val);
5865 static unsigned short fx_twice_value(int val);
5866 static unsigned short fx_conv_pitch(int val);
5867 static unsigned short fx_conv_Q(int val);
5869 /* function for each NRPN */ /* [range] units */
5870 #define fx_env1_delay fx_delay /* [0,5900] 4msec */
5871 #define fx_env1_attack fx_attack /* [0,5940] 1msec */
5872 #define fx_env1_hold fx_hold /* [0,8191] 1msec */
5873 #define fx_env1_decay fx_decay /* [0,5940] 4msec */
5874 #define fx_env1_release fx_decay /* [0,5940] 4msec */
5875 #define fx_env1_sustain fx_the_value /* [0,127] 0.75dB */
5876 #define fx_env1_pitch fx_the_value /* [-127,127] 9.375cents */
5877 #define fx_env1_cutoff fx_the_value /* [-127,127] 56.25cents */
5879 #define fx_env2_delay fx_delay /* [0,5900] 4msec */
5880 #define fx_env2_attack fx_attack /* [0,5940] 1msec */
5881 #define fx_env2_hold fx_hold /* [0,8191] 1msec */
5882 #define fx_env2_decay fx_decay /* [0,5940] 4msec */
5883 #define fx_env2_release fx_decay /* [0,5940] 4msec */
5884 #define fx_env2_sustain fx_the_value /* [0,127] 0.75dB */
5886 #define fx_lfo1_delay fx_delay /* [0,5900] 4msec */
5887 #define fx_lfo1_freq fx_twice_value /* [0,127] 84mHz */
5888 #define fx_lfo1_volume fx_twice_value /* [0,127] 0.1875dB */
5889 #define fx_lfo1_pitch fx_the_value /* [-127,127] 9.375cents */
5890 #define fx_lfo1_cutoff fx_twice_value /* [-64,63] 56.25cents */
5892 #define fx_lfo2_delay fx_delay /* [0,5900] 4msec */
5893 #define fx_lfo2_freq fx_twice_value /* [0,127] 84mHz */
5894 #define fx_lfo2_pitch fx_the_value /* [-127,127] 9.375cents */
5896 #define fx_init_pitch fx_conv_pitch /* [-8192,8192] cents */
5897 #define fx_chorus fx_the_value /* [0,255] -- */
5898 #define fx_reverb fx_the_value /* [0,255] -- */
5899 #define fx_cutoff fx_twice_value /* [0,127] 62Hz */
5900 #define fx_filterQ fx_conv_Q /* [0,127] -- */
5902 static unsigned short fx_delay(int val)
5904 return (unsigned short)calc_parm_delay(val);
5907 static unsigned short fx_attack(int val)
5909 return (unsigned short)calc_parm_attack(val);
5912 static unsigned short fx_hold(int val)
5914 return (unsigned short)calc_parm_hold(val);
5917 static unsigned short fx_decay(int val)
5919 return (unsigned short)calc_parm_decay(val);
5922 static unsigned short fx_the_value(int val)
5924 return (unsigned short)(val & 0xff);
5927 static unsigned short fx_twice_value(int val)
5929 return (unsigned short)((val * 2) & 0xff);
5932 static unsigned short fx_conv_pitch(int val)
5934 return (short)(val * 4096 / 1200);
5937 static unsigned short fx_conv_Q(int val)
5939 return (unsigned short)((val / 8) & 0xff);
5943 static ConvTable awe_effects[] =
5945 { 0, AWE_FX_LFO1_DELAY, fx_lfo1_delay},
5946 { 1, AWE_FX_LFO1_FREQ, fx_lfo1_freq},
5947 { 2, AWE_FX_LFO2_DELAY, fx_lfo2_delay},
5948 { 3, AWE_FX_LFO2_FREQ, fx_lfo2_freq},
5950 { 4, AWE_FX_ENV1_DELAY, fx_env1_delay},
5951 { 5, AWE_FX_ENV1_ATTACK,fx_env1_attack},
5952 { 6, AWE_FX_ENV1_HOLD, fx_env1_hold},
5953 { 7, AWE_FX_ENV1_DECAY, fx_env1_decay},
5954 { 8, AWE_FX_ENV1_SUSTAIN, fx_env1_sustain},
5955 { 9, AWE_FX_ENV1_RELEASE, fx_env1_release},
5957 {10, AWE_FX_ENV2_DELAY, fx_env2_delay},
5958 {11, AWE_FX_ENV2_ATTACK, fx_env2_attack},
5959 {12, AWE_FX_ENV2_HOLD, fx_env2_hold},
5960 {13, AWE_FX_ENV2_DECAY, fx_env2_decay},
5961 {14, AWE_FX_ENV2_SUSTAIN, fx_env2_sustain},
5962 {15, AWE_FX_ENV2_RELEASE, fx_env2_release},
5964 {16, AWE_FX_INIT_PITCH, fx_init_pitch},
5965 {17, AWE_FX_LFO1_PITCH, fx_lfo1_pitch},
5966 {18, AWE_FX_LFO2_PITCH, fx_lfo2_pitch},
5967 {19, AWE_FX_ENV1_PITCH, fx_env1_pitch},
5968 {20, AWE_FX_LFO1_VOLUME, fx_lfo1_volume},
5969 {21, AWE_FX_CUTOFF, fx_cutoff},
5970 {22, AWE_FX_FILTERQ, fx_filterQ},
5971 {23, AWE_FX_LFO1_CUTOFF, fx_lfo1_cutoff},
5972 {24, AWE_FX_ENV1_CUTOFF, fx_env1_cutoff},
5973 {25, AWE_FX_CHORUS, fx_chorus},
5974 {26, AWE_FX_REVERB, fx_reverb},
5977 static int num_awe_effects = numberof(awe_effects);
5981 * GS(SC88) NRPN effects; still experimental
5984 /* cutoff: quarter semitone step, max=255 */
5985 static unsigned short gs_cutoff(int val)
5987 return (val - 64) * gs_sense[FX_CUTOFF] / 50;
5990 /* resonance: 0 to 15(max) */
5991 static unsigned short gs_filterQ(int val)
5993 return (val - 64) * gs_sense[FX_RESONANCE] / 50;
5996 /* attack: */
5997 static unsigned short gs_attack(int val)
5999 return -(val - 64) * gs_sense[FX_ATTACK] / 50;
6002 /* decay: */
6003 static unsigned short gs_decay(int val)
6005 return -(val - 64) * gs_sense[FX_RELEASE] / 50;
6008 /* release: */
6009 static unsigned short gs_release(int val)
6011 return -(val - 64) * gs_sense[FX_RELEASE] / 50;
6014 /* vibrato freq: 0.042Hz step, max=255 */
6015 static unsigned short gs_vib_rate(int val)
6017 return (val - 64) * gs_sense[FX_VIBRATE] / 50;
6020 /* vibrato depth: max=127, 1 octave */
6021 static unsigned short gs_vib_depth(int val)
6023 return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
6026 /* vibrato delay: -0.725msec step */
6027 static unsigned short gs_vib_delay(int val)
6029 return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
6032 static ConvTable gs_effects[] =
6034 {32, AWE_FX_CUTOFF, gs_cutoff},
6035 {33, AWE_FX_FILTERQ, gs_filterQ},
6036 {99, AWE_FX_ENV2_ATTACK, gs_attack},
6037 {100, AWE_FX_ENV2_DECAY, gs_decay},
6038 {102, AWE_FX_ENV2_RELEASE, gs_release},
6039 {8, AWE_FX_LFO1_FREQ, gs_vib_rate},
6040 {9, AWE_FX_LFO1_VOLUME, gs_vib_depth},
6041 {10, AWE_FX_LFO1_DELAY, gs_vib_delay},
6044 static int num_gs_effects = numberof(gs_effects);
6048 * NRPN events: accept as AWE32/SC88 specific controls
6051 static void midi_nrpn_event(MidiStatus *st)
6053 if (rpn_msb[st->chan] == 127 && rpn_lsb[st->chan] <= 26) {
6054 if (! msb_bit) /* both MSB/LSB necessary */
6055 send_converted_effect(awe_effects, num_awe_effects,
6056 st, rpn_lsb[st->chan],
6057 rpn_val[st->chan] - 8192);
6058 } else if (rpn_msb[st->chan] == 1) {
6059 if (msb_bit) /* only MSB is valid */
6060 add_converted_effect(gs_effects, num_gs_effects,
6061 st, rpn_lsb[st->chan],
6062 rpn_val[st->chan] / 128);
6068 * XG control effects; still experimental
6071 /* cutoff: quarter semitone step, max=255 */
6072 static unsigned short xg_cutoff(int val)
6074 return (val - 64) * xg_sense[FX_CUTOFF] / 64;
6077 /* resonance: 0(open) to 15(most nasal) */
6078 static unsigned short xg_filterQ(int val)
6080 return (val - 64) * xg_sense[FX_RESONANCE] / 64;
6083 /* attack: */
6084 static unsigned short xg_attack(int val)
6086 return -(val - 64) * xg_sense[FX_ATTACK] / 64;
6089 /* release: */
6090 static unsigned short xg_release(int val)
6092 return -(val - 64) * xg_sense[FX_RELEASE] / 64;
6095 static ConvTable xg_effects[] =
6097 {71, AWE_FX_CUTOFF, xg_cutoff},
6098 {74, AWE_FX_FILTERQ, xg_filterQ},
6099 {72, AWE_FX_ENV2_RELEASE, xg_release},
6100 {73, AWE_FX_ENV2_ATTACK, xg_attack},
6103 static int num_xg_effects = numberof(xg_effects);
6105 static int xg_control_change(MidiStatus *st, int cmd, int val)
6107 return add_converted_effect(xg_effects, num_xg_effects, st, cmd, val);
6110 #endif /* CONFIG_AWE32_MIDIEMU */
6113 /*----------------------------------------------------------------*/
6116 * device / lowlevel (module) interface
6119 int __init attach_awe(void)
6121 return _attach_awe() ? 0 : -ENODEV;
6124 void __exit unload_awe(void)
6126 _unload_awe();
6127 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
6128 if (isapnp)
6129 awe_deactivate_isapnp();
6130 #endif /* isapnp */
6134 module_init(attach_awe);
6135 module_exit(unload_awe);
6137 #ifndef MODULE
6138 static int __init setup_awe(char *str)
6140 /* io, memsize, isapnp */
6141 int ints[4];
6143 str = get_options(str, ARRAY_SIZE(ints), ints);
6145 io = ints[1];
6146 memsize = ints[2];
6147 isapnp = ints[3];
6149 return 1;
6152 __setup("awe=", setup_awe);
6153 #endif