[ARM] 3754/1: S3C24XX: tidy arch/arm/mach-s3c2410/Makefile
[linux-2.6/btrfs-unstable.git] / sound / oss / awe_wave.c
blobd1a0eb294d6f64c2b45aac340fb05ae0ba913429
1 /*
2 * sound/awe_wave.c
4 * The low level driver for the AWE32/SB32/AWE64 wave table synth.
5 * version 0.4.4; Jan. 4, 2000
7 * Copyright (C) 1996-2000 Takashi Iwai
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * Changelog:
26 * Aug 18, 2003, Adam Belay <ambx1@neo.rr.com>
27 * - detection code rewrite
30 #include <linux/awe_voice.h>
31 #include <linux/config.h>
32 #include <linux/init.h>
33 #include <linux/module.h>
34 #include <linux/string.h>
35 #include <linux/pnp.h>
37 #include "sound_config.h"
39 #include "awe_wave.h"
40 #include "awe_hw.h"
42 #ifdef AWE_HAS_GUS_COMPATIBILITY
43 #include "tuning.h"
44 #include <linux/ultrasound.h>
45 #endif
48 * debug message
51 #ifdef AWE_DEBUG_ON
52 #define DEBUG(LVL,XXX) {if (ctrls[AWE_MD_DEBUG_MODE] > LVL) { XXX; }}
53 #define ERRMSG(XXX) {if (ctrls[AWE_MD_DEBUG_MODE]) { XXX; }}
54 #define FATALERR(XXX) XXX
55 #else
56 #define DEBUG(LVL,XXX) /**/
57 #define ERRMSG(XXX) XXX
58 #define FATALERR(XXX) XXX
59 #endif
62 * bank and voice record
65 typedef struct _sf_list sf_list;
66 typedef struct _awe_voice_list awe_voice_list;
67 typedef struct _awe_sample_list awe_sample_list;
69 /* soundfont record */
70 struct _sf_list {
71 unsigned short sf_id; /* id number */
72 unsigned short type; /* lock & shared flags */
73 int num_info; /* current info table index */
74 int num_sample; /* current sample table index */
75 int mem_ptr; /* current word byte pointer */
76 awe_voice_list *infos, *last_infos; /* instruments */
77 awe_sample_list *samples, *last_samples; /* samples */
78 #ifdef AWE_ALLOW_SAMPLE_SHARING
79 sf_list *shared; /* shared list */
80 unsigned char name[AWE_PATCH_NAME_LEN]; /* sharing id */
81 #endif
82 sf_list *next, *prev;
85 /* instrument list */
86 struct _awe_voice_list {
87 awe_voice_info v; /* instrument information */
88 sf_list *holder; /* parent sf_list of this record */
89 unsigned char bank, instr; /* preset number information */
90 char type, disabled; /* type=normal/mapped, disabled=boolean */
91 awe_voice_list *next; /* linked list with same sf_id */
92 awe_voice_list *next_instr; /* instrument list */
93 awe_voice_list *next_bank; /* hash table list */
96 /* voice list type */
97 #define V_ST_NORMAL 0
98 #define V_ST_MAPPED 1
100 /* sample list */
101 struct _awe_sample_list {
102 awe_sample_info v; /* sample information */
103 sf_list *holder; /* parent sf_list of this record */
104 awe_sample_list *next; /* linked list with same sf_id */
107 /* sample and information table */
108 static int current_sf_id; /* current number of fonts */
109 static int locked_sf_id; /* locked position */
110 static sf_list *sfhead, *sftail; /* linked-lists */
112 #define awe_free_mem_ptr() (sftail ? sftail->mem_ptr : 0)
113 #define awe_free_info() (sftail ? sftail->num_info : 0)
114 #define awe_free_sample() (sftail ? sftail->num_sample : 0)
116 #define AWE_MAX_PRESETS 256
117 #define AWE_DEFAULT_PRESET 0
118 #define AWE_DEFAULT_BANK 0
119 #define AWE_DEFAULT_DRUM 0
120 #define AWE_DRUM_BANK 128
122 #define MAX_LAYERS AWE_MAX_VOICES
124 /* preset table index */
125 static awe_voice_list *preset_table[AWE_MAX_PRESETS];
128 * voice table
131 /* effects table */
132 typedef struct FX_Rec { /* channel effects */
133 unsigned char flags[AWE_FX_END];
134 short val[AWE_FX_END];
135 } FX_Rec;
138 /* channel parameters */
139 typedef struct _awe_chan_info {
140 int channel; /* channel number */
141 int bank; /* current tone bank */
142 int instr; /* current program */
143 int bender; /* midi pitchbend (-8192 - 8192) */
144 int bender_range; /* midi bender range (x100) */
145 int panning; /* panning (0-127) */
146 int main_vol; /* channel volume (0-127) */
147 int expression_vol; /* midi expression (0-127) */
148 int chan_press; /* channel pressure */
149 int sustained; /* sustain status in MIDI */
150 FX_Rec fx; /* effects */
151 FX_Rec fx_layer[MAX_LAYERS]; /* layer effects */
152 } awe_chan_info;
154 /* voice parameters */
155 typedef struct _voice_info {
156 int state;
157 #define AWE_ST_OFF (1<<0) /* no sound */
158 #define AWE_ST_ON (1<<1) /* playing */
159 #define AWE_ST_STANDBY (1<<2) /* stand by for playing */
160 #define AWE_ST_SUSTAINED (1<<3) /* sustained */
161 #define AWE_ST_MARK (1<<4) /* marked for allocation */
162 #define AWE_ST_DRAM (1<<5) /* DRAM read/write */
163 #define AWE_ST_FM (1<<6) /* reserved for FM */
164 #define AWE_ST_RELEASED (1<<7) /* released */
166 int ch; /* midi channel */
167 int key; /* internal key for search */
168 int layer; /* layer number (for channel mode only) */
169 int time; /* allocated time */
170 awe_chan_info *cinfo; /* channel info */
172 int note; /* midi key (0-127) */
173 int velocity; /* midi velocity (0-127) */
174 int sostenuto; /* sostenuto on/off */
175 awe_voice_info *sample; /* assigned voice */
177 /* EMU8000 parameters */
178 int apitch; /* pitch parameter */
179 int avol; /* volume parameter */
180 int apan; /* panning parameter */
181 int acutoff; /* cutoff parameter */
182 short aaux; /* aux word */
183 } voice_info;
185 /* voice information */
186 static voice_info voices[AWE_MAX_VOICES];
188 #define IS_NO_SOUND(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_RELEASED|AWE_ST_STANDBY|AWE_ST_SUSTAINED))
189 #define IS_NO_EFFECT(v) (voices[v].state != AWE_ST_ON)
190 #define IS_PLAYING(v) (voices[v].state & (AWE_ST_ON|AWE_ST_SUSTAINED|AWE_ST_RELEASED))
191 #define IS_EMPTY(v) (voices[v].state & (AWE_ST_OFF|AWE_ST_MARK|AWE_ST_DRAM|AWE_ST_FM))
194 /* MIDI channel effects information (for hw control) */
195 static awe_chan_info channels[AWE_MAX_CHANNELS];
199 * global variables
202 #ifndef AWE_DEFAULT_BASE_ADDR
203 #define AWE_DEFAULT_BASE_ADDR 0 /* autodetect */
204 #endif
206 #ifndef AWE_DEFAULT_MEM_SIZE
207 #define AWE_DEFAULT_MEM_SIZE -1 /* autodetect */
208 #endif
210 static int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
211 static int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
212 #ifdef CONFIG_PNP
213 static int isapnp = -1;
214 #else
215 static int isapnp;
216 #endif
218 MODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>");
219 MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver");
220 MODULE_LICENSE("GPL");
222 module_param(io, int, 0);
223 MODULE_PARM_DESC(io, "base i/o port of Emu8000");
224 module_param(memsize, int, 0);
225 MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes");
226 module_param(isapnp, bool, 0);
227 MODULE_PARM_DESC(isapnp, "use ISAPnP detection");
229 /* DRAM start offset */
230 static int awe_mem_start = AWE_DRAM_OFFSET;
232 /* maximum channels for playing */
233 static int awe_max_voices = AWE_MAX_VOICES;
235 static int patch_opened; /* sample already loaded? */
237 static char atten_relative = FALSE;
238 static short atten_offset;
240 static int awe_present = FALSE; /* awe device present? */
241 static int awe_busy = FALSE; /* awe device opened? */
243 static int my_dev = -1;
245 #define DEFAULT_DRUM_FLAGS ((1 << 9) | (1 << 25))
246 #define IS_DRUM_CHANNEL(c) (drum_flags & (1 << (c)))
247 #define DRUM_CHANNEL_ON(c) (drum_flags |= (1 << (c)))
248 #define DRUM_CHANNEL_OFF(c) (drum_flags &= ~(1 << (c)))
249 static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */
251 static int playing_mode = AWE_PLAY_INDIRECT;
252 #define SINGLE_LAYER_MODE() (playing_mode == AWE_PLAY_INDIRECT || playing_mode == AWE_PLAY_DIRECT)
253 #define MULTI_LAYER_MODE() (playing_mode == AWE_PLAY_MULTI || playing_mode == AWE_PLAY_MULTI2)
255 static int current_alloc_time; /* voice allocation index for channel mode */
257 static struct synth_info awe_info = {
258 "AWE32 Synth", /* name */
259 0, /* device */
260 SYNTH_TYPE_SAMPLE, /* synth_type */
261 SAMPLE_TYPE_AWE32, /* synth_subtype */
262 0, /* perc_mode (obsolete) */
263 AWE_MAX_VOICES, /* nr_voices */
264 0, /* nr_drums (obsolete) */
265 400 /* instr_bank_size */
269 static struct voice_alloc_info *voice_alloc; /* set at initialization */
273 * function prototypes
276 static int awe_request_region(void);
277 static void awe_release_region(void);
279 static void awe_reset_samples(void);
280 /* emu8000 chip i/o access */
281 static void setup_ports(int p1, int p2, int p3);
282 static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);
283 static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);
284 static unsigned short awe_peek(unsigned short cmd, unsigned short port);
285 static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);
286 static void awe_wait(unsigned short delay);
288 /* initialize emu8000 chip */
289 static void awe_initialize(void);
291 /* set voice parameters */
292 static void awe_init_ctrl_parms(int init_all);
293 static void awe_init_voice_info(awe_voice_info *vp);
294 static void awe_init_voice_parm(awe_voice_parm *pp);
295 #ifdef AWE_HAS_GUS_COMPATIBILITY
296 static int freq_to_note(int freq);
297 static int calc_rate_offset(int Hz);
298 /*static int calc_parm_delay(int msec);*/
299 static int calc_parm_hold(int msec);
300 static int calc_parm_attack(int msec);
301 static int calc_parm_decay(int msec);
302 static int calc_parm_search(int msec, short *table);
303 #endif /* gus compat */
305 /* turn on/off note */
306 static void awe_note_on(int voice);
307 static void awe_note_off(int voice);
308 static void awe_terminate(int voice);
309 static void awe_exclusive_off(int voice);
310 static void awe_note_off_all(int do_sustain);
312 /* calculate voice parameters */
313 typedef void (*fx_affect_func)(int voice, int forced);
314 static void awe_set_pitch(int voice, int forced);
315 static void awe_set_voice_pitch(int voice, int forced);
316 static void awe_set_volume(int voice, int forced);
317 static void awe_set_voice_vol(int voice, int forced);
318 static void awe_set_pan(int voice, int forced);
319 static void awe_fx_fmmod(int voice, int forced);
320 static void awe_fx_tremfrq(int voice, int forced);
321 static void awe_fx_fm2frq2(int voice, int forced);
322 static void awe_fx_filterQ(int voice, int forced);
323 static void awe_calc_pitch(int voice);
324 #ifdef AWE_HAS_GUS_COMPATIBILITY
325 static void awe_calc_pitch_from_freq(int voice, int freq);
326 #endif
327 static void awe_calc_volume(int voice);
328 static void awe_update_volume(void);
329 static void awe_change_master_volume(short val);
330 static void awe_voice_init(int voice, int init_all);
331 static void awe_channel_init(int ch, int init_all);
332 static void awe_fx_init(int ch);
333 static void awe_send_effect(int voice, int layer, int type, int val);
334 static void awe_modwheel_change(int voice, int value);
336 /* sequencer interface */
337 static int awe_open(int dev, int mode);
338 static void awe_close(int dev);
339 static int awe_ioctl(int dev, unsigned int cmd, void __user * arg);
340 static int awe_kill_note(int dev, int voice, int note, int velocity);
341 static int awe_start_note(int dev, int v, int note_num, int volume);
342 static int awe_set_instr(int dev, int voice, int instr_no);
343 static int awe_set_instr_2(int dev, int voice, int instr_no);
344 static void awe_reset(int dev);
345 static void awe_hw_control(int dev, unsigned char *event);
346 static int awe_load_patch(int dev, int format, const char __user *addr,
347 int offs, int count, int pmgr_flag);
348 static void awe_aftertouch(int dev, int voice, int pressure);
349 static void awe_controller(int dev, int voice, int ctrl_num, int value);
350 static void awe_panning(int dev, int voice, int value);
351 static void awe_volume_method(int dev, int mode);
352 static void awe_bender(int dev, int voice, int value);
353 static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc);
354 static void awe_setup_voice(int dev, int voice, int chn);
356 #define awe_key_pressure(dev,voice,key,press) awe_start_note(dev,voice,(key)+128,press)
358 /* hardware controls */
359 #ifdef AWE_HAS_GUS_COMPATIBILITY
360 static void awe_hw_gus_control(int dev, int cmd, unsigned char *event);
361 #endif
362 static void awe_hw_awe_control(int dev, int cmd, unsigned char *event);
363 static void awe_voice_change(int voice, fx_affect_func func);
364 static void awe_sostenuto_on(int voice, int forced);
365 static void awe_sustain_off(int voice, int forced);
366 static void awe_terminate_and_init(int voice, int forced);
368 /* voice search */
369 static int awe_search_key(int bank, int preset, int note);
370 static awe_voice_list *awe_search_instr(int bank, int preset, int note);
371 static int awe_search_multi_voices(awe_voice_list *rec, int note, int velocity, awe_voice_info **vlist);
372 static void awe_alloc_multi_voices(int ch, int note, int velocity, int key);
373 static void awe_alloc_one_voice(int voice, int note, int velocity);
374 static int awe_clear_voice(void);
376 /* load / remove patches */
377 static int awe_open_patch(awe_patch_info *patch, const char __user *addr, int count);
378 static int awe_close_patch(awe_patch_info *patch, const char __user *addr, int count);
379 static int awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count);
380 static int awe_load_info(awe_patch_info *patch, const char __user *addr, int count);
381 static int awe_remove_info(awe_patch_info *patch, const char __user *addr, int count);
382 static int awe_load_data(awe_patch_info *patch, const char __user *addr, int count);
383 static int awe_replace_data(awe_patch_info *patch, const char __user *addr, int count);
384 static int awe_load_map(awe_patch_info *patch, const char __user *addr, int count);
385 #ifdef AWE_HAS_GUS_COMPATIBILITY
386 static int awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag);
387 #endif
388 /*static int awe_probe_info(awe_patch_info *patch, const char __user *addr, int count);*/
389 static int awe_probe_data(awe_patch_info *patch, const char __user *addr, int count);
390 static sf_list *check_patch_opened(int type, char *name);
391 static int awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *sp, int channels);
392 static int awe_create_sf(int type, char *name);
393 static void awe_free_sf(sf_list *sf);
394 static void add_sf_info(sf_list *sf, awe_voice_list *rec);
395 static void add_sf_sample(sf_list *sf, awe_sample_list *smp);
396 static void purge_old_list(awe_voice_list *rec, awe_voice_list *next);
397 static void add_info_list(awe_voice_list *rec);
398 static void awe_remove_samples(int sf_id);
399 static void rebuild_preset_list(void);
400 static short awe_set_sample(awe_voice_list *rec);
401 static awe_sample_list *search_sample_index(sf_list *sf, int sample);
403 static int is_identical_holder(sf_list *sf1, sf_list *sf2);
404 #ifdef AWE_ALLOW_SAMPLE_SHARING
405 static int is_identical_name(unsigned char *name, sf_list *p);
406 static int is_shared_sf(unsigned char *name);
407 static int info_duplicated(sf_list *sf, awe_voice_list *rec);
408 #endif /* allow sharing */
410 /* lowlevel functions */
411 static void awe_init_audio(void);
412 static void awe_init_dma(void);
413 static void awe_init_array(void);
414 static void awe_send_array(unsigned short *data);
415 static void awe_tweak_voice(int voice);
416 static void awe_tweak(void);
417 static void awe_init_fm(void);
418 static int awe_open_dram_for_write(int offset, int channels);
419 static void awe_open_dram_for_check(void);
420 static void awe_close_dram(void);
421 /*static void awe_write_dram(unsigned short c);*/
422 static int awe_detect_base(int addr);
423 static int awe_detect(void);
424 static void awe_check_dram(void);
425 static int awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count);
426 static void awe_set_chorus_mode(int mode);
427 static void awe_update_chorus_mode(void);
428 static int awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count);
429 static void awe_set_reverb_mode(int mode);
430 static void awe_update_reverb_mode(void);
431 static void awe_equalizer(int bass, int treble);
432 static void awe_update_equalizer(void);
434 #ifdef CONFIG_AWE32_MIXER
435 static void attach_mixer(void);
436 static void unload_mixer(void);
437 #endif
439 #ifdef CONFIG_AWE32_MIDIEMU
440 static void attach_midiemu(void);
441 static void unload_midiemu(void);
442 #endif
444 #define limitvalue(x, a, b) if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b)
447 * control parameters
451 #ifdef AWE_USE_NEW_VOLUME_CALC
452 #define DEF_VOLUME_CALC TRUE
453 #else
454 #define DEF_VOLUME_CALC FALSE
455 #endif /* new volume */
457 #define DEF_ZERO_ATTEN 32 /* 12dB below */
458 #define DEF_MOD_SENSE 18
459 #define DEF_CHORUS_MODE 2
460 #define DEF_REVERB_MODE 4
461 #define DEF_BASS_LEVEL 5
462 #define DEF_TREBLE_LEVEL 9
464 static struct CtrlParmsDef {
465 int value;
466 int init_each_time;
467 void (*update)(void);
468 } ctrl_parms[AWE_MD_END] = {
469 {0,0, NULL}, {0,0, NULL}, /* <-- not used */
470 {AWE_VERSION_NUMBER, FALSE, NULL},
471 {TRUE, FALSE, NULL}, /* exclusive */
472 {TRUE, FALSE, NULL}, /* realpan */
473 {AWE_DEFAULT_BANK, FALSE, NULL}, /* gusbank */
474 {FALSE, TRUE, NULL}, /* keep effect */
475 {DEF_ZERO_ATTEN, FALSE, awe_update_volume}, /* zero_atten */
476 {FALSE, FALSE, NULL}, /* chn_prior */
477 {DEF_MOD_SENSE, FALSE, NULL}, /* modwheel sense */
478 {AWE_DEFAULT_PRESET, FALSE, NULL}, /* def_preset */
479 {AWE_DEFAULT_BANK, FALSE, NULL}, /* def_bank */
480 {AWE_DEFAULT_DRUM, FALSE, NULL}, /* def_drum */
481 {FALSE, FALSE, NULL}, /* toggle_drum_bank */
482 {DEF_VOLUME_CALC, FALSE, awe_update_volume}, /* new_volume_calc */
483 {DEF_CHORUS_MODE, FALSE, awe_update_chorus_mode}, /* chorus mode */
484 {DEF_REVERB_MODE, FALSE, awe_update_reverb_mode}, /* reverb mode */
485 {DEF_BASS_LEVEL, FALSE, awe_update_equalizer}, /* bass level */
486 {DEF_TREBLE_LEVEL, FALSE, awe_update_equalizer}, /* treble level */
487 {0, FALSE, NULL}, /* debug mode */
488 {FALSE, FALSE, NULL}, /* pan exchange */
491 static int ctrls[AWE_MD_END];
495 * synth operation table
498 static struct synth_operations awe_operations =
500 .owner = THIS_MODULE,
501 .id = "EMU8K",
502 .info = &awe_info,
503 .midi_dev = 0,
504 .synth_type = SYNTH_TYPE_SAMPLE,
505 .synth_subtype = SAMPLE_TYPE_AWE32,
506 .open = awe_open,
507 .close = awe_close,
508 .ioctl = awe_ioctl,
509 .kill_note = awe_kill_note,
510 .start_note = awe_start_note,
511 .set_instr = awe_set_instr_2,
512 .reset = awe_reset,
513 .hw_control = awe_hw_control,
514 .load_patch = awe_load_patch,
515 .aftertouch = awe_aftertouch,
516 .controller = awe_controller,
517 .panning = awe_panning,
518 .volume_method = awe_volume_method,
519 .bender = awe_bender,
520 .alloc_voice = awe_alloc,
521 .setup_voice = awe_setup_voice
524 static void free_tables(void)
526 if (sftail) {
527 sf_list *p, *prev;
528 for (p = sftail; p; p = prev) {
529 prev = p->prev;
530 awe_free_sf(p);
533 sfhead = sftail = NULL;
537 * clear sample tables
540 static void
541 awe_reset_samples(void)
543 /* free all bank tables */
544 memset(preset_table, 0, sizeof(preset_table));
545 free_tables();
547 current_sf_id = 0;
548 locked_sf_id = 0;
549 patch_opened = 0;
554 * EMU register access
557 /* select a given AWE32 pointer */
558 static int awe_ports[5];
559 static int port_setuped = FALSE;
560 static int awe_cur_cmd = -1;
561 #define awe_set_cmd(cmd) \
562 if (awe_cur_cmd != cmd) { outw(cmd, awe_ports[Pointer]); awe_cur_cmd = cmd; }
564 /* write 16bit data */
565 static void
566 awe_poke(unsigned short cmd, unsigned short port, unsigned short data)
568 awe_set_cmd(cmd);
569 outw(data, awe_ports[port]);
572 /* write 32bit data */
573 static void
574 awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data)
576 unsigned short addr = awe_ports[port];
577 awe_set_cmd(cmd);
578 outw(data, addr); /* write lower 16 bits */
579 outw(data >> 16, addr + 2); /* write higher 16 bits */
582 /* read 16bit data */
583 static unsigned short
584 awe_peek(unsigned short cmd, unsigned short port)
586 unsigned short k;
587 awe_set_cmd(cmd);
588 k = inw(awe_ports[port]);
589 return k;
592 /* read 32bit data */
593 static unsigned int
594 awe_peek_dw(unsigned short cmd, unsigned short port)
596 unsigned int k1, k2;
597 unsigned short addr = awe_ports[port];
598 awe_set_cmd(cmd);
599 k1 = inw(addr);
600 k2 = inw(addr + 2);
601 k1 |= k2 << 16;
602 return k1;
605 /* wait delay number of AWE32 44100Hz clocks */
606 #ifdef WAIT_BY_LOOP /* wait by loop -- that's not good.. */
607 static void
608 awe_wait(unsigned short delay)
610 unsigned short clock, target;
611 unsigned short port = awe_ports[AWE_WC_Port];
612 int counter;
614 /* sample counter */
615 awe_set_cmd(AWE_WC_Cmd);
616 clock = (unsigned short)inw(port);
617 target = clock + delay;
618 counter = 0;
619 if (target < clock) {
620 for (; (unsigned short)inw(port) > target; counter++)
621 if (counter > 65536)
622 break;
624 for (; (unsigned short)inw(port) < target; counter++)
625 if (counter > 65536)
626 break;
628 #else
630 static void awe_wait(unsigned short delay)
632 current->state = TASK_INTERRUPTIBLE;
633 schedule_timeout((HZ*(unsigned long)delay + 44099)/44100);
636 static void awe_wait(unsigned short delay)
638 udelay(((unsigned long)delay * 1000000L + 44099) / 44100);
641 #endif /* wait by loop */
643 /* write a word data */
644 #define awe_write_dram(c) awe_poke(AWE_SMLD, c)
647 * AWE32 voice parameters
650 /* initialize voice_info record */
651 static void
652 awe_init_voice_info(awe_voice_info *vp)
654 vp->sample = 0;
655 vp->rate_offset = 0;
657 vp->start = 0;
658 vp->end = 0;
659 vp->loopstart = 0;
660 vp->loopend = 0;
661 vp->mode = 0;
662 vp->root = 60;
663 vp->tune = 0;
664 vp->low = 0;
665 vp->high = 127;
666 vp->vellow = 0;
667 vp->velhigh = 127;
669 vp->fixkey = -1;
670 vp->fixvel = -1;
671 vp->fixpan = -1;
672 vp->pan = -1;
674 vp->exclusiveClass = 0;
675 vp->amplitude = 127;
676 vp->attenuation = 0;
677 vp->scaleTuning = 100;
679 awe_init_voice_parm(&vp->parm);
682 /* initialize voice_parm record:
683 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
684 * Vibrato and Tremolo effects are zero.
685 * Cutoff is maximum.
686 * Chorus and Reverb effects are zero.
688 static void
689 awe_init_voice_parm(awe_voice_parm *pp)
691 pp->moddelay = 0x8000;
692 pp->modatkhld = 0x7f7f;
693 pp->moddcysus = 0x7f7f;
694 pp->modrelease = 0x807f;
695 pp->modkeyhold = 0;
696 pp->modkeydecay = 0;
698 pp->voldelay = 0x8000;
699 pp->volatkhld = 0x7f7f;
700 pp->voldcysus = 0x7f7f;
701 pp->volrelease = 0x807f;
702 pp->volkeyhold = 0;
703 pp->volkeydecay = 0;
705 pp->lfo1delay = 0x8000;
706 pp->lfo2delay = 0x8000;
707 pp->pefe = 0;
709 pp->fmmod = 0;
710 pp->tremfrq = 0;
711 pp->fm2frq2 = 0;
713 pp->cutoff = 0xff;
714 pp->filterQ = 0;
716 pp->chorus = 0;
717 pp->reverb = 0;
721 #ifdef AWE_HAS_GUS_COMPATIBILITY
723 /* convert frequency mHz to abstract cents (= midi key * 100) */
724 static int
725 freq_to_note(int mHz)
727 /* abscents = log(mHz/8176) / log(2) * 1200 */
728 unsigned int max_val = (unsigned int)0xffffffff / 10000;
729 int i, times;
730 unsigned int base;
731 unsigned int freq;
732 int note, tune;
734 if (mHz == 0)
735 return 0;
736 if (mHz < 0)
737 return 12799; /* maximum */
739 freq = mHz;
740 note = 0;
741 for (base = 8176 * 2; freq >= base; base *= 2) {
742 note += 12;
743 if (note >= 128) /* over maximum */
744 return 12799;
746 base /= 2;
748 /* to avoid overflow... */
749 times = 10000;
750 while (freq > max_val) {
751 max_val *= 10;
752 times /= 10;
753 base /= 10;
756 freq = freq * times / base;
757 for (i = 0; i < 12; i++) {
758 if (freq < semitone_tuning[i+1])
759 break;
760 note++;
763 tune = 0;
764 freq = freq * 10000 / semitone_tuning[i];
765 for (i = 0; i < 100; i++) {
766 if (freq < cent_tuning[i+1])
767 break;
768 tune++;
771 return note * 100 + tune;
775 /* convert Hz to AWE32 rate offset:
776 * sample pitch offset for the specified sample rate
777 * rate=44100 is no offset, each 4096 is 1 octave (twice).
778 * eg, when rate is 22050, this offset becomes -4096.
780 static int
781 calc_rate_offset(int Hz)
783 /* offset = log(Hz / 44100) / log(2) * 4096 */
784 int freq, base, i;
786 /* maybe smaller than max (44100Hz) */
787 if (Hz <= 0 || Hz >= 44100) return 0;
789 base = 0;
790 for (freq = Hz * 2; freq < 44100; freq *= 2)
791 base++;
792 base *= 1200;
794 freq = 44100 * 10000 / (freq/2);
795 for (i = 0; i < 12; i++) {
796 if (freq < semitone_tuning[i+1])
797 break;
798 base += 100;
800 freq = freq * 10000 / semitone_tuning[i];
801 for (i = 0; i < 100; i++) {
802 if (freq < cent_tuning[i+1])
803 break;
804 base++;
806 return -base * 4096 / 1200;
811 * convert envelope time parameter to AWE32 raw parameter
814 /* attack & decay/release time table (msec) */
815 static short attack_time_tbl[128] = {
816 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
817 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
818 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
819 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
820 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
821 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
822 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
823 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
826 static short decay_time_tbl[128] = {
827 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
828 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
829 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
830 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
831 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
832 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
833 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
834 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
837 #define calc_parm_delay(msec) (0x8000 - (msec) * 1000 / 725);
839 /* delay time = 0x8000 - msec/92 */
840 static int
841 calc_parm_hold(int msec)
843 int val = (0x7f * 92 - msec) / 92;
844 if (val < 1) val = 1;
845 if (val > 127) val = 127;
846 return val;
849 /* attack time: search from time table */
850 static int
851 calc_parm_attack(int msec)
853 return calc_parm_search(msec, attack_time_tbl);
856 /* decay/release time: search from time table */
857 static int
858 calc_parm_decay(int msec)
860 return calc_parm_search(msec, decay_time_tbl);
863 /* search an index for specified time from given time table */
864 static int
865 calc_parm_search(int msec, short *table)
867 int left = 1, right = 127, mid;
868 while (left < right) {
869 mid = (left + right) / 2;
870 if (msec < (int)table[mid])
871 left = mid + 1;
872 else
873 right = mid;
875 return left;
877 #endif /* AWE_HAS_GUS_COMPATIBILITY */
881 * effects table
884 /* set an effect value */
885 #define FX_FLAG_OFF 0
886 #define FX_FLAG_SET 1
887 #define FX_FLAG_ADD 2
889 #define FX_SET(rec,type,value) \
890 ((rec)->flags[type] = FX_FLAG_SET, (rec)->val[type] = (value))
891 #define FX_ADD(rec,type,value) \
892 ((rec)->flags[type] = FX_FLAG_ADD, (rec)->val[type] = (value))
893 #define FX_UNSET(rec,type) \
894 ((rec)->flags[type] = FX_FLAG_OFF, (rec)->val[type] = 0)
896 /* check the effect value is set */
897 #define FX_ON(rec,type) ((rec)->flags[type])
899 #define PARM_BYTE 0
900 #define PARM_WORD 1
901 #define PARM_SIGN 2
903 static struct PARM_DEFS {
904 int type; /* byte or word */
905 int low, high; /* value range */
906 fx_affect_func realtime; /* realtime paramater change */
907 } parm_defs[] = {
908 {PARM_WORD, 0, 0x8000, NULL}, /* env1 delay */
909 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 attack */
910 {PARM_BYTE, 0, 0x7e, NULL}, /* env1 hold */
911 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 decay */
912 {PARM_BYTE, 1, 0x7f, NULL}, /* env1 release */
913 {PARM_BYTE, 0, 0x7f, NULL}, /* env1 sustain */
914 {PARM_BYTE, 0, 0xff, NULL}, /* env1 pitch */
915 {PARM_BYTE, 0, 0xff, NULL}, /* env1 cutoff */
917 {PARM_WORD, 0, 0x8000, NULL}, /* env2 delay */
918 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 attack */
919 {PARM_BYTE, 0, 0x7e, NULL}, /* env2 hold */
920 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 decay */
921 {PARM_BYTE, 1, 0x7f, NULL}, /* env2 release */
922 {PARM_BYTE, 0, 0x7f, NULL}, /* env2 sustain */
924 {PARM_WORD, 0, 0x8000, NULL}, /* lfo1 delay */
925 {PARM_BYTE, 0, 0xff, awe_fx_tremfrq}, /* lfo1 freq */
926 {PARM_SIGN, -128, 127, awe_fx_tremfrq}, /* lfo1 volume */
927 {PARM_SIGN, -128, 127, awe_fx_fmmod}, /* lfo1 pitch */
928 {PARM_BYTE, 0, 0xff, awe_fx_fmmod}, /* lfo1 cutoff */
930 {PARM_WORD, 0, 0x8000, NULL}, /* lfo2 delay */
931 {PARM_BYTE, 0, 0xff, awe_fx_fm2frq2}, /* lfo2 freq */
932 {PARM_SIGN, -128, 127, awe_fx_fm2frq2}, /* lfo2 pitch */
934 {PARM_WORD, 0, 0xffff, awe_set_voice_pitch}, /* initial pitch */
935 {PARM_BYTE, 0, 0xff, NULL}, /* chorus */
936 {PARM_BYTE, 0, 0xff, NULL}, /* reverb */
937 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial cutoff */
938 {PARM_BYTE, 0, 15, awe_fx_filterQ}, /* initial resonance */
940 {PARM_WORD, 0, 0xffff, NULL}, /* sample start */
941 {PARM_WORD, 0, 0xffff, NULL}, /* loop start */
942 {PARM_WORD, 0, 0xffff, NULL}, /* loop end */
943 {PARM_WORD, 0, 0xffff, NULL}, /* coarse sample start */
944 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop start */
945 {PARM_WORD, 0, 0xffff, NULL}, /* coarse loop end */
946 {PARM_BYTE, 0, 0xff, awe_set_volume}, /* initial attenuation */
950 static unsigned char
951 FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value)
953 int effect = 0;
954 int on = 0;
955 if (lay && (on = FX_ON(lay, type)) != 0)
956 effect = lay->val[type];
957 if (!on && (on = FX_ON(rec, type)) != 0)
958 effect = rec->val[type];
959 if (on == FX_FLAG_ADD) {
960 if (parm_defs[type].type == PARM_SIGN) {
961 if (value > 0x7f)
962 effect += (int)value - 0x100;
963 else
964 effect += (int)value;
965 } else {
966 effect += (int)value;
969 if (on) {
970 if (effect < parm_defs[type].low)
971 effect = parm_defs[type].low;
972 else if (effect > parm_defs[type].high)
973 effect = parm_defs[type].high;
974 return (unsigned char)effect;
976 return value;
979 /* get word effect value */
980 static unsigned short
981 FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value)
983 int effect = 0;
984 int on = 0;
985 if (lay && (on = FX_ON(lay, type)) != 0)
986 effect = lay->val[type];
987 if (!on && (on = FX_ON(rec, type)) != 0)
988 effect = rec->val[type];
989 if (on == FX_FLAG_ADD)
990 effect += (int)value;
991 if (on) {
992 if (effect < parm_defs[type].low)
993 effect = parm_defs[type].low;
994 else if (effect > parm_defs[type].high)
995 effect = parm_defs[type].high;
996 return (unsigned short)effect;
998 return value;
1001 /* get word (upper=type1/lower=type2) effect value */
1002 static unsigned short
1003 FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value)
1005 unsigned short tmp;
1006 tmp = FX_BYTE(rec, lay, type1, (unsigned char)(value >> 8));
1007 tmp <<= 8;
1008 tmp |= FX_BYTE(rec, lay, type2, (unsigned char)(value & 0xff));
1009 return tmp;
1012 /* address offset */
1013 static int
1014 FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode)
1016 int addr = 0;
1017 if (lay && FX_ON(lay, hi))
1018 addr = (short)lay->val[hi];
1019 else if (FX_ON(rec, hi))
1020 addr = (short)rec->val[hi];
1021 addr = addr << 15;
1022 if (lay && FX_ON(lay, lo))
1023 addr += (short)lay->val[lo];
1024 else if (FX_ON(rec, lo))
1025 addr += (short)rec->val[lo];
1026 if (!(mode & AWE_SAMPLE_8BITS))
1027 addr /= 2;
1028 return addr;
1033 * turn on/off sample
1036 /* table for volume target calculation */
1037 static unsigned short voltarget[16] = {
1038 0xEAC0, 0XE0C8, 0XD740, 0XCE20, 0XC560, 0XBD08, 0XB500, 0XAD58,
1039 0XA5F8, 0X9EF0, 0X9830, 0X91C0, 0X8B90, 0X85A8, 0X8000, 0X7A90
1042 static void
1043 awe_note_on(int voice)
1045 unsigned int temp;
1046 int addr;
1047 int vtarget, ftarget, ptarget, pitch;
1048 awe_voice_info *vp;
1049 awe_voice_parm_block *parm;
1050 FX_Rec *fx = &voices[voice].cinfo->fx;
1051 FX_Rec *fx_lay = NULL;
1052 if (voices[voice].layer < MAX_LAYERS)
1053 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1055 /* A voice sample must assigned before calling */
1056 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1057 return;
1059 parm = (awe_voice_parm_block*)&vp->parm;
1061 /* channel to be silent and idle */
1062 awe_poke(AWE_DCYSUSV(voice), 0x0080);
1063 awe_poke(AWE_VTFT(voice), 0x0000FFFF);
1064 awe_poke(AWE_CVCF(voice), 0x0000FFFF);
1065 awe_poke(AWE_PTRX(voice), 0);
1066 awe_poke(AWE_CPF(voice), 0);
1068 /* set pitch offset */
1069 awe_set_pitch(voice, TRUE);
1071 /* modulation & volume envelope */
1072 if (parm->modatk >= 0x80 && parm->moddelay >= 0x8000) {
1073 awe_poke(AWE_ENVVAL(voice), 0xBFFF);
1074 pitch = (parm->env1pit<<4) + voices[voice].apitch;
1075 if (pitch > 0xffff) pitch = 0xffff;
1076 /* calculate filter target */
1077 ftarget = parm->cutoff + parm->env1fc;
1078 limitvalue(ftarget, 0, 255);
1079 ftarget <<= 8;
1080 } else {
1081 awe_poke(AWE_ENVVAL(voice),
1082 FX_WORD(fx, fx_lay, AWE_FX_ENV1_DELAY, parm->moddelay));
1083 ftarget = parm->cutoff;
1084 ftarget <<= 8;
1085 pitch = voices[voice].apitch;
1088 /* calcualte pitch target */
1089 if (pitch != 0xffff) {
1090 ptarget = 1 << (pitch >> 12);
1091 if (pitch & 0x800) ptarget += (ptarget*0x102e)/0x2710;
1092 if (pitch & 0x400) ptarget += (ptarget*0x764)/0x2710;
1093 if (pitch & 0x200) ptarget += (ptarget*0x389)/0x2710;
1094 ptarget += (ptarget>>1);
1095 if (ptarget > 0xffff) ptarget = 0xffff;
1097 } else ptarget = 0xffff;
1098 if (parm->modatk >= 0x80)
1099 awe_poke(AWE_ATKHLD(voice),
1100 FX_BYTE(fx, fx_lay, AWE_FX_ENV1_HOLD, parm->modhld) << 8 | 0x7f);
1101 else
1102 awe_poke(AWE_ATKHLD(voice),
1103 FX_COMB(fx, fx_lay, AWE_FX_ENV1_HOLD, AWE_FX_ENV1_ATTACK,
1104 vp->parm.modatkhld));
1105 awe_poke(AWE_DCYSUS(voice),
1106 FX_COMB(fx, fx_lay, AWE_FX_ENV1_SUSTAIN, AWE_FX_ENV1_DECAY,
1107 vp->parm.moddcysus));
1109 if (parm->volatk >= 0x80 && parm->voldelay >= 0x8000) {
1110 awe_poke(AWE_ENVVOL(voice), 0xBFFF);
1111 vtarget = voltarget[voices[voice].avol%0x10]>>(voices[voice].avol>>4);
1112 } else {
1113 awe_poke(AWE_ENVVOL(voice),
1114 FX_WORD(fx, fx_lay, AWE_FX_ENV2_DELAY, vp->parm.voldelay));
1115 vtarget = 0;
1117 if (parm->volatk >= 0x80)
1118 awe_poke(AWE_ATKHLDV(voice),
1119 FX_BYTE(fx, fx_lay, AWE_FX_ENV2_HOLD, parm->volhld) << 8 | 0x7f);
1120 else
1121 awe_poke(AWE_ATKHLDV(voice),
1122 FX_COMB(fx, fx_lay, AWE_FX_ENV2_HOLD, AWE_FX_ENV2_ATTACK,
1123 vp->parm.volatkhld));
1124 /* decay/sustain parameter for volume envelope must be set at last */
1126 /* cutoff and volume */
1127 awe_set_volume(voice, TRUE);
1129 /* modulation envelope heights */
1130 awe_poke(AWE_PEFE(voice),
1131 FX_COMB(fx, fx_lay, AWE_FX_ENV1_PITCH, AWE_FX_ENV1_CUTOFF,
1132 vp->parm.pefe));
1134 /* lfo1/2 delay */
1135 awe_poke(AWE_LFO1VAL(voice),
1136 FX_WORD(fx, fx_lay, AWE_FX_LFO1_DELAY, vp->parm.lfo1delay));
1137 awe_poke(AWE_LFO2VAL(voice),
1138 FX_WORD(fx, fx_lay, AWE_FX_LFO2_DELAY, vp->parm.lfo2delay));
1140 /* lfo1 pitch & cutoff shift */
1141 awe_fx_fmmod(voice, TRUE);
1142 /* lfo1 volume & freq */
1143 awe_fx_tremfrq(voice, TRUE);
1144 /* lfo2 pitch & freq */
1145 awe_fx_fm2frq2(voice, TRUE);
1146 /* pan & loop start */
1147 awe_set_pan(voice, TRUE);
1149 /* chorus & loop end (chorus 8bit, MSB) */
1150 addr = vp->loopend - 1;
1151 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_END,
1152 AWE_FX_COARSE_LOOP_END, vp->mode);
1153 temp = FX_BYTE(fx, fx_lay, AWE_FX_CHORUS, vp->parm.chorus);
1154 temp = (temp <<24) | (unsigned int)addr;
1155 awe_poke_dw(AWE_CSL(voice), temp);
1156 DEBUG(4,printk("AWE32: [-- loopend=%x/%x]\n", vp->loopend, addr));
1158 /* Q & current address (Q 4bit value, MSB) */
1159 addr = vp->start - 1;
1160 addr += FX_OFFSET(fx, fx_lay, AWE_FX_SAMPLE_START,
1161 AWE_FX_COARSE_SAMPLE_START, vp->mode);
1162 temp = FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ);
1163 temp = (temp<<28) | (unsigned int)addr;
1164 awe_poke_dw(AWE_CCCA(voice), temp);
1165 DEBUG(4,printk("AWE32: [-- startaddr=%x/%x]\n", vp->start, addr));
1167 /* clear unknown registers */
1168 awe_poke_dw(AWE_00A0(voice), 0);
1169 awe_poke_dw(AWE_0080(voice), 0);
1171 /* reset volume */
1172 awe_poke_dw(AWE_VTFT(voice), (vtarget<<16)|ftarget);
1173 awe_poke_dw(AWE_CVCF(voice), (vtarget<<16)|ftarget);
1175 /* set reverb */
1176 temp = FX_BYTE(fx, fx_lay, AWE_FX_REVERB, vp->parm.reverb);
1177 temp = (temp << 8) | (ptarget << 16) | voices[voice].aaux;
1178 awe_poke_dw(AWE_PTRX(voice), temp);
1179 awe_poke_dw(AWE_CPF(voice), ptarget << 16);
1180 /* turn on envelope */
1181 awe_poke(AWE_DCYSUSV(voice),
1182 FX_COMB(fx, fx_lay, AWE_FX_ENV2_SUSTAIN, AWE_FX_ENV2_DECAY,
1183 vp->parm.voldcysus));
1185 voices[voice].state = AWE_ST_ON;
1187 /* clear voice position for the next note on this channel */
1188 if (SINGLE_LAYER_MODE()) {
1189 FX_UNSET(fx, AWE_FX_SAMPLE_START);
1190 FX_UNSET(fx, AWE_FX_COARSE_SAMPLE_START);
1195 /* turn off the voice */
1196 static void
1197 awe_note_off(int voice)
1199 awe_voice_info *vp;
1200 unsigned short tmp;
1201 FX_Rec *fx = &voices[voice].cinfo->fx;
1202 FX_Rec *fx_lay = NULL;
1203 if (voices[voice].layer < MAX_LAYERS)
1204 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1206 if ((vp = voices[voice].sample) == NULL) {
1207 voices[voice].state = AWE_ST_OFF;
1208 return;
1211 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV1_RELEASE,
1212 (unsigned char)vp->parm.modrelease);
1213 awe_poke(AWE_DCYSUS(voice), tmp);
1214 tmp = 0x8000 | FX_BYTE(fx, fx_lay, AWE_FX_ENV2_RELEASE,
1215 (unsigned char)vp->parm.volrelease);
1216 awe_poke(AWE_DCYSUSV(voice), tmp);
1217 voices[voice].state = AWE_ST_RELEASED;
1220 /* force to terminate the voice (no releasing echo) */
1221 static void
1222 awe_terminate(int voice)
1224 awe_poke(AWE_DCYSUSV(voice), 0x807F);
1225 awe_tweak_voice(voice);
1226 voices[voice].state = AWE_ST_OFF;
1229 /* turn off other voices with the same exclusive class (for drums) */
1230 static void
1231 awe_exclusive_off(int voice)
1233 int i, exclass;
1235 if (voices[voice].sample == NULL)
1236 return;
1237 if ((exclass = voices[voice].sample->exclusiveClass) == 0)
1238 return; /* not exclusive */
1240 /* turn off voices with the same class */
1241 for (i = 0; i < awe_max_voices; i++) {
1242 if (i != voice && IS_PLAYING(i) &&
1243 voices[i].sample && voices[i].ch == voices[voice].ch &&
1244 voices[i].sample->exclusiveClass == exclass) {
1245 DEBUG(4,printk("AWE32: [exoff(%d)]\n", i));
1246 awe_terminate(i);
1247 awe_voice_init(i, TRUE);
1254 * change the parameters of an audible voice
1257 /* change pitch */
1258 static void
1259 awe_set_pitch(int voice, int forced)
1261 if (IS_NO_EFFECT(voice) && !forced) return;
1262 awe_poke(AWE_IP(voice), voices[voice].apitch);
1263 DEBUG(3,printk("AWE32: [-- pitch=%x]\n", voices[voice].apitch));
1266 /* calculate & change pitch */
1267 static void
1268 awe_set_voice_pitch(int voice, int forced)
1270 awe_calc_pitch(voice);
1271 awe_set_pitch(voice, forced);
1274 /* change volume & cutoff */
1275 static void
1276 awe_set_volume(int voice, int forced)
1278 awe_voice_info *vp;
1279 unsigned short tmp2;
1280 FX_Rec *fx = &voices[voice].cinfo->fx;
1281 FX_Rec *fx_lay = NULL;
1282 if (voices[voice].layer < MAX_LAYERS)
1283 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1285 if (!IS_PLAYING(voice) && !forced) return;
1286 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1287 return;
1289 tmp2 = FX_BYTE(fx, fx_lay, AWE_FX_CUTOFF,
1290 (unsigned char)voices[voice].acutoff);
1291 tmp2 = (tmp2 << 8);
1292 tmp2 |= FX_BYTE(fx, fx_lay, AWE_FX_ATTEN,
1293 (unsigned char)voices[voice].avol);
1294 awe_poke(AWE_IFATN(voice), tmp2);
1297 /* calculate & change volume */
1298 static void
1299 awe_set_voice_vol(int voice, int forced)
1301 if (IS_EMPTY(voice))
1302 return;
1303 awe_calc_volume(voice);
1304 awe_set_volume(voice, forced);
1308 /* change pan; this could make a click noise.. */
1309 static void
1310 awe_set_pan(int voice, int forced)
1312 unsigned int temp;
1313 int addr;
1314 awe_voice_info *vp;
1315 FX_Rec *fx = &voices[voice].cinfo->fx;
1316 FX_Rec *fx_lay = NULL;
1317 if (voices[voice].layer < MAX_LAYERS)
1318 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1320 if (IS_NO_EFFECT(voice) && !forced) return;
1321 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1322 return;
1324 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
1325 if (vp->fixpan > 0) /* 0-127 */
1326 temp = 255 - (int)vp->fixpan * 2;
1327 else {
1328 int pos = 0;
1329 if (vp->pan >= 0) /* 0-127 */
1330 pos = (int)vp->pan * 2 - 128;
1331 pos += voices[voice].cinfo->panning; /* -128 - 127 */
1332 temp = 127 - pos;
1334 limitvalue(temp, 0, 255);
1335 if (ctrls[AWE_MD_PAN_EXCHANGE]) {
1336 temp = 255 - temp;
1338 if (forced || temp != voices[voice].apan) {
1339 voices[voice].apan = temp;
1340 if (temp == 0)
1341 voices[voice].aaux = 0xff;
1342 else
1343 voices[voice].aaux = (-temp) & 0xff;
1344 addr = vp->loopstart - 1;
1345 addr += FX_OFFSET(fx, fx_lay, AWE_FX_LOOP_START,
1346 AWE_FX_COARSE_LOOP_START, vp->mode);
1347 temp = (temp<<24) | (unsigned int)addr;
1348 awe_poke_dw(AWE_PSST(voice), temp);
1349 DEBUG(4,printk("AWE32: [-- loopstart=%x/%x]\n", vp->loopstart, addr));
1353 /* effects change during playing */
1354 static void
1355 awe_fx_fmmod(int voice, int forced)
1357 awe_voice_info *vp;
1358 FX_Rec *fx = &voices[voice].cinfo->fx;
1359 FX_Rec *fx_lay = NULL;
1360 if (voices[voice].layer < MAX_LAYERS)
1361 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1363 if (IS_NO_EFFECT(voice) && !forced) return;
1364 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1365 return;
1366 awe_poke(AWE_FMMOD(voice),
1367 FX_COMB(fx, fx_lay, AWE_FX_LFO1_PITCH, AWE_FX_LFO1_CUTOFF,
1368 vp->parm.fmmod));
1371 /* set tremolo (lfo1) volume & frequency */
1372 static void
1373 awe_fx_tremfrq(int voice, int forced)
1375 awe_voice_info *vp;
1376 FX_Rec *fx = &voices[voice].cinfo->fx;
1377 FX_Rec *fx_lay = NULL;
1378 if (voices[voice].layer < MAX_LAYERS)
1379 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1381 if (IS_NO_EFFECT(voice) && !forced) return;
1382 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1383 return;
1384 awe_poke(AWE_TREMFRQ(voice),
1385 FX_COMB(fx, fx_lay, AWE_FX_LFO1_VOLUME, AWE_FX_LFO1_FREQ,
1386 vp->parm.tremfrq));
1389 /* set lfo2 pitch & frequency */
1390 static void
1391 awe_fx_fm2frq2(int voice, int forced)
1393 awe_voice_info *vp;
1394 FX_Rec *fx = &voices[voice].cinfo->fx;
1395 FX_Rec *fx_lay = NULL;
1396 if (voices[voice].layer < MAX_LAYERS)
1397 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1399 if (IS_NO_EFFECT(voice) && !forced) return;
1400 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1401 return;
1402 awe_poke(AWE_FM2FRQ2(voice),
1403 FX_COMB(fx, fx_lay, AWE_FX_LFO2_PITCH, AWE_FX_LFO2_FREQ,
1404 vp->parm.fm2frq2));
1408 /* Q & current address (Q 4bit value, MSB) */
1409 static void
1410 awe_fx_filterQ(int voice, int forced)
1412 unsigned int addr;
1413 awe_voice_info *vp;
1414 FX_Rec *fx = &voices[voice].cinfo->fx;
1415 FX_Rec *fx_lay = NULL;
1416 if (voices[voice].layer < MAX_LAYERS)
1417 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1419 if (IS_NO_EFFECT(voice) && !forced) return;
1420 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1421 return;
1423 addr = awe_peek_dw(AWE_CCCA(voice)) & 0xffffff;
1424 addr |= (FX_BYTE(fx, fx_lay, AWE_FX_FILTERQ, vp->parm.filterQ) << 28);
1425 awe_poke_dw(AWE_CCCA(voice), addr);
1429 * calculate pitch offset
1431 * 0xE000 is no pitch offset at 44100Hz sample.
1432 * Every 4096 is one octave.
1435 static void
1436 awe_calc_pitch(int voice)
1438 voice_info *vp = &voices[voice];
1439 awe_voice_info *ap;
1440 awe_chan_info *cp = voices[voice].cinfo;
1441 int offset;
1443 /* search voice information */
1444 if ((ap = vp->sample) == NULL)
1445 return;
1446 if (ap->index == 0) {
1447 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1448 if (awe_set_sample((awe_voice_list*)ap) == 0)
1449 return;
1452 /* calculate offset */
1453 if (ap->fixkey >= 0) {
1454 DEBUG(3,printk("AWE32: p-> fixkey(%d) tune(%d)\n", ap->fixkey, ap->tune));
1455 offset = (ap->fixkey - ap->root) * 4096 / 12;
1456 } else {
1457 DEBUG(3,printk("AWE32: p(%d)-> root(%d) tune(%d)\n", vp->note, ap->root, ap->tune));
1458 offset = (vp->note - ap->root) * 4096 / 12;
1459 DEBUG(4,printk("AWE32: p-> ofs=%d\n", offset));
1461 offset = (offset * ap->scaleTuning) / 100;
1462 DEBUG(4,printk("AWE32: p-> scale* ofs=%d\n", offset));
1463 offset += ap->tune * 4096 / 1200;
1464 DEBUG(4,printk("AWE32: p-> tune+ ofs=%d\n", offset));
1465 if (cp->bender != 0) {
1466 DEBUG(3,printk("AWE32: p-> bend(%d) %d\n", voice, cp->bender));
1467 /* (819200: 1 semitone) ==> (4096: 12 semitones) */
1468 offset += cp->bender * cp->bender_range / 2400;
1471 /* add initial pitch correction */
1472 if (FX_ON(&cp->fx_layer[vp->layer], AWE_FX_INIT_PITCH))
1473 offset += cp->fx_layer[vp->layer].val[AWE_FX_INIT_PITCH];
1474 else if (FX_ON(&cp->fx, AWE_FX_INIT_PITCH))
1475 offset += cp->fx.val[AWE_FX_INIT_PITCH];
1477 /* 0xe000: root pitch */
1478 vp->apitch = 0xe000 + ap->rate_offset + offset;
1479 DEBUG(4,printk("AWE32: p-> sum aofs=%x, rate_ofs=%d\n", vp->apitch, ap->rate_offset));
1480 if (vp->apitch > 0xffff)
1481 vp->apitch = 0xffff;
1482 if (vp->apitch < 0)
1483 vp->apitch = 0;
1487 #ifdef AWE_HAS_GUS_COMPATIBILITY
1488 /* calculate MIDI key and semitone from the specified frequency */
1489 static void
1490 awe_calc_pitch_from_freq(int voice, int freq)
1492 voice_info *vp = &voices[voice];
1493 awe_voice_info *ap;
1494 FX_Rec *fx = &voices[voice].cinfo->fx;
1495 FX_Rec *fx_lay = NULL;
1496 int offset;
1497 int note;
1499 if (voices[voice].layer < MAX_LAYERS)
1500 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1502 /* search voice information */
1503 if ((ap = vp->sample) == NULL)
1504 return;
1505 if (ap->index == 0) {
1506 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1507 if (awe_set_sample((awe_voice_list*)ap) == 0)
1508 return;
1510 note = freq_to_note(freq);
1511 offset = (note - ap->root * 100 + ap->tune) * 4096 / 1200;
1512 offset = (offset * ap->scaleTuning) / 100;
1513 if (fx_lay && FX_ON(fx_lay, AWE_FX_INIT_PITCH))
1514 offset += fx_lay->val[AWE_FX_INIT_PITCH];
1515 else if (FX_ON(fx, AWE_FX_INIT_PITCH))
1516 offset += fx->val[AWE_FX_INIT_PITCH];
1517 vp->apitch = 0xe000 + ap->rate_offset + offset;
1518 if (vp->apitch > 0xffff)
1519 vp->apitch = 0xffff;
1520 if (vp->apitch < 0)
1521 vp->apitch = 0;
1523 #endif /* AWE_HAS_GUS_COMPATIBILITY */
1527 * calculate volume attenuation
1529 * Voice volume is controlled by volume attenuation parameter.
1530 * So volume becomes maximum when avol is 0 (no attenuation), and
1531 * minimum when 255 (-96dB or silence).
1534 static int vol_table[128] = {
1535 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
1536 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
1537 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
1538 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
1539 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
1540 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
1541 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
1542 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
1545 /* tables for volume->attenuation calculation */
1546 static unsigned char voltab1[128] = {
1547 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1548 0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
1549 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
1550 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
1551 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
1552 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
1553 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
1554 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
1555 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
1556 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
1557 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
1558 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
1559 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1562 static unsigned char voltab2[128] = {
1563 0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
1564 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
1565 0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
1566 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
1567 0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
1568 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
1569 0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
1570 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
1571 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
1572 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
1573 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
1574 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
1575 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
1578 static unsigned char expressiontab[128] = {
1579 0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
1580 0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
1581 0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
1582 0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
1583 0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
1584 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
1585 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
1586 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
1587 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
1588 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
1589 0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
1590 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
1591 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1594 static void
1595 awe_calc_volume(int voice)
1597 voice_info *vp = &voices[voice];
1598 awe_voice_info *ap;
1599 awe_chan_info *cp = voices[voice].cinfo;
1600 int vol;
1602 /* search voice information */
1603 if ((ap = vp->sample) == NULL)
1604 return;
1606 ap = vp->sample;
1607 if (ap->index == 0) {
1608 DEBUG(3,printk("AWE32: set sample (%d)\n", ap->sample));
1609 if (awe_set_sample((awe_voice_list*)ap) == 0)
1610 return;
1613 if (ctrls[AWE_MD_NEW_VOLUME_CALC]) {
1614 int main_vol = cp->main_vol * ap->amplitude / 127;
1615 limitvalue(vp->velocity, 0, 127);
1616 limitvalue(main_vol, 0, 127);
1617 limitvalue(cp->expression_vol, 0, 127);
1619 vol = voltab1[main_vol] + voltab2[vp->velocity];
1620 vol = (vol * 8) / 3;
1621 vol += ap->attenuation;
1622 if (cp->expression_vol < 127)
1623 vol += ((0x100 - vol) * expressiontab[cp->expression_vol])/128;
1624 vol += atten_offset;
1625 if (atten_relative)
1626 vol += ctrls[AWE_MD_ZERO_ATTEN];
1627 limitvalue(vol, 0, 255);
1628 vp->avol = vol;
1630 } else {
1631 /* 0 - 127 */
1632 vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127);
1633 vol = vol * ap->amplitude / 127;
1635 if (vol < 0) vol = 0;
1636 if (vol > 127) vol = 127;
1638 /* calc to attenuation */
1639 vol = vol_table[vol];
1640 vol += (int)ap->attenuation;
1641 vol += atten_offset;
1642 if (atten_relative)
1643 vol += ctrls[AWE_MD_ZERO_ATTEN];
1644 if (vol > 255) vol = 255;
1646 vp->avol = vol;
1648 if (cp->bank != AWE_DRUM_BANK && ((awe_voice_parm_block*)(&ap->parm))->volatk < 0x7d) {
1649 int atten;
1650 if (vp->velocity < 70) atten = 70;
1651 else atten = vp->velocity;
1652 vp->acutoff = (atten * ap->parm.cutoff + 0xa0) >> 7;
1653 } else {
1654 vp->acutoff = ap->parm.cutoff;
1656 DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));
1659 /* change master volume */
1660 static void
1661 awe_change_master_volume(short val)
1663 limitvalue(val, 0, 127);
1664 atten_offset = vol_table[val];
1665 atten_relative = TRUE;
1666 awe_update_volume();
1669 /* update volumes of all available channels */
1670 static void awe_update_volume(void)
1672 int i;
1673 for (i = 0; i < awe_max_voices; i++)
1674 awe_set_voice_vol(i, TRUE);
1677 /* set sostenuto on */
1678 static void awe_sostenuto_on(int voice, int forced)
1680 if (IS_NO_EFFECT(voice) && !forced) return;
1681 voices[voice].sostenuto = 127;
1685 /* drop sustain */
1686 static void awe_sustain_off(int voice, int forced)
1688 if (voices[voice].state == AWE_ST_SUSTAINED) {
1689 awe_note_off(voice);
1690 awe_fx_init(voices[voice].ch);
1691 awe_voice_init(voice, FALSE);
1696 /* terminate and initialize voice */
1697 static void awe_terminate_and_init(int voice, int forced)
1699 awe_terminate(voice);
1700 awe_fx_init(voices[voice].ch);
1701 awe_voice_init(voice, TRUE);
1706 * synth operation routines
1709 #define AWE_VOICE_KEY(v) (0x8000 | (v))
1710 #define AWE_CHAN_KEY(c,n) (((c) << 8) | ((n) + 1))
1711 #define KEY_CHAN_MATCH(key,c) (((key) >> 8) == (c))
1713 /* initialize the voice */
1714 static void
1715 awe_voice_init(int voice, int init_all)
1717 voice_info *vp = &voices[voice];
1719 /* reset voice search key */
1720 if (playing_mode == AWE_PLAY_DIRECT)
1721 vp->key = AWE_VOICE_KEY(voice);
1722 else
1723 vp->key = 0;
1725 /* clear voice mapping */
1726 voice_alloc->map[voice] = 0;
1728 /* touch the timing flag */
1729 vp->time = current_alloc_time;
1731 /* initialize other parameters if necessary */
1732 if (init_all) {
1733 vp->note = -1;
1734 vp->velocity = 0;
1735 vp->sostenuto = 0;
1737 vp->sample = NULL;
1738 vp->cinfo = &channels[voice];
1739 vp->ch = voice;
1740 vp->state = AWE_ST_OFF;
1742 /* emu8000 parameters */
1743 vp->apitch = 0;
1744 vp->avol = 255;
1745 vp->apan = -1;
1749 /* clear effects */
1750 static void awe_fx_init(int ch)
1752 if (SINGLE_LAYER_MODE() && !ctrls[AWE_MD_KEEP_EFFECT]) {
1753 memset(&channels[ch].fx, 0, sizeof(channels[ch].fx));
1754 memset(&channels[ch].fx_layer, 0, sizeof(&channels[ch].fx_layer));
1758 /* initialize channel info */
1759 static void awe_channel_init(int ch, int init_all)
1761 awe_chan_info *cp = &channels[ch];
1762 cp->channel = ch;
1763 if (init_all) {
1764 cp->panning = 0; /* zero center */
1765 cp->bender_range = 200; /* sense * 100 */
1766 cp->main_vol = 127;
1767 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch)) {
1768 cp->instr = ctrls[AWE_MD_DEF_DRUM];
1769 cp->bank = AWE_DRUM_BANK;
1770 } else {
1771 cp->instr = ctrls[AWE_MD_DEF_PRESET];
1772 cp->bank = ctrls[AWE_MD_DEF_BANK];
1776 cp->bender = 0; /* zero tune skew */
1777 cp->expression_vol = 127;
1778 cp->chan_press = 0;
1779 cp->sustained = 0;
1781 if (! ctrls[AWE_MD_KEEP_EFFECT]) {
1782 memset(&cp->fx, 0, sizeof(cp->fx));
1783 memset(&cp->fx_layer, 0, sizeof(cp->fx_layer));
1788 /* change the voice parameters; voice = channel */
1789 static void awe_voice_change(int voice, fx_affect_func func)
1791 int i;
1792 switch (playing_mode) {
1793 case AWE_PLAY_DIRECT:
1794 func(voice, FALSE);
1795 break;
1796 case AWE_PLAY_INDIRECT:
1797 for (i = 0; i < awe_max_voices; i++)
1798 if (voices[i].key == AWE_VOICE_KEY(voice))
1799 func(i, FALSE);
1800 break;
1801 default:
1802 for (i = 0; i < awe_max_voices; i++)
1803 if (KEY_CHAN_MATCH(voices[i].key, voice))
1804 func(i, FALSE);
1805 break;
1811 * device open / close
1814 /* open device:
1815 * reset status of all voices, and clear sample position flag
1817 static int
1818 awe_open(int dev, int mode)
1820 if (awe_busy)
1821 return -EBUSY;
1823 awe_busy = TRUE;
1825 /* set default mode */
1826 awe_init_ctrl_parms(FALSE);
1827 atten_relative = TRUE;
1828 atten_offset = 0;
1829 drum_flags = DEFAULT_DRUM_FLAGS;
1830 playing_mode = AWE_PLAY_INDIRECT;
1832 /* reset voices & channels */
1833 awe_reset(dev);
1835 patch_opened = 0;
1837 return 0;
1841 /* close device:
1842 * reset all voices again (terminate sounds)
1844 static void
1845 awe_close(int dev)
1847 awe_reset(dev);
1848 awe_busy = FALSE;
1852 /* set miscellaneous mode parameters
1854 static void
1855 awe_init_ctrl_parms(int init_all)
1857 int i;
1858 for (i = 0; i < AWE_MD_END; i++) {
1859 if (init_all || ctrl_parms[i].init_each_time)
1860 ctrls[i] = ctrl_parms[i].value;
1865 /* sequencer I/O control:
1867 static int
1868 awe_ioctl(int dev, unsigned int cmd, void __user *arg)
1870 switch (cmd) {
1871 case SNDCTL_SYNTH_INFO:
1872 if (playing_mode == AWE_PLAY_DIRECT)
1873 awe_info.nr_voices = awe_max_voices;
1874 else
1875 awe_info.nr_voices = AWE_MAX_CHANNELS;
1876 if (copy_to_user(arg, &awe_info, sizeof(awe_info)))
1877 return -EFAULT;
1878 return 0;
1879 break;
1881 case SNDCTL_SEQ_RESETSAMPLES:
1882 awe_reset(dev);
1883 awe_reset_samples();
1884 return 0;
1885 break;
1887 case SNDCTL_SEQ_PERCMODE:
1888 /* what's this? */
1889 return 0;
1890 break;
1892 case SNDCTL_SYNTH_MEMAVL:
1893 return memsize - awe_free_mem_ptr() * 2;
1894 break;
1896 default:
1897 printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd);
1898 return -EINVAL;
1899 break;
1904 static int voice_in_range(int voice)
1906 if (playing_mode == AWE_PLAY_DIRECT) {
1907 if (voice < 0 || voice >= awe_max_voices)
1908 return FALSE;
1909 } else {
1910 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
1911 return FALSE;
1913 return TRUE;
1916 static void release_voice(int voice, int do_sustain)
1918 if (IS_NO_SOUND(voice))
1919 return;
1920 if (do_sustain && (voices[voice].cinfo->sustained == 127 ||
1921 voices[voice].sostenuto == 127))
1922 voices[voice].state = AWE_ST_SUSTAINED;
1923 else {
1924 awe_note_off(voice);
1925 awe_fx_init(voices[voice].ch);
1926 awe_voice_init(voice, FALSE);
1930 /* release all notes */
1931 static void awe_note_off_all(int do_sustain)
1933 int i;
1934 for (i = 0; i < awe_max_voices; i++)
1935 release_voice(i, do_sustain);
1938 /* kill a voice:
1939 * not terminate, just release the voice.
1941 static int
1942 awe_kill_note(int dev, int voice, int note, int velocity)
1944 int i, v2, key;
1946 DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));
1947 if (! voice_in_range(voice))
1948 return -EINVAL;
1950 switch (playing_mode) {
1951 case AWE_PLAY_DIRECT:
1952 case AWE_PLAY_INDIRECT:
1953 key = AWE_VOICE_KEY(voice);
1954 break;
1956 case AWE_PLAY_MULTI2:
1957 v2 = voice_alloc->map[voice] >> 8;
1958 voice_alloc->map[voice] = 0;
1959 voice = v2;
1960 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
1961 return -EINVAL;
1962 /* continue to below */
1963 default:
1964 key = AWE_CHAN_KEY(voice, note);
1965 break;
1968 for (i = 0; i < awe_max_voices; i++) {
1969 if (voices[i].key == key)
1970 release_voice(i, TRUE);
1972 return 0;
1976 static void start_or_volume_change(int voice, int velocity)
1978 voices[voice].velocity = velocity;
1979 awe_calc_volume(voice);
1980 if (voices[voice].state == AWE_ST_STANDBY)
1981 awe_note_on(voice);
1982 else if (voices[voice].state == AWE_ST_ON)
1983 awe_set_volume(voice, FALSE);
1986 static void set_and_start_voice(int voice, int state)
1988 /* calculate pitch & volume parameters */
1989 voices[voice].state = state;
1990 awe_calc_pitch(voice);
1991 awe_calc_volume(voice);
1992 if (state == AWE_ST_ON)
1993 awe_note_on(voice);
1996 /* start a voice:
1997 * if note is 255, identical with aftertouch function.
1998 * Otherwise, start a voice with specified not and volume.
2000 static int
2001 awe_start_note(int dev, int voice, int note, int velocity)
2003 int i, key, state, volonly;
2005 DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));
2006 if (! voice_in_range(voice))
2007 return -EINVAL;
2009 if (velocity == 0)
2010 state = AWE_ST_STANDBY; /* stand by for playing */
2011 else
2012 state = AWE_ST_ON; /* really play */
2013 volonly = FALSE;
2015 switch (playing_mode) {
2016 case AWE_PLAY_DIRECT:
2017 case AWE_PLAY_INDIRECT:
2018 key = AWE_VOICE_KEY(voice);
2019 if (note == 255)
2020 volonly = TRUE;
2021 break;
2023 case AWE_PLAY_MULTI2:
2024 voice = voice_alloc->map[voice] >> 8;
2025 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2026 return -EINVAL;
2027 /* continue to below */
2028 default:
2029 if (note >= 128) { /* key volume mode */
2030 note -= 128;
2031 volonly = TRUE;
2033 key = AWE_CHAN_KEY(voice, note);
2034 break;
2037 /* dynamic volume change */
2038 if (volonly) {
2039 for (i = 0; i < awe_max_voices; i++) {
2040 if (voices[i].key == key)
2041 start_or_volume_change(i, velocity);
2043 return 0;
2046 /* if the same note still playing, stop it */
2047 if (playing_mode != AWE_PLAY_DIRECT || ctrls[AWE_MD_EXCLUSIVE_SOUND]) {
2048 for (i = 0; i < awe_max_voices; i++)
2049 if (voices[i].key == key) {
2050 if (voices[i].state == AWE_ST_ON) {
2051 awe_note_off(i);
2052 awe_voice_init(i, FALSE);
2053 } else if (voices[i].state == AWE_ST_STANDBY)
2054 awe_voice_init(i, TRUE);
2058 /* allocate voices */
2059 if (playing_mode == AWE_PLAY_DIRECT)
2060 awe_alloc_one_voice(voice, note, velocity);
2061 else
2062 awe_alloc_multi_voices(voice, note, velocity, key);
2064 /* turn off other voices exlusively (for drums) */
2065 for (i = 0; i < awe_max_voices; i++)
2066 if (voices[i].key == key)
2067 awe_exclusive_off(i);
2069 /* set up pitch and volume parameters */
2070 for (i = 0; i < awe_max_voices; i++) {
2071 if (voices[i].key == key && voices[i].state == AWE_ST_OFF)
2072 set_and_start_voice(i, state);
2075 return 0;
2079 /* calculate hash key */
2080 static int
2081 awe_search_key(int bank, int preset, int note)
2083 unsigned int key;
2085 #if 1 /* new hash table */
2086 if (bank == AWE_DRUM_BANK)
2087 key = preset + note + 128;
2088 else
2089 key = bank + preset;
2090 #else
2091 key = preset;
2092 #endif
2093 key %= AWE_MAX_PRESETS;
2095 return (int)key;
2099 /* search instrument from hash table */
2100 static awe_voice_list *
2101 awe_search_instr(int bank, int preset, int note)
2103 awe_voice_list *p;
2104 int key, key2;
2106 key = awe_search_key(bank, preset, note);
2107 for (p = preset_table[key]; p; p = p->next_bank) {
2108 if (p->instr == preset && p->bank == bank)
2109 return p;
2111 key2 = awe_search_key(bank, preset, 0); /* search default */
2112 if (key == key2)
2113 return NULL;
2114 for (p = preset_table[key2]; p; p = p->next_bank) {
2115 if (p->instr == preset && p->bank == bank)
2116 return p;
2118 return NULL;
2122 /* assign the instrument to a voice */
2123 static int
2124 awe_set_instr_2(int dev, int voice, int instr_no)
2126 if (playing_mode == AWE_PLAY_MULTI2) {
2127 voice = voice_alloc->map[voice] >> 8;
2128 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2129 return -EINVAL;
2131 return awe_set_instr(dev, voice, instr_no);
2134 /* assign the instrument to a channel; voice is the channel number */
2135 static int
2136 awe_set_instr(int dev, int voice, int instr_no)
2138 awe_chan_info *cinfo;
2140 if (! voice_in_range(voice))
2141 return -EINVAL;
2143 if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)
2144 return -EINVAL;
2146 cinfo = &channels[voice];
2147 cinfo->instr = instr_no;
2148 DEBUG(2,printk("AWE32: [program(%d) %d]\n", voice, instr_no));
2150 return 0;
2154 /* reset all voices; terminate sounds and initialize parameters */
2155 static void
2156 awe_reset(int dev)
2158 int i;
2159 current_alloc_time = 0;
2160 /* don't turn off voice 31 and 32. they are used also for FM voices */
2161 for (i = 0; i < awe_max_voices; i++) {
2162 awe_terminate(i);
2163 awe_voice_init(i, TRUE);
2165 for (i = 0; i < AWE_MAX_CHANNELS; i++)
2166 awe_channel_init(i, TRUE);
2167 for (i = 0; i < 16; i++) {
2168 awe_operations.chn_info[i].controllers[CTL_MAIN_VOLUME] = 127;
2169 awe_operations.chn_info[i].controllers[CTL_EXPRESSION] = 127;
2171 awe_init_fm();
2172 awe_tweak();
2176 /* hardware specific control:
2177 * GUS specific and AWE32 specific controls are available.
2179 static void
2180 awe_hw_control(int dev, unsigned char *event)
2182 int cmd = event[2];
2183 if (cmd & _AWE_MODE_FLAG)
2184 awe_hw_awe_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2185 #ifdef AWE_HAS_GUS_COMPATIBILITY
2186 else
2187 awe_hw_gus_control(dev, cmd & _AWE_MODE_VALUE_MASK, event);
2188 #endif
2192 #ifdef AWE_HAS_GUS_COMPATIBILITY
2194 /* GUS compatible controls */
2195 static void
2196 awe_hw_gus_control(int dev, int cmd, unsigned char *event)
2198 int voice, i, key;
2199 unsigned short p1;
2200 short p2;
2201 int plong;
2203 if (MULTI_LAYER_MODE())
2204 return;
2205 if (cmd == _GUS_NUMVOICES)
2206 return;
2208 voice = event[3];
2209 if (! voice_in_range(voice))
2210 return;
2212 p1 = *(unsigned short *) &event[4];
2213 p2 = *(short *) &event[6];
2214 plong = *(int*) &event[4];
2216 switch (cmd) {
2217 case _GUS_VOICESAMPLE:
2218 awe_set_instr(dev, voice, p1);
2219 return;
2221 case _GUS_VOICEBALA:
2222 /* 0 to 15 --> -128 to 127 */
2223 awe_panning(dev, voice, ((int)p1 << 4) - 128);
2224 return;
2226 case _GUS_VOICEVOL:
2227 case _GUS_VOICEVOL2:
2228 /* not supported yet */
2229 return;
2231 case _GUS_RAMPRANGE:
2232 case _GUS_RAMPRATE:
2233 case _GUS_RAMPMODE:
2234 case _GUS_RAMPON:
2235 case _GUS_RAMPOFF:
2236 /* volume ramping not supported */
2237 return;
2239 case _GUS_VOLUME_SCALE:
2240 return;
2242 case _GUS_VOICE_POS:
2243 FX_SET(&channels[voice].fx, AWE_FX_SAMPLE_START,
2244 (short)(plong & 0x7fff));
2245 FX_SET(&channels[voice].fx, AWE_FX_COARSE_SAMPLE_START,
2246 (plong >> 15) & 0xffff);
2247 return;
2250 key = AWE_VOICE_KEY(voice);
2251 for (i = 0; i < awe_max_voices; i++) {
2252 if (voices[i].key == key) {
2253 switch (cmd) {
2254 case _GUS_VOICEON:
2255 awe_note_on(i);
2256 break;
2258 case _GUS_VOICEOFF:
2259 awe_terminate(i);
2260 awe_fx_init(voices[i].ch);
2261 awe_voice_init(i, TRUE);
2262 break;
2264 case _GUS_VOICEFADE:
2265 awe_note_off(i);
2266 awe_fx_init(voices[i].ch);
2267 awe_voice_init(i, FALSE);
2268 break;
2270 case _GUS_VOICEFREQ:
2271 awe_calc_pitch_from_freq(i, plong);
2272 break;
2278 #endif /* gus_compat */
2281 /* AWE32 specific controls */
2282 static void
2283 awe_hw_awe_control(int dev, int cmd, unsigned char *event)
2285 int voice;
2286 unsigned short p1;
2287 short p2;
2288 int i;
2290 voice = event[3];
2291 if (! voice_in_range(voice))
2292 return;
2294 if (playing_mode == AWE_PLAY_MULTI2) {
2295 voice = voice_alloc->map[voice] >> 8;
2296 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2297 return;
2300 p1 = *(unsigned short *) &event[4];
2301 p2 = *(short *) &event[6];
2303 switch (cmd) {
2304 case _AWE_DEBUG_MODE:
2305 ctrls[AWE_MD_DEBUG_MODE] = p1;
2306 printk(KERN_DEBUG "AWE32: debug mode = %d\n", ctrls[AWE_MD_DEBUG_MODE]);
2307 break;
2308 case _AWE_REVERB_MODE:
2309 ctrls[AWE_MD_REVERB_MODE] = p1;
2310 awe_update_reverb_mode();
2311 break;
2313 case _AWE_CHORUS_MODE:
2314 ctrls[AWE_MD_CHORUS_MODE] = p1;
2315 awe_update_chorus_mode();
2316 break;
2318 case _AWE_REMOVE_LAST_SAMPLES:
2319 DEBUG(0,printk("AWE32: remove last samples\n"));
2320 awe_reset(0);
2321 if (locked_sf_id > 0)
2322 awe_remove_samples(locked_sf_id);
2323 break;
2325 case _AWE_INITIALIZE_CHIP:
2326 awe_initialize();
2327 break;
2329 case _AWE_SEND_EFFECT:
2330 i = -1;
2331 if (p1 >= 0x100) {
2332 i = (p1 >> 8);
2333 if (i < 0 || i >= MAX_LAYERS)
2334 break;
2336 awe_send_effect(voice, i, p1, p2);
2337 break;
2339 case _AWE_RESET_CHANNEL:
2340 awe_channel_init(voice, !p1);
2341 break;
2343 case _AWE_TERMINATE_ALL:
2344 awe_reset(0);
2345 break;
2347 case _AWE_TERMINATE_CHANNEL:
2348 awe_voice_change(voice, awe_terminate_and_init);
2349 break;
2351 case _AWE_RELEASE_ALL:
2352 awe_note_off_all(FALSE);
2353 break;
2354 case _AWE_NOTEOFF_ALL:
2355 awe_note_off_all(TRUE);
2356 break;
2358 case _AWE_INITIAL_VOLUME:
2359 DEBUG(0,printk("AWE32: init attenuation %d\n", p1));
2360 atten_relative = (char)p2;
2361 atten_offset = (short)p1;
2362 awe_update_volume();
2363 break;
2365 case _AWE_CHN_PRESSURE:
2366 channels[voice].chan_press = p1;
2367 awe_modwheel_change(voice, p1);
2368 break;
2370 case _AWE_CHANNEL_MODE:
2371 DEBUG(0,printk("AWE32: channel mode = %d\n", p1));
2372 playing_mode = p1;
2373 awe_reset(0);
2374 break;
2376 case _AWE_DRUM_CHANNELS:
2377 DEBUG(0,printk("AWE32: drum flags = %x\n", p1));
2378 drum_flags = *(unsigned int*)&event[4];
2379 break;
2381 case _AWE_MISC_MODE:
2382 DEBUG(0,printk("AWE32: ctrl parms = %d %d\n", p1, p2));
2383 if (p1 > AWE_MD_VERSION && p1 < AWE_MD_END) {
2384 ctrls[p1] = p2;
2385 if (ctrl_parms[p1].update)
2386 ctrl_parms[p1].update();
2388 break;
2390 case _AWE_EQUALIZER:
2391 ctrls[AWE_MD_BASS_LEVEL] = p1;
2392 ctrls[AWE_MD_TREBLE_LEVEL] = p2;
2393 awe_update_equalizer();
2394 break;
2396 default:
2397 DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice));
2398 break;
2403 /* change effects */
2404 static void
2405 awe_send_effect(int voice, int layer, int type, int val)
2407 awe_chan_info *cinfo;
2408 FX_Rec *fx;
2409 int mode;
2411 cinfo = &channels[voice];
2412 if (layer >= 0 && layer < MAX_LAYERS)
2413 fx = &cinfo->fx_layer[layer];
2414 else
2415 fx = &cinfo->fx;
2417 if (type & 0x40)
2418 mode = FX_FLAG_OFF;
2419 else if (type & 0x80)
2420 mode = FX_FLAG_ADD;
2421 else
2422 mode = FX_FLAG_SET;
2423 type &= 0x3f;
2425 if (type >= 0 && type < AWE_FX_END) {
2426 DEBUG(2,printk("AWE32: effects (%d) %d %d\n", voice, type, val));
2427 if (mode == FX_FLAG_SET)
2428 FX_SET(fx, type, val);
2429 else if (mode == FX_FLAG_ADD)
2430 FX_ADD(fx, type, val);
2431 else
2432 FX_UNSET(fx, type);
2433 if (mode != FX_FLAG_OFF && parm_defs[type].realtime) {
2434 DEBUG(2,printk("AWE32: fx_realtime (%d)\n", voice));
2435 awe_voice_change(voice, parm_defs[type].realtime);
2441 /* change modulation wheel; voice is already mapped on multi2 mode */
2442 static void
2443 awe_modwheel_change(int voice, int value)
2445 int i;
2446 awe_chan_info *cinfo;
2448 cinfo = &channels[voice];
2449 i = value * ctrls[AWE_MD_MOD_SENSE] / 1200;
2450 FX_ADD(&cinfo->fx, AWE_FX_LFO1_PITCH, i);
2451 awe_voice_change(voice, awe_fx_fmmod);
2452 FX_ADD(&cinfo->fx, AWE_FX_LFO2_PITCH, i);
2453 awe_voice_change(voice, awe_fx_fm2frq2);
2457 /* voice pressure change */
2458 static void
2459 awe_aftertouch(int dev, int voice, int pressure)
2461 int note;
2463 DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure));
2464 if (! voice_in_range(voice))
2465 return;
2467 switch (playing_mode) {
2468 case AWE_PLAY_DIRECT:
2469 case AWE_PLAY_INDIRECT:
2470 awe_start_note(dev, voice, 255, pressure);
2471 break;
2472 case AWE_PLAY_MULTI2:
2473 note = (voice_alloc->map[voice] & 0xff) - 1;
2474 awe_key_pressure(dev, voice, note + 0x80, pressure);
2475 break;
2480 /* voice control change */
2481 static void
2482 awe_controller(int dev, int voice, int ctrl_num, int value)
2484 awe_chan_info *cinfo;
2486 if (! voice_in_range(voice))
2487 return;
2489 if (playing_mode == AWE_PLAY_MULTI2) {
2490 voice = voice_alloc->map[voice] >> 8;
2491 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2492 return;
2495 cinfo = &channels[voice];
2497 switch (ctrl_num) {
2498 case CTL_BANK_SELECT: /* MIDI control #0 */
2499 DEBUG(2,printk("AWE32: [bank(%d) %d]\n", voice, value));
2500 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice) &&
2501 !ctrls[AWE_MD_TOGGLE_DRUM_BANK])
2502 break;
2503 if (value < 0 || value > 255)
2504 break;
2505 cinfo->bank = value;
2506 if (cinfo->bank == AWE_DRUM_BANK)
2507 DRUM_CHANNEL_ON(cinfo->channel);
2508 else
2509 DRUM_CHANNEL_OFF(cinfo->channel);
2510 awe_set_instr(dev, voice, cinfo->instr);
2511 break;
2513 case CTL_MODWHEEL: /* MIDI control #1 */
2514 DEBUG(2,printk("AWE32: [modwheel(%d) %d]\n", voice, value));
2515 awe_modwheel_change(voice, value);
2516 break;
2518 case CTRL_PITCH_BENDER: /* SEQ1 V2 contorl */
2519 DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, value));
2520 /* zero centered */
2521 cinfo->bender = value;
2522 awe_voice_change(voice, awe_set_voice_pitch);
2523 break;
2525 case CTRL_PITCH_BENDER_RANGE: /* SEQ1 V2 control */
2526 DEBUG(2,printk("AWE32: [range(%d) %d]\n", voice, value));
2527 /* value = sense x 100 */
2528 cinfo->bender_range = value;
2529 /* no audible pitch change yet.. */
2530 break;
2532 case CTL_EXPRESSION: /* MIDI control #11 */
2533 if (SINGLE_LAYER_MODE())
2534 value /= 128;
2535 case CTRL_EXPRESSION: /* SEQ1 V2 control */
2536 DEBUG(2,printk("AWE32: [expr(%d) %d]\n", voice, value));
2537 /* 0 - 127 */
2538 cinfo->expression_vol = value;
2539 awe_voice_change(voice, awe_set_voice_vol);
2540 break;
2542 case CTL_PAN: /* MIDI control #10 */
2543 DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, value));
2544 /* (0-127) -> signed 8bit */
2545 cinfo->panning = value * 2 - 128;
2546 if (ctrls[AWE_MD_REALTIME_PAN])
2547 awe_voice_change(voice, awe_set_pan);
2548 break;
2550 case CTL_MAIN_VOLUME: /* MIDI control #7 */
2551 if (SINGLE_LAYER_MODE())
2552 value = (value * 100) / 16383;
2553 case CTRL_MAIN_VOLUME: /* SEQ1 V2 control */
2554 DEBUG(2,printk("AWE32: [mainvol(%d) %d]\n", voice, value));
2555 /* 0 - 127 */
2556 cinfo->main_vol = value;
2557 awe_voice_change(voice, awe_set_voice_vol);
2558 break;
2560 case CTL_EXT_EFF_DEPTH: /* reverb effects: 0-127 */
2561 DEBUG(2,printk("AWE32: [reverb(%d) %d]\n", voice, value));
2562 FX_SET(&cinfo->fx, AWE_FX_REVERB, value * 2);
2563 break;
2565 case CTL_CHORUS_DEPTH: /* chorus effects: 0-127 */
2566 DEBUG(2,printk("AWE32: [chorus(%d) %d]\n", voice, value));
2567 FX_SET(&cinfo->fx, AWE_FX_CHORUS, value * 2);
2568 break;
2570 case 120: /* all sounds off */
2571 awe_note_off_all(FALSE);
2572 break;
2573 case 123: /* all notes off */
2574 awe_note_off_all(TRUE);
2575 break;
2577 case CTL_SUSTAIN: /* MIDI control #64 */
2578 cinfo->sustained = value;
2579 if (value != 127)
2580 awe_voice_change(voice, awe_sustain_off);
2581 break;
2583 case CTL_SOSTENUTO: /* MIDI control #66 */
2584 if (value == 127)
2585 awe_voice_change(voice, awe_sostenuto_on);
2586 else
2587 awe_voice_change(voice, awe_sustain_off);
2588 break;
2590 default:
2591 DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n",
2592 voice, ctrl_num, value));
2593 break;
2598 /* voice pan change (value = -128 - 127) */
2599 static void
2600 awe_panning(int dev, int voice, int value)
2602 awe_chan_info *cinfo;
2604 if (! voice_in_range(voice))
2605 return;
2607 if (playing_mode == AWE_PLAY_MULTI2) {
2608 voice = voice_alloc->map[voice] >> 8;
2609 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2610 return;
2613 cinfo = &channels[voice];
2614 cinfo->panning = value;
2615 DEBUG(2,printk("AWE32: [pan(%d) %d]\n", voice, cinfo->panning));
2616 if (ctrls[AWE_MD_REALTIME_PAN])
2617 awe_voice_change(voice, awe_set_pan);
2621 /* volume mode change */
2622 static void
2623 awe_volume_method(int dev, int mode)
2625 /* not impremented */
2626 DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode));
2630 /* pitch wheel change: 0-16384 */
2631 static void
2632 awe_bender(int dev, int voice, int value)
2634 awe_chan_info *cinfo;
2636 if (! voice_in_range(voice))
2637 return;
2639 if (playing_mode == AWE_PLAY_MULTI2) {
2640 voice = voice_alloc->map[voice] >> 8;
2641 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2642 return;
2645 /* convert to zero centered value */
2646 cinfo = &channels[voice];
2647 cinfo->bender = value - 8192;
2648 DEBUG(2,printk("AWE32: [bend(%d) %d]\n", voice, cinfo->bender));
2649 awe_voice_change(voice, awe_set_voice_pitch);
2654 * load a sound patch:
2655 * three types of patches are accepted: AWE, GUS, and SYSEX.
2658 static int
2659 awe_load_patch(int dev, int format, const char __user *addr,
2660 int offs, int count, int pmgr_flag)
2662 awe_patch_info patch;
2663 int rc = 0;
2665 #ifdef AWE_HAS_GUS_COMPATIBILITY
2666 if (format == GUS_PATCH) {
2667 return awe_load_guspatch(addr, offs, count, pmgr_flag);
2668 } else
2669 #endif
2670 if (format == SYSEX_PATCH) {
2671 /* no system exclusive message supported yet */
2672 return 0;
2673 } else if (format != AWE_PATCH) {
2674 printk(KERN_WARNING "AWE32 Error: Invalid patch format (key) 0x%x\n", format);
2675 return -EINVAL;
2678 if (count < AWE_PATCH_INFO_SIZE) {
2679 printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
2680 return -EINVAL;
2682 if (copy_from_user(((char*)&patch) + offs, addr + offs,
2683 AWE_PATCH_INFO_SIZE - offs))
2684 return -EFAULT;
2686 count -= AWE_PATCH_INFO_SIZE;
2687 if (count < patch.len) {
2688 printk(KERN_WARNING "AWE32: sample: Patch record too short (%d<%d)\n",
2689 count, patch.len);
2690 return -EINVAL;
2693 switch (patch.type) {
2694 case AWE_LOAD_INFO:
2695 rc = awe_load_info(&patch, addr, count);
2696 break;
2697 case AWE_LOAD_DATA:
2698 rc = awe_load_data(&patch, addr, count);
2699 break;
2700 case AWE_OPEN_PATCH:
2701 rc = awe_open_patch(&patch, addr, count);
2702 break;
2703 case AWE_CLOSE_PATCH:
2704 rc = awe_close_patch(&patch, addr, count);
2705 break;
2706 case AWE_UNLOAD_PATCH:
2707 rc = awe_unload_patch(&patch, addr, count);
2708 break;
2709 case AWE_REPLACE_DATA:
2710 rc = awe_replace_data(&patch, addr, count);
2711 break;
2712 case AWE_MAP_PRESET:
2713 rc = awe_load_map(&patch, addr, count);
2714 break;
2715 /* case AWE_PROBE_INFO:
2716 rc = awe_probe_info(&patch, addr, count);
2717 break;*/
2718 case AWE_PROBE_DATA:
2719 rc = awe_probe_data(&patch, addr, count);
2720 break;
2721 case AWE_REMOVE_INFO:
2722 rc = awe_remove_info(&patch, addr, count);
2723 break;
2724 case AWE_LOAD_CHORUS_FX:
2725 rc = awe_load_chorus_fx(&patch, addr, count);
2726 break;
2727 case AWE_LOAD_REVERB_FX:
2728 rc = awe_load_reverb_fx(&patch, addr, count);
2729 break;
2731 default:
2732 printk(KERN_WARNING "AWE32 Error: unknown patch format type %d\n",
2733 patch.type);
2734 rc = -EINVAL;
2737 return rc;
2741 /* create an sf list record */
2742 static int
2743 awe_create_sf(int type, char *name)
2745 sf_list *rec;
2747 /* terminate sounds */
2748 awe_reset(0);
2749 rec = (sf_list *)kmalloc(sizeof(*rec), GFP_KERNEL);
2750 if (rec == NULL)
2751 return 1; /* no memory */
2752 rec->sf_id = current_sf_id + 1;
2753 rec->type = type;
2754 if (/*current_sf_id == 0 ||*/ (type & AWE_PAT_LOCKED) != 0)
2755 locked_sf_id = current_sf_id + 1;
2756 rec->num_info = awe_free_info();
2757 rec->num_sample = awe_free_sample();
2758 rec->mem_ptr = awe_free_mem_ptr();
2759 rec->infos = rec->last_infos = NULL;
2760 rec->samples = rec->last_samples = NULL;
2762 /* add to linked-list */
2763 rec->next = NULL;
2764 rec->prev = sftail;
2765 if (sftail)
2766 sftail->next = rec;
2767 else
2768 sfhead = rec;
2769 sftail = rec;
2770 current_sf_id++;
2772 #ifdef AWE_ALLOW_SAMPLE_SHARING
2773 rec->shared = NULL;
2774 if (name)
2775 memcpy(rec->name, name, AWE_PATCH_NAME_LEN);
2776 else
2777 strcpy(rec->name, "*TEMPORARY*");
2778 if (current_sf_id > 1 && name && (type & AWE_PAT_SHARED) != 0) {
2779 /* is the current font really a shared font? */
2780 if (is_shared_sf(rec->name)) {
2781 /* check if the shared font is already installed */
2782 sf_list *p;
2783 for (p = rec->prev; p; p = p->prev) {
2784 if (is_identical_name(rec->name, p)) {
2785 rec->shared = p;
2786 break;
2791 #endif /* allow sharing */
2793 return 0;
2797 #ifdef AWE_ALLOW_SAMPLE_SHARING
2799 /* check if the given name is a valid shared name */
2800 #define ASC_TO_KEY(c) ((c) - 'A' + 1)
2801 static int is_shared_sf(unsigned char *name)
2803 static unsigned char id_head[4] = {
2804 ASC_TO_KEY('A'), ASC_TO_KEY('W'), ASC_TO_KEY('E'),
2805 AWE_MAJOR_VERSION,
2807 if (memcmp(name, id_head, 4) == 0)
2808 return TRUE;
2809 return FALSE;
2812 /* check if the given name matches to the existing list */
2813 static int is_identical_name(unsigned char *name, sf_list *p)
2815 char *id = p->name;
2816 if (is_shared_sf(id) && memcmp(id, name, AWE_PATCH_NAME_LEN) == 0)
2817 return TRUE;
2818 return FALSE;
2821 /* check if the given voice info exists */
2822 static int info_duplicated(sf_list *sf, awe_voice_list *rec)
2824 /* search for all sharing lists */
2825 for (; sf; sf = sf->shared) {
2826 awe_voice_list *p;
2827 for (p = sf->infos; p; p = p->next) {
2828 if (p->type == V_ST_NORMAL &&
2829 p->bank == rec->bank &&
2830 p->instr == rec->instr &&
2831 p->v.low == rec->v.low &&
2832 p->v.high == rec->v.high &&
2833 p->v.sample == rec->v.sample)
2834 return TRUE;
2837 return FALSE;
2840 #endif /* AWE_ALLOW_SAMPLE_SHARING */
2843 /* free sf_list record */
2844 /* linked-list in this function is not cared */
2845 static void
2846 awe_free_sf(sf_list *sf)
2848 if (sf->infos) {
2849 awe_voice_list *p, *next;
2850 for (p = sf->infos; p; p = next) {
2851 next = p->next;
2852 kfree(p);
2855 if (sf->samples) {
2856 awe_sample_list *p, *next;
2857 for (p = sf->samples; p; p = next) {
2858 next = p->next;
2859 kfree(p);
2862 kfree(sf);
2866 /* open patch; create sf list and set opened flag */
2867 static int
2868 awe_open_patch(awe_patch_info *patch, const char __user *addr, int count)
2870 awe_open_parm parm;
2871 int shared;
2873 if (copy_from_user(&parm, addr + AWE_PATCH_INFO_SIZE, sizeof(parm)))
2874 return -EFAULT;
2875 shared = FALSE;
2877 #ifdef AWE_ALLOW_SAMPLE_SHARING
2878 if (sftail && (parm.type & AWE_PAT_SHARED) != 0) {
2879 /* is the previous font the same font? */
2880 if (is_identical_name(parm.name, sftail)) {
2881 /* then append to the previous */
2882 shared = TRUE;
2883 awe_reset(0);
2884 if (parm.type & AWE_PAT_LOCKED)
2885 locked_sf_id = current_sf_id;
2888 #endif /* allow sharing */
2889 if (! shared) {
2890 if (awe_create_sf(parm.type, parm.name)) {
2891 printk(KERN_ERR "AWE32: can't open: failed to alloc new list\n");
2892 return -ENOMEM;
2895 patch_opened = TRUE;
2896 return current_sf_id;
2899 /* check if the patch is already opened */
2900 static sf_list *
2901 check_patch_opened(int type, char *name)
2903 if (! patch_opened) {
2904 if (awe_create_sf(type, name)) {
2905 printk(KERN_ERR "AWE32: failed to alloc new list\n");
2906 return NULL;
2908 patch_opened = TRUE;
2909 return sftail;
2911 return sftail;
2914 /* close the patch; if no voice is loaded, remove the patch */
2915 static int
2916 awe_close_patch(awe_patch_info *patch, const char __user *addr, int count)
2918 if (patch_opened && sftail) {
2919 /* if no voice is loaded, release the current patch */
2920 if (sftail->infos == NULL) {
2921 awe_reset(0);
2922 awe_remove_samples(current_sf_id - 1);
2925 patch_opened = 0;
2926 return 0;
2930 /* remove the latest patch */
2931 static int
2932 awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count)
2934 if (current_sf_id > 0 && current_sf_id > locked_sf_id) {
2935 awe_reset(0);
2936 awe_remove_samples(current_sf_id - 1);
2938 return 0;
2941 /* allocate voice info list records */
2942 static awe_voice_list *
2943 alloc_new_info(void)
2945 awe_voice_list *newlist;
2947 newlist = kmalloc(sizeof(*newlist), GFP_KERNEL);
2948 if (newlist == NULL) {
2949 printk(KERN_ERR "AWE32: can't alloc info table\n");
2950 return NULL;
2952 return newlist;
2955 /* allocate sample info list records */
2956 static awe_sample_list *
2957 alloc_new_sample(void)
2959 awe_sample_list *newlist;
2961 newlist = (awe_sample_list *)kmalloc(sizeof(*newlist), GFP_KERNEL);
2962 if (newlist == NULL) {
2963 printk(KERN_ERR "AWE32: can't alloc sample table\n");
2964 return NULL;
2966 return newlist;
2969 /* load voice map */
2970 static int
2971 awe_load_map(awe_patch_info *patch, const char __user *addr, int count)
2973 awe_voice_map map;
2974 awe_voice_list *rec, *p;
2975 sf_list *sf;
2977 /* get the link info */
2978 if (count < sizeof(map)) {
2979 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
2980 return -EINVAL;
2982 if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
2983 return -EFAULT;
2985 /* check if the identical mapping already exists */
2986 p = awe_search_instr(map.map_bank, map.map_instr, map.map_key);
2987 for (; p; p = p->next_instr) {
2988 if (p->type == V_ST_MAPPED &&
2989 p->v.start == map.src_instr &&
2990 p->v.end == map.src_bank &&
2991 p->v.fixkey == map.src_key)
2992 return 0; /* already present! */
2995 if ((sf = check_patch_opened(AWE_PAT_TYPE_MAP, NULL)) == NULL)
2996 return -ENOMEM;
2998 if ((rec = alloc_new_info()) == NULL)
2999 return -ENOMEM;
3001 rec->bank = map.map_bank;
3002 rec->instr = map.map_instr;
3003 rec->type = V_ST_MAPPED;
3004 rec->disabled = FALSE;
3005 awe_init_voice_info(&rec->v);
3006 if (map.map_key >= 0) {
3007 rec->v.low = map.map_key;
3008 rec->v.high = map.map_key;
3010 rec->v.start = map.src_instr;
3011 rec->v.end = map.src_bank;
3012 rec->v.fixkey = map.src_key;
3013 add_sf_info(sf, rec);
3014 add_info_list(rec);
3016 return 0;
3019 #if 0
3020 /* probe preset in the current list -- nothing to be loaded */
3021 static int
3022 awe_probe_info(awe_patch_info *patch, const char __user *addr, int count)
3024 #ifdef AWE_ALLOW_SAMPLE_SHARING
3025 awe_voice_map map;
3026 awe_voice_list *p;
3028 if (! patch_opened)
3029 return -EINVAL;
3031 /* get the link info */
3032 if (count < sizeof(map)) {
3033 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3034 return -EINVAL;
3036 if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
3037 return -EFAULT;
3039 /* check if the identical mapping already exists */
3040 if (sftail == NULL)
3041 return -EINVAL;
3042 p = awe_search_instr(map.src_bank, map.src_instr, map.src_key);
3043 for (; p; p = p->next_instr) {
3044 if (p->type == V_ST_NORMAL &&
3045 is_identical_holder(p->holder, sftail) &&
3046 p->v.low <= map.src_key &&
3047 p->v.high >= map.src_key)
3048 return 0; /* already present! */
3050 #endif /* allow sharing */
3051 return -EINVAL;
3053 #endif
3055 /* probe sample in the current list -- nothing to be loaded */
3056 static int
3057 awe_probe_data(awe_patch_info *patch, const char __user *addr, int count)
3059 #ifdef AWE_ALLOW_SAMPLE_SHARING
3060 if (! patch_opened)
3061 return -EINVAL;
3063 /* search the specified sample by optarg */
3064 if (search_sample_index(sftail, patch->optarg) != NULL)
3065 return 0;
3066 #endif /* allow sharing */
3067 return -EINVAL;
3071 /* remove the present instrument layers */
3072 static int
3073 remove_info(sf_list *sf, int bank, int instr)
3075 awe_voice_list *prev, *next, *p;
3076 int removed = 0;
3078 prev = NULL;
3079 for (p = sf->infos; p; p = next) {
3080 next = p->next;
3081 if (p->type == V_ST_NORMAL &&
3082 p->bank == bank && p->instr == instr) {
3083 /* remove this layer */
3084 if (prev)
3085 prev->next = next;
3086 else
3087 sf->infos = next;
3088 if (p == sf->last_infos)
3089 sf->last_infos = prev;
3090 sf->num_info--;
3091 removed++;
3092 kfree(p);
3093 } else
3094 prev = p;
3096 if (removed)
3097 rebuild_preset_list();
3098 return removed;
3101 /* load voice information data */
3102 static int
3103 awe_load_info(awe_patch_info *patch, const char __user *addr, int count)
3105 int offset;
3106 awe_voice_rec_hdr hdr;
3107 int i;
3108 int total_size;
3109 sf_list *sf;
3110 awe_voice_list *rec;
3112 if (count < AWE_VOICE_REC_SIZE) {
3113 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3114 return -EINVAL;
3117 offset = AWE_PATCH_INFO_SIZE;
3118 if (copy_from_user((char*)&hdr, addr + offset, AWE_VOICE_REC_SIZE))
3119 return -EFAULT;
3120 offset += AWE_VOICE_REC_SIZE;
3122 if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
3123 printk(KERN_WARNING "AWE32 Error: Invalid voice number %d\n", hdr.nvoices);
3124 return -EINVAL;
3126 total_size = AWE_VOICE_REC_SIZE + AWE_VOICE_INFO_SIZE * hdr.nvoices;
3127 if (count < total_size) {
3128 printk(KERN_WARNING "AWE32 Error: patch length(%d) is smaller than nvoices(%d)\n",
3129 count, hdr.nvoices);
3130 return -EINVAL;
3133 if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
3134 return -ENOMEM;
3136 switch (hdr.write_mode) {
3137 case AWE_WR_EXCLUSIVE:
3138 /* exclusive mode - if the instrument already exists,
3139 return error */
3140 for (rec = sf->infos; rec; rec = rec->next) {
3141 if (rec->type == V_ST_NORMAL &&
3142 rec->bank == hdr.bank &&
3143 rec->instr == hdr.instr)
3144 return -EINVAL;
3146 break;
3147 case AWE_WR_REPLACE:
3148 /* replace mode - remove the instrument if it already exists */
3149 remove_info(sf, hdr.bank, hdr.instr);
3150 break;
3153 /* append new layers */
3154 for (i = 0; i < hdr.nvoices; i++) {
3155 rec = alloc_new_info();
3156 if (rec == NULL)
3157 return -ENOMEM;
3159 rec->bank = hdr.bank;
3160 rec->instr = hdr.instr;
3161 rec->type = V_ST_NORMAL;
3162 rec->disabled = FALSE;
3164 /* copy awe_voice_info parameters */
3165 if (copy_from_user(&rec->v, addr + offset, AWE_VOICE_INFO_SIZE)) {
3166 kfree(rec);
3167 return -EFAULT;
3169 offset += AWE_VOICE_INFO_SIZE;
3170 #ifdef AWE_ALLOW_SAMPLE_SHARING
3171 if (sf && sf->shared) {
3172 if (info_duplicated(sf, rec)) {
3173 kfree(rec);
3174 continue;
3177 #endif /* allow sharing */
3178 if (rec->v.mode & AWE_MODE_INIT_PARM)
3179 awe_init_voice_parm(&rec->v.parm);
3180 add_sf_info(sf, rec);
3181 awe_set_sample(rec);
3182 add_info_list(rec);
3185 return 0;
3189 /* remove instrument layers */
3190 static int
3191 awe_remove_info(awe_patch_info *patch, const char __user *addr, int count)
3193 unsigned char bank, instr;
3194 sf_list *sf;
3196 if (! patch_opened || (sf = sftail) == NULL) {
3197 printk(KERN_WARNING "AWE32: remove_info: patch not opened\n");
3198 return -EINVAL;
3201 bank = ((unsigned short)patch->optarg >> 8) & 0xff;
3202 instr = (unsigned short)patch->optarg & 0xff;
3203 if (! remove_info(sf, bank, instr))
3204 return -EINVAL;
3205 return 0;
3209 /* load wave sample data */
3210 static int
3211 awe_load_data(awe_patch_info *patch, const char __user *addr, int count)
3213 int offset, size;
3214 int rc;
3215 awe_sample_info tmprec;
3216 awe_sample_list *rec;
3217 sf_list *sf;
3219 if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
3220 return -ENOMEM;
3222 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3223 offset = AWE_PATCH_INFO_SIZE;
3224 if (copy_from_user(&tmprec, addr + offset, AWE_SAMPLE_INFO_SIZE))
3225 return -EFAULT;
3226 offset += AWE_SAMPLE_INFO_SIZE;
3227 if (size != tmprec.size) {
3228 printk(KERN_WARNING "AWE32: load: sample size differed (%d != %d)\n",
3229 tmprec.size, size);
3230 return -EINVAL;
3233 if (search_sample_index(sf, tmprec.sample) != NULL) {
3234 #ifdef AWE_ALLOW_SAMPLE_SHARING
3235 /* if shared sample, skip this data */
3236 if (sf->type & AWE_PAT_SHARED)
3237 return 0;
3238 #endif /* allow sharing */
3239 DEBUG(1,printk("AWE32: sample data %d already present\n", tmprec.sample));
3240 return -EINVAL;
3243 if ((rec = alloc_new_sample()) == NULL)
3244 return -ENOMEM;
3246 memcpy(&rec->v, &tmprec, sizeof(tmprec));
3248 if (rec->v.size > 0) {
3249 if ((rc = awe_write_wave_data(addr, offset, rec, -1)) < 0) {
3250 kfree(rec);
3251 return rc;
3253 sf->mem_ptr += rc;
3256 add_sf_sample(sf, rec);
3257 return 0;
3261 /* replace wave sample data */
3262 static int
3263 awe_replace_data(awe_patch_info *patch, const char __user *addr, int count)
3265 int offset;
3266 int size;
3267 int rc;
3268 int channels;
3269 awe_sample_info cursmp;
3270 int save_mem_ptr;
3271 sf_list *sf;
3272 awe_sample_list *rec;
3274 if (! patch_opened || (sf = sftail) == NULL) {
3275 printk(KERN_WARNING "AWE32: replace: patch not opened\n");
3276 return -EINVAL;
3279 size = (count - AWE_SAMPLE_INFO_SIZE) / 2;
3280 offset = AWE_PATCH_INFO_SIZE;
3281 if (copy_from_user(&cursmp, addr + offset, AWE_SAMPLE_INFO_SIZE))
3282 return -EFAULT;
3283 offset += AWE_SAMPLE_INFO_SIZE;
3284 if (cursmp.size == 0 || size != cursmp.size) {
3285 printk(KERN_WARNING "AWE32: replace: invalid sample size (%d!=%d)\n",
3286 cursmp.size, size);
3287 return -EINVAL;
3289 channels = patch->optarg;
3290 if (channels <= 0 || channels > AWE_NORMAL_VOICES) {
3291 printk(KERN_WARNING "AWE32: replace: invalid channels %d\n", channels);
3292 return -EINVAL;
3295 for (rec = sf->samples; rec; rec = rec->next) {
3296 if (rec->v.sample == cursmp.sample)
3297 break;
3299 if (rec == NULL) {
3300 printk(KERN_WARNING "AWE32: replace: cannot find existing sample data %d\n",
3301 cursmp.sample);
3302 return -EINVAL;
3305 if (rec->v.size != cursmp.size) {
3306 printk(KERN_WARNING "AWE32: replace: exiting size differed (%d!=%d)\n",
3307 rec->v.size, cursmp.size);
3308 return -EINVAL;
3311 save_mem_ptr = awe_free_mem_ptr();
3312 sftail->mem_ptr = rec->v.start - awe_mem_start;
3313 memcpy(&rec->v, &cursmp, sizeof(cursmp));
3314 rec->v.sf_id = current_sf_id;
3315 if ((rc = awe_write_wave_data(addr, offset, rec, channels)) < 0)
3316 return rc;
3317 sftail->mem_ptr = save_mem_ptr;
3319 return 0;
3323 /*----------------------------------------------------------------*/
3325 static const char __user *readbuf_addr;
3326 static int readbuf_offs;
3327 static int readbuf_flags;
3329 /* initialize read buffer */
3330 static int
3331 readbuf_init(const char __user *addr, int offset, awe_sample_info *sp)
3333 readbuf_addr = addr;
3334 readbuf_offs = offset;
3335 readbuf_flags = sp->mode_flags;
3336 return 0;
3339 /* read directly from user buffer */
3340 static unsigned short
3341 readbuf_word(int pos)
3343 unsigned short c;
3344 /* read from user buffer */
3345 if (readbuf_flags & AWE_SAMPLE_8BITS) {
3346 unsigned char cc;
3347 get_user(cc, (unsigned char __user *)(readbuf_addr + readbuf_offs + pos));
3348 c = (unsigned short)cc << 8; /* convert 8bit -> 16bit */
3349 } else {
3350 get_user(c, (unsigned short __user *)(readbuf_addr + readbuf_offs + pos * 2));
3352 if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
3353 c ^= 0x8000; /* unsigned -> signed */
3354 return c;
3357 #define readbuf_word_cache readbuf_word
3358 #define readbuf_end() /**/
3360 /*----------------------------------------------------------------*/
3362 #define BLANK_LOOP_START 8
3363 #define BLANK_LOOP_END 40
3364 #define BLANK_LOOP_SIZE 48
3366 /* loading onto memory - return the actual written size */
3367 static int
3368 awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *list, int channels)
3370 int i, truesize, dram_offset;
3371 awe_sample_info *sp = &list->v;
3372 int rc;
3374 /* be sure loop points start < end */
3375 if (sp->loopstart > sp->loopend) {
3376 int tmp = sp->loopstart;
3377 sp->loopstart = sp->loopend;
3378 sp->loopend = tmp;
3381 /* compute true data size to be loaded */
3382 truesize = sp->size;
3383 if (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))
3384 truesize += sp->loopend - sp->loopstart;
3385 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK)
3386 truesize += BLANK_LOOP_SIZE;
3387 if (awe_free_mem_ptr() + truesize >= memsize/2) {
3388 DEBUG(-1,printk("AWE32 Error: Sample memory full\n"));
3389 return -ENOSPC;
3392 /* recalculate address offset */
3393 sp->end -= sp->start;
3394 sp->loopstart -= sp->start;
3395 sp->loopend -= sp->start;
3397 dram_offset = awe_free_mem_ptr() + awe_mem_start;
3398 sp->start = dram_offset;
3399 sp->end += dram_offset;
3400 sp->loopstart += dram_offset;
3401 sp->loopend += dram_offset;
3403 /* set the total size (store onto obsolete checksum value) */
3404 if (sp->size == 0)
3405 sp->checksum = 0;
3406 else
3407 sp->checksum = truesize;
3409 if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0)
3410 return rc;
3412 if (readbuf_init(addr, offset, sp) < 0)
3413 return -ENOSPC;
3415 for (i = 0; i < sp->size; i++) {
3416 unsigned short c;
3417 c = readbuf_word(i);
3418 awe_write_dram(c);
3419 if (i == sp->loopend &&
3420 (sp->mode_flags & (AWE_SAMPLE_BIDIR_LOOP|AWE_SAMPLE_REVERSE_LOOP))) {
3421 int looplen = sp->loopend - sp->loopstart;
3422 /* copy reverse loop */
3423 int k;
3424 for (k = 1; k <= looplen; k++) {
3425 c = readbuf_word_cache(i - k);
3426 awe_write_dram(c);
3428 if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) {
3429 sp->end += looplen;
3430 } else {
3431 sp->start += looplen;
3432 sp->end += looplen;
3436 readbuf_end();
3438 /* if no blank loop is attached in the sample, add it */
3439 if (sp->mode_flags & AWE_SAMPLE_NO_BLANK) {
3440 for (i = 0; i < BLANK_LOOP_SIZE; i++)
3441 awe_write_dram(0);
3442 if (sp->mode_flags & AWE_SAMPLE_SINGLESHOT) {
3443 sp->loopstart = sp->end + BLANK_LOOP_START;
3444 sp->loopend = sp->end + BLANK_LOOP_END;
3448 awe_close_dram();
3450 /* initialize FM */
3451 awe_init_fm();
3453 return truesize;
3457 /*----------------------------------------------------------------*/
3459 #ifdef AWE_HAS_GUS_COMPATIBILITY
3461 /* calculate GUS envelope time:
3462 * is this correct? i have no idea..
3464 static int
3465 calc_gus_envelope_time(int rate, int start, int end)
3467 int r, p, t;
3468 r = (3 - ((rate >> 6) & 3)) * 3;
3469 p = rate & 0x3f;
3470 t = end - start;
3471 if (t < 0) t = -t;
3472 if (13 > r)
3473 t = t << (13 - r);
3474 else
3475 t = t >> (r - 13);
3476 return (t * 10) / (p * 441);
3479 #define calc_gus_sustain(val) (0x7f - vol_table[(val)/2])
3480 #define calc_gus_attenuation(val) vol_table[(val)/2]
3482 /* load GUS patch */
3483 static int
3484 awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag)
3486 struct patch_info patch;
3487 awe_voice_info *rec;
3488 awe_sample_info *smp;
3489 awe_voice_list *vrec;
3490 awe_sample_list *smprec;
3491 int sizeof_patch;
3492 int note, rc;
3493 sf_list *sf;
3495 sizeof_patch = (int)((long)&patch.data[0] - (long)&patch); /* header size */
3496 if (size < sizeof_patch) {
3497 printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
3498 return -EINVAL;
3500 if (copy_from_user(((char*)&patch) + offs, addr + offs, sizeof_patch - offs))
3501 return -EFAULT;
3502 size -= sizeof_patch;
3503 if (size < patch.len) {
3504 printk(KERN_WARNING "AWE32 Error: Patch record too short (%d<%d)\n",
3505 size, patch.len);
3506 return -EINVAL;
3508 if ((sf = check_patch_opened(AWE_PAT_TYPE_GUS, NULL)) == NULL)
3509 return -ENOMEM;
3510 if ((smprec = alloc_new_sample()) == NULL)
3511 return -ENOMEM;
3512 if ((vrec = alloc_new_info()) == NULL) {
3513 kfree(smprec);
3514 return -ENOMEM;
3517 smp = &smprec->v;
3518 smp->sample = sf->num_sample;
3519 smp->start = 0;
3520 smp->end = patch.len;
3521 smp->loopstart = patch.loop_start;
3522 smp->loopend = patch.loop_end;
3523 smp->size = patch.len;
3525 /* set up mode flags */
3526 smp->mode_flags = 0;
3527 if (!(patch.mode & WAVE_16_BITS))
3528 smp->mode_flags |= AWE_SAMPLE_8BITS;
3529 if (patch.mode & WAVE_UNSIGNED)
3530 smp->mode_flags |= AWE_SAMPLE_UNSIGNED;
3531 smp->mode_flags |= AWE_SAMPLE_NO_BLANK;
3532 if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
3533 smp->mode_flags |= AWE_SAMPLE_SINGLESHOT;
3534 if (patch.mode & WAVE_BIDIR_LOOP)
3535 smp->mode_flags |= AWE_SAMPLE_BIDIR_LOOP;
3536 if (patch.mode & WAVE_LOOP_BACK)
3537 smp->mode_flags |= AWE_SAMPLE_REVERSE_LOOP;
3539 DEBUG(0,printk("AWE32: [sample %d mode %x]\n", patch.instr_no, smp->mode_flags));
3540 if (patch.mode & WAVE_16_BITS) {
3541 /* convert to word offsets */
3542 smp->size /= 2;
3543 smp->end /= 2;
3544 smp->loopstart /= 2;
3545 smp->loopend /= 2;
3547 smp->checksum_flag = 0;
3548 smp->checksum = 0;
3550 if ((rc = awe_write_wave_data(addr, sizeof_patch, smprec, -1)) < 0) {
3551 kfree(vrec);
3552 return rc;
3554 sf->mem_ptr += rc;
3555 add_sf_sample(sf, smprec);
3557 /* set up voice info */
3558 rec = &vrec->v;
3559 awe_init_voice_info(rec);
3560 rec->sample = sf->num_info; /* the last sample */
3561 rec->rate_offset = calc_rate_offset(patch.base_freq);
3562 note = freq_to_note(patch.base_note);
3563 rec->root = note / 100;
3564 rec->tune = -(note % 100);
3565 rec->low = freq_to_note(patch.low_note) / 100;
3566 rec->high = freq_to_note(patch.high_note) / 100;
3567 DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%d-%d)]\n",
3568 rec->rate_offset, note,
3569 rec->low, rec->high,
3570 patch.low_note, patch.high_note));
3571 /* panning position; -128 - 127 => 0-127 */
3572 rec->pan = (patch.panning + 128) / 2;
3574 /* detuning is ignored */
3575 /* 6points volume envelope */
3576 if (patch.mode & WAVE_ENVELOPES) {
3577 int attack, hold, decay, release;
3578 attack = calc_gus_envelope_time
3579 (patch.env_rate[0], 0, patch.env_offset[0]);
3580 hold = calc_gus_envelope_time
3581 (patch.env_rate[1], patch.env_offset[0],
3582 patch.env_offset[1]);
3583 decay = calc_gus_envelope_time
3584 (patch.env_rate[2], patch.env_offset[1],
3585 patch.env_offset[2]);
3586 release = calc_gus_envelope_time
3587 (patch.env_rate[3], patch.env_offset[1],
3588 patch.env_offset[4]);
3589 release += calc_gus_envelope_time
3590 (patch.env_rate[4], patch.env_offset[3],
3591 patch.env_offset[4]);
3592 release += calc_gus_envelope_time
3593 (patch.env_rate[5], patch.env_offset[4],
3594 patch.env_offset[5]);
3595 rec->parm.volatkhld = (calc_parm_hold(hold) << 8) |
3596 calc_parm_attack(attack);
3597 rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
3598 calc_parm_decay(decay);
3599 rec->parm.volrelease = 0x8000 | calc_parm_decay(release);
3600 DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release));
3601 rec->attenuation = calc_gus_attenuation(patch.env_offset[0]);
3604 /* tremolo effect */
3605 if (patch.mode & WAVE_TREMOLO) {
3606 int rate = (patch.tremolo_rate * 1000 / 38) / 42;
3607 rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
3608 DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n",
3609 patch.tremolo_rate, patch.tremolo_depth,
3610 rec->parm.tremfrq));
3612 /* vibrato effect */
3613 if (patch.mode & WAVE_VIBRATO) {
3614 int rate = (patch.vibrato_rate * 1000 / 38) / 42;
3615 rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
3616 DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n",
3617 patch.tremolo_rate, patch.tremolo_depth,
3618 rec->parm.tremfrq));
3621 /* scale_freq, scale_factor, volume, and fractions not implemented */
3623 /* append to the tail of the list */
3624 vrec->bank = ctrls[AWE_MD_GUS_BANK];
3625 vrec->instr = patch.instr_no;
3626 vrec->disabled = FALSE;
3627 vrec->type = V_ST_NORMAL;
3629 add_sf_info(sf, vrec);
3630 add_info_list(vrec);
3632 /* set the voice index */
3633 awe_set_sample(vrec);
3635 return 0;
3638 #endif /* AWE_HAS_GUS_COMPATIBILITY */
3641 * sample and voice list handlers
3644 /* append this to the current sf list */
3645 static void add_sf_info(sf_list *sf, awe_voice_list *rec)
3647 if (sf == NULL)
3648 return;
3649 rec->holder = sf;
3650 rec->v.sf_id = sf->sf_id;
3651 if (sf->last_infos)
3652 sf->last_infos->next = rec;
3653 else
3654 sf->infos = rec;
3655 sf->last_infos = rec;
3656 rec->next = NULL;
3657 sf->num_info++;
3660 /* prepend this sample to sf list */
3661 static void add_sf_sample(sf_list *sf, awe_sample_list *rec)
3663 if (sf == NULL)
3664 return;
3665 rec->holder = sf;
3666 rec->v.sf_id = sf->sf_id;
3667 if (sf->last_samples)
3668 sf->last_samples->next = rec;
3669 else
3670 sf->samples = rec;
3671 sf->last_samples = rec;
3672 rec->next = NULL;
3673 sf->num_sample++;
3676 /* purge the old records which don't belong with the same file id */
3677 static void purge_old_list(awe_voice_list *rec, awe_voice_list *next)
3679 rec->next_instr = next;
3680 if (rec->bank == AWE_DRUM_BANK) {
3681 /* remove samples with the same note range */
3682 awe_voice_list *cur, *prev = rec;
3683 int low = rec->v.low;
3684 int high = rec->v.high;
3685 for (cur = next; cur; cur = cur->next_instr) {
3686 if (cur->v.low == low &&
3687 cur->v.high == high &&
3688 ! is_identical_holder(cur->holder, rec->holder))
3689 prev->next_instr = cur->next_instr;
3690 else
3691 prev = cur;
3693 } else {
3694 if (! is_identical_holder(next->holder, rec->holder))
3695 /* remove all samples */
3696 rec->next_instr = NULL;
3700 /* prepend to top of the preset table */
3701 static void add_info_list(awe_voice_list *rec)
3703 awe_voice_list *prev, *cur;
3704 int key;
3706 if (rec->disabled)
3707 return;
3709 key = awe_search_key(rec->bank, rec->instr, rec->v.low);
3710 prev = NULL;
3711 for (cur = preset_table[key]; cur; cur = cur->next_bank) {
3712 /* search the first record with the same bank number */
3713 if (cur->instr == rec->instr && cur->bank == rec->bank) {
3714 /* replace the list with the new record */
3715 rec->next_bank = cur->next_bank;
3716 if (prev)
3717 prev->next_bank = rec;
3718 else
3719 preset_table[key] = rec;
3720 purge_old_list(rec, cur);
3721 return;
3723 prev = cur;
3726 /* this is the first bank record.. just add this */
3727 rec->next_instr = NULL;
3728 rec->next_bank = preset_table[key];
3729 preset_table[key] = rec;
3732 /* remove samples later than the specified sf_id */
3733 static void
3734 awe_remove_samples(int sf_id)
3736 sf_list *p, *prev;
3738 if (sf_id <= 0) {
3739 awe_reset_samples();
3740 return;
3742 /* already removed? */
3743 if (current_sf_id <= sf_id)
3744 return;
3746 for (p = sftail; p; p = prev) {
3747 if (p->sf_id <= sf_id)
3748 break;
3749 prev = p->prev;
3750 awe_free_sf(p);
3752 sftail = p;
3753 if (sftail) {
3754 sf_id = sftail->sf_id;
3755 sftail->next = NULL;
3756 } else {
3757 sf_id = 0;
3758 sfhead = NULL;
3760 current_sf_id = sf_id;
3761 if (locked_sf_id > sf_id)
3762 locked_sf_id = sf_id;
3764 rebuild_preset_list();
3767 /* rebuild preset search list */
3768 static void rebuild_preset_list(void)
3770 sf_list *p;
3771 awe_voice_list *rec;
3773 memset(preset_table, 0, sizeof(preset_table));
3775 for (p = sfhead; p; p = p->next) {
3776 for (rec = p->infos; rec; rec = rec->next)
3777 add_info_list(rec);
3781 /* compare the given sf_id pair */
3782 static int is_identical_holder(sf_list *sf1, sf_list *sf2)
3784 if (sf1 == NULL || sf2 == NULL)
3785 return FALSE;
3786 if (sf1 == sf2)
3787 return TRUE;
3788 #ifdef AWE_ALLOW_SAMPLE_SHARING
3790 /* compare with the sharing id */
3791 sf_list *p;
3792 int counter = 0;
3793 if (sf1->sf_id < sf2->sf_id) { /* make sure id1 > id2 */
3794 sf_list *tmp; tmp = sf1; sf1 = sf2; sf2 = tmp;
3796 for (p = sf1->shared; p; p = p->shared) {
3797 if (counter++ > current_sf_id)
3798 break; /* strange sharing loop.. quit */
3799 if (p == sf2)
3800 return TRUE;
3803 #endif /* allow sharing */
3804 return FALSE;
3807 /* search the sample index matching with the given sample id */
3808 static awe_sample_list *
3809 search_sample_index(sf_list *sf, int sample)
3811 awe_sample_list *p;
3812 #ifdef AWE_ALLOW_SAMPLE_SHARING
3813 int counter = 0;
3814 while (sf) {
3815 for (p = sf->samples; p; p = p->next) {
3816 if (p->v.sample == sample)
3817 return p;
3819 sf = sf->shared;
3820 if (counter++ > current_sf_id)
3821 break; /* strange sharing loop.. quit */
3823 #else
3824 if (sf) {
3825 for (p = sf->samples; p; p = p->next) {
3826 if (p->v.sample == sample)
3827 return p;
3830 #endif
3831 return NULL;
3834 /* search the specified sample */
3835 /* non-zero = found */
3836 static short
3837 awe_set_sample(awe_voice_list *rec)
3839 awe_sample_list *smp;
3840 awe_voice_info *vp = &rec->v;
3842 vp->index = 0;
3843 if ((smp = search_sample_index(rec->holder, vp->sample)) == NULL)
3844 return 0;
3846 /* set the actual sample offsets */
3847 vp->start += smp->v.start;
3848 vp->end += smp->v.end;
3849 vp->loopstart += smp->v.loopstart;
3850 vp->loopend += smp->v.loopend;
3851 /* copy mode flags */
3852 vp->mode = smp->v.mode_flags;
3853 /* set flag */
3854 vp->index = 1;
3856 return 1;
3861 * voice allocation
3864 /* look for all voices associated with the specified note & velocity */
3865 static int
3866 awe_search_multi_voices(awe_voice_list *rec, int note, int velocity,
3867 awe_voice_info **vlist)
3869 int nvoices;
3871 nvoices = 0;
3872 for (; rec; rec = rec->next_instr) {
3873 if (note >= rec->v.low &&
3874 note <= rec->v.high &&
3875 velocity >= rec->v.vellow &&
3876 velocity <= rec->v.velhigh) {
3877 if (rec->type == V_ST_MAPPED) {
3878 /* mapper */
3879 vlist[0] = &rec->v;
3880 return -1;
3882 vlist[nvoices++] = &rec->v;
3883 if (nvoices >= AWE_MAX_VOICES)
3884 break;
3887 return nvoices;
3890 /* store the voice list from the specified note and velocity.
3891 if the preset is mapped, seek for the destination preset, and rewrite
3892 the note number if necessary.
3894 static int
3895 really_alloc_voices(int bank, int instr, int *note, int velocity, awe_voice_info **vlist)
3897 int nvoices;
3898 awe_voice_list *vrec;
3899 int level = 0;
3901 for (;;) {
3902 vrec = awe_search_instr(bank, instr, *note);
3903 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3904 if (nvoices == 0) {
3905 if (bank == AWE_DRUM_BANK)
3906 /* search default drumset */
3907 vrec = awe_search_instr(bank, ctrls[AWE_MD_DEF_DRUM], *note);
3908 else
3909 /* search default preset */
3910 vrec = awe_search_instr(ctrls[AWE_MD_DEF_BANK], instr, *note);
3911 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3913 if (nvoices == 0) {
3914 if (bank == AWE_DRUM_BANK && ctrls[AWE_MD_DEF_DRUM] != 0)
3915 /* search default drumset */
3916 vrec = awe_search_instr(bank, 0, *note);
3917 else if (bank != AWE_DRUM_BANK && ctrls[AWE_MD_DEF_BANK] != 0)
3918 /* search default preset */
3919 vrec = awe_search_instr(0, instr, *note);
3920 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3922 if (nvoices < 0) { /* mapping */
3923 int key = vlist[0]->fixkey;
3924 instr = vlist[0]->start;
3925 bank = vlist[0]->end;
3926 if (level++ > 5) {
3927 printk(KERN_ERR "AWE32: too deep mapping level\n");
3928 return 0;
3930 if (key >= 0)
3931 *note = key;
3932 } else
3933 break;
3936 return nvoices;
3939 /* allocate voices corresponding note and velocity; supports multiple insts. */
3940 static void
3941 awe_alloc_multi_voices(int ch, int note, int velocity, int key)
3943 int i, v, nvoices, bank;
3944 awe_voice_info *vlist[AWE_MAX_VOICES];
3946 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch))
3947 bank = AWE_DRUM_BANK; /* always search drumset */
3948 else
3949 bank = channels[ch].bank;
3951 /* check the possible voices; note may be changeable if mapped */
3952 nvoices = really_alloc_voices(bank, channels[ch].instr,
3953 &note, velocity, vlist);
3955 /* set the voices */
3956 current_alloc_time++;
3957 for (i = 0; i < nvoices; i++) {
3958 v = awe_clear_voice();
3959 voices[v].key = key;
3960 voices[v].ch = ch;
3961 voices[v].note = note;
3962 voices[v].velocity = velocity;
3963 voices[v].time = current_alloc_time;
3964 voices[v].cinfo = &channels[ch];
3965 voices[v].sample = vlist[i];
3966 voices[v].state = AWE_ST_MARK;
3967 voices[v].layer = nvoices - i - 1; /* in reverse order */
3970 /* clear the mark in allocated voices */
3971 for (i = 0; i < awe_max_voices; i++) {
3972 if (voices[i].state == AWE_ST_MARK)
3973 voices[i].state = AWE_ST_OFF;
3979 /* search an empty voice.
3980 if no empty voice is found, at least terminate a voice
3982 static int
3983 awe_clear_voice(void)
3985 enum {
3986 OFF=0, RELEASED, SUSTAINED, PLAYING, END
3988 struct voice_candidate_t {
3989 int best;
3990 int time;
3991 int vtarget;
3992 } candidate[END];
3993 int i, type, vtarget;
3995 vtarget = 0xffff;
3996 for (type = OFF; type < END; type++) {
3997 candidate[type].best = -1;
3998 candidate[type].time = current_alloc_time + 1;
3999 candidate[type].vtarget = vtarget;
4002 for (i = 0; i < awe_max_voices; i++) {
4003 if (voices[i].state & AWE_ST_OFF)
4004 type = OFF;
4005 else if (voices[i].state & AWE_ST_RELEASED)
4006 type = RELEASED;
4007 else if (voices[i].state & AWE_ST_SUSTAINED)
4008 type = SUSTAINED;
4009 else if (voices[i].state & ~AWE_ST_MARK)
4010 type = PLAYING;
4011 else
4012 continue;
4013 #ifdef AWE_CHECK_VTARGET
4014 /* get current volume */
4015 vtarget = (awe_peek_dw(AWE_VTFT(i)) >> 16) & 0xffff;
4016 #endif
4017 if (candidate[type].best < 0 ||
4018 vtarget < candidate[type].vtarget ||
4019 (vtarget == candidate[type].vtarget &&
4020 voices[i].time < candidate[type].time)) {
4021 candidate[type].best = i;
4022 candidate[type].time = voices[i].time;
4023 candidate[type].vtarget = vtarget;
4027 for (type = OFF; type < END; type++) {
4028 if ((i = candidate[type].best) >= 0) {
4029 if (voices[i].state != AWE_ST_OFF)
4030 awe_terminate(i);
4031 awe_voice_init(i, TRUE);
4032 return i;
4035 return 0;
4039 /* search sample for the specified note & velocity and set it on the voice;
4040 * note that voice is the voice index (not channel index)
4042 static void
4043 awe_alloc_one_voice(int voice, int note, int velocity)
4045 int ch, nvoices, bank;
4046 awe_voice_info *vlist[AWE_MAX_VOICES];
4048 ch = voices[voice].ch;
4049 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice))
4050 bank = AWE_DRUM_BANK; /* always search drumset */
4051 else
4052 bank = voices[voice].cinfo->bank;
4054 nvoices = really_alloc_voices(bank, voices[voice].cinfo->instr,
4055 &note, velocity, vlist);
4056 if (nvoices > 0) {
4057 voices[voice].time = ++current_alloc_time;
4058 voices[voice].sample = vlist[0]; /* use the first one */
4059 voices[voice].layer = 0;
4060 voices[voice].note = note;
4061 voices[voice].velocity = velocity;
4067 * sequencer2 functions
4070 /* search an empty voice; used by sequencer2 */
4071 static int
4072 awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
4074 playing_mode = AWE_PLAY_MULTI2;
4075 awe_info.nr_voices = AWE_MAX_CHANNELS;
4076 return awe_clear_voice();
4080 /* set up voice; used by sequencer2 */
4081 static void
4082 awe_setup_voice(int dev, int voice, int chn)
4084 struct channel_info *info;
4085 if (synth_devs[dev] == NULL ||
4086 (info = &synth_devs[dev]->chn_info[chn]) == NULL)
4087 return;
4089 if (voice < 0 || voice >= awe_max_voices)
4090 return;
4092 DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn));
4093 channels[chn].expression_vol = info->controllers[CTL_EXPRESSION];
4094 channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME];
4095 channels[chn].panning =
4096 info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */
4097 channels[chn].bender = info->bender_value; /* zero center */
4098 channels[chn].bank = info->controllers[CTL_BANK_SELECT];
4099 channels[chn].sustained = info->controllers[CTL_SUSTAIN];
4100 if (info->controllers[CTL_EXT_EFF_DEPTH]) {
4101 FX_SET(&channels[chn].fx, AWE_FX_REVERB,
4102 info->controllers[CTL_EXT_EFF_DEPTH] * 2);
4104 if (info->controllers[CTL_CHORUS_DEPTH]) {
4105 FX_SET(&channels[chn].fx, AWE_FX_CHORUS,
4106 info->controllers[CTL_CHORUS_DEPTH] * 2);
4108 awe_set_instr(dev, chn, info->pgm_num);
4112 #ifdef CONFIG_AWE32_MIXER
4114 * AWE32 mixer device control
4117 static int awe_mixer_ioctl(int dev, unsigned int cmd, void __user *arg);
4119 static int my_mixerdev = -1;
4121 static struct mixer_operations awe_mixer_operations = {
4122 .owner = THIS_MODULE,
4123 .id = "AWE",
4124 .name = "AWE32 Equalizer",
4125 .ioctl = awe_mixer_ioctl,
4128 static void __init attach_mixer(void)
4130 if ((my_mixerdev = sound_alloc_mixerdev()) >= 0) {
4131 mixer_devs[my_mixerdev] = &awe_mixer_operations;
4135 static void unload_mixer(void)
4137 if (my_mixerdev >= 0)
4138 sound_unload_mixerdev(my_mixerdev);
4141 static int
4142 awe_mixer_ioctl(int dev, unsigned int cmd, void __user * arg)
4144 int i, level, value;
4146 if (((cmd >> 8) & 0xff) != 'M')
4147 return -EINVAL;
4149 if (get_user(level, (int __user *)arg))
4150 return -EFAULT;
4151 level = ((level & 0xff) + (level >> 8)) / 2;
4152 DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
4154 if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
4155 switch (cmd & 0xff) {
4156 case SOUND_MIXER_BASS:
4157 value = level * 12 / 100;
4158 if (value >= 12)
4159 value = 11;
4160 ctrls[AWE_MD_BASS_LEVEL] = value;
4161 awe_update_equalizer();
4162 break;
4163 case SOUND_MIXER_TREBLE:
4164 value = level * 12 / 100;
4165 if (value >= 12)
4166 value = 11;
4167 ctrls[AWE_MD_TREBLE_LEVEL] = value;
4168 awe_update_equalizer();
4169 break;
4170 case SOUND_MIXER_VOLUME:
4171 level = level * 127 / 100;
4172 if (level >= 128) level = 127;
4173 atten_relative = FALSE;
4174 atten_offset = vol_table[level];
4175 awe_update_volume();
4176 break;
4179 switch (cmd & 0xff) {
4180 case SOUND_MIXER_BASS:
4181 level = ctrls[AWE_MD_BASS_LEVEL] * 100 / 24;
4182 level = (level << 8) | level;
4183 break;
4184 case SOUND_MIXER_TREBLE:
4185 level = ctrls[AWE_MD_TREBLE_LEVEL] * 100 / 24;
4186 level = (level << 8) | level;
4187 break;
4188 case SOUND_MIXER_VOLUME:
4189 value = atten_offset;
4190 if (atten_relative)
4191 value += ctrls[AWE_MD_ZERO_ATTEN];
4192 for (i = 127; i > 0; i--) {
4193 if (value <= vol_table[i])
4194 break;
4196 level = i * 100 / 127;
4197 level = (level << 8) | level;
4198 break;
4199 case SOUND_MIXER_DEVMASK:
4200 level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME;
4201 break;
4202 default:
4203 level = 0;
4204 break;
4206 if (put_user(level, (int __user *)arg))
4207 return -EFAULT;
4208 return level;
4210 #endif /* CONFIG_AWE32_MIXER */
4214 * initialization of Emu8000
4217 /* intiailize audio channels */
4218 static void
4219 awe_init_audio(void)
4221 int ch;
4223 /* turn off envelope engines */
4224 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4225 awe_poke(AWE_DCYSUSV(ch), 0x80);
4228 /* reset all other parameters to zero */
4229 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4230 awe_poke(AWE_ENVVOL(ch), 0);
4231 awe_poke(AWE_ENVVAL(ch), 0);
4232 awe_poke(AWE_DCYSUS(ch), 0);
4233 awe_poke(AWE_ATKHLDV(ch), 0);
4234 awe_poke(AWE_LFO1VAL(ch), 0);
4235 awe_poke(AWE_ATKHLD(ch), 0);
4236 awe_poke(AWE_LFO2VAL(ch), 0);
4237 awe_poke(AWE_IP(ch), 0);
4238 awe_poke(AWE_IFATN(ch), 0);
4239 awe_poke(AWE_PEFE(ch), 0);
4240 awe_poke(AWE_FMMOD(ch), 0);
4241 awe_poke(AWE_TREMFRQ(ch), 0);
4242 awe_poke(AWE_FM2FRQ2(ch), 0);
4243 awe_poke_dw(AWE_PTRX(ch), 0);
4244 awe_poke_dw(AWE_VTFT(ch), 0);
4245 awe_poke_dw(AWE_PSST(ch), 0);
4246 awe_poke_dw(AWE_CSL(ch), 0);
4247 awe_poke_dw(AWE_CCCA(ch), 0);
4250 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4251 awe_poke_dw(AWE_CPF(ch), 0);
4252 awe_poke_dw(AWE_CVCF(ch), 0);
4257 /* initialize DMA address */
4258 static void
4259 awe_init_dma(void)
4261 awe_poke_dw(AWE_SMALR, 0);
4262 awe_poke_dw(AWE_SMARR, 0);
4263 awe_poke_dw(AWE_SMALW, 0);
4264 awe_poke_dw(AWE_SMARW, 0);
4268 /* initialization arrays; from ADIP */
4270 static unsigned short init1[128] = {
4271 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330,
4272 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730,
4273 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30,
4274 0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30,
4276 0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330,
4277 0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730,
4278 0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30,
4279 0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30,
4281 0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330,
4282 0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730,
4283 0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30,
4284 0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30,
4286 0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330,
4287 0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730,
4288 0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30,
4289 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30,
4292 static unsigned short init2[128] = {
4293 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
4294 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
4295 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
4296 0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
4298 0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
4299 0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
4300 0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
4301 0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
4303 0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
4304 0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
4305 0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
4306 0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
4308 0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
4309 0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
4310 0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
4311 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
4314 static unsigned short init3[128] = {
4315 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4316 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
4317 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
4318 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
4320 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
4321 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
4322 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
4323 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
4325 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
4326 0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
4327 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
4328 0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
4330 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
4331 0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
4332 0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
4333 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
4336 static unsigned short init4[128] = {
4337 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4338 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
4339 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
4340 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
4342 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
4343 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
4344 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
4345 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
4347 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
4348 0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
4349 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
4350 0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
4352 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
4353 0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
4354 0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
4355 0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
4359 /* send initialization arrays to start up */
4360 static void
4361 awe_init_array(void)
4363 awe_send_array(init1);
4364 awe_wait(1024);
4365 awe_send_array(init2);
4366 awe_send_array(init3);
4367 awe_poke_dw(AWE_HWCF4, 0);
4368 awe_poke_dw(AWE_HWCF5, 0x83);
4369 awe_poke_dw(AWE_HWCF6, 0x8000);
4370 awe_send_array(init4);
4373 /* send an initialization array */
4374 static void
4375 awe_send_array(unsigned short *data)
4377 int i;
4378 unsigned short *p;
4380 p = data;
4381 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4382 awe_poke(AWE_INIT1(i), *p);
4383 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4384 awe_poke(AWE_INIT2(i), *p);
4385 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4386 awe_poke(AWE_INIT3(i), *p);
4387 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4388 awe_poke(AWE_INIT4(i), *p);
4393 * set up awe32 channels to some known state.
4396 /* set the envelope & LFO parameters to the default values; see ADIP */
4397 static void
4398 awe_tweak_voice(int i)
4400 /* set all mod/vol envelope shape to minimum */
4401 awe_poke(AWE_ENVVOL(i), 0x8000);
4402 awe_poke(AWE_ENVVAL(i), 0x8000);
4403 awe_poke(AWE_DCYSUS(i), 0x7F7F);
4404 awe_poke(AWE_ATKHLDV(i), 0x7F7F);
4405 awe_poke(AWE_ATKHLD(i), 0x7F7F);
4406 awe_poke(AWE_PEFE(i), 0); /* mod envelope height to zero */
4407 awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */
4408 awe_poke(AWE_LFO2VAL(i), 0x8000);
4409 awe_poke(AWE_IP(i), 0xE000); /* no pitch shift */
4410 awe_poke(AWE_IFATN(i), 0xFF00); /* volume to minimum */
4411 awe_poke(AWE_FMMOD(i), 0);
4412 awe_poke(AWE_TREMFRQ(i), 0);
4413 awe_poke(AWE_FM2FRQ2(i), 0);
4416 static void
4417 awe_tweak(void)
4419 int i;
4420 /* reset all channels */
4421 for (i = 0; i < awe_max_voices; i++)
4422 awe_tweak_voice(i);
4427 * initializes the FM section of AWE32;
4428 * see Vince Vu's unofficial AWE32 programming guide
4431 static void
4432 awe_init_fm(void)
4434 #ifndef AWE_ALWAYS_INIT_FM
4435 /* if no extended memory is on board.. */
4436 if (memsize <= 0)
4437 return;
4438 #endif
4439 DEBUG(3,printk("AWE32: initializing FM\n"));
4441 /* Initialize the last two channels for DRAM refresh and producing
4442 the reverb and chorus effects for Yamaha OPL-3 synthesizer */
4444 /* 31: FM left channel, 0xffffe0-0xffffe8 */
4445 awe_poke(AWE_DCYSUSV(30), 0x80);
4446 awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */
4447 awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 |
4448 (DEF_FM_CHORUS_DEPTH << 24));
4449 awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8));
4450 awe_poke_dw(AWE_CPF(30), 0);
4451 awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3);
4453 /* 32: FM right channel, 0xfffff0-0xfffff8 */
4454 awe_poke(AWE_DCYSUSV(31), 0x80);
4455 awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */
4456 awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 |
4457 (DEF_FM_CHORUS_DEPTH << 24));
4458 awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8));
4459 awe_poke_dw(AWE_CPF(31), 0x8000);
4460 awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3);
4462 /* skew volume & cutoff */
4463 awe_poke_dw(AWE_VTFT(30), 0x8000FFFF);
4464 awe_poke_dw(AWE_VTFT(31), 0x8000FFFF);
4466 voices[30].state = AWE_ST_FM;
4467 voices[31].state = AWE_ST_FM;
4469 /* change maximum channels to 30 */
4470 awe_max_voices = AWE_NORMAL_VOICES;
4471 if (playing_mode == AWE_PLAY_DIRECT)
4472 awe_info.nr_voices = awe_max_voices;
4473 else
4474 awe_info.nr_voices = AWE_MAX_CHANNELS;
4475 voice_alloc->max_voice = awe_max_voices;
4479 * AWE32 DRAM access routines
4482 /* open DRAM write accessing mode */
4483 static int
4484 awe_open_dram_for_write(int offset, int channels)
4486 int vidx[AWE_NORMAL_VOICES];
4487 int i;
4489 if (channels < 0 || channels >= AWE_NORMAL_VOICES) {
4490 channels = AWE_NORMAL_VOICES;
4491 for (i = 0; i < AWE_NORMAL_VOICES; i++)
4492 vidx[i] = i;
4493 } else {
4494 for (i = 0; i < channels; i++) {
4495 vidx[i] = awe_clear_voice();
4496 voices[vidx[i]].state = AWE_ST_MARK;
4500 /* use all channels for DMA transfer */
4501 for (i = 0; i < channels; i++) {
4502 if (vidx[i] < 0) continue;
4503 awe_poke(AWE_DCYSUSV(vidx[i]), 0x80);
4504 awe_poke_dw(AWE_VTFT(vidx[i]), 0);
4505 awe_poke_dw(AWE_CVCF(vidx[i]), 0);
4506 awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000);
4507 awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000);
4508 awe_poke_dw(AWE_PSST(vidx[i]), 0);
4509 awe_poke_dw(AWE_CSL(vidx[i]), 0);
4510 awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000);
4511 voices[vidx[i]].state = AWE_ST_DRAM;
4513 /* point channels 31 & 32 to ROM samples for DRAM refresh */
4514 awe_poke_dw(AWE_VTFT(30), 0);
4515 awe_poke_dw(AWE_PSST(30), 0x1d8);
4516 awe_poke_dw(AWE_CSL(30), 0x1e0);
4517 awe_poke_dw(AWE_CCCA(30), 0x1d8);
4518 awe_poke_dw(AWE_VTFT(31), 0);
4519 awe_poke_dw(AWE_PSST(31), 0x1d8);
4520 awe_poke_dw(AWE_CSL(31), 0x1e0);
4521 awe_poke_dw(AWE_CCCA(31), 0x1d8);
4522 voices[30].state = AWE_ST_FM;
4523 voices[31].state = AWE_ST_FM;
4525 /* if full bit is on, not ready to write on */
4526 if (awe_peek_dw(AWE_SMALW) & 0x80000000) {
4527 for (i = 0; i < channels; i++) {
4528 awe_poke_dw(AWE_CCCA(vidx[i]), 0);
4529 voices[vidx[i]].state = AWE_ST_OFF;
4531 printk("awe: not ready to write..\n");
4532 return -EPERM;
4535 /* set address to write */
4536 awe_poke_dw(AWE_SMALW, offset);
4538 return 0;
4541 /* open DRAM for RAM size detection */
4542 static void
4543 awe_open_dram_for_check(void)
4545 int i;
4546 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4547 awe_poke(AWE_DCYSUSV(i), 0x80);
4548 awe_poke_dw(AWE_VTFT(i), 0);
4549 awe_poke_dw(AWE_CVCF(i), 0);
4550 awe_poke_dw(AWE_PTRX(i), 0x40000000);
4551 awe_poke_dw(AWE_CPF(i), 0x40000000);
4552 awe_poke_dw(AWE_PSST(i), 0);
4553 awe_poke_dw(AWE_CSL(i), 0);
4554 if (i & 1) /* DMA write */
4555 awe_poke_dw(AWE_CCCA(i), 0x06000000);
4556 else /* DMA read */
4557 awe_poke_dw(AWE_CCCA(i), 0x04000000);
4558 voices[i].state = AWE_ST_DRAM;
4563 /* close dram access */
4564 static void
4565 awe_close_dram(void)
4567 int i;
4568 /* wait until FULL bit in SMAxW register be false */
4569 for (i = 0; i < 10000; i++) {
4570 if (!(awe_peek_dw(AWE_SMALW) & 0x80000000))
4571 break;
4572 awe_wait(10);
4575 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4576 if (voices[i].state == AWE_ST_DRAM) {
4577 awe_poke_dw(AWE_CCCA(i), 0);
4578 awe_poke(AWE_DCYSUSV(i), 0x807F);
4579 voices[i].state = AWE_ST_OFF;
4586 * check dram size on AWE board
4589 /* any three numbers you like */
4590 #define UNIQUE_ID1 0x1234
4591 #define UNIQUE_ID2 0x4321
4592 #define UNIQUE_ID3 0xABCD
4594 static void __init
4595 awe_check_dram(void)
4597 if (awe_present) /* already initialized */
4598 return;
4600 if (memsize >= 0) { /* given by config file or module option */
4601 memsize *= 1024; /* convert to Kbytes */
4602 return;
4605 awe_open_dram_for_check();
4607 memsize = 0;
4609 /* set up unique two id numbers */
4610 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET);
4611 awe_poke(AWE_SMLD, UNIQUE_ID1);
4612 awe_poke(AWE_SMLD, UNIQUE_ID2);
4614 while (memsize < AWE_MAX_DRAM_SIZE) {
4615 awe_wait(5);
4616 /* read a data on the DRAM start address */
4617 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET);
4618 awe_peek(AWE_SMLD); /* discard stale data */
4619 if (awe_peek(AWE_SMLD) != UNIQUE_ID1)
4620 break;
4621 if (awe_peek(AWE_SMLD) != UNIQUE_ID2)
4622 break;
4623 memsize += 512; /* increment 512kbytes */
4624 /* Write a unique data on the test address;
4625 * if the address is out of range, the data is written on
4626 * 0x200000(=AWE_DRAM_OFFSET). Then the two id words are
4627 * broken by this data.
4629 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + memsize*512L);
4630 awe_poke(AWE_SMLD, UNIQUE_ID3);
4631 awe_wait(5);
4632 /* read a data on the just written DRAM address */
4633 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + memsize*512L);
4634 awe_peek(AWE_SMLD); /* discard stale data */
4635 if (awe_peek(AWE_SMLD) != UNIQUE_ID3)
4636 break;
4638 awe_close_dram();
4640 DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", memsize));
4642 /* convert to Kbytes */
4643 memsize *= 1024;
4647 /*----------------------------------------------------------------*/
4650 * chorus and reverb controls; from VV's guide
4653 /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
4654 static char chorus_defined[AWE_CHORUS_NUMBERS];
4655 static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = {
4656 {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
4657 {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
4658 {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
4659 {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
4660 {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
4661 {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
4662 {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */
4663 {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */
4666 static int
4667 awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count)
4669 if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) {
4670 printk(KERN_WARNING "AWE32 Error: invalid chorus mode %d for uploading\n", patch->optarg);
4671 return -EINVAL;
4673 if (count < sizeof(awe_chorus_fx_rec)) {
4674 printk(KERN_WARNING "AWE32 Error: too short chorus fx parameters\n");
4675 return -EINVAL;
4677 if (copy_from_user(&chorus_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
4678 sizeof(awe_chorus_fx_rec)))
4679 return -EFAULT;
4680 chorus_defined[patch->optarg] = TRUE;
4681 return 0;
4684 static void
4685 awe_set_chorus_mode(int effect)
4687 if (effect < 0 || effect >= AWE_CHORUS_NUMBERS ||
4688 (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect]))
4689 return;
4690 awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback);
4691 awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset);
4692 awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth);
4693 awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay);
4694 awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq);
4695 awe_poke_dw(AWE_HWCF6, 0x8000);
4696 awe_poke_dw(AWE_HWCF7, 0x0000);
4699 static void
4700 awe_update_chorus_mode(void)
4702 awe_set_chorus_mode(ctrls[AWE_MD_CHORUS_MODE]);
4705 /*----------------------------------------------------------------*/
4707 /* reverb mode settings; write the following 28 data of 16 bit length
4708 * on the corresponding ports in the reverb_cmds array
4710 static char reverb_defined[AWE_CHORUS_NUMBERS];
4711 static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = {
4712 {{ /* room 1 */
4713 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
4714 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
4715 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4716 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4718 {{ /* room 2 */
4719 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4720 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4721 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4722 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4724 {{ /* room 3 */
4725 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4726 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
4727 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
4728 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
4730 {{ /* hall 1 */
4731 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4732 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4733 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
4734 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
4736 {{ /* hall 2 */
4737 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
4738 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
4739 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4740 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4742 {{ /* plate */
4743 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
4744 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
4745 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4746 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4748 {{ /* delay */
4749 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
4750 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4751 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4752 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4754 {{ /* panning delay */
4755 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
4756 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4757 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4758 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4762 static struct ReverbCmdPair {
4763 unsigned short cmd, port;
4764 } reverb_cmds[28] = {
4765 {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
4766 {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
4767 {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
4768 {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
4769 {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
4770 {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
4771 {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
4774 static int
4775 awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count)
4777 if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) {
4778 printk(KERN_WARNING "AWE32 Error: invalid reverb mode %d for uploading\n", patch->optarg);
4779 return -EINVAL;
4781 if (count < sizeof(awe_reverb_fx_rec)) {
4782 printk(KERN_WARNING "AWE32 Error: too short reverb fx parameters\n");
4783 return -EINVAL;
4785 if (copy_from_user(&reverb_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
4786 sizeof(awe_reverb_fx_rec)))
4787 return -EFAULT;
4788 reverb_defined[patch->optarg] = TRUE;
4789 return 0;
4792 static void
4793 awe_set_reverb_mode(int effect)
4795 int i;
4796 if (effect < 0 || effect >= AWE_REVERB_NUMBERS ||
4797 (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect]))
4798 return;
4799 for (i = 0; i < 28; i++)
4800 awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port,
4801 reverb_parm[effect].parms[i]);
4804 static void
4805 awe_update_reverb_mode(void)
4807 awe_set_reverb_mode(ctrls[AWE_MD_REVERB_MODE]);
4811 * treble/bass equalizer control
4814 static unsigned short bass_parm[12][3] = {
4815 {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
4816 {0xD25B, 0xD35B, 0x0000}, /* -8 */
4817 {0xD24C, 0xD34C, 0x0000}, /* -6 */
4818 {0xD23D, 0xD33D, 0x0000}, /* -4 */
4819 {0xD21F, 0xD31F, 0x0000}, /* -2 */
4820 {0xC208, 0xC308, 0x0001}, /* 0 (HW default) */
4821 {0xC219, 0xC319, 0x0001}, /* +2 */
4822 {0xC22A, 0xC32A, 0x0001}, /* +4 */
4823 {0xC24C, 0xC34C, 0x0001}, /* +6 */
4824 {0xC26E, 0xC36E, 0x0001}, /* +8 */
4825 {0xC248, 0xC348, 0x0002}, /* +10 */
4826 {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
4829 static unsigned short treble_parm[12][9] = {
4830 {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
4831 {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4832 {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4833 {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4834 {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4835 {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
4836 {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
4837 {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
4838 {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
4839 {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
4840 {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
4841 {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */
4846 * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
4848 static void
4849 awe_equalizer(int bass, int treble)
4851 unsigned short w;
4853 if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
4854 return;
4855 awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]);
4856 awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]);
4857 awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]);
4858 awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]);
4859 awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]);
4860 awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]);
4861 awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]);
4862 awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]);
4863 awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]);
4864 awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]);
4865 w = bass_parm[bass][2] + treble_parm[treble][8];
4866 awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262));
4867 awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362));
4870 static void awe_update_equalizer(void)
4872 awe_equalizer(ctrls[AWE_MD_BASS_LEVEL], ctrls[AWE_MD_TREBLE_LEVEL]);
4876 /*----------------------------------------------------------------*/
4878 #ifdef CONFIG_AWE32_MIDIEMU
4881 * Emu8000 MIDI Emulation
4885 * midi queue record
4888 /* queue type */
4889 enum { Q_NONE, Q_VARLEN, Q_READ, Q_SYSEX, };
4891 #define MAX_MIDIBUF 64
4893 /* midi status */
4894 typedef struct MidiStatus {
4895 int queue; /* queue type */
4896 int qlen; /* queue length */
4897 int read; /* chars read */
4898 int status; /* current status */
4899 int chan; /* current channel */
4900 unsigned char buf[MAX_MIDIBUF];
4901 } MidiStatus;
4903 /* MIDI mode type */
4904 enum { MODE_GM, MODE_GS, MODE_XG, };
4906 /* NRPN / CC -> Emu8000 parameter converter */
4907 typedef struct {
4908 int control;
4909 int awe_effect;
4910 unsigned short (*convert)(int val);
4911 } ConvTable;
4915 * prototypes
4918 static int awe_midi_open(int dev, int mode, void (*input)(int,unsigned char), void (*output)(int));
4919 static void awe_midi_close(int dev);
4920 static int awe_midi_ioctl(int dev, unsigned cmd, void __user * arg);
4921 static int awe_midi_outputc(int dev, unsigned char midi_byte);
4923 static void init_midi_status(MidiStatus *st);
4924 static void clear_rpn(void);
4925 static void get_midi_char(MidiStatus *st, int c);
4926 /*static void queue_varlen(MidiStatus *st, int c);*/
4927 static void special_event(MidiStatus *st, int c);
4928 static void queue_read(MidiStatus *st, int c);
4929 static void midi_note_on(MidiStatus *st);
4930 static void midi_note_off(MidiStatus *st);
4931 static void midi_key_pressure(MidiStatus *st);
4932 static void midi_channel_pressure(MidiStatus *st);
4933 static void midi_pitch_wheel(MidiStatus *st);
4934 static void midi_program_change(MidiStatus *st);
4935 static void midi_control_change(MidiStatus *st);
4936 static void midi_select_bank(MidiStatus *st, int val);
4937 static void midi_nrpn_event(MidiStatus *st);
4938 static void midi_rpn_event(MidiStatus *st);
4939 static void midi_detune(int chan, int coarse, int fine);
4940 static void midi_system_exclusive(MidiStatus *st);
4941 static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
4942 static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
4943 static int xg_control_change(MidiStatus *st, int cmd, int val);
4945 #define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
4949 * OSS Midi device record
4952 static struct midi_operations awe_midi_operations =
4954 .owner = THIS_MODULE,
4955 .info = {"AWE Midi Emu", 0, 0, SNDCARD_SB},
4956 .in_info = {0},
4957 .open = awe_midi_open, /*open*/
4958 .close = awe_midi_close, /*close*/
4959 .ioctl = awe_midi_ioctl, /*ioctl*/
4960 .outputc = awe_midi_outputc, /*outputc*/
4963 static int my_mididev = -1;
4965 static void __init attach_midiemu(void)
4967 if ((my_mididev = sound_alloc_mididev()) < 0)
4968 printk ("Sound: Too many midi devices detected\n");
4969 else
4970 midi_devs[my_mididev] = &awe_midi_operations;
4973 static void unload_midiemu(void)
4975 if (my_mididev >= 0)
4976 sound_unload_mididev(my_mididev);
4981 * open/close midi device
4984 static int midi_opened = FALSE;
4986 static int midi_mode;
4987 static int coarsetune, finetune;
4989 static int xg_mapping = TRUE;
4990 static int xg_bankmode;
4992 /* effect sensitivity */
4994 #define FX_CUTOFF 0
4995 #define FX_RESONANCE 1
4996 #define FX_ATTACK 2
4997 #define FX_RELEASE 3
4998 #define FX_VIBRATE 4
4999 #define FX_VIBDEPTH 5
5000 #define FX_VIBDELAY 6
5001 #define FX_NUMS 7
5003 #define DEF_FX_CUTOFF 170
5004 #define DEF_FX_RESONANCE 6
5005 #define DEF_FX_ATTACK 50
5006 #define DEF_FX_RELEASE 50
5007 #define DEF_FX_VIBRATE 30
5008 #define DEF_FX_VIBDEPTH 4
5009 #define DEF_FX_VIBDELAY 1500
5011 /* effect sense: */
5012 static int gs_sense[] =
5014 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
5015 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
5017 static int xg_sense[] =
5019 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
5020 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
5024 /* current status */
5025 static MidiStatus curst;
5028 static int
5029 awe_midi_open (int dev, int mode,
5030 void (*input)(int,unsigned char),
5031 void (*output)(int))
5033 if (midi_opened)
5034 return -EBUSY;
5036 midi_opened = TRUE;
5038 midi_mode = MODE_GM;
5040 curst.queue = Q_NONE;
5041 curst.qlen = 0;
5042 curst.read = 0;
5043 curst.status = 0;
5044 curst.chan = 0;
5045 memset(curst.buf, 0, sizeof(curst.buf));
5047 init_midi_status(&curst);
5049 return 0;
5052 static void
5053 awe_midi_close (int dev)
5055 midi_opened = FALSE;
5059 static int
5060 awe_midi_ioctl (int dev, unsigned cmd, void __user *arg)
5062 return -EPERM;
5065 static int
5066 awe_midi_outputc (int dev, unsigned char midi_byte)
5068 if (! midi_opened)
5069 return 1;
5071 /* force to change playing mode */
5072 playing_mode = AWE_PLAY_MULTI;
5074 get_midi_char(&curst, midi_byte);
5075 return 1;
5080 * initialize
5083 static void init_midi_status(MidiStatus *st)
5085 clear_rpn();
5086 coarsetune = 0;
5087 finetune = 0;
5092 * RPN & NRPN
5095 #define MAX_MIDI_CHANNELS 16
5097 /* RPN & NRPN */
5098 static unsigned char nrpn[MAX_MIDI_CHANNELS]; /* current event is NRPN? */
5099 static int msb_bit; /* current event is msb for RPN/NRPN */
5100 /* RPN & NRPN indeces */
5101 static unsigned char rpn_msb[MAX_MIDI_CHANNELS], rpn_lsb[MAX_MIDI_CHANNELS];
5102 /* RPN & NRPN values */
5103 static int rpn_val[MAX_MIDI_CHANNELS];
5105 static void clear_rpn(void)
5107 int i;
5108 for (i = 0; i < MAX_MIDI_CHANNELS; i++) {
5109 nrpn[i] = 0;
5110 rpn_msb[i] = 127;
5111 rpn_lsb[i] = 127;
5112 rpn_val[i] = 0;
5114 msb_bit = 0;
5119 * process midi queue
5122 /* status event types */
5123 typedef void (*StatusEvent)(MidiStatus *st);
5124 static struct StatusEventList {
5125 StatusEvent process;
5126 int qlen;
5127 } status_event[8] = {
5128 {midi_note_off, 2},
5129 {midi_note_on, 2},
5130 {midi_key_pressure, 2},
5131 {midi_control_change, 2},
5132 {midi_program_change, 1},
5133 {midi_channel_pressure, 1},
5134 {midi_pitch_wheel, 2},
5135 {NULL, 0},
5139 /* read a char from fifo and process it */
5140 static void get_midi_char(MidiStatus *st, int c)
5142 if (c == 0xfe) {
5143 /* ignore active sense */
5144 st->queue = Q_NONE;
5145 return;
5148 switch (st->queue) {
5149 /* case Q_VARLEN: queue_varlen(st, c); break;*/
5150 case Q_READ:
5151 case Q_SYSEX:
5152 queue_read(st, c);
5153 break;
5154 case Q_NONE:
5155 st->read = 0;
5156 if ((c & 0xf0) == 0xf0) {
5157 special_event(st, c);
5158 } else if (c & 0x80) { /* status change */
5159 st->status = (c >> 4) & 0x07;
5160 st->chan = c & 0x0f;
5161 st->queue = Q_READ;
5162 st->qlen = status_event[st->status].qlen;
5163 if (st->qlen == 0)
5164 st->queue = Q_NONE;
5166 break;
5170 /* 0xfx events */
5171 static void special_event(MidiStatus *st, int c)
5173 switch (c) {
5174 case 0xf0: /* system exclusive */
5175 st->queue = Q_SYSEX;
5176 st->qlen = 0;
5177 break;
5178 case 0xf1: /* MTC quarter frame */
5179 case 0xf3: /* song select */
5180 st->queue = Q_READ;
5181 st->qlen = 1;
5182 break;
5183 case 0xf2: /* song position */
5184 st->queue = Q_READ;
5185 st->qlen = 2;
5186 break;
5190 #if 0
5191 /* read variable length value */
5192 static void queue_varlen(MidiStatus *st, int c)
5194 st->qlen += (c & 0x7f);
5195 if (c & 0x80) {
5196 st->qlen <<= 7;
5197 return;
5199 if (st->qlen <= 0) {
5200 st->qlen = 0;
5201 st->queue = Q_NONE;
5203 st->queue = Q_READ;
5204 st->read = 0;
5206 #endif
5209 /* read a char */
5210 static void queue_read(MidiStatus *st, int c)
5212 if (st->read < MAX_MIDIBUF) {
5213 if (st->queue != Q_SYSEX)
5214 c &= 0x7f;
5215 st->buf[st->read] = (unsigned char)c;
5217 st->read++;
5218 if (st->queue == Q_SYSEX && c == 0xf7) {
5219 midi_system_exclusive(st);
5220 st->queue = Q_NONE;
5221 } else if (st->queue == Q_READ && st->read >= st->qlen) {
5222 if (status_event[st->status].process)
5223 status_event[st->status].process(st);
5224 st->queue = Q_NONE;
5230 * status events
5233 /* note on */
5234 static void midi_note_on(MidiStatus *st)
5236 DEBUG(2,printk("midi: note_on (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
5237 if (st->buf[1] == 0)
5238 midi_note_off(st);
5239 else
5240 awe_start_note(0, st->chan, st->buf[0], st->buf[1]);
5243 /* note off */
5244 static void midi_note_off(MidiStatus *st)
5246 DEBUG(2,printk("midi: note_off (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
5247 awe_kill_note(0, st->chan, st->buf[0], st->buf[1]);
5250 /* key pressure change */
5251 static void midi_key_pressure(MidiStatus *st)
5253 awe_key_pressure(0, st->chan, st->buf[0], st->buf[1]);
5256 /* channel pressure change */
5257 static void midi_channel_pressure(MidiStatus *st)
5259 channels[st->chan].chan_press = st->buf[0];
5260 awe_modwheel_change(st->chan, st->buf[0]);
5263 /* pitch wheel change */
5264 static void midi_pitch_wheel(MidiStatus *st)
5266 int val = (int)st->buf[1] * 128 + st->buf[0];
5267 awe_bender(0, st->chan, val);
5270 /* program change */
5271 static void midi_program_change(MidiStatus *st)
5273 int preset;
5274 preset = st->buf[0];
5275 if (midi_mode == MODE_GS && IS_DRUM_CHANNEL(st->chan) && preset == 127)
5276 preset = 0;
5277 else if (midi_mode == MODE_XG && xg_mapping && IS_DRUM_CHANNEL(st->chan))
5278 preset += 64;
5280 awe_set_instr(0, st->chan, preset);
5283 #define send_effect(chan,type,val) awe_send_effect(chan,-1,type,val)
5284 #define add_effect(chan,type,val) awe_send_effect(chan,-1,(type)|0x80,val)
5285 #define unset_effect(chan,type) awe_send_effect(chan,-1,(type)|0x40,0)
5287 /* midi control change */
5288 static void midi_control_change(MidiStatus *st)
5290 int cmd = st->buf[0];
5291 int val = st->buf[1];
5293 DEBUG(2,printk("midi: control (%d) %d %d\n", st->chan, cmd, val));
5294 if (midi_mode == MODE_XG) {
5295 if (xg_control_change(st, cmd, val))
5296 return;
5299 /* controls #31 - #64 are LSB of #0 - #31 */
5300 msb_bit = 1;
5301 if (cmd >= 0x20 && cmd < 0x40) {
5302 msb_bit = 0;
5303 cmd -= 0x20;
5306 switch (cmd) {
5307 case CTL_SOFT_PEDAL:
5308 if (val == 127)
5309 add_effect(st->chan, AWE_FX_CUTOFF, -160);
5310 else
5311 unset_effect(st->chan, AWE_FX_CUTOFF);
5312 break;
5314 case CTL_BANK_SELECT:
5315 midi_select_bank(st, val);
5316 break;
5318 /* set RPN/NRPN parameter */
5319 case CTL_REGIST_PARM_NUM_MSB:
5320 nrpn[st->chan]=0; rpn_msb[st->chan]=val;
5321 break;
5322 case CTL_REGIST_PARM_NUM_LSB:
5323 nrpn[st->chan]=0; rpn_lsb[st->chan]=val;
5324 break;
5325 case CTL_NONREG_PARM_NUM_MSB:
5326 nrpn[st->chan]=1; rpn_msb[st->chan]=val;
5327 break;
5328 case CTL_NONREG_PARM_NUM_LSB:
5329 nrpn[st->chan]=1; rpn_lsb[st->chan]=val;
5330 break;
5332 /* send RPN/NRPN entry */
5333 case CTL_DATA_ENTRY:
5334 if (msb_bit)
5335 rpn_val[st->chan] = val * 128;
5336 else
5337 rpn_val[st->chan] |= val;
5338 if (nrpn[st->chan])
5339 midi_nrpn_event(st);
5340 else
5341 midi_rpn_event(st);
5342 break;
5344 /* increase/decrease data entry */
5345 case CTL_DATA_INCREMENT:
5346 rpn_val[st->chan]++;
5347 midi_rpn_event(st);
5348 break;
5349 case CTL_DATA_DECREMENT:
5350 rpn_val[st->chan]--;
5351 midi_rpn_event(st);
5352 break;
5354 /* default */
5355 default:
5356 awe_controller(0, st->chan, cmd, val);
5357 break;
5361 /* tone bank change */
5362 static void midi_select_bank(MidiStatus *st, int val)
5364 if (midi_mode == MODE_XG && msb_bit) {
5365 xg_bankmode = val;
5366 /* XG MSB value; not normal bank selection */
5367 switch (val) {
5368 case 127: /* remap to drum channel */
5369 awe_controller(0, st->chan, CTL_BANK_SELECT, 128);
5370 break;
5371 default: /* remap to normal channel */
5372 awe_controller(0, st->chan, CTL_BANK_SELECT, val);
5373 break;
5375 return;
5376 } else if (midi_mode == MODE_GS && !msb_bit)
5377 /* ignore LSB bank in GS mode (used for mapping) */
5378 return;
5380 /* normal bank controls; accept both MSB and LSB */
5381 if (! IS_DRUM_CHANNEL(st->chan)) {
5382 if (midi_mode == MODE_XG) {
5383 if (xg_bankmode) return;
5384 if (val == 64 || val == 126)
5385 val = 0;
5386 } else if (midi_mode == MODE_GS && val == 127)
5387 val = 0;
5388 awe_controller(0, st->chan, CTL_BANK_SELECT, val);
5394 * RPN events
5397 static void midi_rpn_event(MidiStatus *st)
5399 int type;
5400 type = (rpn_msb[st->chan]<<8) | rpn_lsb[st->chan];
5401 switch (type) {
5402 case 0x0000: /* Pitch bend sensitivity */
5403 /* MSB only / 1 semitone per 128 */
5404 if (msb_bit) {
5405 channels[st->chan].bender_range =
5406 rpn_val[st->chan] * 100 / 128;
5408 break;
5410 case 0x0001: /* fine tuning: */
5411 /* MSB/LSB, 8192=center, 100/8192 cent step */
5412 finetune = rpn_val[st->chan] - 8192;
5413 midi_detune(st->chan, coarsetune, finetune);
5414 break;
5416 case 0x0002: /* coarse tuning */
5417 /* MSB only / 8192=center, 1 semitone per 128 */
5418 if (msb_bit) {
5419 coarsetune = rpn_val[st->chan] - 8192;
5420 midi_detune(st->chan, coarsetune, finetune);
5422 break;
5424 case 0x7F7F: /* "lock-in" RPN */
5425 break;
5430 /* tuning:
5431 * coarse = -8192 to 8192 (100 cent per 128)
5432 * fine = -8192 to 8192 (max=100cent)
5434 static void midi_detune(int chan, int coarse, int fine)
5436 /* 4096 = 1200 cents in AWE parameter */
5437 int val;
5438 val = coarse * 4096 / (12 * 128);
5439 val += fine / 24;
5440 if (val)
5441 send_effect(chan, AWE_FX_INIT_PITCH, val);
5442 else
5443 unset_effect(chan, AWE_FX_INIT_PITCH);
5448 * system exclusive message
5449 * GM/GS/XG macros are accepted
5452 static void midi_system_exclusive(MidiStatus *st)
5454 /* GM on */
5455 static unsigned char gm_on_macro[] = {
5456 0x7e,0x7f,0x09,0x01,
5458 /* XG on */
5459 static unsigned char xg_on_macro[] = {
5460 0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,
5462 /* GS prefix
5463 * drum channel: XX=0x1?(channel), YY=0x15, ZZ=on/off
5464 * reverb mode: XX=0x01, YY=0x30, ZZ=0-7
5465 * chorus mode: XX=0x01, YY=0x38, ZZ=0-7
5467 static unsigned char gs_pfx_macro[] = {
5468 0x41,0x10,0x42,0x12,0x40,/*XX,YY,ZZ*/
5471 #if 0
5472 /* SC88 system mode set
5473 * single module mode: XX=1
5474 * double module mode: XX=0
5476 static unsigned char gs_mode_macro[] = {
5477 0x41,0x10,0x42,0x12,0x00,0x00,0x7F,/*ZZ*/
5479 /* SC88 display macro: XX=01:bitmap, 00:text
5481 static unsigned char gs_disp_macro[] = {
5482 0x41,0x10,0x45,0x12,0x10,/*XX,00*/
5484 #endif
5486 /* GM on */
5487 if (memcmp(st->buf, gm_on_macro, sizeof(gm_on_macro)) == 0) {
5488 if (midi_mode != MODE_GS && midi_mode != MODE_XG)
5489 midi_mode = MODE_GM;
5490 init_midi_status(st);
5493 /* GS macros */
5494 else if (memcmp(st->buf, gs_pfx_macro, sizeof(gs_pfx_macro)) == 0) {
5495 if (midi_mode != MODE_GS && midi_mode != MODE_XG)
5496 midi_mode = MODE_GS;
5498 if (st->buf[5] == 0x00 && st->buf[6] == 0x7f && st->buf[7] == 0x00) {
5499 /* GS reset */
5500 init_midi_status(st);
5503 else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x15) {
5504 /* drum pattern */
5505 int p = st->buf[5] & 0x0f;
5506 if (p == 0) p = 9;
5507 else if (p < 10) p--;
5508 if (st->buf[7] == 0)
5509 DRUM_CHANNEL_OFF(p);
5510 else
5511 DRUM_CHANNEL_ON(p);
5513 } else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x21) {
5514 /* program */
5515 int p = st->buf[5] & 0x0f;
5516 if (p == 0) p = 9;
5517 else if (p < 10) p--;
5518 if (! IS_DRUM_CHANNEL(p))
5519 awe_set_instr(0, p, st->buf[7]);
5521 } else if (st->buf[5] == 0x01 && st->buf[6] == 0x30) {
5522 /* reverb mode */
5523 awe_set_reverb_mode(st->buf[7]);
5525 } else if (st->buf[5] == 0x01 && st->buf[6] == 0x38) {
5526 /* chorus mode */
5527 awe_set_chorus_mode(st->buf[7]);
5529 } else if (st->buf[5] == 0x00 && st->buf[6] == 0x04) {
5530 /* master volume */
5531 awe_change_master_volume(st->buf[7]);
5536 /* XG on */
5537 else if (memcmp(st->buf, xg_on_macro, sizeof(xg_on_macro)) == 0) {
5538 midi_mode = MODE_XG;
5539 xg_mapping = TRUE;
5540 xg_bankmode = 0;
5545 /*----------------------------------------------------------------*/
5548 * convert NRPN/control values
5551 static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
5553 int i, cval;
5554 for (i = 0; i < num_tables; i++) {
5555 if (table[i].control == type) {
5556 cval = table[i].convert(val);
5557 send_effect(st->chan, table[i].awe_effect, cval);
5558 return TRUE;
5561 return FALSE;
5564 static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
5566 int i, cval;
5567 for (i = 0; i < num_tables; i++) {
5568 if (table[i].control == type) {
5569 cval = table[i].convert(val);
5570 add_effect(st->chan, table[i].awe_effect|0x80, cval);
5571 return TRUE;
5574 return FALSE;
5579 * AWE32 NRPN effects
5582 static unsigned short fx_delay(int val);
5583 static unsigned short fx_attack(int val);
5584 static unsigned short fx_hold(int val);
5585 static unsigned short fx_decay(int val);
5586 static unsigned short fx_the_value(int val);
5587 static unsigned short fx_twice_value(int val);
5588 static unsigned short fx_conv_pitch(int val);
5589 static unsigned short fx_conv_Q(int val);
5591 /* function for each NRPN */ /* [range] units */
5592 #define fx_env1_delay fx_delay /* [0,5900] 4msec */
5593 #define fx_env1_attack fx_attack /* [0,5940] 1msec */
5594 #define fx_env1_hold fx_hold /* [0,8191] 1msec */
5595 #define fx_env1_decay fx_decay /* [0,5940] 4msec */
5596 #define fx_env1_release fx_decay /* [0,5940] 4msec */
5597 #define fx_env1_sustain fx_the_value /* [0,127] 0.75dB */
5598 #define fx_env1_pitch fx_the_value /* [-127,127] 9.375cents */
5599 #define fx_env1_cutoff fx_the_value /* [-127,127] 56.25cents */
5601 #define fx_env2_delay fx_delay /* [0,5900] 4msec */
5602 #define fx_env2_attack fx_attack /* [0,5940] 1msec */
5603 #define fx_env2_hold fx_hold /* [0,8191] 1msec */
5604 #define fx_env2_decay fx_decay /* [0,5940] 4msec */
5605 #define fx_env2_release fx_decay /* [0,5940] 4msec */
5606 #define fx_env2_sustain fx_the_value /* [0,127] 0.75dB */
5608 #define fx_lfo1_delay fx_delay /* [0,5900] 4msec */
5609 #define fx_lfo1_freq fx_twice_value /* [0,127] 84mHz */
5610 #define fx_lfo1_volume fx_twice_value /* [0,127] 0.1875dB */
5611 #define fx_lfo1_pitch fx_the_value /* [-127,127] 9.375cents */
5612 #define fx_lfo1_cutoff fx_twice_value /* [-64,63] 56.25cents */
5614 #define fx_lfo2_delay fx_delay /* [0,5900] 4msec */
5615 #define fx_lfo2_freq fx_twice_value /* [0,127] 84mHz */
5616 #define fx_lfo2_pitch fx_the_value /* [-127,127] 9.375cents */
5618 #define fx_init_pitch fx_conv_pitch /* [-8192,8192] cents */
5619 #define fx_chorus fx_the_value /* [0,255] -- */
5620 #define fx_reverb fx_the_value /* [0,255] -- */
5621 #define fx_cutoff fx_twice_value /* [0,127] 62Hz */
5622 #define fx_filterQ fx_conv_Q /* [0,127] -- */
5624 static unsigned short fx_delay(int val)
5626 return (unsigned short)calc_parm_delay(val);
5629 static unsigned short fx_attack(int val)
5631 return (unsigned short)calc_parm_attack(val);
5634 static unsigned short fx_hold(int val)
5636 return (unsigned short)calc_parm_hold(val);
5639 static unsigned short fx_decay(int val)
5641 return (unsigned short)calc_parm_decay(val);
5644 static unsigned short fx_the_value(int val)
5646 return (unsigned short)(val & 0xff);
5649 static unsigned short fx_twice_value(int val)
5651 return (unsigned short)((val * 2) & 0xff);
5654 static unsigned short fx_conv_pitch(int val)
5656 return (short)(val * 4096 / 1200);
5659 static unsigned short fx_conv_Q(int val)
5661 return (unsigned short)((val / 8) & 0xff);
5665 static ConvTable awe_effects[] =
5667 { 0, AWE_FX_LFO1_DELAY, fx_lfo1_delay},
5668 { 1, AWE_FX_LFO1_FREQ, fx_lfo1_freq},
5669 { 2, AWE_FX_LFO2_DELAY, fx_lfo2_delay},
5670 { 3, AWE_FX_LFO2_FREQ, fx_lfo2_freq},
5672 { 4, AWE_FX_ENV1_DELAY, fx_env1_delay},
5673 { 5, AWE_FX_ENV1_ATTACK,fx_env1_attack},
5674 { 6, AWE_FX_ENV1_HOLD, fx_env1_hold},
5675 { 7, AWE_FX_ENV1_DECAY, fx_env1_decay},
5676 { 8, AWE_FX_ENV1_SUSTAIN, fx_env1_sustain},
5677 { 9, AWE_FX_ENV1_RELEASE, fx_env1_release},
5679 {10, AWE_FX_ENV2_DELAY, fx_env2_delay},
5680 {11, AWE_FX_ENV2_ATTACK, fx_env2_attack},
5681 {12, AWE_FX_ENV2_HOLD, fx_env2_hold},
5682 {13, AWE_FX_ENV2_DECAY, fx_env2_decay},
5683 {14, AWE_FX_ENV2_SUSTAIN, fx_env2_sustain},
5684 {15, AWE_FX_ENV2_RELEASE, fx_env2_release},
5686 {16, AWE_FX_INIT_PITCH, fx_init_pitch},
5687 {17, AWE_FX_LFO1_PITCH, fx_lfo1_pitch},
5688 {18, AWE_FX_LFO2_PITCH, fx_lfo2_pitch},
5689 {19, AWE_FX_ENV1_PITCH, fx_env1_pitch},
5690 {20, AWE_FX_LFO1_VOLUME, fx_lfo1_volume},
5691 {21, AWE_FX_CUTOFF, fx_cutoff},
5692 {22, AWE_FX_FILTERQ, fx_filterQ},
5693 {23, AWE_FX_LFO1_CUTOFF, fx_lfo1_cutoff},
5694 {24, AWE_FX_ENV1_CUTOFF, fx_env1_cutoff},
5695 {25, AWE_FX_CHORUS, fx_chorus},
5696 {26, AWE_FX_REVERB, fx_reverb},
5699 static int num_awe_effects = numberof(awe_effects);
5703 * GS(SC88) NRPN effects; still experimental
5706 /* cutoff: quarter semitone step, max=255 */
5707 static unsigned short gs_cutoff(int val)
5709 return (val - 64) * gs_sense[FX_CUTOFF] / 50;
5712 /* resonance: 0 to 15(max) */
5713 static unsigned short gs_filterQ(int val)
5715 return (val - 64) * gs_sense[FX_RESONANCE] / 50;
5718 /* attack: */
5719 static unsigned short gs_attack(int val)
5721 return -(val - 64) * gs_sense[FX_ATTACK] / 50;
5724 /* decay: */
5725 static unsigned short gs_decay(int val)
5727 return -(val - 64) * gs_sense[FX_RELEASE] / 50;
5730 /* release: */
5731 static unsigned short gs_release(int val)
5733 return -(val - 64) * gs_sense[FX_RELEASE] / 50;
5736 /* vibrato freq: 0.042Hz step, max=255 */
5737 static unsigned short gs_vib_rate(int val)
5739 return (val - 64) * gs_sense[FX_VIBRATE] / 50;
5742 /* vibrato depth: max=127, 1 octave */
5743 static unsigned short gs_vib_depth(int val)
5745 return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
5748 /* vibrato delay: -0.725msec step */
5749 static unsigned short gs_vib_delay(int val)
5751 return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
5754 static ConvTable gs_effects[] =
5756 {32, AWE_FX_CUTOFF, gs_cutoff},
5757 {33, AWE_FX_FILTERQ, gs_filterQ},
5758 {99, AWE_FX_ENV2_ATTACK, gs_attack},
5759 {100, AWE_FX_ENV2_DECAY, gs_decay},
5760 {102, AWE_FX_ENV2_RELEASE, gs_release},
5761 {8, AWE_FX_LFO1_FREQ, gs_vib_rate},
5762 {9, AWE_FX_LFO1_VOLUME, gs_vib_depth},
5763 {10, AWE_FX_LFO1_DELAY, gs_vib_delay},
5766 static int num_gs_effects = numberof(gs_effects);
5770 * NRPN events: accept as AWE32/SC88 specific controls
5773 static void midi_nrpn_event(MidiStatus *st)
5775 if (rpn_msb[st->chan] == 127 && rpn_lsb[st->chan] <= 26) {
5776 if (! msb_bit) /* both MSB/LSB necessary */
5777 send_converted_effect(awe_effects, num_awe_effects,
5778 st, rpn_lsb[st->chan],
5779 rpn_val[st->chan] - 8192);
5780 } else if (rpn_msb[st->chan] == 1) {
5781 if (msb_bit) /* only MSB is valid */
5782 add_converted_effect(gs_effects, num_gs_effects,
5783 st, rpn_lsb[st->chan],
5784 rpn_val[st->chan] / 128);
5790 * XG control effects; still experimental
5793 /* cutoff: quarter semitone step, max=255 */
5794 static unsigned short xg_cutoff(int val)
5796 return (val - 64) * xg_sense[FX_CUTOFF] / 64;
5799 /* resonance: 0(open) to 15(most nasal) */
5800 static unsigned short xg_filterQ(int val)
5802 return (val - 64) * xg_sense[FX_RESONANCE] / 64;
5805 /* attack: */
5806 static unsigned short xg_attack(int val)
5808 return -(val - 64) * xg_sense[FX_ATTACK] / 64;
5811 /* release: */
5812 static unsigned short xg_release(int val)
5814 return -(val - 64) * xg_sense[FX_RELEASE] / 64;
5817 static ConvTable xg_effects[] =
5819 {71, AWE_FX_CUTOFF, xg_cutoff},
5820 {74, AWE_FX_FILTERQ, xg_filterQ},
5821 {72, AWE_FX_ENV2_RELEASE, xg_release},
5822 {73, AWE_FX_ENV2_ATTACK, xg_attack},
5825 static int num_xg_effects = numberof(xg_effects);
5827 static int xg_control_change(MidiStatus *st, int cmd, int val)
5829 return add_converted_effect(xg_effects, num_xg_effects, st, cmd, val);
5832 #endif /* CONFIG_AWE32_MIDIEMU */
5835 /*----------------------------------------------------------------*/
5839 * initialization of AWE driver
5842 static void
5843 awe_initialize(void)
5845 DEBUG(0,printk("AWE32: initializing..\n"));
5847 /* initialize hardware configuration */
5848 awe_poke(AWE_HWCF1, 0x0059);
5849 awe_poke(AWE_HWCF2, 0x0020);
5851 /* disable audio; this seems to reduce a clicking noise a bit.. */
5852 awe_poke(AWE_HWCF3, 0);
5854 /* initialize audio channels */
5855 awe_init_audio();
5857 /* initialize DMA */
5858 awe_init_dma();
5860 /* initialize init array */
5861 awe_init_array();
5863 /* check DRAM memory size */
5864 awe_check_dram();
5866 /* initialize the FM section of the AWE32 */
5867 awe_init_fm();
5869 /* set up voice envelopes */
5870 awe_tweak();
5872 /* enable audio */
5873 awe_poke(AWE_HWCF3, 0x0004);
5875 /* set default values */
5876 awe_init_ctrl_parms(TRUE);
5878 /* set equalizer */
5879 awe_update_equalizer();
5881 /* set reverb & chorus modes */
5882 awe_update_reverb_mode();
5883 awe_update_chorus_mode();
5888 * Core Device Management Functions
5891 /* store values to i/o port array */
5892 static void setup_ports(int port1, int port2, int port3)
5894 awe_ports[0] = port1;
5895 if (port2 == 0)
5896 port2 = port1 + 0x400;
5897 awe_ports[1] = port2;
5898 awe_ports[2] = port2 + 2;
5899 if (port3 == 0)
5900 port3 = port1 + 0x800;
5901 awe_ports[3] = port3;
5902 awe_ports[4] = port3 + 2;
5904 port_setuped = TRUE;
5908 * port request
5909 * 0x620-623, 0xA20-A23, 0xE20-E23
5912 static int
5913 awe_request_region(void)
5915 if (! port_setuped)
5916 return 0;
5917 if (! request_region(awe_ports[0], 4, "sound driver (AWE32)"))
5918 return 0;
5919 if (! request_region(awe_ports[1], 4, "sound driver (AWE32)"))
5920 goto err_out;
5921 if (! request_region(awe_ports[3], 4, "sound driver (AWE32)"))
5922 goto err_out1;
5923 return 1;
5924 err_out1:
5925 release_region(awe_ports[1], 4);
5926 err_out:
5927 release_region(awe_ports[0], 4);
5928 return 0;
5931 static void
5932 awe_release_region(void)
5934 if (! port_setuped) return;
5935 release_region(awe_ports[0], 4);
5936 release_region(awe_ports[1], 4);
5937 release_region(awe_ports[3], 4);
5940 static int awe_attach_device(void)
5942 if (awe_present) return 0; /* for OSS38.. called twice? */
5944 /* reserve I/O ports for awedrv */
5945 if (! awe_request_region()) {
5946 printk(KERN_ERR "AWE32: I/O area already used.\n");
5947 return 0;
5950 /* set buffers to NULL */
5951 sfhead = sftail = NULL;
5953 my_dev = sound_alloc_synthdev();
5954 if (my_dev == -1) {
5955 printk(KERN_ERR "AWE32 Error: too many synthesizers\n");
5956 awe_release_region();
5957 return 0;
5960 voice_alloc = &awe_operations.alloc;
5961 voice_alloc->max_voice = awe_max_voices;
5962 synth_devs[my_dev] = &awe_operations;
5964 #ifdef CONFIG_AWE32_MIXER
5965 attach_mixer();
5966 #endif
5967 #ifdef CONFIG_AWE32_MIDIEMU
5968 attach_midiemu();
5969 #endif
5971 /* clear all samples */
5972 awe_reset_samples();
5974 /* initialize AWE32 hardware */
5975 awe_initialize();
5977 sprintf(awe_info.name, "AWE32-%s (RAM%dk)",
5978 AWEDRV_VERSION, memsize/1024);
5979 printk(KERN_INFO "<SoundBlaster EMU8000 (RAM%dk)>\n", memsize/1024);
5981 awe_present = TRUE;
5983 return 1;
5986 static void awe_dettach_device(void)
5988 if (awe_present) {
5989 awe_reset_samples();
5990 awe_release_region();
5991 free_tables();
5992 #ifdef CONFIG_AWE32_MIXER
5993 unload_mixer();
5994 #endif
5995 #ifdef CONFIG_AWE32_MIDIEMU
5996 unload_midiemu();
5997 #endif
5998 sound_unload_synthdev(my_dev);
5999 awe_present = FALSE;
6005 * Legacy device Probing
6008 /* detect emu8000 chip on the specified address; from VV's guide */
6010 static int __init
6011 awe_detect_base(int addr)
6013 setup_ports(addr, 0, 0);
6014 if ((awe_peek(AWE_U1) & 0x000F) != 0x000C)
6015 return 0;
6016 if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058)
6017 return 0;
6018 if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003)
6019 return 0;
6020 DEBUG(0,printk("AWE32 found at %x\n", addr));
6021 return 1;
6024 static int __init awe_detect_legacy_devices(void)
6026 int base;
6027 for (base = 0x620; base <= 0x680; base += 0x20)
6028 if (awe_detect_base(base)) {
6029 awe_attach_device();
6030 return 1;
6032 DEBUG(0,printk("AWE32 Legacy detection failed\n"));
6033 return 0;
6038 * PnP device Probing
6041 static struct pnp_device_id awe_pnp_ids[] = {
6042 {.id = "CTL0021", .driver_data = 0}, /* AWE32 WaveTable */
6043 {.id = "CTL0022", .driver_data = 0}, /* AWE64 WaveTable */
6044 {.id = "CTL0023", .driver_data = 0}, /* AWE64 Gold WaveTable */
6045 { } /* terminator */
6048 MODULE_DEVICE_TABLE(pnp, awe_pnp_ids);
6050 static int awe_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
6052 int io1, io2, io3;
6054 if (awe_present) {
6055 printk(KERN_ERR "AWE32: This driver only supports one AWE32 device, skipping.\n");
6058 if (!pnp_port_valid(dev,0) ||
6059 !pnp_port_valid(dev,1) ||
6060 !pnp_port_valid(dev,2)) {
6061 printk(KERN_ERR "AWE32: The PnP device does not have the required resources.\n");
6062 return -EINVAL;
6064 io1 = pnp_port_start(dev,0);
6065 io2 = pnp_port_start(dev,1);
6066 io3 = pnp_port_start(dev,2);
6067 printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x.\n",
6068 io1, io2, io3);
6069 setup_ports(io1, io2, io3);
6071 awe_attach_device();
6072 return 0;
6075 static void awe_pnp_remove(struct pnp_dev *dev)
6077 awe_dettach_device();
6080 static struct pnp_driver awe_pnp_driver = {
6081 .name = "AWE32",
6082 .id_table = awe_pnp_ids,
6083 .probe = awe_pnp_probe,
6084 .remove = awe_pnp_remove,
6087 static int __init awe_detect_pnp_devices(void)
6089 int ret;
6091 ret = pnp_register_driver(&awe_pnp_driver);
6092 if (ret<0)
6093 printk(KERN_ERR "AWE32: PnP support is unavailable.\n");
6094 return ret;
6099 * device / lowlevel (module) interface
6102 static int __init
6103 awe_detect(void)
6105 printk(KERN_INFO "AWE32: Probing for WaveTable...\n");
6106 if (isapnp) {
6107 if (awe_detect_pnp_devices()>=0)
6108 return 1;
6109 } else
6110 printk(KERN_INFO "AWE32: Skipping PnP detection.\n");
6112 if (awe_detect_legacy_devices())
6113 return 1;
6115 return 0;
6118 static int __init attach_awe(void)
6120 return awe_detect() ? 0 : -ENODEV;
6123 static void __exit unload_awe(void)
6125 pnp_unregister_driver(&awe_pnp_driver);
6126 awe_dettach_device();
6130 module_init(attach_awe);
6131 module_exit(unload_awe);
6133 #ifndef MODULE
6134 static int __init setup_awe(char *str)
6136 /* io, memsize, isapnp */
6137 int ints[4];
6139 str = get_options(str, ARRAY_SIZE(ints), ints);
6141 io = ints[1];
6142 memsize = ints[2];
6143 isapnp = ints[3];
6145 return 1;
6148 __setup("awe=", setup_awe);
6149 #endif