File: /usr/src/linux/drivers/sound/awe_wave.c
1 /*
2 * sound/awe_wave.c
3 *
4 * The low level driver for the AWE32/SB32/AWE64 wave table synth.
5 * version 0.4.4; Jan. 4, 2000
6 *
7 * Copyright (C) 1996-2000 Takashi Iwai
8 *
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.
13 *
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.
18 *
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.
22 */
23
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
32
33 #include "sound_config.h"
34
35 #include "awe_wave.h"
36 #include "awe_hw.h"
37
38 #ifdef AWE_HAS_GUS_COMPATIBILITY
39 #include "tuning.h"
40 #include <linux/ultrasound.h>
41 #endif
42
43 /*
44 * debug message
45 */
46
47 #ifdef AWE_DEBUG_ON
48 #define DEBUG(LVL,XXX) {if (ctrls[AWE_MD_DEBUG_MODE] > LVL) { XXX; }}
49 #define ERRMSG(XXX) {if (ctrls[AWE_MD_DEBUG_MODE]) { XXX; }}
50 #define FATALERR(XXX) XXX
51 #else
52 #define DEBUG(LVL,XXX) /**/
53 #define ERRMSG(XXX) XXX
54 #define FATALERR(XXX) XXX
55 #endif
56
57 /*
58 * bank and voice record
59 */
60
61 typedef struct _sf_list sf_list;
62 typedef struct _awe_voice_list awe_voice_list;
63 typedef struct _awe_sample_list awe_sample_list;
64
65 /* soundfont record */
66 struct _sf_list {
67 unsigned short sf_id; /* id number */
68 unsigned short type; /* lock & shared flags */
69 int num_info; /* current info table index */
70 int num_sample; /* current sample table index */
71 int mem_ptr; /* current word byte pointer */
72 awe_voice_list *infos, *last_infos; /* instruments */
73 awe_sample_list *samples, *last_samples; /* samples */
74 #ifdef AWE_ALLOW_SAMPLE_SHARING
75 sf_list *shared; /* shared list */
76 unsigned char name[AWE_PATCH_NAME_LEN]; /* sharing id */
77 #endif
78 sf_list *next, *prev;
79 };
80
81 /* instrument list */
82 struct _awe_voice_list {
83 awe_voice_info v; /* instrument information */
84 sf_list *holder; /* parent sf_list of this record */
85 unsigned char bank, instr; /* preset number information */
86 char type, disabled; /* type=normal/mapped, disabled=boolean */
87 awe_voice_list *next; /* linked list with same sf_id */
88 awe_voice_list *next_instr; /* instrument list */
89 awe_voice_list *next_bank; /* hash table list */
90 };
91
92 /* voice list type */
93 #define V_ST_NORMAL 0
94 #define V_ST_MAPPED 1
95
96 /* sample list */
97 struct _awe_sample_list {
98 awe_sample_info v; /* sample information */
99 sf_list *holder; /* parent sf_list of this record */
100 awe_sample_list *next; /* linked list with same sf_id */
101 };
102
103 /* sample and information table */
104 static int current_sf_id = 0; /* current number of fonts */
105 static int locked_sf_id = 0; /* locked position */
106 static sf_list *sfhead = NULL, *sftail = NULL; /* linked-lists */
107
108 #define awe_free_mem_ptr() (sftail ? sftail->mem_ptr : 0)
109 #define awe_free_info() (sftail ? sftail->num_info : 0)
110 #define awe_free_sample() (sftail ? sftail->num_sample : 0)
111
112 #define AWE_MAX_PRESETS 256
113 #define AWE_DEFAULT_PRESET 0
114 #define AWE_DEFAULT_BANK 0
115 #define AWE_DEFAULT_DRUM 0
116 #define AWE_DRUM_BANK 128
117
118 #define MAX_LAYERS AWE_MAX_VOICES
119
120 /* preset table index */
121 static awe_voice_list *preset_table[AWE_MAX_PRESETS];
122
123 /*
124 * voice table
125 */
126
127 /* effects table */
128 typedef struct FX_Rec { /* channel effects */
129 unsigned char flags[AWE_FX_END];
130 short val[AWE_FX_END];
131 } FX_Rec;
132
133
134 /* channel parameters */
135 typedef struct _awe_chan_info {
136 int channel; /* channel number */
137 int bank; /* current tone bank */
138 int instr; /* current program */
139 int bender; /* midi pitchbend (-8192 - 8192) */
140 int bender_range; /* midi bender range (x100) */
141 int panning; /* panning (0-127) */
142 int main_vol; /* channel volume (0-127) */
143 int expression_vol; /* midi expression (0-127) */
144 int chan_press; /* channel pressure */
145 int sustained; /* sustain status in MIDI */
146 FX_Rec fx; /* effects */
147 FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */
148 } awe_chan_info;
149
150 /* voice parameters */
151 typedef struct _voice_info {
152 int state;
153 #define AWE_ST_OFF (1<<0) /* no sound */
154 #define AWE_ST_ON (1<<1) /* playing */
155 #define AWE_ST_STANDBY (1<<2) /* stand by for playing */
156 #define AWE_ST_SUSTAINED (1<<3) /* sustained */
157 #define AWE_ST_MARK (1<<4) /* marked for allocation */
158 #define AWE_ST_DRAM (1<<5) /* DRAM read/write */
159 #define AWE_ST_FM (1<<6) /* reserved for FM */
160 #define AWE_ST_RELEASED (1<<7) /* released */
161
162 int ch; /* midi channel */
163 int key; /* internal key for search */
164 int layer; /* layer number (for channel mode only) */
165 int time; /* allocated time */
166 awe_chan_info *cinfo; /* channel info */
167
168 int note; /* midi key (0-127) */
169 int velocity; /* midi velocity (0-127) */
170 int sostenuto; /* sostenuto on/off */
171 awe_voice_info *sample; /* assigned voice */
172
173 /* EMU8000 parameters */
174 int apitch; /* pitch parameter */
175 int avol; /* volume parameter */
176 int apan; /* panning parameter */
177 int acutoff; /* cutoff parameter */
178 short aaux; /* aux word */
179 } voice_info;
180
181 /* voice information */
182 static voice_info voices[AWE_MAX_VOICES];
183
184 #define IS_NO_SOUND(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED))
185 #define IS_NO_EFFECT(v) (voices[v].state != AWE_ST_ON)
186 #define IS_PLAYING(v) (voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED))
187 #define IS_EMPTY(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM))
188
189
190 /* MIDI channel effects information (for hw control) */
191 static awe_chan_info channels[AWE_MAX_CHANNELS];
192
193
194 /*
195 * global variables
196 */
197
198 #ifndef AWE_DEFAULT_BASE_ADDR
199 #define AWE_DEFAULT_BASE_ADDR 0 /* autodetect */
200 #endif
201
202 #ifndef AWE_DEFAULT_MEM_SIZE
203 #define AWE_DEFAULT_MEM_SIZE -1 /* autodetect */
204 #endif
205
206 int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
207 int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
208 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
209 static int isapnp = -1;
210 #else
211 static int isapnp = 0;
212 #endif
213
214 MODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>");
215 MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver");
216 MODULE_PARM(io, "i");
217 MODULE_PARM_DESC(io, "base i/o port of Emu8000");
218 MODULE_PARM(memsize, "i");
219 MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes");
220 MODULE_PARM(isapnp, "i");
221 MODULE_PARM_DESC(isapnp, "use ISAPnP detection");
222 EXPORT_NO_SYMBOLS;
223
224 /* DRAM start offset */
225 static int awe_mem_start = AWE_DRAM_OFFSET;
226
227 /* maximum channels for playing */
228 static int awe_max_voices = AWE_MAX_VOICES;
229
230 static int patch_opened = 0; /* sample already loaded? */
231
232 static char atten_relative = FALSE;
233 static short atten_offset = 0;
234
235 static int awe_present = FALSE; /* awe device present? */
236 static int awe_busy = FALSE; /* awe device opened? */
237
238 static int my_dev = -1;
239
240 #define DEFAULT_DRUM_FLAGS ((1 << 9) | (1 << 25))
241 #define IS_DRUM_CHANNEL(c) (drum_flags & (1 << (c)))
242 #define DRUM_CHANNEL_ON(c) (drum_flags |= (1 << (c)))
243 #define DRUM_CHANNEL_OFF(c) (drum_flags &= ~(1 << (c)))
244 static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */
245
246 static int playing_mode = AWE_PLAY_INDIRECT;
247 #define SINGLE_LAYER_MODE() (playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT)
248 #define MULTI_LAYER_MODE() (playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2)
249
250 static int current_alloc_time = 0; /* voice allocation index for channel mode */
251
252 static struct synth_info awe_info = {
253 "AWE32 Synth", /* name */
254 0, /* device */
255 SYNTH_TYPE_SAMPLE, /* synth_type */
256 SAMPLE_TYPE_AWE32, /* synth_subtype */
257 0, /* perc_mode (obsolete) */
258 AWE_MAX_VOICES, /* nr_voices */
259 0, /* nr_drums (obsolete) */
260 400 /* instr_bank_size */
261 };
262
263
264 static struct voice_alloc_info *voice_alloc; /* set at initialization */
265
266
267 /*
268 * function prototypes
269 */
270
271 static int awe_check_port(void);
272 static void awe_request_region(void);
273 static void awe_release_region(void);
274
275 static void awe_reset_samples(void);
276 /* emu8000 chip i/o access */
277 static void setup_ports(int p1, int p2, int p3);
278 static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);
279 static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);
280 static unsigned short awe_peek(unsigned short cmd, unsigned short port);
281 static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);
282 static void awe_wait(unsigned short delay);
283
284 /* initialize emu8000 chip */
285 static int _attach_awe(void);
286 static void _unload_awe(void);
287 static void awe_initialize(void);
288
289 /* set voice parameters */
290 static void awe_init_ctrl_parms(int init_all);
291 static void awe_init_voice_info(awe_voice_info *vp);
292 static void awe_init_voice_parm(awe_voice_parm *pp);
293 #ifdef AWE_HAS_GUS_COMPATIBILITY
294 static int freq_to_note(int freq);
295 static int calc_rate_offset(int Hz);
296 /*static int calc_parm_delay(int msec);*/
297 static int calc_parm_hold(int msec);
298 static int calc_parm_attack(int msec);
299 static int calc_parm_decay(int msec);
300 static int calc_parm_search(int msec, short *table);
301 #endif /* gus compat */
302
303 /* turn on/off note */
304 static void awe_note_on(int voice);
305 static void awe_note_off(int voice);
306 static void awe_terminate(int voice);
307 static void awe_exclusive_off(int voice);
308 static void awe_note_off_all(int do_sustain);
309
310 /* calculate voice parameters */
311 typedef void (*fx_affect_func)(int voice, int forced);
312 static void awe_set_pitch(int voice, int forced);
313 static void awe_set_voice_pitch(int voice, int forced);
314 static void awe_set_volume(int voice, int forced);
315 static void awe_set_voice_vol(int voice, int forced);
316 static void awe_set_pan(int voice, int forced);
317 static void awe_fx_fmmod(int voice, int forced);
318 static void awe_fx_tremfrq(int voice, int forced);
319 static void awe_fx_fm2frq2(int voice, int forced);
320 static void awe_fx_filterQ(int voice, int forced);
321 static void awe_calc_pitch(int voice);
322 #ifdef AWE_HAS_GUS_COMPATIBILITY
323 static void awe_calc_pitch_from_freq(int voice, int freq);
324 #endif
325 static void awe_calc_volume(int voice);
326 static void awe_update_volume(void);
327 static void awe_change_master_volume(short val);
328 static void awe_voice_init(int voice, int init_all);
329 static void awe_channel_init(int ch, int init_all);
330 static void awe_fx_init(int ch);
331 static void awe_send_effect(int voice, int layer, int type, int val);
332 static void awe_modwheel_change(int voice, int value);
333
334 /* sequencer interface */
335 static int awe_open(int dev, int mode);
336 static void awe_close(int dev);
337 static int awe_ioctl(int dev, unsigned int cmd, caddr_t arg);
338 static int awe_kill_note(int dev, int voice, int note, int velocity);
339 static int awe_start_note(int dev, int v, int note_num, int volume);
340 static int awe_set_instr(int dev, int voice, int instr_no);
341 static int awe_set_instr_2(int dev, int voice, int instr_no);
342 static void awe_reset(int dev);
343 static void awe_hw_control(int dev, unsigned char *event);
344 static int awe_load_patch(int dev, int format, const char *addr,
345 int offs, int count, int pmgr_flag);
346 static void awe_aftertouch(int dev, int voice, int pressure);
347 static void awe_controller(int dev, int voice, int ctrl_num, int value);
348 static void awe_panning(int dev, int voice, int value);
349 static void awe_volume_method(int dev, int mode);
350 static void awe_bender(int dev, int voice, int value);
351 static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc);
352 static void awe_setup_voice(int dev, int voice, int chn);
353
354 #define awe_key_pressure(dev,voice,key,press) awe_start_note(dev,voice,(key)+128,press)
355
356 /* hardware controls */
357 #ifdef AWE_HAS_GUS_COMPATIBILITY
358 static void awe_hw_gus_control(int dev, int cmd, unsigned char *event);
359 #endif
360 static void awe_hw_awe_control(int dev, int cmd, unsigned char *event);
361 static void awe_voice_change(int voice, fx_affect_func func);
362 static void awe_sostenuto_on(int voice, int forced);
363 static void awe_sustain_off(int voice, int forced);
364 static void awe_terminate_and_init(int voice, int forced);
365
366 /* voice search */
367 static int awe_search_key(int bank, int preset, int note);
368 static awe_voice_list *awe_search_instr(int bank, int preset, int note);
369 static int awe_search_multi_voices(awe_voice_list *rec, int note, int velocity, awe_voice_info **vlist);
370 static void awe_alloc_multi_voices(int ch, int note, int velocity, int key);
371 static void awe_alloc_one_voice(int voice, int note, int velocity);
372 static int awe_clear_voice(void);
373
374 /* load / remove patches */
375 static int awe_open_patch(awe_patch_info *patch, const char *addr, int count);
376 static int awe_close_patch(awe_patch_info *patch, const char *addr, int count);
377 static int awe_unload_patch(awe_patch_info *patch, const char *addr, int count);
378 static int awe_load_info(awe_patch_info *patch, const char *addr, int count);
379 static int awe_remove_info(awe_patch_info *patch, const char *addr, int count);
380 static int awe_load_data(awe_patch_info *patch, const char *addr, int count);
381 static int awe_replace_data(awe_patch_info *patch, const char *addr, int count);
382 static int awe_load_map(awe_patch_info *patch, const char *addr, int count);
383 #ifdef AWE_HAS_GUS_COMPATIBILITY
384 static int awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag);
385 #endif
386 /*static int awe_probe_info(awe_patch_info *patch, const char *addr, int count);*/
387 static int awe_probe_data(awe_patch_info *patch, const char *addr, int count);
388 static sf_list *check_patch_opened(int type, char *name);
389 static int awe_write_wave_data(const char *addr, int offset, awe_sample_list *sp, int channels);
390 static int awe_create_sf(int type, char *name);
391 static void awe_free_sf(sf_list *sf);
392 static void add_sf_info(sf_list *sf, awe_voice_list *rec);
393 static void add_sf_sample(sf_list *sf, awe_sample_list *smp);
394 static void purge_old_list(awe_voice_list *rec, awe_voice_list *next);
395 static void add_info_list(awe_voice_list *rec);
396 static void awe_remove_samples(int sf_id);
397 static void rebuild_preset_list(void);
398 static short awe_set_sample(awe_voice_list *rec);
399 static awe_sample_list *search_sample_index(sf_list *sf, int sample);
400
401 static int is_identical_holder(sf_list *sf1, sf_list *sf2);
402 #ifdef AWE_ALLOW_SAMPLE_SHARING
403 static int is_identical_name(unsigned char *name, sf_list *p);
404 static int is_shared_sf(unsigned char *name);
405 static int info_duplicated(sf_list *sf, awe_voice_list *rec);
406 #endif /* allow sharing */
407
408 /* lowlevel functions */
409 static void awe_init_audio(void);
410 static void awe_init_dma(void);
411 static void awe_init_array(void);
412 static void awe_send_array(unsigned short *data);
413 static void awe_tweak_voice(int voice);
414 static void awe_tweak(void);
415 static void awe_init_fm(void);
416 static int awe_open_dram_for_write(int offset, int channels);
417 static void awe_open_dram_for_check(void);
418 static void awe_close_dram(void);
419 /*static void awe_write_dram(unsigned short c);*/
420 static int awe_detect_base(int addr);
421 static int awe_detect(void);
422 static void awe_check_dram(void);
423 static int awe_load_chorus_fx(awe_patch_info *patch, const char *addr, int count);
424 static void awe_set_chorus_mode(int mode);
425 static void awe_update_chorus_mode(void);
426 static int awe_load_reverb_fx(awe_patch_info *patch, const char *addr, int count);
427 static void awe_set_reverb_mode(int mode);
428 static void awe_update_reverb_mode(void);
429 static void awe_equalizer(int bass, int treble);
430 static void awe_update_equalizer(void);
431
432 #ifdef CONFIG_AWE32_MIXER
433 static void attach_mixer(void);
434 static void unload_mixer(void);
435 #endif
436
437 #ifdef CONFIG_AWE32_MIDIEMU
438 static void attach_midiemu(void);
439 static void unload_midiemu(void);
440 #endif
441
442 #define limitvalue(x, a, b) if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b)
443
444 /*
445 * control parameters
446 */
447
448
449 #ifdef AWE_USE_NEW_VOLUME_CALC
450 #define DEF_VOLUME_CALC TRUE
451 #else
452 #define DEF_VOLUME_CALC FALSE
453 #endif /* new volume */
454
455 #define DEF_ZERO_ATTEN 32 /* 12dB below */
456 #define DEF_MOD_SENSE 18
457 #define DEF_CHORUS_MODE 2
458 #define DEF_REVERB_MODE 4
459 #define DEF_BASS_LEVEL 5
460 #define DEF_TREBLE_LEVEL 9
461
462 static struct CtrlParmsDef {
463 int value;
464 int init_each_time;
465 void (*update)(void);
466 } ctrl_parms[AWE_MD_END] = {
467 {0,0, NULL}, {0,0, NULL}, /* <-- not used */
468 {AWE_VERSION_NUMBER, FALSE, NULL},
469 {TRUE, FALSE, NULL}, /* exclusive */
470 {TRUE, FALSE, NULL}, /* realpan */
471 {AWE_DEFAULT_BANK, FALSE, NULL}, /* gusbank */
472 {FALSE, TRUE, NULL}, /* keep effect */
473 {DEF_ZERO_ATTEN, FALSE, awe_update_volume}, /* zero_atten */
474 {FALSE, FALSE, NULL}, /* chn_prior */
475 {DEF_MOD_SENSE, FALSE, NULL}, /* modwheel sense */
476 {AWE_DEFAULT_PRESET, FALSE, NULL}, /* def_preset */
477 {AWE_DEFAULT_BANK, FALSE, NULL}, /* def_bank */
478 {AWE_DEFAULT_DRUM, FALSE, NULL}, /* def_drum */
479 {FALSE, FALSE, NULL}, /* toggle_drum_bank */
480 {DEF_VOLUME_CALC, FALSE, awe_update_volume}, /* new_volume_calc */
481 {DEF_CHORUS_MODE, FALSE, awe_update_chorus_mode}, /* chorus mode */
482 {DEF_REVERB_MODE, FALSE, awe_update_reverb_mode}, /* reverb mode */
483 {DEF_BASS_LEVEL, FALSE, awe_update_equalizer}, /* bass level */
484 {DEF_TREBLE_LEVEL, FALSE, awe_update_equalizer}, /* treble level */
485 {0, FALSE, NULL}, /* debug mode */
486 {FALSE, FALSE, NULL}, /* pan exchange */
487 };
488
489 static int ctrls[AWE_MD_END];
490
491
492 /*
493 * synth operation table
494 */
495
496 static struct synth_operations awe_operations =
497 {
498 owner: THIS_MODULE,
499 id: "EMU8K",
500 info: &awe_info,
501 midi_dev: 0,
502 synth_type: SYNTH_TYPE_SAMPLE,
503 synth_subtype: SAMPLE_TYPE_AWE32,
504 open: awe_open,
505 close: awe_close,
506 ioctl: awe_ioctl,
507 kill_note: awe_kill_note,
508 start_note: awe_start_note,
509 set_instr: awe_set_instr_2,
510 reset: awe_reset,
511 hw_control: awe_hw_control,
512 load_patch: awe_load_patch,
513 aftertouch: awe_aftertouch,
514 controller: awe_controller,
515 panning: awe_panning,
516 volume_method: awe_volume_method,
517 bender: awe_bender,
518 alloc_voice: awe_alloc,
519 setup_voice: awe_setup_voice
520 };
521
522
523 /*
524 * General attach / unload interface
525 */
526
527 static int __init _attach_awe(void)
528 {
529 if (awe_present) return 0; /* for OSS38.. called twice? */
530
531 /* check presence of AWE32 card */
532 if (! awe_detect()) {
533 printk(KERN_ERR "AWE32: not detected\n");
534 return 0;
535 }
536
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;
541 }
542
543 /* set buffers to NULL */
544 sfhead = sftail = NULL;
545
546 my_dev = sound_alloc_synthdev();
547 if (my_dev == -1) {
548 printk(KERN_ERR "AWE32 Error: too many synthesizers\n");
549 return 0;
550 }
551
552 voice_alloc = &awe_operations.alloc;
553 voice_alloc->max_voice = awe_max_voices;
554 synth_devs[my_dev] = &awe_operations;
555
556 #ifdef CONFIG_AWE32_MIXER
557 attach_mixer();
558 #endif
559 #ifdef CONFIG_AWE32_MIDIEMU
560 attach_midiemu();
561 #endif
562
563 /* reserve I/O ports for awedrv */
564 awe_request_region();
565
566 /* clear all samples */
567 awe_reset_samples();
568
569 /* intialize AWE32 hardware */
570 awe_initialize();
571
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);
575
576 awe_present = TRUE;
577
578 return 1;
579 }
580
581
582 static void free_tables(void)
583 {
584 if (sftail) {
585 sf_list *p, *prev;
586 for (p = sftail; p; p = prev) {
587 prev = p->prev;
588 awe_free_sf(p);
589 }
590 }
591 sfhead = sftail = NULL;
592 }
593
594
595 static void __exit _unload_awe(void)
596 {
597 if (awe_present) {
598 awe_reset_samples();
599 awe_release_region();
600 free_tables();
601 #ifdef CONFIG_AWE32_MIXER
602 unload_mixer();
603 #endif
604 #ifdef CONFIG_AWE32_MIDIEMU
605 unload_midiemu();
606 #endif
607 sound_unload_synthdev(my_dev);
608 awe_present = FALSE;
609 }
610 }
611
612
613 /*
614 * clear sample tables
615 */
616
617 static void
618 awe_reset_samples(void)
619 {
620 /* free all bank tables */
621 memset(preset_table, 0, sizeof(preset_table));
622 free_tables();
623
624 current_sf_id = 0;
625 locked_sf_id = 0;
626 patch_opened = 0;
627 }
628
629
630 /*
631 * EMU register access
632 */
633
634 /* select a given AWE32 pointer */
635 static int awe_ports[5];
636 static int port_setuped = FALSE;
637 static int awe_cur_cmd = -1;
638 #define awe_set_cmd(cmd) \
639 if (awe_cur_cmd != cmd) { outw(cmd, awe_ports[Pointer]); awe_cur_cmd = cmd; }
640
641 /* store values to i/o port array */
642 static void setup_ports(int port1, int port2, int port3)
643 {
644 awe_ports[0] = port1;
645 if (port2 == 0)
646 port2 = port1 + 0x400;
647 awe_ports[1] = port2;
648 awe_ports[2] = port2 + 2;
649 if (port3 == 0)
650 port3 = port1 + 0x800;
651 awe_ports[3] = port3;
652 awe_ports[4] = port3 + 2;
653
654 port_setuped = TRUE;
655 }
656
657 /* write 16bit data */
658 static void
659 awe_poke(unsigned short cmd, unsigned short port, unsigned short data)
660 {
661 awe_set_cmd(cmd);
662 outw(data, awe_ports[port]);
663 }
664
665 /* write 32bit data */
666 static void
667 awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data)
668 {
669 unsigned short addr = awe_ports[port];
670 awe_set_cmd(cmd);
671 outw(data, addr); /* write lower 16 bits */
672 outw(data >> 16, addr + 2); /* write higher 16 bits */
673 }
674
675 /* read 16bit data */
676 static unsigned short
677 awe_peek(unsigned short cmd, unsigned short port)
678 {
679 unsigned short k;
680 awe_set_cmd(cmd);
681 k = inw(awe_ports[port]);
682 return k;
683 }
684
685 /* read 32bit data */
686 static unsigned int
687 awe_peek_dw(unsigned short cmd, unsigned short port)
688 {
689 unsigned int k1, k2;
690 unsigned short addr = awe_ports[port];
691 awe_set_cmd(cmd);
692 k1 = inw(addr);
693 k2 = inw(addr + 2);
694 k1 |= k2 << 16;
695 return k1;
696 }
697
698 /* wait delay number of AWE32 44100Hz clocks */
699 #ifdef WAIT_BY_LOOP /* wait by loop -- that's not good.. */
700 static void
701 awe_wait(unsigned short delay)
702 {
703 unsigned short clock, target;
704 unsigned short port = awe_ports[AWE_WC_Port];
705 int counter;
706
707 /* sample counter */
708 awe_set_cmd(AWE_WC_Cmd);
709 clock = (unsigned short)inw(port);
710 target = clock + delay;
711 counter = 0;
712 if (target < clock) {
713 for (; (unsigned short)inw(port) > target; counter++)
714 if (counter > 65536)
715 break;
716 }
717 for (; (unsigned short)inw(port) < target; counter++)
718 if (counter > 65536)
719 break;
720 }
721 #else
722
723 static void awe_wait(unsigned short delay)
724 {
725 current->state = TASK_INTERRUPTIBLE;
726 schedule_timeout((HZ*(unsigned long)delay + 44099)/44100);
727 }
728 /*
729 static void awe_wait(unsigned short delay)
730 {
731 udelay(((unsigned long)delay * 1000000L + 44099) / 44100);
732 }
733 */
734 #endif /* wait by loop */
735
736 /* write a word data */
737 #define awe_write_dram(c) awe_poke(AWE_SMLD, c)
738
739
740 /*
741 * port check / request
742 * 0x620-623, 0xA20-A23, 0xE20-E23
743 */
744
745 static int __init
746 awe_check_port(void)
747 {
748 if (! port_setuped) return 0;
749 return (check_region(awe_ports[0], 4) ||
750 check_region(awe_ports[1], 4) ||
751 check_region(awe_ports[3], 4));
752 }
753
754 static void __init
755 awe_request_region(void)
756 {
757 if (! port_setuped) return;
758 request_region(awe_ports[0], 4, "sound driver (AWE32)");
759 request_region(awe_ports[1], 4, "sound driver (AWE32)");
760 request_region(awe_ports[3], 4, "sound driver (AWE32)");
761 }
762
763 static void __exit
764 awe_release_region(void)
765 {
766 if (! port_setuped) return;
767 release_region(awe_ports[0], 4);
768 release_region(awe_ports[1], 4);
769 release_region(awe_ports[3], 4);
770 }
771
772
773 /*
774 * initialization of AWE driver
775 */
776
777 static void
778 awe_initialize(void)
779 {
780 DEBUG(0,printk("AWE32: initializing..\n"));
781
782 /* initialize hardware configuration */
783 awe_poke(AWE_HWCF1, 0x0059);
784 awe_poke(AWE_HWCF2, 0x0020);
785
786 /* disable audio; this seems to reduce a clicking noise a bit.. */
787 awe_poke(AWE_HWCF3, 0);
788
789 /* initialize audio channels */
790 awe_init_audio();
791
792 /* initialize DMA */
793 awe_init_dma();
794
795 /* initialize init array */
796 awe_init_array();
797
798 /* check DRAM memory size */
799 awe_check_dram();
800
801 /* initialize the FM section of the AWE32 */
802 awe_init_fm();
803
804 /* set up voice envelopes */
805 awe_tweak();
806
807 /* enable audio */
808 awe_poke(AWE_HWCF3, 0x0004);
809
810 /* set default values */
811 awe_init_ctrl_parms(TRUE);
812
813 /* set equalizer */
814 awe_update_equalizer();
815
816 /* set reverb & chorus modes */
817 awe_update_reverb_mode();
818 awe_update_chorus_mode();
819 }
820
821
822 /*
823 * AWE32 voice parameters
824 */
825
826 /* initialize voice_info record */
827 static void
828 awe_init_voice_info(awe_voice_info *vp)
829 {
830 vp->sample = 0;
831 vp->rate_offset = 0;
832
833 vp->start = 0;
834 vp->end = 0;
835 vp->loopstart = 0;
836 vp->loopend = 0;
837 vp->mode = 0;
838 vp->root = 60;
839 vp->tune = 0;
840 vp->low = 0;
841 vp->high = 127;
842 vp->vellow = 0;
843 vp->velhigh = 127;
844
845 vp->fixkey = -1;
846 vp->fixvel = -1;
847 vp->fixpan = -1;
848 vp->pan = -1;
849
850 vp->exclusiveClass = 0;
851 vp->amplitude = 127;
852 vp->attenuation = 0;
853 vp->scaleTuning = 100;
854
855 awe_init_voice_parm(&vp->parm);
856 }
857
858 /* initialize voice_parm record:
859 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
860 * Vibrato and Tremolo effects are zero.
861 * Cutoff is maximum.
862 * Chorus and Reverb effects are zero.
863 */
864 static void
865 awe_init_voice_parm(awe_voice_parm *pp)
866 {
867 pp->moddelay = 0x8000;
868 pp->modatkhld = 0x7f7f;
869 pp->moddcysus = 0x7f7f;
870 pp->modrelease = 0x807f;
871 pp->modkeyhold = 0;
872 pp->modkeydecay = 0;
873
874 pp->voldelay = 0x8000;
875 pp->volatkhld = 0x7f7f;
876 pp->voldcysus = 0x7f7f;
877 pp->volrelease = 0x807f;
878 pp->volkeyhold = 0;
879 pp->volkeydecay = 0;
880
881 pp->lfo1delay = 0x8000;
882 pp->lfo2delay = 0x8000;
883 pp->pefe = 0;
884
885 pp->fmmod = 0;
886 pp->tremfrq = 0;
887 pp->fm2frq2 = 0;
888
889 pp->cutoff = 0xff;
890 pp->filterQ = 0;
891
892 pp->chorus = 0;
893 pp->reverb = 0;
894 }
895
896
897 #ifdef AWE_HAS_GUS_COMPATIBILITY
898
899 /* convert frequency mHz to abstract cents (= midi key * 100) */
900 static int
901 freq_to_note(int mHz)
902 {
903 /* abscents = log(mHz/8176) / log(2) * 1200 */
904 unsigned int max_val = (unsigned int)0xffffffff / 10000;
905 int i, times;
906 unsigned int base;
907 unsigned int freq;
908 int note, tune;
909
910 if (mHz == 0)
911 return 0;
912 if (mHz < 0)
913 return 12799; /* maximum */
914
915 freq = mHz;
916 note = 0;
917 for (base = 8176 * 2; freq >= base; base *= 2) {
918 note += 12;
919 if (note >= 128) /* over maximum */
920 return 12799;
921 }
922 base /= 2;
923
924 /* to avoid overflow... */
925 times = 10000;
926 while (freq > max_val) {
927 max_val *= 10;
928 times /= 10;
929 base /= 10;
930 }
931
932 freq = freq * times / base;
933 for (i = 0; i < 12; i++) {
934 if (freq < semitone_tuning[i+1])
935 break;
936 note++;
937 }
938
939 tune = 0;
940 freq = freq * 10000 / semitone_tuning[i];
941 for (i = 0; i < 100; i++) {
942 if (freq < cent_tuning[i+1])
943 break;
944 tune++;
945 }
946
947 return note * 100 + tune;
948 }
949
950
951 /* convert Hz to AWE32 rate offset:
952 * sample pitch offset for the specified sample rate
953 * rate=44100 is no offset, each 4096 is 1 octave (twice).
954 * eg, when rate is 22050, this offset becomes -4096.
955 */
956 static int
957 calc_rate_offset(int Hz)
958 {
959 /* offset = log(Hz / 44100) / log(2) * 4096 */
960 int freq, base, i;
961
962 /* maybe smaller than max (44100Hz) */
963 if (Hz <= 0 || Hz >= 44100) return 0;
964
965 base = 0;
966 for (freq = Hz * 2; freq < 44100; freq *= 2)
967 base++;
968 base *= 1200;
969
970 freq = 44100 * 10000 / (freq/2);
971 for (i = 0; i < 12; i++) {
972 if (freq < semitone_tuning[i+1])
973 break;
974 base += 100;
975 }
976 freq = freq * 10000 / semitone_tuning[i];
977 for (i = 0; i < 100; i++) {
978 if (freq < cent_tuning[i+1])
979 break;
980 base++;
981 }
982 return -base * 4096 / 1200;
983 }
984
985
986 /*
987 * convert envelope time parameter to AWE32 raw parameter
988 */
989
990 /* attack & decay/release time table (msec) */
991 static short attack_time_tbl[128] = {
992 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
993 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
994 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
995 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
996 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
997 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
998 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
999 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
1000 };
1001
1002 static short decay_time_tbl[128] = {
1003 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
1004 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
1005 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
1006 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
1007 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
1008 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
1009 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
1010 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
1011 };
1012
1013 #define calc_parm_delay(msec) (0x8000 - (msec) * 1000 / 725);
1014
1015 /* delay time = 0x8000 - msec/92 */
1016 static int
1017 calc_parm_hold(int msec)
1018 {
1019 int val = (0x7f * 92 - msec) / 92;
1020 if (val < 1) val = 1;
1021 if (val > 127) val = 127;
1022 return val;
1023 }
1024
1025 /* attack time: search from time table */
1026 static int
1027 calc_parm_attack(int msec)
1028 {
1029 return calc_parm_search(msec, attack_time_tbl);
1030 }
1031
1032 /* decay/release time: search from time table */
1033 static int
1034 calc_parm_decay(int msec)
1035 {
1036 return calc_parm_search(msec, decay_time_tbl);
1037 }
1038
1039 /* search an index for specified time from given time table */
1040 static int
1041 calc_parm_search(int msec, short *table)
1042 {
1043 int left = 1, right = 127, mid;
1044 while (left < right) {
1045 mid = (left + right) / 2;
1046 if (msec < (int)table[mid])
1047 left = mid + 1;
1048 else
1049 right = mid;
1050 }
1051 return left;
1052 }
1053 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1054
1055
1056 /*
1057 * effects table
1058 */
1059
1060 /* set an effect value */
1061 #define FX_FLAG_OFF 0
1062 #define FX_FLAG_SET 1
1063 #define FX_FLAG_ADD 2
1064
1065 #define FX_SET(rec,type,value) \
1066 ((rec)->flags[type] = FX_FLAG_SET, (rec)->val[type] = (value))
1067 #define FX_ADD(rec,type,value) \
1068 ((rec)->flags[type] = FX_FLAG_ADD, (rec)->val[type] = (value))
1069 #define FX_UNSET(rec,type) \
1070 ((rec)->flags[type] = FX_FLAG_OFF, (rec)->val[type] = 0)
1071
1072 /* check the effect value is set */
1073 #define FX_ON(rec,type) ((rec)->flags[type])
1074
1075 #define PARM_BYTE 0
1076 #define PARM_WORD 1
1077 #define PARM_SIGN 2
1078
1079 static struct PARM_DEFS {
1080 int type; /* byte or word */
1081 int low, high; /* value range */
1082 fx_affect_func realtime; /* realtime paramater change */
1083 } parm_defs[] = {
1084 {PARM_WORD, 0, 0x8000, NULL}, /* env1 delay */
1085 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 attack */
1086 {PARM_BYTE, 0, 0x7e, NULL}, /* env1 hold */
1087 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 decay */
1088 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 release */
1089 {PARM_BYTE, 0, 0x7f, NULL}, /* env1 sustain */
1090 {PARM_BYTE, 0, 0xff, NULL}, /* env1 pitch */
1091 {PARM_BYTE, 0, 0xff, NULL}, /* env1 cutoff */
1092
1093 {PARM_WORD, 0, 0x8000, NULL}, /* env2 delay */
1094 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 attack */
1095 {PARM_BYTE, 0, 0x7e, NULL}, /* env2 hold */
1096 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 decay */
1097 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 release */
1098 {PARM_BYTE, 0, 0x7f, NULL}, /* env2 sustain */
1099
1100 {PARM_WORD, 0, 0x8000, NULL}, /* lfo1 delay */
1101 {PARM_BYTE, 0, 0xff, awe_fx_tremfrq}, /* lfo1 freq */
1102 {PARM_SIGN, -128, 127, awe_fx_tremfrq}, /* lfo1 volume */
1103 {PARM_SIGN, -128, 127, awe_fx_fmmod}, /* lfo1 pitch */
1104 {PARM_BYTE, 0, 0xff, awe_fx_fmmod}, /* lfo1 cutoff */
1105
1106 {PARM_WORD, 0, 0x8000, NULL}, /* lfo2 delay */
1107 {PARM_BYTE, 0, 0xff, awe_fx_fm2frq2}, /* lfo2 freq */
1108 {PARM_SIGN, -128, 127, awe_fx_fm2frq2}, /* lfo2 pitch */
1109
1110 {PARM_WORD, 0, 0xffff, awe_set_voice_pitch}, /* initial pitch */
1111 {PARM_BYTE, 0, 0xff, NULL}, /* chorus */
1112 {PARM_BYTE, 0, 0xff, NULL}, /* reverb */
1113 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial cutoff */
1114 {PARM_BYTE, 0, 15, awe_fx_filterQ}, /* initial resonance */
1115
1116 {PARM_WORD, 0, 0xffff, NULL}, /* sample start */
1117 {PARM_WORD, 0, 0xffff, NULL}, /* loop start */
1118 {PARM_WORD, 0, 0xffff, NULL}, /* loop end */
1119 {PARM_WORD, 0, 0xffff, NULL}, /* coarse sample start */
1120 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop start */
1121 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop end */
1122 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial attenuation */
1123 };
1124
1125
1126 static unsigned char
1127 FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value)
1128 {
1129 int effect = 0;
1130 int on = 0;
1131 if (lay && (on = FX_ON(lay, type)) != 0)
1132 effect = lay->val[type];
1133 if (!on && (on = FX_ON(rec, type)) != 0)
1134 effect = rec->val[type];
1135 if (on == FX_FLAG_ADD) {
1136 if (parm_defs[type].type == PARM_SIGN) {
1137 if (value > 0x7f)
1138 effect += (int)value - 0x100;
1139 else
1140 effect += (int)value;
1141 } else {
1142 effect += (int)value;
1143 }
1144 }
1145 if (on) {
1146 if (effect < parm_defs[type].low)
1147 effect = parm_defs[type].low;
1148 else if (effect > parm_defs[type].high)
1149 effect = parm_defs[type].high;
1150 return (unsigned char)effect;
1151 }
1152 return value;
1153 }
1154
1155 /* get word effect value */
1156 static unsigned short
1157 FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value)
1158 {
1159 int effect = 0;
1160 int on = 0;
1161 if (lay && (on = FX_ON(lay, type)) != 0)
1162 effect = lay->val[type];
1163 if (!on && (on = FX_ON(rec, type)) != 0)
1164 effect = rec->val[type];
1165 if (on == FX_FLAG_ADD)
1166 effect += (int)value;
1167 if (on) {
1168 if (effect < parm_defs[type].low)
1169 effect = parm_defs[type].low;
1170 else if (effect > parm_defs[type].high)
1171 effect = parm_defs[type].high;
1172 return (unsigned short)effect;
1173 }
1174 return value;
1175 }
1176
1177 /* get word (upper=type1/lower=type2) effect value */
1178 static unsigned short
1179 FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value)
1180 {
1181 unsigned short tmp;
1182 tmp = FX_BYTE(rec, lay, type1, (unsigned char)(value >> 8));
1183 tmp <<= 8;
1184 tmp |= FX_BYTE(rec, lay, type2, (unsigned char)(value & 0xff));
1185 return tmp;
1186 }
1187
1188 /* address offset */
1189 static int
1190 FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode)
1191 {
1192 int addr = 0;
1193 if (lay && FX_ON(lay, hi))
1194 addr = (short)lay->val[hi];
1195 else if (FX_ON(rec, hi))
1196 addr = (short)rec->val[hi];
1197 addr = addr << 15;
1198 if (lay && FX_ON(lay, lo))
1199 addr += (short)lay->val[lo];
1200 else if (FX_ON(rec, lo))
1201 addr += (short)rec->val[lo];
1202 if (!(mode & AWE_SAMPLE_8BITS))
1203 addr /= 2;
1204 return addr;
1205 }
1206
1207
1208 /*
1209 * turn on/off sample
1210 */
1211
1212 /* table for volume target calculation */
1213 static unsigned short voltarget[16] = {
1214 0xEAC0, 0XE0C8, 0XD740, 0XCE20, 0XC560, 0XBD08, 0XB500, 0XAD58,
1215 0XA5F8, 0X9EF0, 0X9830, 0X91C0, 0X8B90, 0X85A8, 0X8000, 0X7A90
1216 };
1217
1218 static void
1219 awe_note_on(int voice)
1220 {
1221 unsigned int temp;
1222 int addr;
1223 int vtarget, ftarget, ptarget, pitch;
1224 awe_voice_info *vp;
1225 awe_voice_parm_block *parm;
1226 FX_Rec *fx = &voices[voice].cinfo->fx;
1227 FX_Rec *fx_lay = NULL;
1228 if (voices[voice].layer < MAX_LAYERS)
1229 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1230
1231 /* A voice sample must assigned before calling */
1232 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1233 return;
1234
1235 parm = (awe_voice_parm_block*)&vp->parm;
1236
1237 /* channel to be silent and idle */
1238 awe_poke(AWE_DCYSUSV(voice), 0x0080);
1239 awe_poke(AWE_VTFT(voice), 0x0000FFFF);
1240 awe_poke(AWE_CVCF(voice), 0x0000FFFF);
1241 awe_poke(AWE_PTRX(voice), 0);
1242 awe_poke(AWE_CPF(voice), 0);
1243
1244 /* set pitch offset */
1245 awe_set_pitch(voice, TRUE);
1246
1247 /* modulation & volume envelope */
1248 if (parm->modatk >= 0x80 && parm->moddelay >= 0x8000) {
1249 awe_poke(AWE_ENVVAL(voice), 0xBFFF);
1250 pitch = (parm->env1pit<<4) + voices[voice].apitch;
1251 if (pitch > 0xffff) pitch = 0xffff;
1252 /* calculate filter target */
1253 ftarget = parm->cutoff + parm->env1fc;
1254 limitvalue(ftarget, 0, 255);
1255 ftarget <<= 8;
1256 } else {
1257 awe_poke(AWE_ENVVAL(voice),
1258 FX_WORD(fx, fx_lay, AWE_FX_ENV1_DELAY, parm->moddelay));
1259 ftarget = parm->cutoff;
1260 ftarget <<= 8;
1261 pitch = voices[voice].apitch;
1262 }
1263
1264 /* calcualte pitch target */
1265 if (pitch != 0xffff) {
1266 ptarget = 1 << (pitch >> 12);
1267 if (pitch & 0x800) ptarget += (ptarget*0x102e)/0x2710;
1268 if (pitch & 0x400) ptarget += (ptarget*0x764)/0x2710;
1269 if (pitch & 0x200) ptarget += (ptarget*0x389)/0x2710;
1270 ptarget += (ptarget>>1);
1271 if (ptarget > 0xffff) ptarget = 0xffff;
1272
1273 } else ptarget = 0xffff;
1274 if (parm->modatk >= 0x80)
1275 awe_poke(AWE_ATKHLD(voice),
1276 FX_BYTE(fx, fx_lay, AWE_FX_ENV1_HOLD, parm->modhld) << 8 | 0x7f);
1277 else
1278 awe_poke(AWE_ATKHLD(voice),
1279 FX_COMB(fx, fx_lay, AWE_FX_ENV1_HOLD, AWE_FX_ENV1_ATTACK,
1280 vp->parm.modatkhld));
1281 awe_poke(AWE_DCYSUS(voice),
1282 FX_COMB(fx, fx_lay, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY,
1283 vp->parm.moddcysus));
1284
1285 if (parm->volatk >= 0x80 && parm->voldelay >= 0x8000) {
1286 awe_poke(AWE_ENVVOL(voice), 0xBFFF);
1287 vtarget = voltarget[voices[voice].avol%0x10]>>(voices[voice].avol>>4);
1288 } else {
1289 awe_poke(AWE_ENVVOL(voice),
1290 FX_WORD(fx, fx_lay, AWE_FX_ENV2_DELAY, vp->parm.voldelay));
1291 vtarget = 0;
1292 }
1293 if (parm->volatk >= 0x80)
1294 awe_poke(AWE_ATKHLDV(voice),
1295 FX_BYTE(fx, fx_lay, AWE_FX_ENV2_HOLD, parm->volhld) << 8 | 0x7f);
1296 else
1297 awe_poke(AWE_ATKHLDV(voice),
1298 FX_COMB(fx, fx_lay, AWE_FX_ENV2_HOLD, AWE_FX_ENV2_ATTACK,
1299 vp->parm.volatkhld));
1300 /* decay/sustain parameter for volume envelope must be set at last */
1301
1302 /* cutoff and volume */
1303 awe_set_volume(voice, TRUE);
1304
1305 /* modulation envelope heights */
1306 awe_poke(AWE_PEFE(voice),
1307 FX_COMB(fx, fx_lay, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF,
1308 vp->parm.pefe));
1309
1310 /* lfo1/2 delay */
1311 awe_poke(AWE_LFO1VAL(voice),
1312 FX_WORD(fx, fx_lay, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay));
1313 awe_poke(AWE_LFO2VAL(voice),
1314 FX_WORD(fx, fx_lay, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay));
1315
1316 /* lfo1 pitch & cutoff shift */
1317 awe_fx_fmmod(voice, TRUE);
1318 /* lfo1 volume & freq */
1319 awe_fx_tremfrq(voice, TRUE);
1320 /* lfo2 pitch & freq */
1321 awe_fx_fm2frq2(voice, TRUE);
1322 /* pan & loop start */
1323 awe_set_pan(voice, TRUE);
1324
1325 /* chorus & loop end (chorus 8bit, MSB) */
1326 addr = vp->loopend - 1;
1327 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_END,
1328 AWE_FX_COARSE_LOOP_END, vp->mode);
1329 temp = FX_BYTE(fx, fx_lay, AWE_FX_CHORUS, vp->parm.chorus);
1330 temp = (temp <<24) | (unsigned int)addr;
1331 awe_poke_dw(AWE_CSL(voice), temp);
1332 DEBUG(4,printk("AWE32: [-- loopend=%x/%x]\n", vp->loopend, addr));
1333
1334 /* Q & current address (Q 4bit value, MSB) */
1335 addr = vp->start - 1;
1336 addr += FX_OFFSET(fx, fx_lay, AWE_FX_SAMPLE_START,
1337 AWE_FX_COARSE_SAMPLE_START, vp->mode);
1338 temp = FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ);
1339 temp = (temp<<28) | (unsigned int)addr;
1340 awe_poke_dw(AWE_CCCA(voice), temp);
1341 DEBUG(4,printk("AWE32: [-- startaddr=%x/%x]\n", vp->start, addr));
1342
1343 /* clear unknown registers */
1344 awe_poke_dw(AWE_00A0(voice), 0);
1345 awe_poke_dw(AWE_0080(voice), 0);
1346
1347 /* reset volume */
1348 awe_poke_dw(AWE_VTFT(voice), (vtarget<<16)|ftarget);
1349 awe_poke_dw(AWE_CVCF(voice), (vtarget<<16)|ftarget);
1350
1351 /* set reverb */
1352 temp = FX_BYTE(fx, fx_lay, AWE_FX_REVERB, vp->parm.reverb);
1353 temp = (temp << 8) | (ptarget << 16) | voices[voice].aaux;
1354 awe_poke_dw(AWE_PTRX(voice), temp);
1355 awe_poke_dw(AWE_CPF(voice), ptarget << 16);
1356 /* turn on envelope */
1357 awe_poke(AWE_DCYSUSV(voice),
1358 FX_COMB(fx, fx_lay, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY,
1359 vp->parm.voldcysus));
1360
1361 voices[voice].state = AWE_ST_ON;
1362
1363 /* clear voice position for the next note on this channel */
1364 if (SINGLE_LAYER_MODE()) {
1365 FX_UNSET(fx, AWE_FX_SAMPLE_START);
1366 FX_UNSET(fx, AWE_FX_COARSE_SAMPLE_START);
1367 }
1368 }
1369
1370
1371 /* turn off the voice */
1372 static void
1373 awe_note_off(int voice)
1374 {
1375 awe_voice_info *vp;
1376 unsigned short tmp;
1377 FX_Rec *fx = &voices[voice].cinfo->fx;
1378 FX_Rec *fx_lay = NULL;
1379 if (voices[voice].layer < MAX_LAYERS)
1380 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1381
1382 if ((vp = voices[voice].sample) == NULL) {
1383 voices[voice].state = AWE_ST_OFF;
1384 return;
1385 }
1386
1387 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_RELEASE,
1388 (unsigned char)vp->parm.modrelease);
1389 awe_poke(AWE_DCYSUS(voice), tmp);
1390 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_RELEASE,
1391 (unsigned char)vp->parm.volrelease);
1392 awe_poke(AWE_DCYSUSV(voice), tmp);
1393 voices[voice].state = AWE_ST_RELEASED;
1394 }
1395
1396 /* force to terminate the voice (no releasing echo) */
1397 static void
1398 awe_terminate(int voice)
1399 {
1400 awe_poke(AWE_DCYSUSV(voice), 0x807F);
1401 awe_tweak_voice(voice);
1402 voices[voice].state = AWE_ST_OFF;
1403 }
1404
1405 /* turn off other voices with the same exclusive class (for drums) */
1406 static void
1407 awe_exclusive_off(int voice)
1408 {
1409 int i, exclass;
1410
1411 if (voices[voice].sample == NULL)
1412 return;
1413 if ((exclass = voices[voice].sample->exclusiveClass) == 0)
1414 return; /* not exclusive */
1415
1416 /* turn off voices with the same class */
1417 for (i = 0; i < awe_max_voices; i++) {
1418 if (i != voice && IS_PLAYING(i) &&
1419 voices[i].sample && voices[i].ch == voices[voice].ch &&
1420 voices[i].sample->exclusiveClass == exclass) {
1421 DEBUG(4,printk("AWE32: [exoff(%d)]\n", i));
1422 awe_terminate(i);
1423 awe_voice_init(i, TRUE);
1424 }
1425 }
1426 }
1427
1428
1429 /*
1430 * change the parameters of an audible voice
1431 */
1432
1433 /* change pitch */
1434 static void
1435 awe_set_pitch(int voice, int forced)
1436 {
1437 if (IS_NO_EFFECT(voice) && !forced) return;
1438 awe_poke(AWE_IP(voice), voices[voice].apitch);
1439 DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch));
1440 }
1441
1442 /* calculate & change pitch */
1443 static void
1444 awe_set_voice_pitch(int voice, int forced)
1445 {
1446 awe_calc_pitch(voice);
1447 awe_set_pitch(voice, forced);
1448 }
1449
1450 /* change volume & cutoff */
1451 static void
1452 awe_set_volume(int voice, int forced)
1453 {
1454 awe_voice_info *vp;
1455 unsigned short tmp2;
1456 FX_Rec *fx = &voices[voice].cinfo->fx;
1457 FX_Rec *fx_lay = NULL;
1458 if (voices[voice].layer < MAX_LAYERS)
1459 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1460
1461 if (!IS_PLAYING(voice) && !forced) return;
1462 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1463 return;
1464
1465 tmp2 = FX_BYTE(fx, fx_lay, AWE_FX_CUTOFF,
1466 (unsigned char)voices[voice].acutoff);
1467 tmp2 = (tmp2 << 8);
1468 tmp2 |= FX_BYTE(fx, fx_lay, AWE_FX_ATTEN,
1469 (unsigned char)voices[voice].avol);
1470 awe_poke(AWE_IFATN(voice), tmp2);
1471 }
1472
1473 /* calculate & change volume */
1474 static void
1475 awe_set_voice_vol(int voice, int forced)
1476 {
1477 if (IS_EMPTY(voice))
1478 return;
1479 awe_calc_volume(voice);
1480 awe_set_volume(voice, forced);
1481 }
1482
1483
1484 /* change pan; this could make a click noise.. */
1485 static void
1486 awe_set_pan(int voice, int forced)
1487 {
1488 unsigned int temp;
1489 int addr;
1490 awe_voice_info *vp;
1491 FX_Rec *fx = &voices[voice].cinfo->fx;
1492 FX_Rec *fx_lay = NULL;
1493 if (voices[voice].layer < MAX_LAYERS)
1494 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1495
1496 if (IS_NO_EFFECT(voice) && !forced) return;
1497 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1498 return;
1499
1500 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
1501 if (vp->fixpan > 0) /* 0-127 */
1502 temp = 255 - (int)vp->fixpan * 2;
1503 else {
1504 int pos = 0;
1505 if (vp->pan >= 0) /* 0-127 */
1506 pos = (int)vp->pan * 2 - 128;
1507 pos += voices[voice].cinfo->panning; /* -128 - 127 */
1508 temp = 127 - pos;
1509 }
1510 limitvalue(temp, 0, 255);
1511 if (ctrls[AWE_MD_PAN_EXCHANGE]) {
1512 temp = 255 - temp;
1513 }
1514 if (forced || temp != voices[voice].apan) {
1515 voices[voice].apan = temp;
1516 if (temp == 0)
1517 voices[voice].aaux = 0xff;
1518 else
1519 voices[voice].aaux = (-temp) & 0xff;
1520 addr = vp->loopstart - 1;
1521 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START,
1522 AWE_FX_COARSE_LOOP_START, vp->mode);
1523 temp = (temp<<24) | (unsigned int)addr;
1524 awe_poke_dw(AWE_PSST(voice), temp);
1525 DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr));
1526 }
1527 }
1528
1529 /* effects change during playing */
1530 static void
1531 awe_fx_fmmod(int voice, int forced)
1532 {
1533 awe_voice_info *vp;
1534 FX_Rec *fx = &voices[voice].cinfo->fx;
1535 FX_Rec *fx_lay = NULL;
1536 if (voices[voice].layer < MAX_LAYERS)
1537 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1538
1539 if (IS_NO_EFFECT(voice) && !forced) return;
1540 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1541 return;
1542 awe_poke(AWE_FMMOD(voice),
1543 FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,
1544 vp->parm.fmmod));
1545 }
1546
1547 /* set tremolo (lfo1) volume & frequency */
1548 static void
1549 awe_fx_tremfrq(int voice, int forced)
1550 {
1551 awe_voice_info *vp;
1552 FX_Rec *fx = &voices[voice].cinfo->fx;
1553 FX_Rec *fx_lay = NULL;
1554 if (voices[voice].layer < MAX_LAYERS)
1555 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1556
1557 if (IS_NO_EFFECT(voice) && !forced) return;
1558 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1559 return;
1560 awe_poke(AWE_TREMFRQ(voice),
1561 FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,
1562 vp->parm.tremfrq));
1563 }
1564
1565 /* set lfo2 pitch & frequency */
1566 static void
1567 awe_fx_fm2frq2(int voice, int forced)
1568 {
1569 awe_voice_info *vp;
1570 FX_Rec *fx = &voices[voice].cinfo->fx;
1571 FX_Rec *fx_lay = NULL;
1572 if (voices[voice].layer < MAX_LAYERS)
1573 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1574
1575 if (IS_NO_EFFECT(voice) && !forced) return;
1576 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1577 return;
1578 awe_poke(AWE_FM2FRQ2(voice),
1579 FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,
1580 vp->parm.fm2frq2));
1581 }
1582
1583
1584 /* Q & current address (Q 4bit value, MSB) */
1585 static void
1586 awe_fx_filterQ(int voice, int forced)
1587 {
1588 unsigned int addr;
1589 awe_voice_info *vp;
1590 FX_Rec *fx = &voices[voice].cinfo->fx;
1591 FX_Rec *fx_lay = NULL;
1592 if (voices[voice].layer < MAX_LAYERS)
1593 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1594
1595 if (IS_NO_EFFECT(voice) && !forced) return;
1596 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1597 return;
1598
1599 addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff;
1600 addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28);
1601 awe_poke_dw(AWE_CCCA(voice), addr);
1602 }
1603
1604 /*
1605 * calculate pitch offset
1606 *
1607 * 0xE000 is no pitch offset at 44100Hz sample.
1608 * Every 4096 is one octave.
1609 */
1610
1611 static void
1612 awe_calc_pitch(int voice)
1613 {
1614 voice_info *vp = &voices[voice];
1615 awe_voice_info *ap;
1616 awe_chan_info *cp = voices[voice].cinfo;
1617 int offset;
1618
1619 /* search voice information */
1620 if ((ap = vp->sample) == NULL)
1621 return;
1622 if (ap->index == 0) {
1623 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1624 if (awe_set_sample((awe_voice_list*)ap) == 0)
1625 return;
1626 }
1627
1628 /* calculate offset */
1629 if (ap->fixkey >= 0) {
1630 DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune));
1631 offset = (ap->fixkey - ap->root) * 4096 / 12;
1632 } else {
1633 DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune));
1634 offset = (vp->note - ap->root) * 4096 / 12;
1635 DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset));
1636 }
1637 offset = (offset * ap->scaleTuning) / 100;
1638 DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));
1639 offset += ap->tune * 4096 / 1200;
1640 DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));
1641 if (cp->bender != 0) {
1642 DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender));
1643 /* (819200: 1 semitone) ==> (4096: 12 semitones) */
1644 offset += cp->bender * cp->bender_range / 2400;
1645 }
1646
1647 /* add initial pitch correction */
1648 if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH))
1649 offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH];
1650 else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH))
1651 offset += cp->fx.val[AWE_FX_INIT_PITCH];
1652
1653 /* 0xe000: root pitch */
1654 vp->apitch = 0xe000 + ap->rate_offset + offset;
1655 DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset));
1656 if (vp->apitch > 0xffff)
1657 vp->apitch = 0xffff;
1658 if (vp->apitch < 0)
1659 vp->apitch = 0;
1660 }
1661
1662
1663 #ifdef AWE_HAS_GUS_COMPATIBILITY
1664 /* calculate MIDI key and semitone from the specified frequency */
1665 static void
1666 awe_calc_pitch_from_freq(int voice, int freq)
1667 {
1668 voice_info *vp = &voices[voice];
1669 awe_voice_info *ap;
1670 FX_Rec *fx = &voices[voice].cinfo->fx;
1671 FX_Rec *fx_lay = NULL;
1672 int offset;
1673 int note;
1674
1675 if (voices[voice].layer < MAX_LAYERS)
1676 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1677
1678 /* search voice information */
1679 if ((ap = vp->sample) == NULL)
1680 return;
1681 if (ap->index == 0) {
1682 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1683 if (awe_set_sample((awe_voice_list*)ap) == 0)
1684 return;
1685 }
1686 note = freq_to_note(freq);
1687 offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;
1688 offset = (offset * ap->scaleTuning) / 100;
1689 if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH))
1690 offset += fx_lay->val[AWE_FX_INIT_PITCH];
1691 else if (FX_ON(fx, AWE_FX_INIT_PITCH))
1692 offset += fx->val[AWE_FX_INIT_PITCH];
1693 vp->apitch = 0xe000 + ap->rate_offset + offset;
1694 if (vp->apitch > 0xffff)
1695 vp->apitch = 0xffff;
1696 if (vp->apitch < 0)
1697 vp->apitch = 0;
1698 }
1699 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1700
1701
1702 /*
1703 * calculate volume attenuation
1704 *
1705 * Voice volume is controlled by volume attenuation parameter.
1706 * So volume becomes maximum when avol is 0 (no attenuation), and
1707 * minimum when 255 (-96dB or silence).
1708 */
1709
1710 static int vol_table[128] = {
1711 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
1712 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
1713 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
1714 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
1715 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
1716 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
1717 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
1718 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
1719 };
1720
1721 /* tables for volume->attenuation calculation */
1722 static unsigned char voltab1[128] = {
1723 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1724 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
1725 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
1726 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
1727 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
1728 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
1729 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
1730 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
1731 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
1732 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
1733 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
1734 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
1735 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1736 };
1737
1738 static unsigned char voltab2[128] = {
1739 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
1740 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
1741 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
1742 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
1743 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
1744 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
1745 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
1746 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
1747 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
1748 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
1749 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
1750 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
1751 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
1752 };
1753
1754 static unsigned char expressiontab[128] = {
1755 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
1756 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
1757 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
1758 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
1759 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
1760 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
1761 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
1762 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
1763 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
1764 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
1765 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
1766 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
1767 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1768 };
1769
1770 static void
1771 awe_calc_volume(int voice)
1772 {
1773 voice_info *vp = &voices[voice];
1774 awe_voice_info *ap;
1775 awe_chan_info *cp = voices[voice].cinfo;
1776 int vol;
1777
1778 /* search voice information */
1779 if ((ap = vp->sample) == NULL)
1780 return;
1781
1782 ap = vp->sample;
1783 if (ap->index == 0) {
1784 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1785 if (awe_set_sample((awe_voice_list*)ap) == 0)
1786 return;
1787 }
1788
1789 if (ctrls[AWE_MD_NEW_VOLUME_CALC]) {
1790 int main_vol = cp->main_vol * ap->amplitude / 127;
1791 limitvalue(vp->velocity, 0, 127);
1792 limitvalue(main_vol, 0, 127);
1793 limitvalue(cp->expression_vol, 0, 127);
1794
1795 vol = voltab1[main_vol] + voltab2[vp->velocity];
1796 vol = (vol * 8) / 3;
1797 vol += ap->attenuation;
1798 if (cp->expression_vol < 127)
1799 vol += ((0x100 - vol) * expressiontab[cp->expression_vol])/128;
1800 vol += atten_offset;
1801 if (atten_relative)
1802 vol += ctrls[AWE_MD_ZERO_ATTEN];
1803 limitvalue(vol, 0, 255);
1804 vp->avol = vol;
1805
1806 } else {
1807 /* 0 - 127 */
1808 vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127);
1809 vol = vol * ap->amplitude / 127;
1810
1811 if (vol < 0) vol = 0;
1812 if (vol > 127) vol = 127;
1813
1814 /* calc to attenuation */
1815 vol = vol_table[vol];
1816 vol += (int)ap->attenuation;
1817 vol += atten_offset;
1818 if (atten_relative)
1819 vol += ctrls[AWE_MD_ZERO_ATTEN];
1820 if (vol > 255) vol = 255;
1821
1822 vp->avol = vol;
1823 }
1824 if (cp->bank != AWE_DRUM_BANK && ((awe_voice_parm_block*)(&ap->parm))->volatk < 0x7d) {
1825 int atten;
1826 if (vp->velocity < 70) atten = 70;
1827 else atten = vp->velocity;
1828 vp->acutoff = (atten * ap->parm.cutoff + 0xa0) >> 7;
1829 } else {
1830 vp->acutoff = ap->parm.cutoff;
1831 }
1832 DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));
1833 }
1834
1835 /* change master volume */
1836 static void
1837 awe_change_master_volume(short val)
1838 {
1839 limitvalue(val, 0, 127);
1840 atten_offset = vol_table[val];
1841 atten_relative = TRUE;
1842 awe_update_volume();
1843 }
1844
1845 /* update volumes of all available channels */
1846 static void awe_update_volume(void)
1847 {
1848 int i;
1849 for (i = 0; i < awe_max_voices; i++)
1850 awe_set_voice_vol(i, TRUE);
1851 }
1852
1853 /* set sostenuto on */
1854 static void awe_sostenuto_on(int voice, int forced)
1855 {
1856 if (IS_NO_EFFECT(voice) && !forced) return;
1857 voices[voice].sostenuto = 127;
1858 }
1859
1860
1861 /* drop sustain */
1862 static void awe_sustain_off(int voice, int forced)
1863 {
1864 if (voices[voice].state == AWE_ST_SUSTAINED) {
1865 awe_note_off(voice);
1866 awe_fx_init(voices[voice].ch);
1867 awe_voice_init(voice, FALSE);
1868 }
1869 }
1870
1871
1872 /* terminate and initialize voice */
1873 static void awe_terminate_and_init(int voice, int forced)
1874 {
1875 awe_terminate(voice);
1876 awe_fx_init(voices[voice].ch);
1877 awe_voice_init(voice, TRUE);
1878 }
1879
1880
1881 /*
1882 * synth operation routines
1883 */
1884
1885 #define AWE_VOICE_KEY(v) (0x8000 | (v))
1886 #define AWE_CHAN_KEY(c,n) (((c) << 8) | ((n) + 1))
1887 #define KEY_CHAN_MATCH(key,c) (((key) >> 8) == (c))
1888
1889 /* initialize the voice */
1890 static void
1891 awe_voice_init(int voice, int init_all)
1892 {
1893 voice_info *vp = &voices[voice];
1894
1895 /* reset voice search key */
1896 if (playing_mode == AWE_PLAY_DIRECT)
1897 vp->key = AWE_VOICE_KEY(voice);
1898 else
1899 vp->key = 0;
1900
1901 /* clear voice mapping */
1902 voice_alloc->map[voice] = 0;
1903
1904 /* touch the timing flag */
1905 vp->time = current_alloc_time;
1906
1907 /* initialize other parameters if necessary */
1908 if (init_all) {
1909 vp->note = -1;
1910 vp->velocity = 0;
1911 vp->sostenuto = 0;
1912
1913 vp->sample = NULL;
1914 vp->cinfo = &channels[voice];
1915 vp->ch = voice;
1916 vp->state = AWE_ST_OFF;
1917
1918 /* emu8000 parameters */
1919 vp->apitch = 0;
1920 vp->avol = 255;
1921 vp->apan = -1;
1922 }
1923 }
1924
1925 /* clear effects */
1926 static void awe_fx_init(int ch)
1927 {
1928 if (SINGLE_LAYER_MODE() && !ctrls[AWE_MD_KEEP_EFFECT]) {
1929 memset(&channels[ch].fx, 0, sizeof(channels[ch].fx));
1930 memset(&channels[ch].fx_layer, 0, sizeof(&channels[ch].fx_layer));
1931 }
1932 }
1933
1934 /* initialize channel info */
1935 static void awe_channel_init(int ch, int init_all)
1936 {
1937 awe_chan_info *cp = &channels[ch];
1938 cp->channel = ch;
1939 if (init_all) {
1940 cp->panning = 0; /* zero center */
1941 cp->bender_range = 200; /* sense * 100 */
1942 cp->main_vol = 127;
1943 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) {
1944 cp->instr = ctrls[AWE_MD_DEF_DRUM];
1945 cp->bank = AWE_DRUM_BANK;
1946 } else {
1947 cp->instr = ctrls[AWE_MD_DEF_PRESET];
1948 cp->bank = ctrls[AWE_MD_DEF_BANK];
1949 }
1950 }
1951
1952 cp->bender = 0; /* zero tune skew */
1953 cp->expression_vol = 127;
1954 cp->chan_press = 0;
1955 cp->sustained = 0;
1956
1957 if (! ctrls[AWE_MD_KEEP_EFFECT]) {
1958 memset(&cp->fx, 0, sizeof(cp->fx));
1959 memset(&cp->fx_layer, 0, sizeof(cp->fx_layer));
1960 }
1961 }
1962
1963
1964 /* change the voice parameters; voice = channel */
1965 static void awe_voice_change(int voice, fx_affect_func func)
1966 {
1967 int i;
1968 switch (playing_mode) {
1969 case AWE_PLAY_DIRECT:
1970 func(voice, FALSE);
1971 break;
1972 case AWE_PLAY_INDIRECT:
1973 for (i = 0; i < awe_max_voices; i++)
1974 if (voices[i].key == AWE_VOICE_KEY(voice))
1975 func(i, FALSE);
1976 break;
1977 default:
1978 for (i = 0; i < awe_max_voices; i++)
1979 if (KEY_CHAN_MATCH(voices[i].key, voice))
1980 func(i, FALSE);
1981 break;
1982 }
1983 }
1984
1985
1986 /*
1987 * device open / close
1988 */
1989
1990 /* open device:
1991 * reset status of all voices, and clear sample position flag
1992 */
1993 static int
1994 awe_open(int dev, int mode)
1995 {
1996 if (awe_busy)
1997 return -EBUSY;
1998
1999 awe_busy = TRUE;
2000
2001 /* set default mode */
2002 awe_init_ctrl_parms(FALSE);
2003 atten_relative = TRUE;
2004 atten_offset = 0;
2005 drum_flags = DEFAULT_DRUM_FLAGS;
2006 playing_mode = AWE_PLAY_INDIRECT;
2007
2008 /* reset voices & channels */
2009 awe_reset(dev);
2010
2011 patch_opened = 0;
2012
2013 return 0;
2014 }
2015
2016
2017 /* close device:
2018 * reset all voices again (terminate sounds)
2019 */
2020 static void
2021 awe_close(int dev)
2022 {
2023 awe_reset(dev);
2024 awe_busy = FALSE;
2025 }
2026
2027
2028 /* set miscellaneous mode parameters
2029 */
2030 static void
2031 awe_init_ctrl_parms(int init_all)
2032 {
2033 int i;
2034 for (i = 0; i < AWE_MD_END; i++) {
2035 if (init_all || ctrl_parms[i].init_each_time)
2036 ctrls[i] = ctrl_parms[i].value;
2037 }
2038 }
2039
2040
2041 /* sequencer I/O control:
2042 */
2043 static int
2044 awe_ioctl(int dev, unsigned int cmd, caddr_t arg)
2045 {
2046 switch (cmd) {
2047 case SNDCTL_SYNTH_INFO:
2048 if (playing_mode == AWE_PLAY_DIRECT)
2049 awe_info.nr_voices = awe_max_voices;
2050 else
2051 awe_info.nr_voices = AWE_MAX_CHANNELS;
2052 memcpy((char*)arg, &awe_info, sizeof(awe_info));
2053 return 0;
2054 break;
2055
2056 case SNDCTL_SEQ_RESETSAMPLES:
2057 awe_reset(dev);
2058 awe_reset_samples();
2059 return 0;
2060 break;
2061
2062 case SNDCTL_SEQ_PERCMODE:
2063 /* what's this? */
2064 return 0;
2065 break;
2066
2067 case SNDCTL_SYNTH_MEMAVL:
2068 return memsize - awe_free_mem_ptr() * 2;
2069
2070 default:
2071 printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd);
2072 return -EINVAL;
2073 }
2074 }
2075
2076
2077 static int voice_in_range(int voice)
2078 {
2079 if (playing_mode == AWE_PLAY_DIRECT) {
2080 if (voice < 0 || voice >= awe_max_voices)
2081 return FALSE;
2082 } else {
2083 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2084 return FALSE;
2085 }
2086 return TRUE;
2087 }
2088
2089 static void release_voice(int voice, int do_sustain)
2090 {
2091 if (IS_NO_SOUND(voice))
2092 return;
2093 if (do_sustain && (voices[voice].cinfo->sustained == 127 ||
2094 voices[voice].sostenuto == 127))
2095 voices[voice].state = AWE_ST_SUSTAINED;
2096 else {
2097 awe_note_off(voice);
2098 awe_fx_init(voices[voice].ch);
2099 awe_voice_init(voice, FALSE);
2100 }
2101 }
2102
2103 /* release all notes */
2104 static void awe_note_off_all(int do_sustain)
2105 {
2106 int i;
2107 for (i = 0; i < awe_max_voices; i++)
2108 release_voice(i, do_sustain);
2109 }
2110
2111 /* kill a voice:
2112 * not terminate, just release the voice.
2113 */
2114 static int
2115 awe_kill_note(int dev, int voice, int note, int velocity)
2116 {
2117 int i, v2, key;
2118
2119 DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));
2120 if (! voice_in_range(voice))
2121 return -EINVAL;
2122
2123 switch (playing_mode) {
2124 case AWE_PLAY_DIRECT:
2125 case AWE_PLAY_INDIRECT:
2126 key = AWE_VOICE_KEY(voice);
2127 break;
2128
2129 case AWE_PLAY_MULTI2:
2130 v2 = voice_alloc->map[voice] >> 8;
2131 voice_alloc->map[voice] = 0;
2132 voice = v2;
2133 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2134 return -EINVAL;
2135 /* continue to below */
2136 default:
2137 key = AWE_CHAN_KEY(voice, note);
2138 break;
2139 }
2140
2141 for (i = 0; i < awe_max_voices; i++) {
2142 if (voices[i].key == key)
2143 release_voice(i, TRUE);
2144 }
2145 return 0;
2146 }
2147
2148
2149 static void start_or_volume_change(int voice, int velocity)
2150 {
2151 voices[voice].velocity = velocity;
2152 awe_calc_volume(voice);
2153 if (voices[voice].state == AWE_ST_STANDBY)
2154 awe_note_on(voice);
2155 else if (voices[voice].state == AWE_ST_ON)
2156 awe_set_volume(voice, FALSE);
2157 }
2158
2159 static void set_and_start_voice(int voice, int state)
2160 {
2161 /* calculate pitch & volume parameters */
2162 voices[voice].state = state;
2163 awe_calc_pitch(voice);
2164 awe_calc_volume(voice);
2165 if (state == AWE_ST_ON)
2166 awe_note_on(voice);
2167 }
2168
2169 /* start a voice:
2170 * if note is 255, identical with aftertouch function.
2171 * Otherwise, start a voice with specified not and volume.
2172 */
2173 static int
2174 awe_start_note(int dev, int voice, int note, int velocity)
2175 {
2176 int i, key, state, volonly;
2177
2178 DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));
2179 if (! voice_in_range(voice))
2180 return -EINVAL;
2181
2182 if (velocity == 0)
2183 state = AWE_ST_STANDBY; /* stand by for playing */
2184 else
2185 state = AWE_ST_ON; /* really play */
2186 volonly = FALSE;
2187
2188 switch (playing_mode) {
2189 case AWE_PLAY_DIRECT:
2190 case AWE_PLAY_INDIRECT:
2191 key = AWE_VOICE_KEY(voice);
2192 if (note == 255)
2193 volonly = TRUE;
2194 break;
2195
2196 case AWE_PLAY_MULTI2:
2197 voice = voice_alloc->map[voice] >> 8;
2198 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2199 return -EINVAL;
2200 /* continue to below */
2201 default:
2202 if (note >= 128) { /* key volume mode */
2203 note -= 128;
2204 volonly = TRUE;
2205 }
2206 key = AWE_CHAN_KEY(voice, note);
2207 break;
2208 }
2209
2210 /* dynamic volume change */
2211 if (volonly) {
2212 for (i = 0; i < awe_max_voices; i++) {
2213 if (voices[i].key == key)
2214 start_or_volume_change(i, velocity);
2215 }
2216 return 0;
2217 }
2218
2219 /* if the same note still playing, stop it */
2220 if (playing_mode != AWE_PLAY_DIRECT || ctrls[AWE_MD_EXCLUSIVE_SOUND]) {
2221 for (i = 0; i < awe_max_voices; i++)
2222 if (voices[i].key == key) {
2223 if (voices[i].state == AWE_ST_ON) {
2224 awe_note_off(i);
2225 awe_voice_init(i, FALSE);
2226 } else if (voices[i].state == AWE_ST_STANDBY)
2227 awe_voice_init(i, TRUE);
2228 }
2229 }
2230
2231 /* allocate voices */
2232 if (playing_mode == AWE_PLAY_DIRECT)
2233 awe_alloc_one_voice(voice, note, velocity);
2234 else
2235 awe_alloc_multi_voices(voice, note, velocity, key);
2236
2237 /* turn off other voices exlusively (for drums) */
2238 for (i = 0; i < awe_max_voices; i++)
2239 if (voices[i].key == key)
2240 awe_exclusive_off(i);
2241
2242 /* set up pitch and volume parameters */
2243 for (i = 0; i < awe_max_voices; i++) {
2244 if (voices[i].key == key && voices[i].state == AWE_ST_OFF)
2245 set_and_start_voice(i, state);
2246 }
2247
2248 return 0;
2249 }
2250
2251
2252 /* calculate hash key */
2253 static int
2254 awe_search_key(int bank, int preset, int note)
2255 {
2256 unsigned int key;
2257
2258 #if 1 /* new hash table */
2259 if (bank == AWE_DRUM_BANK)
2260 key = preset + note + 128;
2261 else
2262 key = bank + preset;
2263 #else
2264 key = preset;
2265 #endif
2266 key %= AWE_MAX_PRESETS;
2267
2268 return (int)key;
2269 }
2270
2271
2272 /* search instrument from hash table */
2273 static awe_voice_list *
2274 awe_search_instr(int bank, int preset, int note)
2275 {
2276 awe_voice_list *p;
2277 int key, key2;
2278
2279 key = awe_search_key(bank, preset, note);
2280 for (p = preset_table[key]; p; p = p->next_bank) {
2281 if (p->instr == preset && p->bank == bank)
2282 return p;
2283 }
2284 key2 = awe_search_key(bank, preset, 0); /* search default */
2285 if (key == key2)
2286 return NULL;
2287 for (p = preset_table[key2]; p; p = p->next_bank) {
2288 if (p->instr == preset && p->bank == bank)
2289 return p;
2290 }
2291 return NULL;
2292 }
2293
2294
2295 /* assign the instrument to a voice */
2296 static int
2297 awe_set_instr_2(int dev, int voice, int instr_no)
2298 {
2299 if (playing_mode == AWE_PLAY_MULTI2) {
2300 voice = voice_alloc->map[voice] >> 8;
2301 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2302 return -EINVAL;
2303 }
2304 return awe_set_instr(dev, voice, instr_no);
2305 }
2306
2307 /* assign the instrument to a channel; voice is the channel number */
2308 static int
2309 awe_set_instr(int dev, int voice, int instr_no)
2310 {
2311 awe_chan_info *cinfo;
2312
2313 if (! voice_in_range(voice))
2314 return -EINVAL;
2315
2316 if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)
2317 return -EINVAL;
2318
2319 cinfo = &channels[voice];
2320 cinfo->instr = instr_no;
2321 DEBUG(2,printk("AWE32: [program(%d) %d]\n", voice, instr_no));
2322
2323 return 0;
2324 }
2325
2326
2327 /* reset all voices; terminate sounds and initialize parameters */
2328 static void
2329 awe_reset(int dev)
2330 {
2331 int i;
2332 current_alloc_time = 0;
2333 /* don't turn off voice 31 and 32. they are used also for FM voices */
2334 for (i = 0; i < awe_max_voices; i++) {
2335 awe_terminate(i);
2336 awe_voice_init(i, TRUE);
2337 }
2338 for (i = 0; i < AWE_MAX_CHANNELS; i++)
2339 awe_channel_init(i, TRUE);
2340 for (i = 0; i < 16; i++) {
2341 awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127;
2342 awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127;
2343 }
2344 awe_init_fm();
2345 awe_tweak();
2346 }
2347
2348
2349 /* hardware specific control:
2350 * GUS specific and AWE32 specific controls are available.
2351 */
2352 static void
2353 awe_hw_control(int dev, unsigned char *event)
2354 {
2355 int cmd = event[2];
2356 if (cmd & _AWE_MODE_FLAG)
2357 awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2358 #ifdef AWE_HAS_GUS_COMPATIBILITY
2359 else
2360 awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2361 #endif
2362 }
2363
2364
2365 #ifdef AWE_HAS_GUS_COMPATIBILITY
2366
2367 /* GUS compatible controls */
2368 static void
2369 awe_hw_gus_control(int dev, int cmd, unsigned char *event)
2370 {
2371 int voice, i, key;
2372 unsigned short p1;
2373 short p2;
2374 int plong;
2375
2376 if (MULTI_LAYER_MODE())
2377 return;
2378 if (cmd == _GUS_NUMVOICES)
2379 return;
2380
2381 voice = event[3];
2382 if (! voice_in_range(voice))
2383 return;
2384
2385 p1 = *(unsigned short *) &event[4];
2386 p2 = *(short *) &event[6];
2387 plong = *(int*) &event[4];
2388
2389 switch (cmd) {
2390 case _GUS_VOICESAMPLE:
2391 awe_set_instr(dev, voice, p1);
2392 return;
2393
2394 case _GUS_VOICEBALA:
2395 /* 0 to 15 --> -128 to 127 */
2396 awe_panning(dev, voice, ((int)p1 << 4) - 128);
2397 return;
2398
2399 case _GUS_VOICEVOL:
2400 case _GUS_VOICEVOL2:
2401 /* not supported yet */
2402 return;
2403
2404 case _GUS_RAMPRANGE:
2405 case _GUS_RAMPRATE:
2406 case _GUS_RAMPMODE:
2407 case _GUS_RAMPON:
2408 case _GUS_RAMPOFF:
2409 /* volume ramping not supported */
2410 return;
2411
2412 case _GUS_VOLUME_SCALE:
2413 return;
2414
2415 case _GUS_VOICE_POS:
2416 FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START,
2417 (short)(plong & 0x7fff));
2418 FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START,
2419 (plong >> 15) & 0xffff);
2420 return;
2421 }
2422
2423 key = AWE_VOICE_KEY(voice);
2424 for (i = 0; i < awe_max_voices; i++) {
2425 if (voices[i].key == key) {
2426 switch (cmd) {
2427 case _GUS_VOICEON:
2428 awe_note_on(i);
2429 break;
2430
2431 case _GUS_VOICEOFF:
2432 awe_terminate(i);
2433 awe_fx_init(voices[i].ch);
2434 awe_voice_init(i, TRUE);
2435 break;
2436
2437 case _GUS_VOICEFADE:
2438 awe_note_off(i);
2439 awe_fx_init(voices[i].ch);
2440 awe_voice_init(i, FALSE);
2441 break;
2442
2443 case _GUS_VOICEFREQ:
2444 awe_calc_pitch_from_freq(i, plong);
2445 break;
2446 }
2447 }
2448 }
2449 }
2450
2451 #endif /* gus_compat */
2452
2453
2454 /* AWE32 specific controls */
2455 static void
2456 awe_hw_awe_control(int dev, int cmd, unsigned char *event)
2457 {
2458 int voice;
2459 unsigned short p1;
2460 short p2;
2461 int i;
2462
2463 voice = event[3];
2464 if (! voice_in_range(voice))
2465 return;
2466
2467 if (playing_mode == AWE_PLAY_MULTI2) {
2468 voice = voice_alloc->map[voice] >> 8;
2469 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2470 return;
2471 }
2472
2473 p1 = *(unsigned short *) &event[4];
2474 p2 = *(short *) &event[6];
2475
2476 switch (cmd) {
2477 case _AWE_DEBUG_MODE:
2478 ctrls[AWE_MD_DEBUG_MODE] = p1;
2479 printk(KERN_DEBUG "AWE32: debug mode = %d\n", ctrls[AWE_MD_DEBUG_MODE]);
2480 break;
2481 case _AWE_REVERB_MODE:
2482 ctrls[AWE_MD_REVERB_MODE] = p1;
2483 awe_update_reverb_mode();
2484 break;
2485
2486 case _AWE_CHORUS_MODE:
2487 ctrls[AWE_MD_CHORUS_MODE] = p1;
2488 awe_update_chorus_mode();
2489 break;
2490
2491 case _AWE_REMOVE_LAST_SAMPLES:
2492 DEBUG(0,printk("AWE32: remove last samples\n"));
2493 awe_reset(0);
2494 if (locked_sf_id > 0)
2495 awe_remove_samples(locked_sf_id);
2496 break;
2497
2498 case _AWE_INITIALIZE_CHIP:
2499 awe_initialize();
2500 break;
2501
2502 case _AWE_SEND_EFFECT:
2503 i = -1;
2504 if (p1 >= 0x100) {
2505 i = (p1 >> 8);
2506 if (i < 0 || i >= MAX_LAYERS)
2507 break;
2508 }
2509 awe_send_effect(voice, i, p1, p2);
2510 break;
2511
2512 case _AWE_RESET_CHANNEL:
2513 awe_channel_init(voice, !p1);
2514 break;
2515
2516 case _AWE_TERMINATE_ALL:
2517 awe_reset(0);
2518 break;
2519
2520 case _AWE_TERMINATE_CHANNEL:
2521 awe_voice_change(voice, awe_terminate_and_init);
2522 break;
2523
2524 case _AWE_RELEASE_ALL:
2525 awe_note_off_all(FALSE);
2526 break;
2527 case _AWE_NOTEOFF_ALL:
2528 awe_note_off_all(TRUE);
2529 break;
2530
2531 case _AWE_INITIAL_VOLUME:
2532 DEBUG(0,printk("AWE32: init attenuation %d\n", p1));
2533 atten_relative = (char)p2;
2534 atten_offset = (short)p1;
2535 awe_update_volume();
2536 break;
2537
2538 case _AWE_CHN_PRESSURE:
2539 channels[voice].chan_press = p1;
2540 awe_modwheel_change(voice, p1);
2541 break;
2542
2543 case _AWE_CHANNEL_MODE:
2544 DEBUG(0,printk("AWE32: channel mode = %d\n", p1));
2545 playing_mode = p1;
2546 awe_reset(0);
2547 break;
2548
2549 case _AWE_DRUM_CHANNELS:
2550 DEBUG(0,printk("AWE32: drum flags = %x\n", p1));
2551 drum_flags = *(unsigned int*)&event[4];
2552 break;
2553
2554 case _AWE_MISC_MODE:
2555 DEBUG(0,printk("AWE32: ctrl parms = %d %d\n", p1, p2));
2556 if (p1 > AWE_MD_VERSION && p1 < AWE_MD_END) {
2557 ctrls[p1] = p2;
2558 if (ctrl_parms[p1].update)
2559 ctrl_parms[p1].update();
2560 }
2561 break;
2562
2563 case _AWE_EQUALIZER:
2564 ctrls[AWE_MD_BASS_LEVEL] = p1;
2565 ctrls[AWE_MD_TREBLE_LEVEL] = p2;
2566 awe_update_equalizer();
2567 break;
2568
2569 default:
2570 DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice));
2571 break;
2572 }
2573 }
2574
2575
2576 /* change effects */
2577 static void
2578 awe_send_effect(int voice, int layer, int type, int val)
2579 {
2580 awe_chan_info *cinfo;
2581 FX_Rec *fx;
2582 int mode;
2583
2584 cinfo = &channels[voice];
2585 if (layer >= 0 && layer < MAX_LAYERS)
2586 fx = &cinfo->fx_layer[layer];
2587 else
2588 fx = &cinfo->fx;
2589
2590 if (type & 0x40)
2591 mode = FX_FLAG_OFF;
2592 else if (type & 0x80)
2593 mode = FX_FLAG_ADD;
2594 else
2595 mode = FX_FLAG_SET;
2596 type &= 0x3f;
2597
2598 if (type >= 0 && type < AWE_FX_END) {
2599 DEBUG(2,printk("AWE32: effects (%d) %d %d\n", voice, type, val));
2600 if (mode == FX_FLAG_SET)
2601 FX_SET(fx, type, val);
2602 else if (mode == FX_FLAG_ADD)
2603 FX_ADD(fx, type, val);
2604 else
2605 FX_UNSET(fx, type);
2606 if (mode != FX_FLAG_OFF && parm_defs[type].realtime) {
2607 DEBUG(2,printk("AWE32: fx_realtime (%d)\n", voice));
2608 awe_voice_change(voice, parm_defs[type].realtime);
2609 }
2610 }
2611 }
2612
2613
2614 /* change modulation wheel; voice is already mapped on multi2 mode */
2615 static void
2616 awe_modwheel_change(int voice, int value)
2617 {
2618 int i;
2619 awe_chan_info *cinfo;
2620
2621 cinfo = &channels[voice];
2622 i = value * ctrls[AWE_MD_MOD_SENSE] / 1200;
2623 FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, i);
2624 awe_voice_change(voice, awe_fx_fmmod);
2625 FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, i);
2626 awe_voice_change(voice, awe_fx_fm2frq2);
2627 }
2628
2629
2630 /* voice pressure change */
2631 static void
2632 awe_aftertouch(int dev, int voice, int pressure)
2633 {
2634 int note;
2635
2636 DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure));
2637 if (! voice_in_range(voice))
2638 return;
2639
2640 switch (playing_mode) {
2641 case AWE_PLAY_DIRECT:
2642 case AWE_PLAY_INDIRECT:
2643 awe_start_note(dev, voice, 255, pressure);
2644 break;
2645 case AWE_PLAY_MULTI2:
2646 note = (voice_alloc->map[voice] & 0xff) - 1;
2647 awe_key_pressure(dev, voice, note + 0x80, pressure);
2648 break;
2649 }
2650 }
2651
2652
2653 /* voice control change */
2654 static void
2655 awe_controller(int dev, int voice, int ctrl_num, int value)
2656 {
2657 awe_chan_info *cinfo;
2658
2659 if (! voice_in_range(voice))
2660 return;
2661
2662 if (playing_mode == AWE_PLAY_MULTI2) {
2663 voice = voice_alloc->map[voice] >> 8;
2664 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2665 return;
2666 }
2667
2668 cinfo = &channels[voice];
2669
2670 switch (ctrl_num) {
2671 case CTL_BANK_SELECT: /* MIDI control #0 */
2672 DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value));
2673 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice) &&
2674 !ctrls[AWE_MD_TOGGLE_DRUM_BANK])
2675 break;
2676 if (value < 0 || value > 255)
2677 break;
2678 cinfo->bank = value;
2679 if (cinfo->bank == AWE_DRUM_BANK)
2680 DRUM_CHANNEL_ON(cinfo->channel);
2681 else
2682 DRUM_CHANNEL_OFF(cinfo->channel);
2683 awe_set_instr(dev, voice, cinfo->instr);
2684 break;
2685
2686 case CTL_MODWHEEL: /* MIDI control #1 */
2687 DEBUG(2,printk("AWE32: [modwheel(%d) %d]\n", voice, value));
2688 awe_modwheel_change(voice, value);
2689 break;
2690
2691 case CTRL_PITCH_BENDER: /* SEQ1 V2 contorl */
2692 DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value));
2693 /* zero centered */
2694 cinfo->bender = value;
2695 awe_voice_change(voice, awe_set_voice_pitch);
2696 break;
2697
2698 case CTRL_PITCH_BENDER_RANGE: /* SEQ1 V2 control */
2699 DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value));
2700 /* value = sense x 100 */
2701 cinfo->bender_range = value;
2702 /* no audible pitch change yet.. */
2703 break;
2704
2705 case CTL_EXPRESSION: /* MIDI control #11 */
2706 if (SINGLE_LAYER_MODE())
2707 value /= 128;
2708 case CTRL_EXPRESSION: /* SEQ1 V2 control */
2709 DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value));
2710 /* 0 - 127 */
2711 cinfo->expression_vol = value;
2712 awe_voice_change(voice, awe_set_voice_vol);
2713 break;
2714
2715 case CTL_PAN: /* MIDI control #10 */
2716 DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value));
2717 /* (0-127) -> signed 8bit */
2718 cinfo->panning = value * 2 - 128;
2719 if (ctrls[AWE_MD_REALTIME_PAN])
2720 awe_voice_change(voice, awe_set_pan);
2721 break;
2722
2723 case CTL_MAIN_VOLUME: /* MIDI control #7 */
2724 if (SINGLE_LAYER_MODE())
2725 value = (value * 100) / 16383;
2726 case CTRL_MAIN_VOLUME: /* SEQ1 V2 control */
2727 DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value));
2728 /* 0 - 127 */
2729 cinfo->main_vol = value;
2730 awe_voice_change(voice, awe_set_voice_vol);
2731 break;
2732
2733 case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */
2734 DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value));
2735 FX_SET(&cinfo->fx, AWE_FX_REVERB, value * 2);
2736 break;
2737
2738 case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */
2739 DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value));
2740 FX_SET(&cinfo->fx, AWE_FX_CHORUS, value * 2);
2741 break;
2742
2743 case 120: /* all sounds off */
2744 awe_note_off_all(FALSE);
2745 break;
2746 case 123: /* all notes off */
2747 awe_note_off_all(TRUE);
2748 break;
2749
2750 case CTL_SUSTAIN: /* MIDI control #64 */
2751 cinfo->sustained = value;
2752 if (value != 127)
2753 awe_voice_change(voice, awe_sustain_off);
2754 break;
2755
2756 case CTL_SOSTENUTO: /* MIDI control #66 */
2757 if (value == 127)
2758 awe_voice_change(voice, awe_sostenuto_on);
2759 else
2760 awe_voice_change(voice, awe_sustain_off);
2761 break;
2762
2763 default:
2764 DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n",
2765 voice, ctrl_num, value));
2766 break;
2767 }
2768 }
2769
2770
2771 /* voice pan change (value = -128 - 127) */
2772 static void
2773 awe_panning(int dev, int voice, int value)
2774 {
2775 awe_chan_info *cinfo;
2776
2777 if (! voice_in_range(voice))
2778 return;
2779
2780 if (playing_mode == AWE_PLAY_MULTI2) {
2781 voice = voice_alloc->map[voice] >> 8;
2782 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2783 return;
2784 }
2785
2786 cinfo = &channels[voice];
2787 cinfo->panning = value;
2788 DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, cinfo->panning));
2789 if (ctrls[AWE_MD_REALTIME_PAN])
2790 awe_voice_change(voice, awe_set_pan);
2791 }
2792
2793
2794 /* volume mode change */
2795 static void
2796 awe_volume_method(int dev, int mode)
2797 {
2798 /* not impremented */
2799 DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode));
2800 }
2801
2802
2803 /* pitch wheel change: 0-16384 */
2804 static void
2805 awe_bender(int dev, int voice, int value)
2806 {
2807 awe_chan_info *cinfo;
2808
2809 if (! voice_in_range(voice))
2810 return;
2811
2812 if (playing_mode == AWE_PLAY_MULTI2) {
2813 voice = voice_alloc->map[voice] >> 8;
2814 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2815 return;
2816 }
2817
2818 /* convert to zero centered value */
2819 cinfo = &channels[voice];
2820 cinfo->bender = value - 8192;
2821 DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, cinfo->bender));
2822 awe_voice_change(voice, awe_set_voice_pitch);
2823 }
2824
2825
2826 /*
2827 * load a sound patch:
2828 * three types of patches are accepted: AWE, GUS, and SYSEX.
2829 */
2830
2831 static int
2832 awe_load_patch(int dev, int format, const char *addr,
2833 int offs, int count, int pmgr_flag)
2834 {
2835 awe_patch_info patch;
2836 int rc = 0;
2837
2838 #ifdef AWE_HAS_GUS_COMPATIBILITY
2839 if (format == GUS_PATCH) {
2840 return awe_load_guspatch(addr, offs, count, pmgr_flag);
2841 } else
2842 #endif
2843 if (format == SYSEX_PATCH) {
2844 /* no system exclusive message supported yet */
2845 return 0;
2846 } else if (format != AWE_PATCH) {
2847 printk(KERN_WARNING "AWE32 Error: Invalid patch format (key) 0x%x\n", format);
2848 return -EINVAL;
2849 }
2850
2851 if (count < AWE_PATCH_INFO_SIZE) {
2852 printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
2853 return -EINVAL;
2854 }
2855 if (copy_from_user(((char*)&patch) + offs, addr + offs,
2856 AWE_PATCH_INFO_SIZE - offs))
2857 return -EFAULT;
2858
2859 count -= AWE_PATCH_INFO_SIZE;
2860 if (count < patch.len) {
2861 printk(KERN_WARNING "AWE32: sample: Patch record too short (%d<%d)\n",
2862 count, patch.len);
2863 return -EINVAL;
2864 }
2865
2866 switch (patch.type) {
2867 case AWE_LOAD_INFO:
2868 rc = awe_load_info(&patch, addr, count);
2869 break;
2870 case AWE_LOAD_DATA:
2871 rc = awe_load_data(&patch, addr, count);
2872 break;
2873 case AWE_OPEN_PATCH:
2874 rc = awe_open_patch(&patch, addr, count);
2875 break;
2876 case AWE_CLOSE_PATCH:
2877 rc = awe_close_patch(&patch, addr, count);
2878 break;
2879 case AWE_UNLOAD_PATCH:
2880 rc = awe_unload_patch(&patch, addr, count);
2881 break;
2882 case AWE_REPLACE_DATA:
2883 rc = awe_replace_data(&patch, addr, count);
2884 break;
2885 case AWE_MAP_PRESET:
2886 rc = awe_load_map(&patch, addr, count);
2887 break;
2888 /* case AWE_PROBE_INFO:
2889 rc = awe_probe_info(&patch, addr, count);
2890 break;*/
2891 case AWE_PROBE_DATA:
2892 rc = awe_probe_data(&patch, addr, count);
2893 break;
2894 case AWE_REMOVE_INFO:
2895 rc = awe_remove_info(&patch, addr, count);
2896 break;
2897 case AWE_LOAD_CHORUS_FX:
2898 rc = awe_load_chorus_fx(&patch, addr, count);
2899 break;
2900 case AWE_LOAD_REVERB_FX:
2901 rc = awe_load_reverb_fx(&patch, addr, count);
2902 break;
2903
2904 default:
2905 printk(KERN_WARNING "AWE32 Error: unknown patch format type %d\n",
2906 patch.type);
2907 rc = -EINVAL;
2908 }
2909
2910 return rc;
2911 }
2912
2913
2914 /* create an sf list record */
2915 static int
2916 awe_create_sf(int type, char *name)
2917 {
2918 sf_list *rec;
2919
2920 /* terminate sounds */
2921 awe_reset(0);
2922 rec = (sf_list *)kmalloc(sizeof(*rec), GFP_KERNEL);
2923 if (rec == NULL)
2924 return 1; /* no memory */
2925 rec->sf_id = current_sf_id + 1;
2926 rec->type = type;
2927 if (/*current_sf_id == 0 ||*/ (type & AWE_PAT_LOCKED) != 0)
2928 locked_sf_id = current_sf_id + 1;
2929 rec->num_info = awe_free_info();
2930 rec->num_sample = awe_free_sample();
2931 rec->mem_ptr = awe_free_mem_ptr();
2932 rec->infos = rec->last_infos = NULL;
2933 rec->samples = rec->last_samples = NULL;
2934
2935 /* add to linked-list */
2936 rec->next = NULL;
2937 rec->prev = sftail;
2938 if (sftail)
2939 sftail->next = rec;
2940 else
2941 sfhead = rec;
2942 sftail = rec;
2943 current_sf_id++;
2944
2945 #ifdef AWE_ALLOW_SAMPLE_SHARING
2946 rec->shared = NULL;
2947 if (name)
2948 memcpy(rec->name, name, AWE_PATCH_NAME_LEN);
2949 else
2950 strcpy(rec->name, "*TEMPORARY*");
2951 if (current_sf_id > 1 && name && (type & AWE_PAT_SHARED) != 0) {
2952 /* is the current font really a shared font? */
2953 if (is_shared_sf(rec->name)) {
2954 /* check if the shared font is already installed */
2955 sf_list *p;
2956 for (p = rec->prev; p; p = p->prev) {
2957 if (is_identical_name(rec->name, p)) {
2958 rec->shared = p;
2959 break;
2960 }
2961 }
2962 }
2963 }
2964 #endif /* allow sharing */
2965
2966 return 0;
2967 }
2968
2969
2970 #ifdef AWE_ALLOW_SAMPLE_SHARING
2971
2972 /* check if the given name is a valid shared name */
2973 #define ASC_TO_KEY(c) ((c) - 'A' + 1)
2974 static int is_shared_sf(unsigned char *name)
2975 {
2976 static unsigned char id_head[4] = {
2977 ASC_TO_KEY('A'), ASC_TO_KEY('W'), ASC_TO_KEY('E'),
2978 AWE_MAJOR_VERSION,
2979 };
2980 if (memcmp(name, id_head, 4) == 0)
2981 return TRUE;
2982 return FALSE;
2983 }
2984
2985 /* check if the given name matches to the existing list */
2986 static int is_identical_name(unsigned char *name, sf_list *p)
2987 {
2988 char *id = p->name;
2989 if (is_shared_sf(id) && memcmp(id, name, AWE_PATCH_NAME_LEN) == 0)
2990 return TRUE;
2991 return FALSE;
2992 }
2993
2994 /* check if the given voice info exists */
2995 static int info_duplicated(sf_list *sf, awe_voice_list *rec)
2996 {
2997 /* search for all sharing lists */
2998 for (; sf; sf = sf->shared) {
2999 awe_voice_list *p;
3000 for (p = sf->infos; p; p = p->next) {
3001 if (p->type == V_ST_NORMAL &&
3002 p->bank == rec->bank &&
3003 p->instr == rec->instr &&
3004 p->v.low == rec->v.low &&
3005 p->v.high == rec->v.high &&
3006 p->v.sample == rec->v.sample)
3007 return TRUE;
3008 }
3009 }
3010 return FALSE;
3011 }
3012
3013 #endif /* AWE_ALLOW_SAMPLE_SHARING */
3014
3015
3016 /* free sf_list record */
3017 /* linked-list in this function is not cared */
3018 static void
3019 awe_free_sf(sf_list *sf)
3020 {
3021 if (sf->infos) {
3022 awe_voice_list *p, *next;
3023 for (p = sf->infos; p; p = next) {
3024 next = p->next;
3025 kfree(p);
3026 }
3027 }
3028 if (sf->samples) {
3029 awe_sample_list *p, *next;
3030 for (p = sf->samples; p; p = next) {
3031 next = p->next;
3032 kfree(p);
3033 }
3034 }
3035 kfree(sf);
3036 }
3037
3038
3039 /* open patch; create sf list and set opened flag */
3040 static int
3041 awe_open_patch(awe_patch_info *patch, const char *addr, int count)
3042 {
3043 awe_open_parm parm;
3044 int shared;
3045
3046 if (copy_from_user(&parm, addr + AWE_PATCH_INFO_SIZE, sizeof(parm)))
3047 return -EFAULT;
3048 shared = FALSE;
3049
3050 #ifdef AWE_ALLOW_SAMPLE_SHARING
3051 if (sftail && (parm.type & AWE_PAT_SHARED) != 0) {
3052 /* is the previous font the same font? */
3053 if (is_identical_name(parm.name, sftail)) {
3054 /* then append to the previous */
3055 shared = TRUE;
3056 awe_reset(0);
3057 if (parm.type & AWE_PAT_LOCKED)
3058 locked_sf_id = current_sf_id;
3059 }
3060 }
3061 #endif /* allow sharing */
3062 if (! shared) {
3063 if (awe_create_sf(parm.type, parm.name)) {
3064 printk(KERN_ERR "AWE32: can't open: failed to alloc new list\n");
3065 return -ENOMEM;
3066 }
3067 }
3068 patch_opened = TRUE;
3069 return current_sf_id;
3070 }
3071
3072 /* check if the patch is already opened */
3073 static sf_list *
3074 check_patch_opened(int type, char *name)
3075 {
3076 if (! patch_opened) {
3077 if (awe_create_sf(type, name)) {
3078 printk(KERN_ERR "AWE32: failed to alloc new list\n");
3079 return NULL;
3080 }
3081 patch_opened = TRUE;
3082 return sftail;
3083 }
3084 return sftail;
3085 }
3086
3087 /* close the patch; if no voice is loaded, remove the patch */
3088 static int
3089 awe_close_patch(awe_patch_info *patch, const char *addr, int count)
3090 {
3091 if (patch_opened && sftail) {
3092 /* if no voice is loaded, release the current patch */
3093 if (sftail->infos == NULL) {
3094 awe_reset(0);
3095 awe_remove_samples(current_sf_id - 1);
3096 }
3097 }
3098 patch_opened = 0;
3099 return 0;
3100 }
3101
3102
3103 /* remove the latest patch */
3104 static int
3105 awe_unload_patch(awe_patch_info *patch, const char *addr, int count)
3106 {
3107 if (current_sf_id > 0 && current_sf_id > locked_sf_id) {
3108 awe_reset(0);
3109 awe_remove_samples(current_sf_id - 1);
3110 }
3111 return 0;
3112 }
3113
3114 /* allocate voice info list records */
3115 static awe_voice_list *
3116 alloc_new_info(void)
3117 {
3118 awe_voice_list *newlist;
3119
3120 newlist = (awe_voice_list *)kmalloc(sizeof(*newlist), GFP_KERNEL);
3121 if (newlist == NULL) {
3122 printk(KERN_ERR "AWE32: can't alloc info table\n");
3123 return NULL;
3124 }
3125 return newlist;
3126 }
3127
3128 /* allocate sample info list records */
3129 static awe_sample_list *
3130 alloc_new_sample(void)
3131 {
3132 awe_sample_list *newlist;
3133
3134 newlist = (awe_sample_list *)kmalloc(sizeof(*newlist), GFP_KERNEL);
3135 if (newlist == NULL) {
3136 printk(KERN_ERR "AWE32: can't alloc sample table\n");
3137 return NULL;
3138 }
3139 return newlist;
3140 }
3141
3142 /* load voice map */
3143 static int
3144 awe_load_map(awe_patch_info *patch, const char *addr, int count)
3145 {
3146 awe_voice_map map;
3147 awe_voice_list *rec, *p;
3148 sf_list *sf;
3149
3150 /* get the link info */
3151 if (count < sizeof(map)) {
3152 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3153 return -EINVAL;
3154 }
3155 if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
3156 return -EFAULT;
3157
3158 /* check if the identical mapping already exists */
3159 p = awe_search_instr(map.map_bank, map.map_instr, map.map_key);
3160 for (; p; p = p->next_instr) {
3161 if (p->type == V_ST_MAPPED &&
3162 p->v.start == map.src_instr &&
3163 p->v.end == map.src_bank &&
3164 p->v.fixkey == map.src_key)
3165 return 0; /* already present! */
3166 }
3167
3168 if ((sf = check_patch_opened(AWE_PAT_TYPE_MAP, NULL)) == NULL)
3169 return -ENOMEM;
3170
3171 if ((rec = alloc_new_info()) == NULL)
3172 return -ENOMEM;
3173
3174 rec->bank = map.map_bank;
3175 rec->instr = map.map_instr;
3176 rec->type = V_ST_MAPPED;
3177 rec->disabled = FALSE;
3178 awe_init_voice_info(&rec->v);
3179 if (map.map_key >= 0) {
3180 rec->v.low = map.map_key;
3181 rec->v.high = map.map_key;
3182 }
3183 rec->v.start = map.src_instr;
3184 rec->v.end = map.src_bank;
3185 rec->v.fixkey = map.src_key;
3186 add_sf_info(sf, rec);
3187 add_info_list(rec);
3188
3189 return 0;
3190 }
3191
3192 #if 0
3193 /* probe preset in the current list -- nothing to be loaded */
3194 static int
3195 awe_probe_info(awe_patch_info *patch, const char *addr, int count)
3196 {
3197 #ifdef AWE_ALLOW_SAMPLE_SHARING
3198 awe_voice_map map;
3199 awe_voice_list *p;
3200
3201 if (! patch_opened)
3202 return -EINVAL;
3203
3204 /* get the link info */
3205 if (count < sizeof(map)) {
3206 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3207 return -EINVAL;
3208 }
3209 if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
3210 return -EFAULT;
3211
3212 /* check if the identical mapping already exists */
3213 if (sftail == NULL)
3214 return -EINVAL;
3215 p = awe_search_instr(map.src_bank, map.src_instr, map.src_key);
3216 for (; p; p = p->next_instr) {
3217 if (p->type == V_ST_NORMAL &&
3218 is_identical_holder(p->holder, sftail) &&
3219 p->v.low <= map.src_key &&
3220 p->v.high >= map.src_key)
3221 return 0; /* already present! */
3222 }
3223 #endif /* allow sharing */
3224 return -EINVAL;
3225 }
3226 #endif
3227
3228 /* probe sample in the current list -- nothing to be loaded */
3229 static int
3230 awe_probe_data(awe_patch_info *patch, const char *addr, int count)
3231 {
3232 #ifdef AWE_ALLOW_SAMPLE_SHARING
3233 if (! patch_opened)
3234 return -EINVAL;
3235
3236 /* search the specified sample by optarg */
3237 if (search_sample_index(sftail, patch->optarg) != NULL)
3238 return 0;
3239 #endif /* allow sharing */
3240 return -EINVAL;
3241 }
3242
3243
3244 /* remove the present instrument layers */
3245 static int
3246 remove_info(sf_list *sf, int bank, int instr)
3247 {
3248 awe_voice_list *prev, *next, *p;
3249 int removed = 0;
3250
3251 prev = NULL;
3252 for (p = sf->infos; p; p = next) {
3253 next = p->next;
3254 if (p->type == V_ST_NORMAL &&
3255 p->bank == bank && p->instr == instr) {
3256 /* remove this layer */
3257 if (prev)
3258 prev->next = next;
3259 else
3260 sf->infos = next;
3261 if (p == sf->last_infos)
3262 sf->last_infos = prev;
3263 sf->num_info--;
3264 removed++;
3265 kfree(p);
3266 } else
3267 prev = p;
3268 }
3269 if (removed)
3270 rebuild_preset_list();
3271 return removed;
3272 }
3273
3274 /* load voice information data */
3275 static int
3276 awe_load_info(awe_patch_info *patch, const char *addr, int count)
3277 {
3278 int offset;
3279 awe_voice_rec_hdr hdr;
3280 int i;
3281 int total_size;
3282 sf_list *sf;
3283 awe_voice_list *rec;
3284
3285 if (count < AWE_VOICE_REC_SIZE) {
3286 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3287 return -EINVAL;
3288 }
3289
3290 offset = AWE_PATCH_INFO_SIZE;
3291 if (copy_from_user((char*)&hdr, addr + offset, AWE_VOICE_REC_SIZE))
3292 return -EFAULT;
3293 offset += AWE_VOICE_REC_SIZE;
3294
3295 if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
3296 printk(KERN_WARNING "AWE32 Error: Invalid voice number %d\n", hdr.nvoices);
3297 return -EINVAL;
3298 }
3299 total_size = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE * hdr.nvoices;
3300 if (count < total_size) {
3301 printk(KERN_WARNING "AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n",
3302 count, hdr.nvoices);
3303 return -EINVAL;
3304 }
3305
3306 if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
3307 return -ENOMEM;
3308
3309 switch (hdr.write_mode) {
3310 case AWE_WR_EXCLUSIVE:
3311 /* exclusive mode - if the instrument already exists,
3312 return error */
3313 for (rec = sf->infos; rec; rec = rec->next) {
3314 if (rec->type == V_ST_NORMAL &&
3315 rec->bank == hdr.bank &&
3316 rec->instr == hdr.instr)
3317 return -EINVAL;
3318 }
3319 break;
3320 case AWE_WR_REPLACE:
3321 /* replace mode - remove the instrument if it already exists */
3322 remove_info(sf, hdr.bank, hdr.instr);
3323 break;
3324 }
3325
3326 /* append new layers */
3327 for (i = 0; i < hdr.nvoices; i++) {
3328 rec = alloc_new_info();
3329 if (rec == NULL)
3330 return -ENOMEM;
3331
3332 rec->bank = hdr.bank;
3333 rec->instr = hdr.instr;
3334 rec->type = V_ST_NORMAL;
3335 rec->disabled = FALSE;
3336
3337 /* copy awe_voice_info parameters */
3338 if (copy_from_user(&rec->v, addr + offset, AWE_VOICE_INFO_SIZE)) {
3339 kfree(rec);
3340 return -EFAULT;
3341 }
3342 offset += AWE_VOICE_INFO_SIZE;
3343 #ifdef AWE_ALLOW_SAMPLE_SHARING
3344 if (sf && sf->shared) {
3345 if (info_duplicated(sf, rec)) {
3346 kfree(rec);
3347 continue;
3348 }
3349 }
3350 #endif /* allow sharing */
3351 if (rec->v.mode & AWE_MODE_INIT_PARM)
3352 awe_init_voice_parm(&rec->v.parm);
3353 add_sf_info(sf, rec);
3354 awe_set_sample(rec);
3355 add_info_list(rec);
3356 }
3357
3358 return 0;
3359 }
3360
3361
3362 /* remove instrument layers */
3363 static int
3364 awe_remove_info(awe_patch_info *patch, const char *addr, int count)
3365 {
3366 unsigned char bank, instr;
3367 sf_list *sf;
3368
3369 if (! patch_opened || (sf = sftail) == NULL) {
3370 printk(KERN_WARNING "AWE32: remove_info: patch not opened\n");
3371 return -EINVAL;
3372 }
3373
3374 bank = ((unsigned short)patch->optarg >> 8) & 0xff;
3375 instr = (unsigned short)patch->optarg & 0xff;
3376 if (! remove_info(sf, bank, instr))
3377 return -EINVAL;
3378 return 0;
3379 }
3380
3381
3382 /* load wave sample data */
3383 static int
3384 awe_load_data(awe_patch_info *patch, const char *addr, int count)
3385 {
3386 int offset, size;
3387 int rc;
3388 awe_sample_info tmprec;
3389 awe_sample_list *rec;
3390 sf_list *sf;
3391
3392 if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
3393 return -ENOMEM;
3394
3395 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3396 offset = AWE_PATCH_INFO_SIZE;
3397 if (copy_from_user(&tmprec, addr + offset, AWE_SAMPLE_INFO_SIZE))
3398 return -EFAULT;
3399 offset += AWE_SAMPLE_INFO_SIZE;
3400 if (size != tmprec.size) {
3401 printk(KERN_WARNING "AWE32: load: sample size differed (%d != %d)\n",
3402 tmprec.size, size);
3403 return -EINVAL;
3404 }
3405
3406 if (search_sample_index(sf, tmprec.sample) != NULL) {
3407 #ifdef AWE_ALLOW_SAMPLE_SHARING
3408 /* if shared sample, skip this data */
3409 if (sf->type & AWE_PAT_SHARED)
3410 return 0;
3411 #endif /* allow sharing */
3412 DEBUG(1,printk("AWE32: sample data %d already present\n", tmprec.sample));
3413 return -EINVAL;
3414 }
3415
3416 if ((rec = alloc_new_sample()) == NULL)
3417 return -ENOMEM;
3418
3419 memcpy(&rec->v, &tmprec, sizeof(tmprec));
3420
3421 if (rec->v.size > 0) {
3422 if ((rc = awe_write_wave_data(addr, offset, rec, -1)) < 0) {
3423 kfree(rec);
3424 return rc;
3425 }
3426 sf->mem_ptr += rc;
3427 }
3428
3429 add_sf_sample(sf, rec);
3430 return 0;
3431 }
3432
3433
3434 /* replace wave sample data */
3435 static int
3436 awe_replace_data(awe_patch_info *patch, const char *addr, int count)
3437 {
3438 int offset;
3439 int size;
3440 int rc;
3441 int channels;
3442 awe_sample_info cursmp;
3443 int save_mem_ptr;
3444 sf_list *sf;
3445 awe_sample_list *rec;
3446
3447 if (! patch_opened || (sf = sftail) == NULL) {
3448 printk(KERN_WARNING "AWE32: replace: patch not opened\n");
3449 return -EINVAL;
3450 }
3451
3452 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3453 offset = AWE_PATCH_INFO_SIZE;
3454 if (copy_from_user(&cursmp, addr + offset, AWE_SAMPLE_INFO_SIZE))
3455 return -EFAULT;
3456 offset += AWE_SAMPLE_INFO_SIZE;
3457 if (cursmp.size == 0 || size != cursmp.size) {
3458 printk(KERN_WARNING "AWE32: replace: invalid sample size (%d!=%d)\n",
3459 cursmp.size, size);
3460 return -EINVAL;
3461 }
3462 channels = patch->optarg;
3463 if (channels <= 0 || channels > AWE_NORMAL_VOICES) {
3464 printk(KERN_WARNING "AWE32: replace: invalid channels %d\n", channels);
3465 return -EINVAL;
3466 }
3467
3468 for (rec = sf->samples; rec; rec = rec->next) {
3469 if (rec->v.sample == cursmp.sample)
3470 break;
3471 }
3472 if (rec == NULL) {
3473 printk(KERN_WARNING "AWE32: replace: cannot find existing sample data %d\n",
3474 cursmp.sample);
3475 return -EINVAL;
3476 }
3477
3478 if (rec->v.size != cursmp.size) {
3479 printk(KERN_WARNING "AWE32: replace: exiting size differed (%d!=%d)\n",
3480 rec->v.size, cursmp.size);
3481 return -EINVAL;
3482 }
3483
3484 save_mem_ptr = awe_free_mem_ptr();
3485 sftail->mem_ptr = rec->v.start - awe_mem_start;
3486 memcpy(&rec->v, &cursmp, sizeof(cursmp));
3487 rec->v.sf_id = current_sf_id;
3488 if ((rc = awe_write_wave_data(addr, offset, rec, channels)) < 0)
3489 return rc;
3490 sftail->mem_ptr = save_mem_ptr;
3491
3492 return 0;
3493 }
3494
3495
3496 /*----------------------------------------------------------------*/
3497
3498 static const char *readbuf_addr;
3499 static int readbuf_offs;
3500 static int readbuf_flags;
3501
3502 /* initialize read buffer */
3503 static int
3504 readbuf_init(const char *addr, int offset, awe_sample_info *sp)
3505 {
3506 readbuf_addr = addr;
3507 readbuf_offs = offset;
3508 readbuf_flags = sp->mode_flags;
3509 return 0;
3510 }
3511
3512 /* read directly from user buffer */
3513 static unsigned short
3514 readbuf_word(int pos)
3515 {
3516 unsigned short c;
3517 /* read from user buffer */
3518 if (readbuf_flags & AWE_SAMPLE_8BITS) {
3519 unsigned char cc;
3520 get_user(cc, (unsigned char*)(readbuf_addr + readbuf_offs + pos));
3521 c = (unsigned short)cc << 8; /* convert 8bit -> 16bit */
3522 } else {
3523 get_user(c, (unsigned short*)(readbuf_addr + readbuf_offs + pos * 2));
3524 }
3525 if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
3526 c ^= 0x8000; /* unsigned -> signed */
3527 return c;
3528 }
3529
3530 #define readbuf_word_cache readbuf_word
3531 #define readbuf_end() /**/
3532
3533 /*----------------------------------------------------------------*/
3534
3535 #define BLANK_LOOP_START 8
3536 #define BLANK_LOOP_END 40
3537 #define BLANK_LOOP_SIZE 48
3538
3539 /* loading onto memory - return the actual written size */
3540 static int
3541 awe_write_wave_data(const char *addr, int offset, awe_sample_list *list, int channels)
3542 {
3543 int i, truesize, dram_offset;
3544 awe_sample_info *sp = &list->v;
3545 int rc;
3546
3547 /* be sure loop points start < end */
3548 if (sp->loopstart > sp->loopend) {
3549 int tmp = sp->loopstart;
3550 sp->loopstart = sp->loopend;
3551 sp->loopend = tmp;
3552 }
3553
3554 /* compute true data size to be loaded */
3555 truesize = sp->size;
3556 if (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))
3557 truesize += sp->loopend - sp->loopstart;
3558 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK)
3559 truesize += BLANK_LOOP_SIZE;
3560 if (awe_free_mem_ptr() + truesize >= memsize/2) {
3561 DEBUG(-1,printk("AWE32 Error: Sample memory full\n"));
3562 return -ENOSPC;
3563 }
3564
3565 /* recalculate address offset */
3566 sp->end -= sp->start;
3567 sp->loopstart -= sp->start;
3568 sp->loopend -= sp->start;
3569
3570 dram_offset = awe_free_mem_ptr() + awe_mem_start;
3571 sp->start = dram_offset;
3572 sp->end += dram_offset;
3573 sp->loopstart += dram_offset;
3574 sp->loopend += dram_offset;
3575
3576 /* set the total size (store onto obsolete checksum value) */
3577 if (sp->size == 0)
3578 sp->checksum = 0;
3579 else
3580 sp->checksum = truesize;
3581
3582 if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0)
3583 return rc;
3584
3585 if (readbuf_init(addr, offset, sp) < 0)
3586 return -ENOSPC;
3587
3588 for (i = 0; i < sp->size; i++) {
3589 unsigned short c;
3590 c = readbuf_word(i);
3591 awe_write_dram(c);
3592 if (i == sp->loopend &&
3593 (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))) {
3594 int looplen = sp->loopend - sp->loopstart;
3595 /* copy reverse loop */
3596 int k;
3597 for (k = 1; k <= looplen; k++) {
3598 c = readbuf_word_cache(i - k);
3599 awe_write_dram(c);
3600 }
3601 if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) {
3602 sp->end += looplen;
3603 } else {
3604 sp->start += looplen;
3605 sp->end += looplen;
3606 }
3607 }
3608 }
3609 readbuf_end();
3610
3611 /* if no blank loop is attached in the sample, add it */
3612 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) {
3613 for (i = 0; i < BLANK_LOOP_SIZE; i++)
3614 awe_write_dram(0);
3615 if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) {
3616 sp->loopstart = sp->end + BLANK_LOOP_START;
3617 sp->loopend = sp->end + BLANK_LOOP_END;
3618 }
3619 }
3620
3621 awe_close_dram();
3622
3623 /* initialize FM */
3624 awe_init_fm();
3625
3626 return truesize;
3627 }
3628
3629
3630 /*----------------------------------------------------------------*/
3631
3632 #ifdef AWE_HAS_GUS_COMPATIBILITY
3633
3634 /* calculate GUS envelope time:
3635 * is this correct? i have no idea..
3636 */
3637 static int
3638 calc_gus_envelope_time(int rate, int start, int end)
3639 {
3640 int r, p, t;
3641 r = (3 - ((rate >> 6) & 3)) * 3;
3642 p = rate & 0x3f;
3643 t = end - start;
3644 if (t < 0) t = -t;
3645 if (13 > r)
3646 t = t << (13 - r);
3647 else
3648 t = t >> (r - 13);
3649 return (t * 10) / (p * 441);
3650 }
3651
3652 #define calc_gus_sustain(val) (0x7f - vol_table[(val)/2])
3653 #define calc_gus_attenuation(val) vol_table[(val)/2]
3654
3655 /* load GUS patch */
3656 static int
3657 awe_load_guspatch(const char *addr, int offs, int size, int pmgr_flag)
3658 {
3659 struct patch_info patch;
3660 awe_voice_info *rec;
3661 awe_sample_info *smp;
3662 awe_voice_list *vrec;
3663 awe_sample_list *smprec;
3664 int sizeof_patch;
3665 int note, rc;
3666 sf_list *sf;
3667
3668 sizeof_patch = (int)((long)&patch.data[0] - (long)&patch); /* header size */
3669 if (size < sizeof_patch) {
3670 printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
3671 return -EINVAL;
3672 }
3673 if (copy_from_user(((char*)&patch) + offs, addr + offs, sizeof_patch - offs))
3674 return -EFAULT;
3675 size -= sizeof_patch;
3676 if (size < patch.len) {
3677 printk(KERN_WARNING "AWE32 Error: Patch record too short (%d<%d)\n",
3678 size, patch.len);
3679 return -EINVAL;
3680 }
3681 if ((sf = check_patch_opened(AWE_PAT_TYPE_GUS, NULL)) == NULL)
3682 return -ENOMEM;
3683 if ((smprec = alloc_new_sample()) == NULL)
3684 return -ENOMEM;
3685 if ((vrec = alloc_new_info()) == NULL) {
3686 kfree(smprec);
3687 return -ENOMEM;
3688 }
3689
3690 smp = &smprec->v;
3691 smp->sample = sf->num_sample;
3692 smp->start = 0;
3693 smp->end = patch.len;
3694 smp->loopstart = patch.loop_start;
3695 smp->loopend = patch.loop_end;
3696 smp->size = patch.len;
3697
3698 /* set up mode flags */
3699 smp->mode_flags = 0;
3700 if (!(patch.mode & WAVE_16_BITS))
3701 smp->mode_flags |= AWE_SAMPLE_8BITS;
3702 if (patch.mode & WAVE_UNSIGNED)
3703 smp->mode_flags |= AWE_SAMPLE_UNSIGNED;
3704 smp->mode_flags |= AWE_SAMPLE_NO_BLANK;
3705 if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
3706 smp->mode_flags |= AWE_SAMPLE_SINGLESHOT;
3707 if (patch.mode & WAVE_BIDIR_LOOP)
3708 smp->mode_flags |= AWE_SAMPLE_BIDIR_LOOP;
3709 if (patch.mode & WAVE_LOOP_BACK)
3710 smp->mode_flags |= AWE_SAMPLE_REVERSE_LOOP;
3711
3712 DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, smp->mode_flags));
3713 if (patch.mode & WAVE_16_BITS) {
3714 /* convert to word offsets */
3715 smp->size /= 2;
3716 smp->end /= 2;
3717 smp->loopstart /= 2;
3718 smp->loopend /= 2;
3719 }
3720 smp->checksum_flag = 0;
3721 smp->checksum = 0;
3722
3723 if ((rc = awe_write_wave_data(addr, sizeof_patch, smprec, -1)) < 0)
3724 return rc;
3725 sf->mem_ptr += rc;
3726 add_sf_sample(sf, smprec);
3727
3728 /* set up voice info */
3729 rec = &vrec->v;
3730 awe_init_voice_info(rec);
3731 rec->sample = sf->num_info; /* the last sample */
3732 rec->rate_offset = calc_rate_offset(patch.base_freq);
3733 note = freq_to_note(patch.base_note);
3734 rec->root = note / 100;
3735 rec->tune = -(note % 100);
3736 rec->low = freq_to_note(patch.low_note) / 100;
3737 rec->high = freq_to_note(patch.high_note) / 100;
3738 DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%d-%d)]\n",
3739 rec->rate_offset, note,
3740 rec->low, rec->high,
3741 patch.low_note, patch.high_note));
3742 /* panning position; -128 - 127 => 0-127 */
3743 rec->pan = (patch.panning + 128) / 2;
3744
3745 /* detuning is ignored */
3746 /* 6points volume envelope */
3747 if (patch.mode & WAVE_ENVELOPES) {
3748 int attack, hold, decay, release;
3749 attack = calc_gus_envelope_time
3750 (patch.env_rate[0], 0, patch.env_offset[0]);
3751 hold = calc_gus_envelope_time
3752 (patch.env_rate[1], patch.env_offset[0],
3753 patch.env_offset[1]);
3754 decay = calc_gus_envelope_time
3755 (patch.env_rate[2], patch.env_offset[1],
3756 patch.env_offset[2]);
3757 release = calc_gus_envelope_time
3758 (patch.env_rate[3], patch.env_offset[1],
3759 patch.env_offset[4]);
3760 release += calc_gus_envelope_time
3761 (patch.env_rate[4], patch.env_offset[3],
3762 patch.env_offset[4]);
3763 release += calc_gus_envelope_time
3764 (patch.env_rate[5], patch.env_offset[4],
3765 patch.env_offset[5]);
3766 rec->parm.volatkhld = (calc_parm_hold(hold) << 8) |
3767 calc_parm_attack(attack);
3768 rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
3769 calc_parm_decay(decay);
3770 rec->parm.volrelease = 0x8000 | calc_parm_decay(release);
3771 DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release));
3772 rec->attenuation = calc_gus_attenuation(patch.env_offset[0]);
3773 }
3774
3775 /* tremolo effect */
3776 if (patch.mode & WAVE_TREMOLO) {
3777 int rate = (patch.tremolo_rate * 1000 / 38) / 42;
3778 rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
3779 DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n",
3780 patch.tremolo_rate, patch.tremolo_depth,
3781 rec->parm.tremfrq));
3782 }
3783 /* vibrato effect */
3784 if (patch.mode & WAVE_VIBRATO) {
3785 int rate = (patch.vibrato_rate * 1000 / 38) / 42;
3786 rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
3787 DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n",
3788 patch.tremolo_rate, patch.tremolo_depth,
3789 rec->parm.tremfrq));
3790 }
3791
3792 /* scale_freq, scale_factor, volume, and fractions not implemented */
3793
3794 /* append to the tail of the list */
3795 vrec->bank = ctrls[AWE_MD_GUS_BANK];
3796 vrec->instr = patch.instr_no;
3797 vrec->disabled = FALSE;
3798 vrec->type = V_ST_NORMAL;
3799
3800 add_sf_info(sf, vrec);
3801 add_info_list(vrec);
3802
3803 /* set the voice index */
3804 awe_set_sample(vrec);
3805
3806 return 0;
3807 }
3808
3809 #endif /* AWE_HAS_GUS_COMPATIBILITY */
3810
3811 /*
3812 * sample and voice list handlers
3813 */
3814
3815 /* append this to the current sf list */
3816 static void add_sf_info(sf_list *sf, awe_voice_list *rec)
3817 {
3818 if (sf == NULL)
3819 return;
3820 rec->holder = sf;
3821 rec->v.sf_id = sf->sf_id;
3822 if (sf->last_infos)
3823 sf->last_infos->next = rec;
3824 else
3825 sf->infos = rec;
3826 sf->last_infos = rec;
3827 rec->next = NULL;
3828 sf->num_info++;
3829 }
3830
3831 /* prepend this sample to sf list */
3832 static void add_sf_sample(sf_list *sf, awe_sample_list *rec)
3833 {
3834 if (sf == NULL)
3835 return;
3836 rec->holder = sf;
3837 rec->v.sf_id = sf->sf_id;
3838 if (sf->last_samples)
3839 sf->last_samples->next = rec;
3840 else
3841 sf->samples = rec;
3842 sf->last_samples = rec;
3843 rec->next = NULL;
3844 sf->num_sample++;
3845 }
3846
3847 /* purge the old records which don't belong with the same file id */
3848 static void purge_old_list(awe_voice_list *rec, awe_voice_list *next)
3849 {
3850 rec->next_instr = next;
3851 if (rec->bank == AWE_DRUM_BANK) {
3852 /* remove samples with the same note range */
3853 awe_voice_list *cur, *prev = rec;
3854 int low = rec->v.low;
3855 int high = rec->v.high;
3856 for (cur = next; cur; cur = cur->next_instr) {
3857 if (cur->v.low == low &&
3858 cur->v.high == high &&
3859 ! is_identical_holder(cur->holder, rec->holder))
3860 prev->next_instr = cur->next_instr;
3861 else
3862 prev = cur;
3863 }
3864 } else {
3865 if (! is_identical_holder(next->holder, rec->holder))
3866 /* remove all samples */
3867 rec->next_instr = NULL;
3868 }
3869 }
3870
3871 /* prepend to top of the preset table */
3872 static void add_info_list(awe_voice_list *rec)
3873 {
3874 awe_voice_list *prev, *cur;
3875 int key;
3876
3877 if (rec->disabled)
3878 return;
3879
3880 key = awe_search_key(rec->bank, rec->instr, rec->v.low);
3881 prev = NULL;
3882 for (cur = preset_table[key]; cur; cur = cur->next_bank) {
3883 /* search the first record with the same bank number */
3884 if (cur->instr == rec->instr && cur->bank == rec->bank) {
3885 /* replace the list with the new record */
3886 rec->next_bank = cur->next_bank;
3887 if (prev)
3888 prev->next_bank = rec;
3889 else
3890 preset_table[key] = rec;
3891 purge_old_list(rec, cur);
3892 return;
3893 }
3894 prev = cur;
3895 }
3896
3897 /* this is the first bank record.. just add this */
3898 rec->next_instr = NULL;
3899 rec->next_bank = preset_table[key];
3900 preset_table[key] = rec;
3901 }
3902
3903 /* remove samples later than the specified sf_id */
3904 static void
3905 awe_remove_samples(int sf_id)
3906 {
3907 sf_list *p, *prev;
3908
3909 if (sf_id <= 0) {
3910 awe_reset_samples();
3911 return;
3912 }
3913 /* already removed? */
3914 if (current_sf_id <= sf_id)
3915 return;
3916
3917 for (p = sftail; p; p = prev) {
3918 if (p->sf_id <= sf_id)
3919 break;
3920 prev = p->prev;
3921 awe_free_sf(p);
3922 }
3923 sftail = p;
3924 if (sftail) {
3925 sf_id = sftail->sf_id;
3926 sftail->next = NULL;
3927 } else {
3928 sf_id = 0;
3929 sfhead = NULL;
3930 }
3931 current_sf_id = sf_id;
3932 if (locked_sf_id > sf_id)
3933 locked_sf_id = sf_id;
3934
3935 rebuild_preset_list();
3936 }
3937
3938 /* rebuild preset search list */
3939 static void rebuild_preset_list(void)
3940 {
3941 sf_list *p;
3942 awe_voice_list *rec;
3943
3944 memset(preset_table, 0, sizeof(preset_table));
3945
3946 for (p = sfhead; p; p = p->next) {
3947 for (rec = p->infos; rec; rec = rec->next)
3948 add_info_list(rec);
3949 }
3950 }
3951
3952 /* compare the given sf_id pair */
3953 static int is_identical_holder(sf_list *sf1, sf_list *sf2)
3954 {
3955 if (sf1 == NULL || sf2 == NULL)
3956 return FALSE;
3957 if (sf1 == sf2)
3958 return TRUE;
3959 #ifdef AWE_ALLOW_SAMPLE_SHARING
3960 {
3961 /* compare with the sharing id */
3962 sf_list *p;
3963 int counter = 0;
3964 if (sf1->sf_id < sf2->sf_id) { /* make sure id1 > id2 */
3965 sf_list *tmp; tmp = sf1; sf1 = sf2; sf2 = tmp;
3966 }
3967 for (p = sf1->shared; p; p = p->shared) {
3968 if (counter++ > current_sf_id)
3969 break; /* strange sharing loop.. quit */
3970 if (p == sf2)
3971 return TRUE;
3972 }
3973 }
3974 #endif /* allow sharing */
3975 return FALSE;
3976 }
3977
3978 /* search the sample index matching with the given sample id */
3979 static awe_sample_list *
3980 search_sample_index(sf_list *sf, int sample)
3981 {
3982 awe_sample_list *p;
3983 #ifdef AWE_ALLOW_SAMPLE_SHARING
3984 int counter = 0;
3985 while (sf) {
3986 for (p = sf->samples; p; p = p->next) {
3987 if (p->v.sample == sample)
3988 return p;
3989 }
3990 sf = sf->shared;
3991 if (counter++ > current_sf_id)
3992 break; /* strange sharing loop.. quit */
3993 }
3994 #else
3995 if (sf) {
3996 for (p = sf->samples; p; p = p->next) {
3997 if (p->v.sample == sample)
3998 return p;
3999 }
4000 }
4001 #endif
4002 return NULL;
4003 }
4004
4005 /* search the specified sample */
4006 /* non-zero = found */
4007 static short
4008 awe_set_sample(awe_voice_list *rec)
4009 {
4010 awe_sample_list *smp;
4011 awe_voice_info *vp = &rec->v;
4012
4013 vp->index = 0;
4014 if ((smp = search_sample_index(rec->holder, vp->sample)) == NULL)
4015 return 0;
4016
4017 /* set the actual sample offsets */
4018 vp->start += smp->v.start;
4019 vp->end += smp->v.end;
4020 vp->loopstart += smp->v.loopstart;
4021 vp->loopend += smp->v.loopend;
4022 /* copy mode flags */
4023 vp->mode = smp->v.mode_flags;
4024 /* set flag */
4025 vp->index = 1;
4026
4027 return 1;
4028 }
4029
4030
4031 /*
4032 * voice allocation
4033 */
4034
4035 /* look for all voices associated with the specified note & velocity */
4036 static int
4037 awe_search_multi_voices(awe_voice_list *rec, int note, int velocity,
4038 awe_voice_info **vlist)
4039 {
4040 int nvoices;
4041
4042 nvoices = 0;
4043 for (; rec; rec = rec->next_instr) {
4044 if (note >= rec->v.low &&
4045 note <= rec->v.high &&
4046 velocity >= rec->v.vellow &&
4047 velocity <= rec->v.velhigh) {
4048 if (rec->type == V_ST_MAPPED) {
4049 /* mapper */
4050 vlist[0] = &rec->v;
4051 return -1;
4052 }
4053 vlist[nvoices++] = &rec->v;
4054 if (nvoices >= AWE_MAX_VOICES)
4055 break;
4056 }
4057 }
4058 return nvoices;
4059 }
4060
4061 /* store the voice list from the specified note and velocity.
4062 if the preset is mapped, seek for the destination preset, and rewrite
4063 the note number if necessary.
4064 */
4065 static int
4066 really_alloc_voices(int bank, int instr, int *note, int velocity, awe_voice_info **vlist)
4067 {
4068 int nvoices;
4069 awe_voice_list *vrec;
4070 int level = 0;
4071
4072 for (;;) {
4073 vrec = awe_search_instr(bank, instr, *note);
4074 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
4075 if (nvoices == 0) {
4076 if (bank == AWE_DRUM_BANK)
4077 /* search default drumset */
4078 vrec = awe_search_instr(bank, ctrls[AWE_MD_DEF_DRUM], *note);
4079 else
4080 /* search default preset */
4081 vrec = awe_search_instr(ctrls[AWE_MD_DEF_BANK], instr, *note);
4082 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
4083 }
4084 if (nvoices == 0) {
4085 if (bank == AWE_DRUM_BANK && ctrls[AWE_MD_DEF_DRUM] != 0)
4086 /* search default drumset */
4087 vrec = awe_search_instr(bank, 0, *note);
4088 else if (bank != AWE_DRUM_BANK && ctrls[AWE_MD_DEF_BANK] != 0)
4089 /* search default preset */
4090 vrec = awe_search_instr(0, instr, *note);
4091 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
4092 }
4093 if (nvoices < 0) { /* mapping */
4094 int key = vlist[0]->fixkey;
4095 instr = vlist[0]->start;
4096 bank = vlist[0]->end;
4097 if (level++ > 5) {
4098 printk(KERN_ERR "AWE32: too deep mapping level\n");
4099 return 0;
4100 }
4101 if (key >= 0)
4102 *note = key;
4103 } else
4104 break;
4105 }
4106
4107 return nvoices;
4108 }
4109
4110 /* allocate voices corresponding note and velocity; supports multiple insts. */
4111 static void
4112 awe_alloc_multi_voices(int ch, int note, int velocity, int key)
4113 {
4114 int i, v, nvoices, bank;
4115 awe_voice_info *vlist[AWE_MAX_VOICES];
4116
4117 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch))
4118 bank = AWE_DRUM_BANK; /* always search drumset */
4119 else
4120 bank = channels[ch].bank;
4121
4122 /* check the possible voices; note may be changeable if mapped */
4123 nvoices = really_alloc_voices(bank, channels[ch].instr,
4124 ¬e, velocity, vlist);
4125
4126 /* set the voices */
4127 current_alloc_time++;
4128 for (i = 0; i < nvoices; i++) {
4129 v = awe_clear_voice();
4130 voices[v].key = key;
4131 voices[v].ch = ch;
4132 voices[v].note = note;
4133 voices[v].velocity = velocity;
4134 voices[v].time = current_alloc_time;
4135 voices[v].cinfo = &channels[ch];
4136 voices[v].sample = vlist[i];
4137 voices[v].state = AWE_ST_MARK;
4138 voices[v].layer = nvoices - i - 1; /* in reverse order */
4139 }
4140
4141 /* clear the mark in allocated voices */
4142 for (i = 0; i < awe_max_voices; i++) {
4143 if (voices[i].state == AWE_ST_MARK)
4144 voices[i].state = AWE_ST_OFF;
4145
4146 }
4147 }
4148
4149
4150 /* search an empty voice.
4151 if no empty voice is found, at least terminate a voice
4152 */
4153 static int
4154 awe_clear_voice(void)
4155 {
4156 enum {
4157 OFF=0, RELEASED, SUSTAINED, PLAYING, END
4158 };
4159 struct voice_candidate_t {
4160 int best;
4161 int time;
4162 int vtarget;
4163 } candidate[END];
4164 int i, type, vtarget;
4165
4166 vtarget = 0xffff;
4167 for (type = OFF; type < END; type++) {
4168 candidate[type].best = -1;
4169 candidate[type].time = current_alloc_time + 1;
4170 candidate[type].vtarget = vtarget;
4171 }
4172
4173 for (i = 0; i < awe_max_voices; i++) {
4174 if (voices[i].state & AWE_ST_OFF)
4175 type = OFF;
4176 else if (voices[i].state & AWE_ST_RELEASED)
4177 type = RELEASED;
4178 else if (voices[i].state & AWE_ST_SUSTAINED)
4179 type = SUSTAINED;
4180 else if (voices[i].state & ~AWE_ST_MARK)
4181 type = PLAYING;
4182 else
4183 continue;
4184 #ifdef AWE_CHECK_VTARGET
4185 /* get current volume */
4186 vtarget = (awe_peek_dw(AWE_VTFT(i)) >> 16) & 0xffff;
4187 #endif
4188 if (candidate[type].best < 0 ||
4189 vtarget < candidate[type].vtarget ||
4190 (vtarget == candidate[type].vtarget &&
4191 voices[i].time < candidate[type].time)) {
4192 candidate[type].best = i;
4193 candidate[type].time = voices[i].time;
4194 candidate[type].vtarget = vtarget;
4195 }
4196 }
4197
4198 for (type = OFF; type < END; type++) {
4199 if ((i = candidate[type].best) >= 0) {
4200 if (voices[i].state != AWE_ST_OFF)
4201 awe_terminate(i);
4202 awe_voice_init(i, TRUE);
4203 return i;
4204 }
4205 }
4206 return 0;
4207 }
4208
4209
4210 /* search sample for the specified note & velocity and set it on the voice;
4211 * note that voice is the voice index (not channel index)
4212 */
4213 static void
4214 awe_alloc_one_voice(int voice, int note, int velocity)
4215 {
4216 int ch, nvoices, bank;
4217 awe_voice_info *vlist[AWE_MAX_VOICES];
4218
4219 ch = voices[voice].ch;
4220 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice))
4221 bank = AWE_DRUM_BANK; /* always search drumset */
4222 else
4223 bank = voices[voice].cinfo->bank;
4224
4225 nvoices = really_alloc_voices(bank, voices[voice].cinfo->instr,
4226 ¬e, velocity, vlist);
4227 if (nvoices > 0) {
4228 voices[voice].time = ++current_alloc_time;
4229 voices[voice].sample = vlist[0]; /* use the first one */
4230 voices[voice].layer = 0;
4231 voices[voice].note = note;
4232 voices[voice].velocity = velocity;
4233 }
4234 }
4235
4236
4237 /*
4238 * sequencer2 functions
4239 */
4240
4241 /* search an empty voice; used by sequencer2 */
4242 static int
4243 awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
4244 {
4245 playing_mode = AWE_PLAY_MULTI2;
4246 awe_info.nr_voices = AWE_MAX_CHANNELS;
4247 return awe_clear_voice();
4248 }
4249
4250
4251 /* set up voice; used by sequencer2 */
4252 static void
4253 awe_setup_voice(int dev, int voice, int chn)
4254 {
4255 struct channel_info *info;
4256 if (synth_devs[dev] == NULL ||
4257 (info = &synth_devs[dev]->chn_info[chn]) == NULL)
4258 return;
4259
4260 if (voice < 0 || voice >= awe_max_voices)
4261 return;
4262
4263 DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn));
4264 channels[chn].expression_vol = info->controllers[CTL_EXPRESSION];
4265 channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME];
4266 channels[chn].panning =
4267 info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */
4268 channels[chn].bender = info->bender_value; /* zero center */
4269 channels[chn].bank = info->controllers[CTL_BANK_SELECT];
4270 channels[chn].sustained = info->controllers[CTL_SUSTAIN];
4271 if (info->controllers[CTL_EXT_EFF_DEPTH]) {
4272 FX_SET(&channels[chn].fx, AWE_FX_REVERB,
4273 info->controllers[CTL_EXT_EFF_DEPTH] * 2);
4274 }
4275 if (info->controllers[CTL_CHORUS_DEPTH]) {
4276 FX_SET(&channels[chn].fx, AWE_FX_CHORUS,
4277 info->controllers[CTL_CHORUS_DEPTH] * 2);
4278 }
4279 awe_set_instr(dev, chn, info->pgm_num);
4280 }
4281
4282
4283 #ifdef CONFIG_AWE32_MIXER
4284 /*
4285 * AWE32 mixer device control
4286 */
4287
4288 static int awe_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg);
4289
4290 static int my_mixerdev = -1;
4291
4292 static struct mixer_operations awe_mixer_operations = {
4293 owner: THIS_MODULE,
4294 id: "AWE",
4295 name: "AWE32 Equalizer",
4296 ioctl: awe_mixer_ioctl,
4297 };
4298
4299 static void __init attach_mixer(void)
4300 {
4301 if ((my_mixerdev = sound_alloc_mixerdev()) >= 0) {
4302 mixer_devs[my_mixerdev] = &awe_mixer_operations;
4303 }
4304 }
4305
4306 static void __exit unload_mixer(void)
4307 {
4308 if (my_mixerdev >= 0)
4309 sound_unload_mixerdev(my_mixerdev);
4310 }
4311
4312 static int
4313 awe_mixer_ioctl(int dev, unsigned int cmd, caddr_t arg)
4314 {
4315 int i, level, value;
4316
4317 if (((cmd >> 8) & 0xff) != 'M')
4318 return -EINVAL;
4319
4320 level = *(int*)arg;
4321 level = ((level & 0xff) + (level >> 8)) / 2;
4322 DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
4323
4324 if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
4325 switch (cmd & 0xff) {
4326 case SOUND_MIXER_BASS:
4327 value = level * 12 / 100;
4328 if (value >= 12)
4329 value = 11;
4330 ctrls[AWE_MD_BASS_LEVEL] = value;
4331 awe_update_equalizer();
4332 break;
4333 case SOUND_MIXER_TREBLE:
4334 value = level * 12 / 100;
4335 if (value >= 12)
4336 value = 11;
4337 ctrls[AWE_MD_TREBLE_LEVEL] = value;
4338 awe_update_equalizer();
4339 break;
4340 case SOUND_MIXER_VOLUME:
4341 level = level * 127 / 100;
4342 if (level >= 128) level = 127;
4343 atten_relative = FALSE;
4344 atten_offset = vol_table[level];
4345 awe_update_volume();
4346 break;
4347 }
4348 }
4349 switch (cmd & 0xff) {
4350 case SOUND_MIXER_BASS:
4351 level = ctrls[AWE_MD_BASS_LEVEL] * 100 / 24;
4352 level = (level << 8) | level;
4353 break;
4354 case SOUND_MIXER_TREBLE:
4355 level = ctrls[AWE_MD_TREBLE_LEVEL] * 100 / 24;
4356 level = (level << 8) | level;
4357 break;
4358 case SOUND_MIXER_VOLUME:
4359 value = atten_offset;
4360 if (atten_relative)
4361 value += ctrls[AWE_MD_ZERO_ATTEN];
4362 for (i = 127; i > 0; i--) {
4363 if (value <= vol_table[i])
4364 break;
4365 }
4366 level = i * 100 / 127;
4367 level = (level << 8) | level;
4368 break;
4369 case SOUND_MIXER_DEVMASK:
4370 level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME;
4371 break;
4372 default:
4373 level = 0;
4374 break;
4375 }
4376 return *(int*)arg = level;
4377 }
4378 #endif /* CONFIG_AWE32_MIXER */
4379
4380
4381 /*
4382 * initialization of Emu8000
4383 */
4384
4385 /* intiailize audio channels */
4386 static void
4387 awe_init_audio(void)
4388 {
4389 int ch;
4390
4391 /* turn off envelope engines */
4392 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4393 awe_poke(AWE_DCYSUSV(ch), 0x80);
4394 }
4395
4396 /* reset all other parameters to zero */
4397 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4398 awe_poke(AWE_ENVVOL(ch), 0);
4399 awe_poke(AWE_ENVVAL(ch), 0);
4400 awe_poke(AWE_DCYSUS(ch), 0);
4401 awe_poke(AWE_ATKHLDV(ch), 0);
4402 awe_poke(AWE_LFO1VAL(ch), 0);
4403 awe_poke(AWE_ATKHLD(ch), 0);
4404 awe_poke(AWE_LFO2VAL(ch), 0);
4405 awe_poke(AWE_IP(ch), 0);
4406 awe_poke(AWE_IFATN(ch), 0);
4407 awe_poke(AWE_PEFE(ch), 0);
4408 awe_poke(AWE_FMMOD(ch), 0);
4409 awe_poke(AWE_TREMFRQ(ch), 0);
4410 awe_poke(AWE_FM2FRQ2(ch), 0);
4411 awe_poke_dw(AWE_PTRX(ch), 0);
4412 awe_poke_dw(AWE_VTFT(ch), 0);
4413 awe_poke_dw(AWE_PSST(ch), 0);
4414 awe_poke_dw(AWE_CSL(ch), 0);
4415 awe_poke_dw(AWE_CCCA(ch), 0);
4416 }
4417
4418 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4419 awe_poke_dw(AWE_CPF(ch), 0);
4420 awe_poke_dw(AWE_CVCF(ch), 0);
4421 }
4422 }
4423
4424
4425 /* initialize DMA address */
4426 static void
4427 awe_init_dma(void)
4428 {
4429 awe_poke_dw(AWE_SMALR, 0);
4430 awe_poke_dw(AWE_SMARR, 0);
4431 awe_poke_dw(AWE_SMALW, 0);
4432 awe_poke_dw(AWE_SMARW, 0);
4433 }
4434
4435
4436 /* initialization arrays; from ADIP */
4437
4438 static unsigned short init1[128] = {
4439 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330,
4440 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730,
4441 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30,
4442 0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30,
4443
4444 0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330,
4445 0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730,
4446 0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30,
4447 0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30,
4448
4449 0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330,
4450 0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730,
4451 0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30,
4452 0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30,
4453
4454 0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330,
4455 0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730,
4456 0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30,
4457 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30,
4458 };
4459
4460 static unsigned short init2[128] = {
4461 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
4462 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
4463 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
4464 0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
4465
4466 0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
4467 0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
4468 0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
4469 0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
4470
4471 0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
4472 0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
4473 0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
4474 0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
4475
4476 0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
4477 0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
4478 0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
4479 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
4480 };
4481
4482 static unsigned short init3[128] = {
4483 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4484 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
4485 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
4486 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
4487
4488 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
4489 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
4490 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
4491 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
4492
4493 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
4494 0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
4495 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
4496 0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
4497
4498 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
4499 0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
4500 0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
4501 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
4502 };
4503
4504 static unsigned short init4[128] = {
4505 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4506 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
4507 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
4508 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
4509
4510 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
4511 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
4512 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
4513 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
4514
4515 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
4516 0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
4517 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
4518 0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
4519
4520 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
4521 0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
4522 0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
4523 0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
4524 };
4525
4526
4527 /* send initialization arrays to start up */
4528 static void
4529 awe_init_array(void)
4530 {
4531 awe_send_array(init1);
4532 awe_wait(1024);
4533 awe_send_array(init2);
4534 awe_send_array(init3);
4535 awe_poke_dw(AWE_HWCF4, 0);
4536 awe_poke_dw(AWE_HWCF5, 0x83);
4537 awe_poke_dw(AWE_HWCF6, 0x8000);
4538 awe_send_array(init4);
4539 }
4540
4541 /* send an initialization array */
4542 static void
4543 awe_send_array(unsigned short *data)
4544 {
4545 int i;
4546 unsigned short *p;
4547
4548 p = data;
4549 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4550 awe_poke(AWE_INIT1(i), *p);
4551 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4552 awe_poke(AWE_INIT2(i), *p);
4553 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4554 awe_poke(AWE_INIT3(i), *p);
4555 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4556 awe_poke(AWE_INIT4(i), *p);
4557 }
4558
4559
4560 /*
4561 * set up awe32 channels to some known state.
4562 */
4563
4564 /* set the envelope & LFO parameters to the default values; see ADIP */
4565 static void
4566 awe_tweak_voice(int i)
4567 {
4568 /* set all mod/vol envelope shape to minimum */
4569 awe_poke(AWE_ENVVOL(i), 0x8000);
4570 awe_poke(AWE_ENVVAL(i), 0x8000);
4571 awe_poke(AWE_DCYSUS(i), 0x7F7F);
4572 awe_poke(AWE_ATKHLDV(i), 0x7F7F);
4573 awe_poke(AWE_ATKHLD(i), 0x7F7F);
4574 awe_poke(AWE_PEFE(i), 0); /* mod envelope height to zero */
4575 awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */
4576 awe_poke(AWE_LFO2VAL(i), 0x8000);
4577 awe_poke(AWE_IP(i), 0xE000); /* no pitch shift */
4578 awe_poke(AWE_IFATN(i), 0xFF00); /* volume to minimum */
4579 awe_poke(AWE_FMMOD(i), 0);
4580 awe_poke(AWE_TREMFRQ(i), 0);
4581 awe_poke(AWE_FM2FRQ2(i), 0);
4582 }
4583
4584 static void
4585 awe_tweak(void)
4586 {
4587 int i;
4588 /* reset all channels */
4589 for (i = 0; i < awe_max_voices; i++)
4590 awe_tweak_voice(i);
4591 }
4592
4593
4594 /*
4595 * initializes the FM section of AWE32;
4596 * see Vince Vu's unofficial AWE32 programming guide
4597 */
4598
4599 static void
4600 awe_init_fm(void)
4601 {
4602 #ifndef AWE_ALWAYS_INIT_FM
4603 /* if no extended memory is on board.. */
4604 if (memsize <= 0)
4605 return;
4606 #endif
4607 DEBUG(3,printk("AWE32: initializing FM\n"));
4608
4609 /* Initialize the last two channels for DRAM refresh and producing
4610 the reverb and chorus effects for Yamaha OPL-3 synthesizer */
4611
4612 /* 31: FM left channel, 0xffffe0-0xffffe8 */
4613 awe_poke(AWE_DCYSUSV(30), 0x80);
4614 awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */
4615 awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 |
4616 (DEF_FM_CHORUS_DEPTH << 24));
4617 awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8));
4618 awe_poke_dw(AWE_CPF(30), 0);
4619 awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3);
4620
4621 /* 32: FM right channel, 0xfffff0-0xfffff8 */
4622 awe_poke(AWE_DCYSUSV(31), 0x80);
4623 awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */
4624 awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 |
4625 (DEF_FM_CHORUS_DEPTH << 24));
4626 awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8));
4627 awe_poke_dw(AWE_CPF(31), 0x8000);
4628 awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3);
4629
4630 /* skew volume & cutoff */
4631 awe_poke_dw(AWE_VTFT(30), 0x8000FFFF);
4632 awe_poke_dw(AWE_VTFT(31), 0x8000FFFF);
4633
4634 voices[30].state = AWE_ST_FM;
4635 voices[31].state = AWE_ST_FM;
4636
4637 /* change maximum channels to 30 */
4638 awe_max_voices = AWE_NORMAL_VOICES;
4639 if (playing_mode == AWE_PLAY_DIRECT)
4640 awe_info.nr_voices = awe_max_voices;
4641 else
4642 awe_info.nr_voices = AWE_MAX_CHANNELS;
4643 voice_alloc->max_voice = awe_max_voices;
4644 }
4645
4646 /*
4647 * AWE32 DRAM access routines
4648 */
4649
4650 /* open DRAM write accessing mode */
4651 static int
4652 awe_open_dram_for_write(int offset, int channels)
4653 {
4654 int vidx[AWE_NORMAL_VOICES];
4655 int i;
4656
4657 if (channels < 0 || channels >= AWE_NORMAL_VOICES) {
4658 channels = AWE_NORMAL_VOICES;
4659 for (i = 0; i < AWE_NORMAL_VOICES; i++)
4660 vidx[i] = i;
4661 } else {
4662 for (i = 0; i < channels; i++) {
4663 vidx[i] = awe_clear_voice();
4664 voices[vidx[i]].state = AWE_ST_MARK;
4665 }
4666 }
4667
4668 /* use all channels for DMA transfer */
4669 for (i = 0; i < channels; i++) {
4670 if (vidx[i] < 0) continue;
4671 awe_poke(AWE_DCYSUSV(vidx[i]), 0x80);
4672 awe_poke_dw(AWE_VTFT(vidx[i]), 0);
4673 awe_poke_dw(AWE_CVCF(vidx[i]), 0);
4674 awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000);
4675 awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000);
4676 awe_poke_dw(AWE_PSST(vidx[i]), 0);
4677 awe_poke_dw(AWE_CSL(vidx[i]), 0);
4678 awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000);
4679 voices[vidx[i]].state = AWE_ST_DRAM;
4680 }
4681 /* point channels 31 & 32 to ROM samples for DRAM refresh */
4682 awe_poke_dw(AWE_VTFT(30), 0);
4683 awe_poke_dw(AWE_PSST(30), 0x1d8);
4684 awe_poke_dw(AWE_CSL(30), 0x1e0);
4685 awe_poke_dw(AWE_CCCA(30), 0x1d8);
4686 awe_poke_dw(AWE_VTFT(31), 0);
4687 awe_poke_dw(AWE_PSST(31), 0x1d8);
4688 awe_poke_dw(AWE_CSL(31), 0x1e0);
4689 awe_poke_dw(AWE_CCCA(31), 0x1d8);
4690 voices[30].state = AWE_ST_FM;
4691 voices[31].state = AWE_ST_FM;
4692
4693 /* if full bit is on, not ready to write on */
4694 if (awe_peek_dw(AWE_SMALW) & 0x80000000) {
4695 for (i = 0; i < channels; i++) {
4696 awe_poke_dw(AWE_CCCA(vidx[i]), 0);
4697 voices[vidx[i]].state = AWE_ST_OFF;
4698 }
4699 printk("awe: not ready to write..\n");
4700 return -EPERM;
4701 }
4702
4703 /* set address to write */
4704 awe_poke_dw(AWE_SMALW, offset);
4705
4706 return 0;
4707 }
4708
4709 /* open DRAM for RAM size detection */
4710 static void
4711 awe_open_dram_for_check(void)
4712 {
4713 int i;
4714 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4715 awe_poke(AWE_DCYSUSV(i), 0x80);
4716 awe_poke_dw(AWE_VTFT(i), 0);
4717 awe_poke_dw(AWE_CVCF(i), 0);
4718 awe_poke_dw(AWE_PTRX(i), 0x40000000);
4719 awe_poke_dw(AWE_CPF(i), 0x40000000);
4720 awe_poke_dw(AWE_PSST(i), 0);
4721 awe_poke_dw(AWE_CSL(i), 0);
4722 if (i & 1) /* DMA write */
4723 awe_poke_dw(AWE_CCCA(i), 0x06000000);
4724 else /* DMA read */
4725 awe_poke_dw(AWE_CCCA(i), 0x04000000);
4726 voices[i].state = AWE_ST_DRAM;
4727 }
4728 }
4729
4730
4731 /* close dram access */
4732 static void
4733 awe_close_dram(void)
4734 {
4735 int i;
4736 /* wait until FULL bit in SMAxW register be false */
4737 for (i = 0; i < 10000; i++) {
4738 if (!(awe_peek_dw(AWE_SMALW) & 0x80000000))
4739 break;
4740 awe_wait(10);
4741 }
4742
4743 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4744 if (voices[i].state == AWE_ST_DRAM) {
4745 awe_poke_dw(AWE_CCCA(i), 0);
4746 awe_poke(AWE_DCYSUSV(i), 0x807F);
4747 voices[i].state = AWE_ST_OFF;
4748 }
4749 }
4750 }
4751
4752
4753 /*
4754 * detect presence of AWE32 and check memory size
4755 */
4756
4757 /* detect emu8000 chip on the specified address; from VV's guide */
4758
4759 static int __init
4760 awe_detect_base(int addr)
4761 {
4762 setup_ports(addr, 0, 0);
4763 if ((awe_peek(AWE_U1) & 0x000F) != 0x000C)
4764 return 0;
4765 if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058)
4766 return 0;
4767 if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003)
4768 return 0;
4769 DEBUG(0,printk("AWE32 found at %x\n", addr));
4770 return 1;
4771 }
4772
4773 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
4774 static struct {
4775 unsigned short card_vendor, card_device;
4776 unsigned short vendor;
4777 unsigned short function;
4778 char *name;
4779 } isapnp_awe_list[] __initdata = {
4780 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
4781 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0021),
4782 "AWE32 WaveTable" },
4783 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
4784 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0022),
4785 "AWE64 WaveTable" },
4786 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
4787 ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0023),
4788 "AWE64 Gold WaveTable" },
4789 {0}
4790 };
4791
4792 MODULE_DEVICE_TABLE(isapnp, isapnp_awe_list);
4793
4794 static struct pci_dev *idev = NULL;
4795
4796 static int __init awe_probe_isapnp(int *port)
4797 {
4798 int i;
4799
4800 for (i = 0; isapnp_awe_list[i].vendor != 0; i++) {
4801 while ((idev = isapnp_find_dev(NULL,
4802 isapnp_awe_list[i].vendor,
4803 isapnp_awe_list[i].function,
4804 idev))) {
4805 if (idev->prepare(idev) < 0)
4806 continue;
4807 if (idev->activate(idev) < 0 ||
4808 !idev->resource[0].start) {
4809 idev->deactivate(idev);
4810 idev->deactivate(idev);
4811 continue;
4812 }
4813 *port = idev->resource[0].start;
4814 break;
4815 }
4816 if (!idev)
4817 continue;
4818 printk(KERN_INFO "ISAPnP reports %s at i/o %#x\n",
4819 isapnp_awe_list[i].name, *port);
4820 return 0;
4821 }
4822 return -ENODEV;
4823 }
4824
4825 static void __exit awe_deactivate_isapnp(void)
4826 {
4827 #if 1
4828 if (idev) {
4829 idev->deactivate(idev);
4830 idev = NULL;
4831 }
4832 #endif
4833 }
4834
4835 #endif
4836
4837 static int __init
4838 awe_detect(void)
4839 {
4840 int base;
4841
4842 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
4843 if (isapnp) {
4844 if (awe_probe_isapnp(&io) < 0) {
4845 printk(KERN_ERR "AWE32: No ISAPnP cards found\n");
4846 if (isapnp != -1)
4847 return 0;
4848 } else {
4849 setup_ports(io, 0, 0);
4850 return 1;
4851 }
4852 }
4853 #endif /* isapnp */
4854
4855 if (io) /* use default i/o port value */
4856 setup_ports(io, 0, 0);
4857 else { /* probe it */
4858 for (base = 0x620; base <= 0x680; base += 0x20)
4859 if (awe_detect_base(base))
4860 return 1;
4861 DEBUG(0,printk("AWE32 not found\n"));
4862 return 0;
4863 }
4864
4865 return 1;
4866 }
4867
4868
4869 /*
4870 * check dram size on AWE board
4871 */
4872
4873 /* any three numbers you like */
4874 #define UNIQUE_ID1 0x1234
4875 #define UNIQUE_ID2 0x4321
4876 #define UNIQUE_ID3 0xABCD
4877
4878 static void __init
4879 awe_check_dram(void)
4880 {
4881 if (awe_present) /* already initialized */
4882 return;
4883
4884 if (memsize >= 0) { /* given by config file or module option */
4885 memsize *= 1024; /* convert to Kbytes */
4886 return;
4887 }
4888
4889 awe_open_dram_for_check();
4890
4891 memsize = 0;
4892
4893 /* set up unique two id numbers */
4894 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET);
4895 awe_poke(AWE_SMLD, UNIQUE_ID1);
4896 awe_poke(AWE_SMLD, UNIQUE_ID2);
4897
4898 while (memsize < AWE_MAX_DRAM_SIZE) {
4899 awe_wait(5);
4900 /* read a data on the DRAM start address */
4901 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET);
4902 awe_peek(AWE_SMLD); /* discard stale data */
4903 if (awe_peek(AWE_SMLD) != UNIQUE_ID1)
4904 break;
4905 if (awe_peek(AWE_SMLD) != UNIQUE_ID2)
4906 break;
4907 memsize += 512; /* increment 512kbytes */
4908 /* Write a unique data on the test address;
4909 * if the address is out of range, the data is written on
4910 * 0x200000(=AWE_DRAM_OFFSET). Then the two id words are
4911 * broken by this data.
4912 */
4913 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + memsize*512L);
4914 awe_poke(AWE_SMLD, UNIQUE_ID3);
4915 awe_wait(5);
4916 /* read a data on the just written DRAM address */
4917 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + memsize*512L);
4918 awe_peek(AWE_SMLD); /* discard stale data */
4919 if (awe_peek(AWE_SMLD) != UNIQUE_ID3)
4920 break;
4921 }
4922 awe_close_dram();
4923
4924 DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", memsize));
4925
4926 /* convert to Kbytes */
4927 memsize *= 1024;
4928 }
4929
4930
4931 /*----------------------------------------------------------------*/
4932
4933 /*
4934 * chorus and reverb controls; from VV's guide
4935 */
4936
4937 /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
4938 static char chorus_defined[AWE_CHORUS_NUMBERS];
4939 static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = {
4940 {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
4941 {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
4942 {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
4943 {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
4944 {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
4945 {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
4946 {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */
4947 {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */
4948 };
4949
4950 static int
4951 awe_load_chorus_fx(awe_patch_info *patch, const char *addr, int count)
4952 {
4953 if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) {
4954 printk(KERN_WARNING "AWE32 Error: invalid chorus mode %d for uploading\n", patch->optarg);
4955 return -EINVAL;
4956 }
4957 if (count < sizeof(awe_chorus_fx_rec)) {
4958 printk(KERN_WARNING "AWE32 Error: too short chorus fx parameters\n");
4959 return -EINVAL;
4960 }
4961 if (copy_from_user(&chorus_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
4962 sizeof(awe_chorus_fx_rec)))
4963 return -EFAULT;
4964 chorus_defined[patch->optarg] = TRUE;
4965 return 0;
4966 }
4967
4968 static void
4969 awe_set_chorus_mode(int effect)
4970 {
4971 if (effect < 0 || effect >= AWE_CHORUS_NUMBERS ||
4972 (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect]))
4973 return;
4974 awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback);
4975 awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset);
4976 awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth);
4977 awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay);
4978 awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq);
4979 awe_poke_dw(AWE_HWCF6, 0x8000);
4980 awe_poke_dw(AWE_HWCF7, 0x0000);
4981 }
4982
4983 static void
4984 awe_update_chorus_mode(void)
4985 {
4986 awe_set_chorus_mode(ctrls[AWE_MD_CHORUS_MODE]);
4987 }
4988
4989 /*----------------------------------------------------------------*/
4990
4991 /* reverb mode settings; write the following 28 data of 16 bit length
4992 * on the corresponding ports in the reverb_cmds array
4993 */
4994 static char reverb_defined[AWE_CHORUS_NUMBERS];
4995 static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = {
4996 {{ /* room 1 */
4997 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
4998 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
4999 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
5000 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
5001 }},
5002 {{ /* room 2 */
5003 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
5004 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
5005 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
5006 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
5007 }},
5008 {{ /* room 3 */
5009 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
5010 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
5011 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
5012 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
5013 }},
5014 {{ /* hall 1 */
5015 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
5016 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
5017 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
5018 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
5019 }},
5020 {{ /* hall 2 */
5021 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
5022 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
5023 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
5024 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
5025 }},
5026 {{ /* plate */
5027 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
5028 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
5029 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
5030 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
5031 }},
5032 {{ /* delay */
5033 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
5034 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
5035 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
5036 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
5037 }},
5038 {{ /* panning delay */
5039 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
5040 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
5041 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
5042 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
5043 }},
5044 };
5045
5046 static struct ReverbCmdPair {
5047 unsigned short cmd, port;
5048 } reverb_cmds[28] = {
5049 {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
5050 {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
5051 {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
5052 {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
5053 {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
5054 {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
5055 {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
5056 };
5057
5058 static int
5059 awe_load_reverb_fx(awe_patch_info *patch, const char *addr, int count)
5060 {
5061 if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) {
5062 printk(KERN_WARNING "AWE32 Error: invalid reverb mode %d for uploading\n", patch->optarg);
5063 return -EINVAL;
5064 }
5065 if (count < sizeof(awe_reverb_fx_rec)) {
5066 printk(KERN_WARNING "AWE32 Error: too short reverb fx parameters\n");
5067 return -EINVAL;
5068 }
5069 if (copy_from_user(&reverb_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
5070 sizeof(awe_reverb_fx_rec)))
5071 return -EFAULT;
5072 reverb_defined[patch->optarg] = TRUE;
5073 return 0;
5074 }
5075
5076 static void
5077 awe_set_reverb_mode(int effect)
5078 {
5079 int i;
5080 if (effect < 0 || effect >= AWE_REVERB_NUMBERS ||
5081 (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect]))
5082 return;
5083 for (i = 0; i < 28; i++)
5084 awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port,
5085 reverb_parm[effect].parms[i]);
5086 }
5087
5088 static void
5089 awe_update_reverb_mode(void)
5090 {
5091 awe_set_reverb_mode(ctrls[AWE_MD_REVERB_MODE]);
5092 }
5093
5094 /*
5095 * treble/bass equalizer control
5096 */
5097
5098 static unsigned short bass_parm[12][3] = {
5099 {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
5100 {0xD25B, 0xD35B, 0x0000}, /* -8 */
5101 {0xD24C, 0xD34C, 0x0000}, /* -6 */
5102 {0xD23D, 0xD33D, 0x0000}, /* -4 */
5103 {0xD21F, 0xD31F, 0x0000}, /* -2 */
5104 {0xC208, 0xC308, 0x0001}, /* 0 (HW default) */
5105 {0xC219, 0xC319, 0x0001}, /* +2 */
5106 {0xC22A, 0xC32A, 0x0001}, /* +4 */
5107 {0xC24C, 0xC34C, 0x0001}, /* +6 */
5108 {0xC26E, 0xC36E, 0x0001}, /* +8 */
5109 {0xC248, 0xC348, 0x0002}, /* +10 */
5110 {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
5111 };
5112
5113 static unsigned short treble_parm[12][9] = {
5114 {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
5115 {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
5116 {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
5117 {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
5118 {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
5119 {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
5120 {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
5121 {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
5122 {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
5123 {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
5124 {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
5125 {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */
5126 };
5127
5128
5129 /*
5130 * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
5131 */
5132 static void
5133 awe_equalizer(int bass, int treble)
5134 {
5135 unsigned short w;
5136
5137 if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
5138 return;
5139 awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]);
5140 awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]);
5141 awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]);
5142 awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]);
5143 awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]);
5144 awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]);
5145 awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]);
5146 awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]);
5147 awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]);
5148 awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]);
5149 w = bass_parm[bass][2] + treble_parm[treble][8];
5150 awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262));
5151 awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362));
5152 }
5153
5154 static void awe_update_equalizer(void)
5155 {
5156 awe_equalizer(ctrls[AWE_MD_BASS_LEVEL], ctrls[AWE_MD_TREBLE_LEVEL]);
5157 }
5158
5159
5160 /*----------------------------------------------------------------*/
5161
5162 #ifdef CONFIG_AWE32_MIDIEMU
5163
5164 /*
5165 * Emu8000 MIDI Emulation
5166 */
5167
5168 /*
5169 * midi queue record
5170 */
5171
5172 /* queue type */
5173 enum { Q_NONE, Q_VARLEN, Q_READ, Q_SYSEX, };
5174
5175 #define MAX_MIDIBUF 64
5176
5177 /* midi status */
5178 typedef struct MidiStatus {
5179 int queue; /* queue type */
5180 int qlen; /* queue length */
5181 int read; /* chars read */
5182 int status; /* current status */
5183 int chan; /* current channel */
5184 unsigned char buf[MAX_MIDIBUF];
5185 } MidiStatus;
5186
5187 /* MIDI mode type */
5188 enum { MODE_GM, MODE_GS, MODE_XG, };
5189
5190 /* NRPN / CC -> Emu8000 parameter converter */
5191 typedef struct {
5192 int control;
5193 int awe_effect;
5194 unsigned short (*convert)(int val);
5195 } ConvTable;
5196
5197
5198 /*
5199 * prototypes
5200 */
5201
5202 static int awe_midi_open(int dev, int mode, void (*input)(int,unsigned char), void (*output)(int));
5203 static void awe_midi_close(int dev);
5204 static int awe_midi_ioctl(int dev, unsigned cmd, caddr_t arg);
5205 static int awe_midi_outputc(int dev, unsigned char midi_byte);
5206
5207 static void init_midi_status(MidiStatus *st);
5208 static void clear_rpn(void);
5209 static void get_midi_char(MidiStatus *st, int c);
5210 /*static void queue_varlen(MidiStatus *st, int c);*/
5211 static void special_event(MidiStatus *st, int c);
5212 static void queue_read(MidiStatus *st, int c);
5213 static void midi_note_on(MidiStatus *st);
5214 static void midi_note_off(MidiStatus *st);
5215 static void midi_key_pressure(MidiStatus *st);
5216 static void midi_channel_pressure(MidiStatus *st);
5217 static void midi_pitch_wheel(MidiStatus *st);
5218 static void midi_program_change(MidiStatus *st);
5219 static void midi_control_change(MidiStatus *st);
5220 static void midi_select_bank(MidiStatus *st, int val);
5221 static void midi_nrpn_event(MidiStatus *st);
5222 static void midi_rpn_event(MidiStatus *st);
5223 static void midi_detune(int chan, int coarse, int fine);
5224 static void midi_system_exclusive(MidiStatus *st);
5225 static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
5226 static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
5227 static int xg_control_change(MidiStatus *st, int cmd, int val);
5228
5229 #define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
5230
5231
5232 /*
5233 * OSS Midi device record
5234 */
5235
5236 static struct midi_operations awe_midi_operations =
5237 {
5238 owner: THIS_MODULE,
5239 info: {"AWE Midi Emu", 0, 0, SNDCARD_SB},
5240 in_info: {0},
5241 open: awe_midi_open, /*open*/
5242 close: awe_midi_close, /*close*/
5243 ioctl: awe_midi_ioctl, /*ioctl*/
5244 outputc: awe_midi_outputc, /*outputc*/
5245 };
5246
5247 static int my_mididev = -1;
5248
5249 static void __init attach_midiemu(void)
5250 {
5251 if ((my_mididev = sound_alloc_mididev()) < 0)
5252 printk ("Sound: Too many midi devices detected\n");
5253 else
5254 midi_devs[my_mididev] = &awe_midi_operations;
5255 }
5256
5257 static void __exit unload_midiemu(void)
5258 {
5259 if (my_mididev >= 0)
5260 sound_unload_mididev(my_mididev);
5261 }
5262
5263
5264 /*
5265 * open/close midi device
5266 */
5267
5268 static int midi_opened = FALSE;
5269
5270 static int midi_mode;
5271 static int coarsetune = 0, finetune = 0;
5272
5273 static int xg_mapping = TRUE;
5274 static int xg_bankmode = 0;
5275
5276 /* effect sensitivity */
5277
5278 #define FX_CUTOFF 0
5279 #define FX_RESONANCE 1
5280 #define FX_ATTACK 2
5281 #define FX_RELEASE 3
5282 #define FX_VIBRATE 4
5283 #define FX_VIBDEPTH 5
5284 #define FX_VIBDELAY 6
5285 #define FX_NUMS 7
5286
5287 #define DEF_FX_CUTOFF 170
5288 #define DEF_FX_RESONANCE 6
5289 #define DEF_FX_ATTACK 50
5290 #define DEF_FX_RELEASE 50
5291 #define DEF_FX_VIBRATE 30
5292 #define DEF_FX_VIBDEPTH 4
5293 #define DEF_FX_VIBDELAY 1500
5294
5295 /* effect sense: */
5296 static int gs_sense[] =
5297 {
5298 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
5299 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
5300 };
5301 static int xg_sense[] =
5302 {
5303 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
5304 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
5305 };
5306
5307
5308 /* current status */
5309 static MidiStatus curst;
5310
5311
5312 static int
5313 awe_midi_open (int dev, int mode,
5314 void (*input)(int,unsigned char),
5315 void (*output)(int))
5316 {
5317 if (midi_opened)
5318 return -EBUSY;
5319
5320 midi_opened = TRUE;
5321
5322 midi_mode = MODE_GM;
5323
5324 curst.queue = Q_NONE;
5325 curst.qlen = 0;
5326 curst.read = 0;
5327 curst.status = 0;
5328 curst.chan = 0;
5329 memset(curst.buf, 0, sizeof(curst.buf));
5330
5331 init_midi_status(&curst);
5332
5333 return 0;
5334 }
5335
5336 static void
5337 awe_midi_close (int dev)
5338 {
5339 midi_opened = FALSE;
5340 }
5341
5342
5343 static int
5344 awe_midi_ioctl (int dev, unsigned cmd, caddr_t arg)
5345 {
5346 return -EPERM;
5347 }
5348
5349 static int
5350 awe_midi_outputc (int dev, unsigned char midi_byte)
5351 {
5352 if (! midi_opened)
5353 return 1;
5354
5355 /* force to change playing mode */
5356 playing_mode = AWE_PLAY_MULTI;
5357
5358 get_midi_char(&curst, midi_byte);
5359 return 1;
5360 }
5361
5362
5363 /*
5364 * initialize
5365 */
5366
5367 static void init_midi_status(MidiStatus *st)
5368 {
5369 clear_rpn();
5370 coarsetune = 0;
5371 finetune = 0;
5372 }
5373
5374
5375 /*
5376 * RPN & NRPN
5377 */
5378
5379 #define MAX_MIDI_CHANNELS 16
5380
5381 /* RPN & NRPN */
5382 static unsigned char nrpn[MAX_MIDI_CHANNELS]; /* current event is NRPN? */
5383 static int msb_bit; /* current event is msb for RPN/NRPN */
5384 /* RPN & NRPN indeces */
5385 static unsigned char rpn_msb[MAX_MIDI_CHANNELS], rpn_lsb[MAX_MIDI_CHANNELS];
5386 /* RPN & NRPN values */
5387 static int rpn_val[MAX_MIDI_CHANNELS];
5388
5389 static void clear_rpn(void)
5390 {
5391 int i;
5392 for (i = 0; i < MAX_MIDI_CHANNELS; i++) {
5393 nrpn[i] = 0;
5394 rpn_msb[i] = 127;
5395 rpn_lsb[i] = 127;
5396 rpn_val[i] = 0;
5397 }
5398 msb_bit = 0;
5399 }
5400
5401
5402 /*
5403 * process midi queue
5404 */
5405
5406 /* status event types */
5407 typedef void (*StatusEvent)(MidiStatus *st);
5408 static struct StatusEventList {
5409 StatusEvent process;
5410 int qlen;
5411 } status_event[8] = {
5412 {midi_note_off, 2},
5413 {midi_note_on, 2},
5414 {midi_key_pressure, 2},
5415 {midi_control_change, 2},
5416 {midi_program_change, 1},
5417 {midi_channel_pressure, 1},
5418 {midi_pitch_wheel, 2},
5419 {NULL, 0},
5420 };
5421
5422
5423 /* read a char from fifo and process it */
5424 static void get_midi_char(MidiStatus *st, int c)
5425 {
5426 if (c == 0xfe) {
5427 /* ignore active sense */
5428 st->queue = Q_NONE;
5429 return;
5430 }
5431
5432 switch (st->queue) {
5433 /* case Q_VARLEN: queue_varlen(st, c); break;*/
5434 case Q_READ:
5435 case Q_SYSEX:
5436 queue_read(st, c);
5437 break;
5438 case Q_NONE:
5439 st->read = 0;
5440 if ((c & 0xf0) == 0xf0) {
5441 special_event(st, c);
5442 } else if (c & 0x80) { /* status change */
5443 st->status = (c >> 4) & 0x07;
5444 st->chan = c & 0x0f;
5445 st->queue = Q_READ;
5446 st->qlen = status_event[st->status].qlen;
5447 if (st->qlen == 0)
5448 st->queue = Q_NONE;
5449 }
5450 break;
5451 }
5452 }
5453
5454 /* 0xfx events */
5455 static void special_event(MidiStatus *st, int c)
5456 {
5457 switch (c) {
5458 case 0xf0: /* system exclusive */
5459 st->queue = Q_SYSEX;
5460 st->qlen = 0;
5461 break;
5462 case 0xf1: /* MTC quarter frame */
5463 case 0xf3: /* song select */
5464 st->queue = Q_READ;
5465 st->qlen = 1;
5466 break;
5467 case 0xf2: /* song position */
5468 st->queue = Q_READ;
5469 st->qlen = 2;
5470 break;
5471 }
5472 }
5473
5474 #if 0
5475 /* read variable length value */
5476 static void queue_varlen(MidiStatus *st, int c)
5477 {
5478 st->qlen += (c & 0x7f);
5479 if (c & 0x80) {
5480 st->qlen <<= 7;
5481 return;
5482 }
5483 if (st->qlen <= 0) {
5484 st->qlen = 0;
5485 st->queue = Q_NONE;
5486 }
5487 st->queue = Q_READ;
5488 st->read = 0;
5489 }
5490 #endif
5491
5492
5493 /* read a char */
5494 static void queue_read(MidiStatus *st, int c)
5495 {
5496 if (st->read < MAX_MIDIBUF) {
5497 if (st->queue != Q_SYSEX)
5498 c &= 0x7f;
5499 st->buf[st->read] = (unsigned char)c;
5500 }
5501 st->read++;
5502 if (st->queue == Q_SYSEX && c == 0xf7) {
5503 midi_system_exclusive(st);
5504 st->queue = Q_NONE;
5505 } else if (st->queue == Q_READ && st->read >= st->qlen) {
5506 if (status_event[st->status].process)
5507 status_event[st->status].process(st);
5508 st->queue = Q_NONE;
5509 }
5510 }
5511
5512
5513 /*
5514 * status events
5515 */
5516
5517 /* note on */
5518 static void midi_note_on(MidiStatus *st)
5519 {
5520 DEBUG(2,printk("midi: note_on (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
5521 if (st->buf[1] == 0)
5522 midi_note_off(st);
5523 else
5524 awe_start_note(0, st->chan, st->buf[0], st->buf[1]);
5525 }
5526
5527 /* note off */
5528 static void midi_note_off(MidiStatus *st)
5529 {
5530 DEBUG(2,printk("midi: note_off (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
5531 awe_kill_note(0, st->chan, st->buf[0], st->buf[1]);
5532 }
5533
5534 /* key pressure change */
5535 static void midi_key_pressure(MidiStatus *st)
5536 {
5537 awe_key_pressure(0, st->chan, st->buf[0], st->buf[1]);
5538 }
5539
5540 /* channel pressure change */
5541 static void midi_channel_pressure(MidiStatus *st)
5542 {
5543 channels[st->chan].chan_press = st->buf[0];
5544 awe_modwheel_change(st->chan, st->buf[0]);
5545 }
5546
5547 /* pitch wheel change */
5548 static void midi_pitch_wheel(MidiStatus *st)
5549 {
5550 int val = (int)st->buf[1] * 128 + st->buf[0];
5551 awe_bender(0, st->chan, val);
5552 }
5553
5554 /* program change */
5555 static void midi_program_change(MidiStatus *st)
5556 {
5557 int preset;
5558 preset = st->buf[0];
5559 if (midi_mode == MODE_GS && IS_DRUM_CHANNEL(st->chan) && preset == 127)
5560 preset = 0;
5561 else if (midi_mode == MODE_XG && xg_mapping && IS_DRUM_CHANNEL(st->chan))
5562 preset += 64;
5563
5564 awe_set_instr(0, st->chan, preset);
5565 }
5566
5567 #define send_effect(chan,type,val) awe_send_effect(chan,-1,type,val)
5568 #define add_effect(chan,type,val) awe_send_effect(chan,-1,(type)|0x80,val)
5569 #define unset_effect(chan,type) awe_send_effect(chan,-1,(type)|0x40,0)
5570
5571 /* midi control change */
5572 static void midi_control_change(MidiStatus *st)
5573 {
5574 int cmd = st->buf[0];
5575 int val = st->buf[1];
5576
5577 DEBUG(2,printk("midi: control (%d) %d %d\n", st->chan, cmd, val));
5578 if (midi_mode == MODE_XG) {
5579 if (xg_control_change(st, cmd, val))
5580 return;
5581 }
5582
5583 /* controls #31 - #64 are LSB of #0 - #31 */
5584 msb_bit = 1;
5585 if (cmd >= 0x20 && cmd < 0x40) {
5586 msb_bit = 0;
5587 cmd -= 0x20;
5588 }
5589
5590 switch (cmd) {
5591 case CTL_SOFT_PEDAL:
5592 if (val == 127)
5593 add_effect(st->chan, AWE_FX_CUTOFF, -160);
5594 else
5595 unset_effect(st->chan, AWE_FX_CUTOFF);
5596 break;
5597
5598 case CTL_BANK_SELECT:
5599 midi_select_bank(st, val);
5600 break;
5601
5602 /* set RPN/NRPN parameter */
5603 case CTL_REGIST_PARM_NUM_MSB:
5604 nrpn[st->chan]=0; rpn_msb[st->chan]=val;
5605 break;
5606 case CTL_REGIST_PARM_NUM_LSB:
5607 nrpn[st->chan]=0; rpn_lsb[st->chan]=val;
5608 break;
5609 case CTL_NONREG_PARM_NUM_MSB:
5610 nrpn[st->chan]=1; rpn_msb[st->chan]=val;
5611 break;
5612 case CTL_NONREG_PARM_NUM_LSB:
5613 nrpn[st->chan]=1; rpn_lsb[st->chan]=val;
5614 break;
5615
5616 /* send RPN/NRPN entry */
5617 case CTL_DATA_ENTRY:
5618 if (msb_bit)
5619 rpn_val[st->chan] = val * 128;
5620 else
5621 rpn_val[st->chan] |= val;
5622 if (nrpn[st->chan])
5623 midi_nrpn_event(st);
5624 else
5625 midi_rpn_event(st);
5626 break;
5627
5628 /* increase/decrease data entry */
5629 case CTL_DATA_INCREMENT:
5630 rpn_val[st->chan]++;
5631 midi_rpn_event(st);
5632 break;
5633 case CTL_DATA_DECREMENT:
5634 rpn_val[st->chan]--;
5635 midi_rpn_event(st);
5636 break;
5637
5638 /* default */
5639 default:
5640 awe_controller(0, st->chan, cmd, val);
5641 break;
5642 }
5643 }
5644
5645 /* tone bank change */
5646 static void midi_select_bank(MidiStatus *st, int val)
5647 {
5648 if (midi_mode == MODE_XG && msb_bit) {
5649 xg_bankmode = val;
5650 /* XG MSB value; not normal bank selection */
5651 switch (val) {
5652 case 127: /* remap to drum channel */
5653 awe_controller(0, st->chan, CTL_BANK_SELECT, 128);
5654 break;
5655 default: /* remap to normal channel */
5656 awe_controller(0, st->chan, CTL_BANK_SELECT, val);
5657 break;
5658 }
5659 return;
5660 } else if (midi_mode == MODE_GS && !msb_bit)
5661 /* ignore LSB bank in GS mode (used for mapping) */
5662 return;
5663
5664 /* normal bank controls; accept both MSB and LSB */
5665 if (! IS_DRUM_CHANNEL(st->chan)) {
5666 if (midi_mode == MODE_XG) {
5667 if (xg_bankmode) return;
5668 if (val == 64 || val == 126)
5669 val = 0;
5670 } else if (midi_mode == MODE_GS && val == 127)
5671 val = 0;
5672 awe_controller(0, st->chan, CTL_BANK_SELECT, val);
5673 }
5674 }
5675
5676
5677 /*
5678 * RPN events
5679 */
5680
5681 static void midi_rpn_event(MidiStatus *st)
5682 {
5683 int type;
5684 type = (rpn_msb[st->chan]<<8) | rpn_lsb[st->chan];
5685 switch (type) {
5686 case 0x0000: /* Pitch bend sensitivity */
5687 /* MSB only / 1 semitone per 128 */
5688 if (msb_bit) {
5689 channels[st->chan].bender_range =
5690 rpn_val[st->chan] * 100 / 128;
5691 }
5692 break;
5693
5694 case 0x0001: /* fine tuning: */
5695 /* MSB/LSB, 8192=center, 100/8192 cent step */
5696 finetune = rpn_val[st->chan] - 8192;
5697 midi_detune(st->chan, coarsetune, finetune);
5698 break;
5699
5700 case 0x0002: /* coarse tuning */
5701 /* MSB only / 8192=center, 1 semitone per 128 */
5702 if (msb_bit) {
5703 coarsetune = rpn_val[st->chan] - 8192;
5704 midi_detune(st->chan, coarsetune, finetune);
5705 }
5706 break;
5707
5708 case 0x7F7F: /* "lock-in" RPN */
5709 break;
5710 }
5711 }
5712
5713
5714 /* tuning:
5715 * coarse = -8192 to 8192 (100 cent per 128)
5716 * fine = -8192 to 8192 (max=100cent)
5717 */
5718 static void midi_detune(int chan, int coarse, int fine)
5719 {
5720 /* 4096 = 1200 cents in AWE parameter */
5721 int val;
5722 val = coarse * 4096 / (12 * 128);
5723 val += fine / 24;
5724 if (val)
5725 send_effect(chan, AWE_FX_INIT_PITCH, val);
5726 else
5727 unset_effect(chan, AWE_FX_INIT_PITCH);
5728 }
5729
5730
5731 /*
5732 * system exclusive message
5733 * GM/GS/XG macros are accepted
5734 */
5735
5736 static void midi_system_exclusive(MidiStatus *st)
5737 {
5738 /* GM on */
5739 static unsigned char gm_on_macro[] = {
5740 0x7e,0x7f,0x09,0x01,
5741 };
5742 /* XG on */
5743 static unsigned char xg_on_macro[] = {
5744 0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,
5745 };
5746 /* GS prefix
5747 * drum channel: XX=0x1?(channel), YY=0x15, ZZ=on/off
5748 * reverb mode: XX=0x01, YY=0x30, ZZ=0-7
5749 * chorus mode: XX=0x01, YY=0x38, ZZ=0-7
5750 */
5751 static unsigned char gs_pfx_macro[] = {
5752 0x41,0x10,0x42,0x12,0x40,/*XX,YY,ZZ*/
5753 };
5754
5755 #if 0
5756 /* SC88 system mode set
5757 * single module mode: XX=1
5758 * double module mode: XX=0
5759 */
5760 static unsigned char gs_mode_macro[] = {
5761 0x41,0x10,0x42,0x12,0x00,0x00,0x7F,/*ZZ*/
5762 };
5763 /* SC88 display macro: XX=01:bitmap, 00:text
5764 */
5765 static unsigned char gs_disp_macro[] = {
5766 0x41,0x10,0x45,0x12,0x10,/*XX,00*/
5767 };
5768 #endif
5769
5770 /* GM on */
5771 if (memcmp(st->buf, gm_on_macro, sizeof(gm_on_macro)) == 0) {
5772 if (midi_mode != MODE_GS && midi_mode != MODE_XG)
5773 midi_mode = MODE_GM;
5774 init_midi_status(st);
5775 }
5776
5777 /* GS macros */
5778 else if (memcmp(st->buf, gs_pfx_macro, sizeof(gs_pfx_macro)) == 0) {
5779 if (midi_mode != MODE_GS && midi_mode != MODE_XG)
5780 midi_mode = MODE_GS;
5781
5782 if (st->buf[5] == 0x00 && st->buf[6] == 0x7f && st->buf[7] == 0x00) {
5783 /* GS reset */
5784 init_midi_status(st);
5785 }
5786
5787 else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x15) {
5788 /* drum pattern */
5789 int p = st->buf[5] & 0x0f;
5790 if (p == 0) p = 9;
5791 else if (p < 10) p--;
5792 if (st->buf[7] == 0)
5793 DRUM_CHANNEL_OFF(p);
5794 else
5795 DRUM_CHANNEL_ON(p);
5796
5797 } else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x21) {
5798 /* program */
5799 int p = st->buf[5] & 0x0f;
5800 if (p == 0) p = 9;
5801 else if (p < 10) p--;
5802 if (! IS_DRUM_CHANNEL(p))
5803 awe_set_instr(0, p, st->buf[7]);
5804
5805 } else if (st->buf[5] == 0x01 && st->buf[6] == 0x30) {
5806 /* reverb mode */
5807 awe_set_reverb_mode(st->buf[7]);
5808
5809 } else if (st->buf[5] == 0x01 && st->buf[6] == 0x38) {
5810 /* chorus mode */
5811 awe_set_chorus_mode(st->buf[7]);
5812
5813 } else if (st->buf[5] == 0x00 && st->buf[6] == 0x04) {
5814 /* master volume */
5815 awe_change_master_volume(st->buf[7]);
5816
5817 }
5818 }
5819
5820 /* XG on */
5821 else if (memcmp(st->buf, xg_on_macro, sizeof(xg_on_macro)) == 0) {
5822 midi_mode = MODE_XG;
5823 xg_mapping = TRUE;
5824 xg_bankmode = 0;
5825 }
5826 }
5827
5828
5829 /*----------------------------------------------------------------*/
5830
5831 /*
5832 * convert NRPN/control values
5833 */
5834
5835 static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
5836 {
5837 int i, cval;
5838 for (i = 0; i < num_tables; i++) {
5839 if (table[i].control == type) {
5840 cval = table[i].convert(val);
5841 send_effect(st->chan, table[i].awe_effect, cval);
5842 return TRUE;
5843 }
5844 }
5845 return FALSE;
5846 }
5847
5848 static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
5849 {
5850 int i, cval;
5851 for (i = 0; i < num_tables; i++) {
5852 if (table[i].control == type) {
5853 cval = table[i].convert(val);
5854 add_effect(st->chan, table[i].awe_effect|0x80, cval);
5855 return TRUE;
5856 }
5857 }
5858 return FALSE;
5859 }
5860
5861
5862 /*
5863 * AWE32 NRPN effects
5864 */
5865
5866 static unsigned short fx_delay(int val);
5867 static unsigned short fx_attack(int val);
5868 static unsigned short fx_hold(int val);
5869 static unsigned short fx_decay(int val);
5870 static unsigned short fx_the_value(int val);
5871 static unsigned short fx_twice_value(int val);
5872 static unsigned short fx_conv_pitch(int val);
5873 static unsigned short fx_conv_Q(int val);
5874
5875 /* function for each NRPN */ /* [range] units */
5876 #define fx_env1_delay fx_delay /* [0,5900] 4msec */
5877 #define fx_env1_attack fx_attack /* [0,5940] 1msec */
5878 #define fx_env1_hold fx_hold /* [0,8191] 1msec */
5879 #define fx_env1_decay fx_decay /* [0,5940] 4msec */
5880 #define fx_env1_release fx_decay /* [0,5940] 4msec */
5881 #define fx_env1_sustain fx_the_value /* [0,127] 0.75dB */
5882 #define fx_env1_pitch fx_the_value /* [-127,127] 9.375cents */
5883 #define fx_env1_cutoff fx_the_value /* [-127,127] 56.25cents */
5884
5885 #define fx_env2_delay fx_delay /* [0,5900] 4msec */
5886 #define fx_env2_attack fx_attack /* [0,5940] 1msec */
5887 #define fx_env2_hold fx_hold /* [0,8191] 1msec */
5888 #define fx_env2_decay fx_decay /* [0,5940] 4msec */
5889 #define fx_env2_release fx_decay /* [0,5940] 4msec */
5890 #define fx_env2_sustain fx_the_value /* [0,127] 0.75dB */
5891
5892 #define fx_lfo1_delay fx_delay /* [0,5900] 4msec */
5893 #define fx_lfo1_freq fx_twice_value /* [0,127] 84mHz */
5894 #define fx_lfo1_volume fx_twice_value /* [0,127] 0.1875dB */
5895 #define fx_lfo1_pitch fx_the_value /* [-127,127] 9.375cents */
5896 #define fx_lfo1_cutoff fx_twice_value /* [-64,63] 56.25cents */
5897
5898 #define fx_lfo2_delay fx_delay /* [0,5900] 4msec */
5899 #define fx_lfo2_freq fx_twice_value /* [0,127] 84mHz */
5900 #define fx_lfo2_pitch fx_the_value /* [-127,127] 9.375cents */
5901
5902 #define fx_init_pitch fx_conv_pitch /* [-8192,8192] cents */
5903 #define fx_chorus fx_the_value /* [0,255] -- */
5904 #define fx_reverb fx_the_value /* [0,255] -- */
5905 #define fx_cutoff fx_twice_value /* [0,127] 62Hz */
5906 #define fx_filterQ fx_conv_Q /* [0,127] -- */
5907
5908 static unsigned short fx_delay(int val)
5909 {
5910 return (unsigned short)calc_parm_delay(val);
5911 }
5912
5913 static unsigned short fx_attack(int val)
5914 {
5915 return (unsigned short)calc_parm_attack(val);
5916 }
5917
5918 static unsigned short fx_hold(int val)
5919 {
5920 return (unsigned short)calc_parm_hold(val);
5921 }
5922
5923 static unsigned short fx_decay(int val)
5924 {
5925 return (unsigned short)calc_parm_decay(val);
5926 }
5927
5928 static unsigned short fx_the_value(int val)
5929 {
5930 return (unsigned short)(val & 0xff);
5931 }
5932
5933 static unsigned short fx_twice_value(int val)
5934 {
5935 return (unsigned short)((val * 2) & 0xff);
5936 }
5937
5938 static unsigned short fx_conv_pitch(int val)
5939 {
5940 return (short)(val * 4096 / 1200);
5941 }
5942
5943 static unsigned short fx_conv_Q(int val)
5944 {
5945 return (unsigned short)((val / 8) & 0xff);
5946 }
5947
5948
5949 static ConvTable awe_effects[] =
5950 {
5951 { 0, AWE_FX_LFO1_DELAY, fx_lfo1_delay},
5952 { 1, AWE_FX_LFO1_FREQ, fx_lfo1_freq},
5953 { 2, AWE_FX_LFO2_DELAY, fx_lfo2_delay},
5954 { 3, AWE_FX_LFO2_FREQ, fx_lfo2_freq},
5955
5956 { 4, AWE_FX_ENV1_DELAY, fx_env1_delay},
5957 { 5, AWE_FX_ENV1_ATTACK,fx_env1_attack},
5958 { 6, AWE_FX_ENV1_HOLD, fx_env1_hold},
5959 { 7, AWE_FX_ENV1_DECAY, fx_env1_decay},
5960 { 8, AWE_FX_ENV1_SUSTAIN, fx_env1_sustain},
5961 { 9, AWE_FX_ENV1_RELEASE, fx_env1_release},
5962
5963 {10, AWE_FX_ENV2_DELAY, fx_env2_delay},
5964 {11, AWE_FX_ENV2_ATTACK, fx_env2_attack},
5965 {12, AWE_FX_ENV2_HOLD, fx_env2_hold},
5966 {13, AWE_FX_ENV2_DECAY, fx_env2_decay},
5967 {14, AWE_FX_ENV2_SUSTAIN, fx_env2_sustain},
5968 {15, AWE_FX_ENV2_RELEASE, fx_env2_release},
5969
5970 {16, AWE_FX_INIT_PITCH, fx_init_pitch},
5971 {17, AWE_FX_LFO1_PITCH, fx_lfo1_pitch},
5972 {18, AWE_FX_LFO2_PITCH, fx_lfo2_pitch},
5973 {19, AWE_FX_ENV1_PITCH, fx_env1_pitch},
5974 {20, AWE_FX_LFO1_VOLUME, fx_lfo1_volume},
5975 {21, AWE_FX_CUTOFF, fx_cutoff},
5976 {22, AWE_FX_FILTERQ, fx_filterQ},
5977 {23, AWE_FX_LFO1_CUTOFF, fx_lfo1_cutoff},
5978 {24, AWE_FX_ENV1_CUTOFF, fx_env1_cutoff},
5979 {25, AWE_FX_CHORUS, fx_chorus},
5980 {26, AWE_FX_REVERB, fx_reverb},
5981 };
5982
5983 static int num_awe_effects = numberof(awe_effects);
5984
5985
5986 /*
5987 * GS(SC88) NRPN effects; still experimental
5988 */
5989
5990 /* cutoff: quarter semitone step, max=255 */
5991 static unsigned short gs_cutoff(int val)
5992 {
5993 return (val - 64) * gs_sense[FX_CUTOFF] / 50;
5994 }
5995
5996 /* resonance: 0 to 15(max) */
5997 static unsigned short gs_filterQ(int val)
5998 {
5999 return (val - 64) * gs_sense[FX_RESONANCE] / 50;
6000 }
6001
6002 /* attack: */
6003 static unsigned short gs_attack(int val)
6004 {
6005 return -(val - 64) * gs_sense[FX_ATTACK] / 50;
6006 }
6007
6008 /* decay: */
6009 static unsigned short gs_decay(int val)
6010 {
6011 return -(val - 64) * gs_sense[FX_RELEASE] / 50;
6012 }
6013
6014 /* release: */
6015 static unsigned short gs_release(int val)
6016 {
6017 return -(val - 64) * gs_sense[FX_RELEASE] / 50;
6018 }
6019
6020 /* vibrato freq: 0.042Hz step, max=255 */
6021 static unsigned short gs_vib_rate(int val)
6022 {
6023 return (val - 64) * gs_sense[FX_VIBRATE] / 50;
6024 }
6025
6026 /* vibrato depth: max=127, 1 octave */
6027 static unsigned short gs_vib_depth(int val)
6028 {
6029 return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
6030 }
6031
6032 /* vibrato delay: -0.725msec step */
6033 static unsigned short gs_vib_delay(int val)
6034 {
6035 return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
6036 }
6037
6038 static ConvTable gs_effects[] =
6039 {
6040 {32, AWE_FX_CUTOFF, gs_cutoff},
6041 {33, AWE_FX_FILTERQ, gs_filterQ},
6042 {99, AWE_FX_ENV2_ATTACK, gs_attack},
6043 {100, AWE_FX_ENV2_DECAY, gs_decay},
6044 {102, AWE_FX_ENV2_RELEASE, gs_release},
6045 {8, AWE_FX_LFO1_FREQ, gs_vib_rate},
6046 {9, AWE_FX_LFO1_VOLUME, gs_vib_depth},
6047 {10, AWE_FX_LFO1_DELAY, gs_vib_delay},
6048 };
6049
6050 static int num_gs_effects = numberof(gs_effects);
6051
6052
6053 /*
6054 * NRPN events: accept as AWE32/SC88 specific controls
6055 */
6056
6057 static void midi_nrpn_event(MidiStatus *st)
6058 {
6059 if (rpn_msb[st->chan] == 127 && rpn_lsb[st->chan] <= 26) {
6060 if (! msb_bit) /* both MSB/LSB necessary */
6061 send_converted_effect(awe_effects, num_awe_effects,
6062 st, rpn_lsb[st->chan],
6063 rpn_val[st->chan] - 8192);
6064 } else if (rpn_msb[st->chan] == 1) {
6065 if (msb_bit) /* only MSB is valid */
6066 add_converted_effect(gs_effects, num_gs_effects,
6067 st, rpn_lsb[st->chan],
6068 rpn_val[st->chan] / 128);
6069 }
6070 }
6071
6072
6073 /*
6074 * XG control effects; still experimental
6075 */
6076
6077 /* cutoff: quarter semitone step, max=255 */
6078 static unsigned short xg_cutoff(int val)
6079 {
6080 return (val - 64) * xg_sense[FX_CUTOFF] / 64;
6081 }
6082
6083 /* resonance: 0(open) to 15(most nasal) */
6084 static unsigned short xg_filterQ(int val)
6085 {
6086 return (val - 64) * xg_sense[FX_RESONANCE] / 64;
6087 }
6088
6089 /* attack: */
6090 static unsigned short xg_attack(int val)
6091 {
6092 return -(val - 64) * xg_sense[FX_ATTACK] / 64;
6093 }
6094
6095 /* release: */
6096 static unsigned short xg_release(int val)
6097 {
6098 return -(val - 64) * xg_sense[FX_RELEASE] / 64;
6099 }
6100
6101 static ConvTable xg_effects[] =
6102 {
6103 {71, AWE_FX_CUTOFF, xg_cutoff},
6104 {74, AWE_FX_FILTERQ, xg_filterQ},
6105 {72, AWE_FX_ENV2_RELEASE, xg_release},
6106 {73, AWE_FX_ENV2_ATTACK, xg_attack},
6107 };
6108
6109 static int num_xg_effects = numberof(xg_effects);
6110
6111 static int xg_control_change(MidiStatus *st, int cmd, int val)
6112 {
6113 return add_converted_effect(xg_effects, num_xg_effects, st, cmd, val);
6114 }
6115
6116 #endif /* CONFIG_AWE32_MIDIEMU */
6117
6118
6119 /*----------------------------------------------------------------*/
6120
6121 /*
6122 * device / lowlevel (module) interface
6123 */
6124
6125 int __init attach_awe(void)
6126 {
6127 return _attach_awe() ? 0 : -ENODEV;
6128 }
6129
6130 void __exit unload_awe(void)
6131 {
6132 _unload_awe();
6133 #if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
6134 if (isapnp)
6135 awe_deactivate_isapnp();
6136 #endif /* isapnp */
6137 }
6138
6139
6140 module_init(attach_awe);
6141 module_exit(unload_awe);
6142
6143 #ifndef MODULE
6144 static int __init setup_awe(char *str)
6145 {
6146 /* io, memsize, isapnp */
6147 int ints[4];
6148
6149 str = get_options(str, ARRAY_SIZE(ints), ints);
6150
6151 io = ints[1];
6152 memsize = ints[2];
6153 isapnp = ints[3];
6154
6155 return 1;
6156 }
6157
6158 __setup("awe=", setup_awe);
6159 #endif
6160