aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/awe_wave.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /sound/oss/awe_wave.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'sound/oss/awe_wave.c')
-rw-r--r--sound/oss/awe_wave.c6147
1 files changed, 6147 insertions, 0 deletions
diff --git a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
new file mode 100644
index 000000000000..d2b9beda8ace
--- /dev/null
+++ b/sound/oss/awe_wave.c
@@ -0,0 +1,6147 @@
1/*
2 * sound/awe_wave.c
3 *
4 * The low level driver for the AWE32/SB32/AWE64 wave table synth.
5 * version 0.4.4; Jan. 4, 2000
6 *
7 * Copyright (C) 1996-2000 Takashi Iwai
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24/*
25 * Changelog:
26 * Aug 18, 2003, Adam Belay <ambx1@neo.rr.com>
27 * - detection code rewrite
28 */
29
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>
36
37#include "sound_config.h"
38
39#include "awe_wave.h"
40#include "awe_hw.h"
41
42#ifdef AWE_HAS_GUS_COMPATIBILITY
43#include "tuning.h"
44#include <linux/ultrasound.h>
45#endif
46
47/*
48 * debug message
49 */
50
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
60
61/*
62 * bank and voice record
63 */
64
65typedef struct _sf_list sf_list;
66typedef struct _awe_voice_list awe_voice_list;
67typedef struct _awe_sample_list awe_sample_list;
68
69/* soundfont record */
70struct _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;
83};
84
85/* instrument list */
86struct _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 */
94};
95
96/* voice list type */
97#define V_ST_NORMAL 0
98#define V_ST_MAPPED 1
99
100/* sample list */
101struct _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 */
105};
106
107/* sample and information table */
108static int current_sf_id; /* current number of fonts */
109static int locked_sf_id; /* locked position */
110static sf_list *sfhead, *sftail; /* linked-lists */
111
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)
115
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
121
122#define MAX_LAYERS AWE_MAX_VOICES
123
124/* preset table index */
125static awe_voice_list *preset_table[AWE_MAX_PRESETS];
126
127/*
128 * voice table
129 */
130
131/* effects table */
132typedef struct FX_Rec { /* channel effects */
133 unsigned char flags[AWE_FX_END];
134 short val[AWE_FX_END];
135} FX_Rec;
136
137
138/* channel parameters */
139typedef 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;
153
154/* voice parameters */
155typedef 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 */
165
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 */
171
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 */
176
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;
184
185/* voice information */
186static voice_info voices[AWE_MAX_VOICES];
187
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))
192
193
194/* MIDI channel effects information (for hw control) */
195static awe_chan_info channels[AWE_MAX_CHANNELS];
196
197
198/*
199 * global variables
200 */
201
202#ifndef AWE_DEFAULT_BASE_ADDR
203#define AWE_DEFAULT_BASE_ADDR 0 /* autodetect */
204#endif
205
206#ifndef AWE_DEFAULT_MEM_SIZE
207#define AWE_DEFAULT_MEM_SIZE -1 /* autodetect */
208#endif
209
210static int io = AWE_DEFAULT_BASE_ADDR; /* Emu8000 base address */
211static int memsize = AWE_DEFAULT_MEM_SIZE; /* memory size in Kbytes */
212#ifdef CONFIG_PNP
213static int isapnp = -1;
214#else
215static int isapnp;
216#endif
217
218MODULE_AUTHOR("Takashi Iwai <iwai@ww.uni-erlangen.de>");
219MODULE_DESCRIPTION("SB AWE32/64 WaveTable driver");
220MODULE_LICENSE("GPL");
221
222module_param(io, int, 0);
223MODULE_PARM_DESC(io, "base i/o port of Emu8000");
224module_param(memsize, int, 0);
225MODULE_PARM_DESC(memsize, "onboard DRAM size in Kbytes");
226module_param(isapnp, bool, 0);
227MODULE_PARM_DESC(isapnp, "use ISAPnP detection");
228
229/* DRAM start offset */
230static int awe_mem_start = AWE_DRAM_OFFSET;
231
232/* maximum channels for playing */
233static int awe_max_voices = AWE_MAX_VOICES;
234
235static int patch_opened; /* sample already loaded? */
236
237static char atten_relative = FALSE;
238static short atten_offset;
239
240static int awe_present = FALSE; /* awe device present? */
241static int awe_busy = FALSE; /* awe device opened? */
242
243static int my_dev = -1;
244
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)))
249static unsigned int drum_flags = DEFAULT_DRUM_FLAGS; /* channel flags */
250
251static 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)
254
255static int current_alloc_time; /* voice allocation index for channel mode */
256
257static 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 */
266};
267
268
269static struct voice_alloc_info *voice_alloc; /* set at initialization */
270
271
272/*
273 * function prototypes
274 */
275
276static int awe_request_region(void);
277static void awe_release_region(void);
278
279static void awe_reset_samples(void);
280/* emu8000 chip i/o access */
281static void setup_ports(int p1, int p2, int p3);
282static void awe_poke(unsigned short cmd, unsigned short port, unsigned short data);
283static void awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data);
284static unsigned short awe_peek(unsigned short cmd, unsigned short port);
285static unsigned int awe_peek_dw(unsigned short cmd, unsigned short port);
286static void awe_wait(unsigned short delay);
287
288/* initialize emu8000 chip */
289static void awe_initialize(void);
290
291/* set voice parameters */
292static void awe_init_ctrl_parms(int init_all);
293static void awe_init_voice_info(awe_voice_info *vp);
294static void awe_init_voice_parm(awe_voice_parm *pp);
295#ifdef AWE_HAS_GUS_COMPATIBILITY
296static int freq_to_note(int freq);
297static int calc_rate_offset(int Hz);
298/*static int calc_parm_delay(int msec);*/
299static int calc_parm_hold(int msec);
300static int calc_parm_attack(int msec);
301static int calc_parm_decay(int msec);
302static int calc_parm_search(int msec, short *table);
303#endif /* gus compat */
304
305/* turn on/off note */
306static void awe_note_on(int voice);
307static void awe_note_off(int voice);
308static void awe_terminate(int voice);
309static void awe_exclusive_off(int voice);
310static void awe_note_off_all(int do_sustain);
311
312/* calculate voice parameters */
313typedef void (*fx_affect_func)(int voice, int forced);
314static void awe_set_pitch(int voice, int forced);
315static void awe_set_voice_pitch(int voice, int forced);
316static void awe_set_volume(int voice, int forced);
317static void awe_set_voice_vol(int voice, int forced);
318static void awe_set_pan(int voice, int forced);
319static void awe_fx_fmmod(int voice, int forced);
320static void awe_fx_tremfrq(int voice, int forced);
321static void awe_fx_fm2frq2(int voice, int forced);
322static void awe_fx_filterQ(int voice, int forced);
323static void awe_calc_pitch(int voice);
324#ifdef AWE_HAS_GUS_COMPATIBILITY
325static void awe_calc_pitch_from_freq(int voice, int freq);
326#endif
327static void awe_calc_volume(int voice);
328static void awe_update_volume(void);
329static void awe_change_master_volume(short val);
330static void awe_voice_init(int voice, int init_all);
331static void awe_channel_init(int ch, int init_all);
332static void awe_fx_init(int ch);
333static void awe_send_effect(int voice, int layer, int type, int val);
334static void awe_modwheel_change(int voice, int value);
335
336/* sequencer interface */
337static int awe_open(int dev, int mode);
338static void awe_close(int dev);
339static int awe_ioctl(int dev, unsigned int cmd, void __user * arg);
340static int awe_kill_note(int dev, int voice, int note, int velocity);
341static int awe_start_note(int dev, int v, int note_num, int volume);
342static int awe_set_instr(int dev, int voice, int instr_no);
343static int awe_set_instr_2(int dev, int voice, int instr_no);
344static void awe_reset(int dev);
345static void awe_hw_control(int dev, unsigned char *event);
346static int awe_load_patch(int dev, int format, const char __user *addr,
347 int offs, int count, int pmgr_flag);
348static void awe_aftertouch(int dev, int voice, int pressure);
349static void awe_controller(int dev, int voice, int ctrl_num, int value);
350static void awe_panning(int dev, int voice, int value);
351static void awe_volume_method(int dev, int mode);
352static void awe_bender(int dev, int voice, int value);
353static int awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc);
354static void awe_setup_voice(int dev, int voice, int chn);
355
356#define awe_key_pressure(dev,voice,key,press) awe_start_note(dev,voice,(key)+128,press)
357
358/* hardware controls */
359#ifdef AWE_HAS_GUS_COMPATIBILITY
360static void awe_hw_gus_control(int dev, int cmd, unsigned char *event);
361#endif
362static void awe_hw_awe_control(int dev, int cmd, unsigned char *event);
363static void awe_voice_change(int voice, fx_affect_func func);
364static void awe_sostenuto_on(int voice, int forced);
365static void awe_sustain_off(int voice, int forced);
366static void awe_terminate_and_init(int voice, int forced);
367
368/* voice search */
369static int awe_search_key(int bank, int preset, int note);
370static awe_voice_list *awe_search_instr(int bank, int preset, int note);
371static int awe_search_multi_voices(awe_voice_list *rec, int note, int velocity, awe_voice_info **vlist);
372static void awe_alloc_multi_voices(int ch, int note, int velocity, int key);
373static void awe_alloc_one_voice(int voice, int note, int velocity);
374static int awe_clear_voice(void);
375
376/* load / remove patches */
377static int awe_open_patch(awe_patch_info *patch, const char __user *addr, int count);
378static int awe_close_patch(awe_patch_info *patch, const char __user *addr, int count);
379static int awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count);
380static int awe_load_info(awe_patch_info *patch, const char __user *addr, int count);
381static int awe_remove_info(awe_patch_info *patch, const char __user *addr, int count);
382static int awe_load_data(awe_patch_info *patch, const char __user *addr, int count);
383static int awe_replace_data(awe_patch_info *patch, const char __user *addr, int count);
384static int awe_load_map(awe_patch_info *patch, const char __user *addr, int count);
385#ifdef AWE_HAS_GUS_COMPATIBILITY
386static 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);*/
389static int awe_probe_data(awe_patch_info *patch, const char __user *addr, int count);
390static sf_list *check_patch_opened(int type, char *name);
391static int awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *sp, int channels);
392static int awe_create_sf(int type, char *name);
393static void awe_free_sf(sf_list *sf);
394static void add_sf_info(sf_list *sf, awe_voice_list *rec);
395static void add_sf_sample(sf_list *sf, awe_sample_list *smp);
396static void purge_old_list(awe_voice_list *rec, awe_voice_list *next);
397static void add_info_list(awe_voice_list *rec);
398static void awe_remove_samples(int sf_id);
399static void rebuild_preset_list(void);
400static short awe_set_sample(awe_voice_list *rec);
401static awe_sample_list *search_sample_index(sf_list *sf, int sample);
402
403static int is_identical_holder(sf_list *sf1, sf_list *sf2);
404#ifdef AWE_ALLOW_SAMPLE_SHARING
405static int is_identical_name(unsigned char *name, sf_list *p);
406static int is_shared_sf(unsigned char *name);
407static int info_duplicated(sf_list *sf, awe_voice_list *rec);
408#endif /* allow sharing */
409
410/* lowlevel functions */
411static void awe_init_audio(void);
412static void awe_init_dma(void);
413static void awe_init_array(void);
414static void awe_send_array(unsigned short *data);
415static void awe_tweak_voice(int voice);
416static void awe_tweak(void);
417static void awe_init_fm(void);
418static int awe_open_dram_for_write(int offset, int channels);
419static void awe_open_dram_for_check(void);
420static void awe_close_dram(void);
421/*static void awe_write_dram(unsigned short c);*/
422static int awe_detect_base(int addr);
423static int awe_detect(void);
424static void awe_check_dram(void);
425static int awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count);
426static void awe_set_chorus_mode(int mode);
427static void awe_update_chorus_mode(void);
428static int awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count);
429static void awe_set_reverb_mode(int mode);
430static void awe_update_reverb_mode(void);
431static void awe_equalizer(int bass, int treble);
432static void awe_update_equalizer(void);
433
434#ifdef CONFIG_AWE32_MIXER
435static void attach_mixer(void);
436static void unload_mixer(void);
437#endif
438
439#ifdef CONFIG_AWE32_MIDIEMU
440static void attach_midiemu(void);
441static void unload_midiemu(void);
442#endif
443
444#define limitvalue(x, a, b) if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b)
445
446/*
447 * control parameters
448 */
449
450
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 */
456
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
463
464static 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 */
489};
490
491static int ctrls[AWE_MD_END];
492
493
494/*
495 * synth operation table
496 */
497
498static struct synth_operations awe_operations =
499{
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
522};
523
524static void free_tables(void)
525{
526 if (sftail) {
527 sf_list *p, *prev;
528 for (p = sftail; p; p = prev) {
529 prev = p->prev;
530 awe_free_sf(p);
531 }
532 }
533 sfhead = sftail = NULL;
534}
535
536/*
537 * clear sample tables
538 */
539
540static void
541awe_reset_samples(void)
542{
543 /* free all bank tables */
544 memset(preset_table, 0, sizeof(preset_table));
545 free_tables();
546
547 current_sf_id = 0;
548 locked_sf_id = 0;
549 patch_opened = 0;
550}
551
552
553/*
554 * EMU register access
555 */
556
557/* select a given AWE32 pointer */
558static int awe_ports[5];
559static int port_setuped = FALSE;
560static int awe_cur_cmd = -1;
561#define awe_set_cmd(cmd) \
562if (awe_cur_cmd != cmd) { outw(cmd, awe_ports[Pointer]); awe_cur_cmd = cmd; }
563
564/* write 16bit data */
565static void
566awe_poke(unsigned short cmd, unsigned short port, unsigned short data)
567{
568 awe_set_cmd(cmd);
569 outw(data, awe_ports[port]);
570}
571
572/* write 32bit data */
573static void
574awe_poke_dw(unsigned short cmd, unsigned short port, unsigned int data)
575{
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 */
580}
581
582/* read 16bit data */
583static unsigned short
584awe_peek(unsigned short cmd, unsigned short port)
585{
586 unsigned short k;
587 awe_set_cmd(cmd);
588 k = inw(awe_ports[port]);
589 return k;
590}
591
592/* read 32bit data */
593static unsigned int
594awe_peek_dw(unsigned short cmd, unsigned short port)
595{
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;
603}
604
605/* wait delay number of AWE32 44100Hz clocks */
606#ifdef WAIT_BY_LOOP /* wait by loop -- that's not good.. */
607static void
608awe_wait(unsigned short delay)
609{
610 unsigned short clock, target;
611 unsigned short port = awe_ports[AWE_WC_Port];
612 int counter;
613
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;
623 }
624 for (; (unsigned short)inw(port) < target; counter++)
625 if (counter > 65536)
626 break;
627}
628#else
629
630static void awe_wait(unsigned short delay)
631{
632 current->state = TASK_INTERRUPTIBLE;
633 schedule_timeout((HZ*(unsigned long)delay + 44099)/44100);
634}
635/*
636static void awe_wait(unsigned short delay)
637{
638 udelay(((unsigned long)delay * 1000000L + 44099) / 44100);
639}
640*/
641#endif /* wait by loop */
642
643/* write a word data */
644#define awe_write_dram(c) awe_poke(AWE_SMLD, c)
645
646/*
647 * AWE32 voice parameters
648 */
649
650/* initialize voice_info record */
651static void
652awe_init_voice_info(awe_voice_info *vp)
653{
654 vp->sample = 0;
655 vp->rate_offset = 0;
656
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;
668
669 vp->fixkey = -1;
670 vp->fixvel = -1;
671 vp->fixpan = -1;
672 vp->pan = -1;
673
674 vp->exclusiveClass = 0;
675 vp->amplitude = 127;
676 vp->attenuation = 0;
677 vp->scaleTuning = 100;
678
679 awe_init_voice_parm(&vp->parm);
680}
681
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.
687 */
688static void
689awe_init_voice_parm(awe_voice_parm *pp)
690{
691 pp->moddelay = 0x8000;
692 pp->modatkhld = 0x7f7f;
693 pp->moddcysus = 0x7f7f;
694 pp->modrelease = 0x807f;
695 pp->modkeyhold = 0;
696 pp->modkeydecay = 0;
697
698 pp->voldelay = 0x8000;
699 pp->volatkhld = 0x7f7f;
700 pp->voldcysus = 0x7f7f;
701 pp->volrelease = 0x807f;
702 pp->volkeyhold = 0;
703 pp->volkeydecay = 0;
704
705 pp->lfo1delay = 0x8000;
706 pp->lfo2delay = 0x8000;
707 pp->pefe = 0;
708
709 pp->fmmod = 0;
710 pp->tremfrq = 0;
711 pp->fm2frq2 = 0;
712
713 pp->cutoff = 0xff;
714 pp->filterQ = 0;
715
716 pp->chorus = 0;
717 pp->reverb = 0;
718}
719
720
721#ifdef AWE_HAS_GUS_COMPATIBILITY
722
723/* convert frequency mHz to abstract cents (= midi key * 100) */
724static int
725freq_to_note(int mHz)
726{
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;
733
734 if (mHz == 0)
735 return 0;
736 if (mHz < 0)
737 return 12799; /* maximum */
738
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;
745 }
746 base /= 2;
747
748 /* to avoid overflow... */
749 times = 10000;
750 while (freq > max_val) {
751 max_val *= 10;
752 times /= 10;
753 base /= 10;
754 }
755
756 freq = freq * times / base;
757 for (i = 0; i < 12; i++) {
758 if (freq < semitone_tuning[i+1])
759 break;
760 note++;
761 }
762
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++;
769 }
770
771 return note * 100 + tune;
772}
773
774
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.
779 */
780static int
781calc_rate_offset(int Hz)
782{
783 /* offset = log(Hz / 44100) / log(2) * 4096 */
784 int freq, base, i;
785
786 /* maybe smaller than max (44100Hz) */
787 if (Hz <= 0 || Hz >= 44100) return 0;
788
789 base = 0;
790 for (freq = Hz * 2; freq < 44100; freq *= 2)
791 base++;
792 base *= 1200;
793
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;
799 }
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++;
805 }
806 return -base * 4096 / 1200;
807}
808
809
810/*
811 * convert envelope time parameter to AWE32 raw parameter
812 */
813
814/* attack & decay/release time table (msec) */
815static short attack_time_tbl[128] = {
81632767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
817707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
818361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
819180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
82090, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
82145, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
82222, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
82311, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
824};
825
826static short decay_time_tbl[128] = {
82732767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
8282828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
8291443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
830691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
831345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
832172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
83386, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
83443, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
835};
836
837#define calc_parm_delay(msec) (0x8000 - (msec) * 1000 / 725);
838
839/* delay time = 0x8000 - msec/92 */
840static int
841calc_parm_hold(int msec)
842{
843 int val = (0x7f * 92 - msec) / 92;
844 if (val < 1) val = 1;
845 if (val > 127) val = 127;
846 return val;
847}
848
849/* attack time: search from time table */
850static int
851calc_parm_attack(int msec)
852{
853 return calc_parm_search(msec, attack_time_tbl);
854}
855
856/* decay/release time: search from time table */
857static int
858calc_parm_decay(int msec)
859{
860 return calc_parm_search(msec, decay_time_tbl);
861}
862
863/* search an index for specified time from given time table */
864static int
865calc_parm_search(int msec, short *table)
866{
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;
874 }
875 return left;
876}
877#endif /* AWE_HAS_GUS_COMPATIBILITY */
878
879
880/*
881 * effects table
882 */
883
884/* set an effect value */
885#define FX_FLAG_OFF 0
886#define FX_FLAG_SET 1
887#define FX_FLAG_ADD 2
888
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)
895
896/* check the effect value is set */
897#define FX_ON(rec,type) ((rec)->flags[type])
898
899#define PARM_BYTE 0
900#define PARM_WORD 1
901#define PARM_SIGN 2
902
903static 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 */
916
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 */
923
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 */
929
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 */
933
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 */
939
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 */
947};
948
949
950static unsigned char
951FX_BYTE(FX_Rec *rec, FX_Rec *lay, int type, unsigned char value)
952{
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;
967 }
968 }
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;
975 }
976 return value;
977}
978
979/* get word effect value */
980static unsigned short
981FX_WORD(FX_Rec *rec, FX_Rec *lay, int type, unsigned short value)
982{
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;
997 }
998 return value;
999}
1000
1001/* get word (upper=type1/lower=type2) effect value */
1002static unsigned short
1003FX_COMB(FX_Rec *rec, FX_Rec *lay, int type1, int type2, unsigned short value)
1004{
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;
1010}
1011
1012/* address offset */
1013static int
1014FX_OFFSET(FX_Rec *rec, FX_Rec *lay, int lo, int hi, int mode)
1015{
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;
1029}
1030
1031
1032/*
1033 * turn on/off sample
1034 */
1035
1036/* table for volume target calculation */
1037static unsigned short voltarget[16] = {
1038 0xEAC0, 0XE0C8, 0XD740, 0XCE20, 0XC560, 0XBD08, 0XB500, 0XAD58,
1039 0XA5F8, 0X9EF0, 0X9830, 0X91C0, 0X8B90, 0X85A8, 0X8000, 0X7A90
1040};
1041
1042static void
1043awe_note_on(int voice)
1044{
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];
1054
1055 /* A voice sample must assigned before calling */
1056 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1057 return;
1058
1059 parm = (awe_voice_parm_block*)&vp->parm;
1060
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);
1067
1068 /* set pitch offset */
1069 awe_set_pitch(voice, TRUE);
1070
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;
1086 }
1087
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;
1096
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));
1108
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;
1116 }
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 */
1125
1126 /* cutoff and volume */
1127 awe_set_volume(voice, TRUE);
1128
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));
1133
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));
1139
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);
1148
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));
1157
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));
1166
1167 /* clear unknown registers */
1168 awe_poke_dw(AWE_00A0(voice), 0);
1169 awe_poke_dw(AWE_0080(voice), 0);
1170
1171 /* reset volume */
1172 awe_poke_dw(AWE_VTFT(voice), (vtarget<<16)|ftarget);
1173 awe_poke_dw(AWE_CVCF(voice), (vtarget<<16)|ftarget);
1174
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));
1184
1185 voices[voice].state = AWE_ST_ON;
1186
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);
1191 }
1192}
1193
1194
1195/* turn off the voice */
1196static void
1197awe_note_off(int voice)
1198{
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];
1205
1206 if ((vp = voices[voice].sample) == NULL) {
1207 voices[voice].state = AWE_ST_OFF;
1208 return;
1209 }
1210
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;
1218}
1219
1220/* force to terminate the voice (no releasing echo) */
1221static void
1222awe_terminate(int voice)
1223{
1224 awe_poke(AWE_DCYSUSV(voice), 0x807F);
1225 awe_tweak_voice(voice);
1226 voices[voice].state = AWE_ST_OFF;
1227}
1228
1229/* turn off other voices with the same exclusive class (for drums) */
1230static void
1231awe_exclusive_off(int voice)
1232{
1233 int i, exclass;
1234
1235 if (voices[voice].sample == NULL)
1236 return;
1237 if ((exclass = voices[voice].sample->exclusiveClass) == 0)
1238 return; /* not exclusive */
1239
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);
1248 }
1249 }
1250}
1251
1252
1253/*
1254 * change the parameters of an audible voice
1255 */
1256
1257/* change pitch */
1258static void
1259awe_set_pitch(int voice, int forced)
1260{
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));
1264}
1265
1266/* calculate & change pitch */
1267static void
1268awe_set_voice_pitch(int voice, int forced)
1269{
1270 awe_calc_pitch(voice);
1271 awe_set_pitch(voice, forced);
1272}
1273
1274/* change volume & cutoff */
1275static void
1276awe_set_volume(int voice, int forced)
1277{
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];
1284
1285 if (!IS_PLAYING(voice) && !forced) return;
1286 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1287 return;
1288
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);
1295}
1296
1297/* calculate & change volume */
1298static void
1299awe_set_voice_vol(int voice, int forced)
1300{
1301 if (IS_EMPTY(voice))
1302 return;
1303 awe_calc_volume(voice);
1304 awe_set_volume(voice, forced);
1305}
1306
1307
1308/* change pan; this could make a click noise.. */
1309static void
1310awe_set_pan(int voice, int forced)
1311{
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];
1319
1320 if (IS_NO_EFFECT(voice) && !forced) return;
1321 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1322 return;
1323
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;
1333 }
1334 limitvalue(temp, 0, 255);
1335 if (ctrls[AWE_MD_PAN_EXCHANGE]) {
1336 temp = 255 - temp;
1337 }
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));
1350 }
1351}
1352
1353/* effects change during playing */
1354static void
1355awe_fx_fmmod(int voice, int forced)
1356{
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];
1362
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));
1369}
1370
1371/* set tremolo (lfo1) volume & frequency */
1372static void
1373awe_fx_tremfrq(int voice, int forced)
1374{
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];
1380
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));
1387}
1388
1389/* set lfo2 pitch & frequency */
1390static void
1391awe_fx_fm2frq2(int voice, int forced)
1392{
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];
1398
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));
1405}
1406
1407
1408/* Q & current address (Q 4bit value, MSB) */
1409static void
1410awe_fx_filterQ(int voice, int forced)
1411{
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];
1418
1419 if (IS_NO_EFFECT(voice) && !forced) return;
1420 if ((vp = voices[voice].sample) == NULL || vp->index == 0)
1421 return;
1422
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);
1426}
1427
1428/*
1429 * calculate pitch offset
1430 *
1431 * 0xE000 is no pitch offset at 44100Hz sample.
1432 * Every 4096 is one octave.
1433 */
1434
1435static void
1436awe_calc_pitch(int voice)
1437{
1438 voice_info *vp = &voices[voice];
1439 awe_voice_info *ap;
1440 awe_chan_info *cp = voices[voice].cinfo;
1441 int offset;
1442
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;
1450 }
1451
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));
1460 }
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;
1469 }
1470
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];
1476
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;
1484}
1485
1486
1487#ifdef AWE_HAS_GUS_COMPATIBILITY
1488/* calculate MIDI key and semitone from the specified frequency */
1489static void
1490awe_calc_pitch_from_freq(int voice, int freq)
1491{
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;
1498
1499 if (voices[voice].layer < MAX_LAYERS)
1500 fx_lay = &voices[voice].cinfo->fx_layer[voices[voice].layer];
1501
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;
1509 }
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;
1522}
1523#endif /* AWE_HAS_GUS_COMPATIBILITY */
1524
1525
1526/*
1527 * calculate volume attenuation
1528 *
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).
1532 */
1533
1534static 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,
1543};
1544
1545/* tables for volume->attenuation calculation */
1546static 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
1560};
1561
1562static 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
1576};
1577
1578static 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
1592};
1593
1594static void
1595awe_calc_volume(int voice)
1596{
1597 voice_info *vp = &voices[voice];
1598 awe_voice_info *ap;
1599 awe_chan_info *cp = voices[voice].cinfo;
1600 int vol;
1601
1602 /* search voice information */
1603 if ((ap = vp->sample) == NULL)
1604 return;
1605
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;
1611 }
1612
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);
1618
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;
1629
1630 } else {
1631 /* 0 - 127 */
1632 vol = (vp->velocity * cp->main_vol * cp->expression_vol) / (127*127);
1633 vol = vol * ap->amplitude / 127;
1634
1635 if (vol < 0) vol = 0;
1636 if (vol > 127) vol = 127;
1637
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;
1645
1646 vp->avol = vol;
1647 }
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;
1655 }
1656 DEBUG(3,printk("AWE32: [-- voice(%d) vol=%x]\n", voice, vol));
1657}
1658
1659/* change master volume */
1660static void
1661awe_change_master_volume(short val)
1662{
1663 limitvalue(val, 0, 127);
1664 atten_offset = vol_table[val];
1665 atten_relative = TRUE;
1666 awe_update_volume();
1667}
1668
1669/* update volumes of all available channels */
1670static void awe_update_volume(void)
1671{
1672 int i;
1673 for (i = 0; i < awe_max_voices; i++)
1674 awe_set_voice_vol(i, TRUE);
1675}
1676
1677/* set sostenuto on */
1678static void awe_sostenuto_on(int voice, int forced)
1679{
1680 if (IS_NO_EFFECT(voice) && !forced) return;
1681 voices[voice].sostenuto = 127;
1682}
1683
1684
1685/* drop sustain */
1686static void awe_sustain_off(int voice, int forced)
1687{
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);
1692 }
1693}
1694
1695
1696/* terminate and initialize voice */
1697static void awe_terminate_and_init(int voice, int forced)
1698{
1699 awe_terminate(voice);
1700 awe_fx_init(voices[voice].ch);
1701 awe_voice_init(voice, TRUE);
1702}
1703
1704
1705/*
1706 * synth operation routines
1707 */
1708
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))
1712
1713/* initialize the voice */
1714static void
1715awe_voice_init(int voice, int init_all)
1716{
1717 voice_info *vp = &voices[voice];
1718
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;
1724
1725 /* clear voice mapping */
1726 voice_alloc->map[voice] = 0;
1727
1728 /* touch the timing flag */
1729 vp->time = current_alloc_time;
1730
1731 /* initialize other parameters if necessary */
1732 if (init_all) {
1733 vp->note = -1;
1734 vp->velocity = 0;
1735 vp->sostenuto = 0;
1736
1737 vp->sample = NULL;
1738 vp->cinfo = &channels[voice];
1739 vp->ch = voice;
1740 vp->state = AWE_ST_OFF;
1741
1742 /* emu8000 parameters */
1743 vp->apitch = 0;
1744 vp->avol = 255;
1745 vp->apan = -1;
1746 }
1747}
1748
1749/* clear effects */
1750static void awe_fx_init(int ch)
1751{
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));
1755 }
1756}
1757
1758/* initialize channel info */
1759static void awe_channel_init(int ch, int init_all)
1760{
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];
1773 }
1774 }
1775
1776 cp->bender = 0; /* zero tune skew */
1777 cp->expression_vol = 127;
1778 cp->chan_press = 0;
1779 cp->sustained = 0;
1780
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));
1784 }
1785}
1786
1787
1788/* change the voice parameters; voice = channel */
1789static void awe_voice_change(int voice, fx_affect_func func)
1790{
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;
1806 }
1807}
1808
1809
1810/*
1811 * device open / close
1812 */
1813
1814/* open device:
1815 * reset status of all voices, and clear sample position flag
1816 */
1817static int
1818awe_open(int dev, int mode)
1819{
1820 if (awe_busy)
1821 return -EBUSY;
1822
1823 awe_busy = TRUE;
1824
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;
1831
1832 /* reset voices & channels */
1833 awe_reset(dev);
1834
1835 patch_opened = 0;
1836
1837 return 0;
1838}
1839
1840
1841/* close device:
1842 * reset all voices again (terminate sounds)
1843 */
1844static void
1845awe_close(int dev)
1846{
1847 awe_reset(dev);
1848 awe_busy = FALSE;
1849}
1850
1851
1852/* set miscellaneous mode parameters
1853 */
1854static void
1855awe_init_ctrl_parms(int init_all)
1856{
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;
1861 }
1862}
1863
1864
1865/* sequencer I/O control:
1866 */
1867static int
1868awe_ioctl(int dev, unsigned int cmd, void __user *arg)
1869{
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;
1880
1881 case SNDCTL_SEQ_RESETSAMPLES:
1882 awe_reset(dev);
1883 awe_reset_samples();
1884 return 0;
1885 break;
1886
1887 case SNDCTL_SEQ_PERCMODE:
1888 /* what's this? */
1889 return 0;
1890 break;
1891
1892 case SNDCTL_SYNTH_MEMAVL:
1893 return memsize - awe_free_mem_ptr() * 2;
1894 break;
1895
1896 default:
1897 printk(KERN_WARNING "AWE32: unsupported ioctl %d\n", cmd);
1898 return -EINVAL;
1899 break;
1900 }
1901}
1902
1903
1904static int voice_in_range(int voice)
1905{
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;
1912 }
1913 return TRUE;
1914}
1915
1916static void release_voice(int voice, int do_sustain)
1917{
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);
1927 }
1928}
1929
1930/* release all notes */
1931static void awe_note_off_all(int do_sustain)
1932{
1933 int i;
1934 for (i = 0; i < awe_max_voices; i++)
1935 release_voice(i, do_sustain);
1936}
1937
1938/* kill a voice:
1939 * not terminate, just release the voice.
1940 */
1941static int
1942awe_kill_note(int dev, int voice, int note, int velocity)
1943{
1944 int i, v2, key;
1945
1946 DEBUG(2,printk("AWE32: [off(%d) nt=%d vl=%d]\n", voice, note, velocity));
1947 if (! voice_in_range(voice))
1948 return -EINVAL;
1949
1950 switch (playing_mode) {
1951 case AWE_PLAY_DIRECT:
1952 case AWE_PLAY_INDIRECT:
1953 key = AWE_VOICE_KEY(voice);
1954 break;
1955
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;
1966 }
1967
1968 for (i = 0; i < awe_max_voices; i++) {
1969 if (voices[i].key == key)
1970 release_voice(i, TRUE);
1971 }
1972 return 0;
1973}
1974
1975
1976static void start_or_volume_change(int voice, int velocity)
1977{
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);
1984}
1985
1986static void set_and_start_voice(int voice, int state)
1987{
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);
1994}
1995
1996/* start a voice:
1997 * if note is 255, identical with aftertouch function.
1998 * Otherwise, start a voice with specified not and volume.
1999 */
2000static int
2001awe_start_note(int dev, int voice, int note, int velocity)
2002{
2003 int i, key, state, volonly;
2004
2005 DEBUG(2,printk("AWE32: [on(%d) nt=%d vl=%d]\n", voice, note, velocity));
2006 if (! voice_in_range(voice))
2007 return -EINVAL;
2008
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;
2014
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;
2022
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;
2032 }
2033 key = AWE_CHAN_KEY(voice, note);
2034 break;
2035 }
2036
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);
2042 }
2043 return 0;
2044 }
2045
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);
2055 }
2056 }
2057
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);
2063
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);
2068
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);
2073 }
2074
2075 return 0;
2076}
2077
2078
2079/* calculate hash key */
2080static int
2081awe_search_key(int bank, int preset, int note)
2082{
2083 unsigned int key;
2084
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;
2094
2095 return (int)key;
2096}
2097
2098
2099/* search instrument from hash table */
2100static awe_voice_list *
2101awe_search_instr(int bank, int preset, int note)
2102{
2103 awe_voice_list *p;
2104 int key, key2;
2105
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;
2110 }
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;
2117 }
2118 return NULL;
2119}
2120
2121
2122/* assign the instrument to a voice */
2123static int
2124awe_set_instr_2(int dev, int voice, int instr_no)
2125{
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;
2130 }
2131 return awe_set_instr(dev, voice, instr_no);
2132}
2133
2134/* assign the instrument to a channel; voice is the channel number */
2135static int
2136awe_set_instr(int dev, int voice, int instr_no)
2137{
2138 awe_chan_info *cinfo;
2139
2140 if (! voice_in_range(voice))
2141 return -EINVAL;
2142
2143 if (instr_no < 0 || instr_no >= AWE_MAX_PRESETS)
2144 return -EINVAL;
2145
2146 cinfo = &channels[voice];
2147 cinfo->instr = instr_no;
2148 DEBUG(2,printk("AWE32: [program(%d) %d]\n", voice, instr_no));
2149
2150 return 0;
2151}
2152
2153
2154/* reset all voices; terminate sounds and initialize parameters */
2155static void
2156awe_reset(int dev)
2157{
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);
2164 }
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;
2170 }
2171 awe_init_fm();
2172 awe_tweak();
2173}
2174
2175
2176/* hardware specific control:
2177 * GUS specific and AWE32 specific controls are available.
2178 */
2179static void
2180awe_hw_control(int dev, unsigned char *event)
2181{
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
2189}
2190
2191
2192#ifdef AWE_HAS_GUS_COMPATIBILITY
2193
2194/* GUS compatible controls */
2195static void
2196awe_hw_gus_control(int dev, int cmd, unsigned char *event)
2197{
2198 int voice, i, key;
2199 unsigned short p1;
2200 short p2;
2201 int plong;
2202
2203 if (MULTI_LAYER_MODE())
2204 return;
2205 if (cmd == _GUS_NUMVOICES)
2206 return;
2207
2208 voice = event[3];
2209 if (! voice_in_range(voice))
2210 return;
2211
2212 p1 = *(unsigned short *) &event[4];
2213 p2 = *(short *) &event[6];
2214 plong = *(int*) &event[4];
2215
2216 switch (cmd) {
2217 case _GUS_VOICESAMPLE:
2218 awe_set_instr(dev, voice, p1);
2219 return;
2220
2221 case _GUS_VOICEBALA:
2222 /* 0 to 15 --> -128 to 127 */
2223 awe_panning(dev, voice, ((int)p1 << 4) - 128);
2224 return;
2225
2226 case _GUS_VOICEVOL:
2227 case _GUS_VOICEVOL2:
2228 /* not supported yet */
2229 return;
2230
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;
2238
2239 case _GUS_VOLUME_SCALE:
2240 return;
2241
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;
2248 }
2249
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;
2257
2258 case _GUS_VOICEOFF:
2259 awe_terminate(i);
2260 awe_fx_init(voices[i].ch);
2261 awe_voice_init(i, TRUE);
2262 break;
2263
2264 case _GUS_VOICEFADE:
2265 awe_note_off(i);
2266 awe_fx_init(voices[i].ch);
2267 awe_voice_init(i, FALSE);
2268 break;
2269
2270 case _GUS_VOICEFREQ:
2271 awe_calc_pitch_from_freq(i, plong);
2272 break;
2273 }
2274 }
2275 }
2276}
2277
2278#endif /* gus_compat */
2279
2280
2281/* AWE32 specific controls */
2282static void
2283awe_hw_awe_control(int dev, int cmd, unsigned char *event)
2284{
2285 int voice;
2286 unsigned short p1;
2287 short p2;
2288 int i;
2289
2290 voice = event[3];
2291 if (! voice_in_range(voice))
2292 return;
2293
2294 if (playing_mode == AWE_PLAY_MULTI2) {
2295 voice = voice_alloc->map[voice] >> 8;
2296 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2297 return;
2298 }
2299
2300 p1 = *(unsigned short *) &event[4];
2301 p2 = *(short *) &event[6];
2302
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;
2312
2313 case _AWE_CHORUS_MODE:
2314 ctrls[AWE_MD_CHORUS_MODE] = p1;
2315 awe_update_chorus_mode();
2316 break;
2317
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;
2324
2325 case _AWE_INITIALIZE_CHIP:
2326 awe_initialize();
2327 break;
2328
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;
2335 }
2336 awe_send_effect(voice, i, p1, p2);
2337 break;
2338
2339 case _AWE_RESET_CHANNEL:
2340 awe_channel_init(voice, !p1);
2341 break;
2342
2343 case _AWE_TERMINATE_ALL:
2344 awe_reset(0);
2345 break;
2346
2347 case _AWE_TERMINATE_CHANNEL:
2348 awe_voice_change(voice, awe_terminate_and_init);
2349 break;
2350
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;
2357
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;
2364
2365 case _AWE_CHN_PRESSURE:
2366 channels[voice].chan_press = p1;
2367 awe_modwheel_change(voice, p1);
2368 break;
2369
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;
2375
2376 case _AWE_DRUM_CHANNELS:
2377 DEBUG(0,printk("AWE32: drum flags = %x\n", p1));
2378 drum_flags = *(unsigned int*)&event[4];
2379 break;
2380
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();
2387 }
2388 break;
2389
2390 case _AWE_EQUALIZER:
2391 ctrls[AWE_MD_BASS_LEVEL] = p1;
2392 ctrls[AWE_MD_TREBLE_LEVEL] = p2;
2393 awe_update_equalizer();
2394 break;
2395
2396 default:
2397 DEBUG(0,printk("AWE32: hw control cmd=%d voice=%d\n", cmd, voice));
2398 break;
2399 }
2400}
2401
2402
2403/* change effects */
2404static void
2405awe_send_effect(int voice, int layer, int type, int val)
2406{
2407 awe_chan_info *cinfo;
2408 FX_Rec *fx;
2409 int mode;
2410
2411 cinfo = &channels[voice];
2412 if (layer >= 0 && layer < MAX_LAYERS)
2413 fx = &cinfo->fx_layer[layer];
2414 else
2415 fx = &cinfo->fx;
2416
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;
2424
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);
2436 }
2437 }
2438}
2439
2440
2441/* change modulation wheel; voice is already mapped on multi2 mode */
2442static void
2443awe_modwheel_change(int voice, int value)
2444{
2445 int i;
2446 awe_chan_info *cinfo;
2447
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);
2454}
2455
2456
2457/* voice pressure change */
2458static void
2459awe_aftertouch(int dev, int voice, int pressure)
2460{
2461 int note;
2462
2463 DEBUG(2,printk("AWE32: [after(%d) %d]\n", voice, pressure));
2464 if (! voice_in_range(voice))
2465 return;
2466
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;
2476 }
2477}
2478
2479
2480/* voice control change */
2481static void
2482awe_controller(int dev, int voice, int ctrl_num, int value)
2483{
2484 awe_chan_info *cinfo;
2485
2486 if (! voice_in_range(voice))
2487 return;
2488
2489 if (playing_mode == AWE_PLAY_MULTI2) {
2490 voice = voice_alloc->map[voice] >> 8;
2491 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2492 return;
2493 }
2494
2495 cinfo = &channels[voice];
2496
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;
2512
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;
2517
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;
2524
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;
2531
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;
2541
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;
2549
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;
2559
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;
2564
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;
2569
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;
2576
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;
2582
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;
2589
2590 default:
2591 DEBUG(0,printk("AWE32: [control(%d) ctrl=%d val=%d]\n",
2592 voice, ctrl_num, value));
2593 break;
2594 }
2595}
2596
2597
2598/* voice pan change (value = -128 - 127) */
2599static void
2600awe_panning(int dev, int voice, int value)
2601{
2602 awe_chan_info *cinfo;
2603
2604 if (! voice_in_range(voice))
2605 return;
2606
2607 if (playing_mode == AWE_PLAY_MULTI2) {
2608 voice = voice_alloc->map[voice] >> 8;
2609 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2610 return;
2611 }
2612
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);
2618}
2619
2620
2621/* volume mode change */
2622static void
2623awe_volume_method(int dev, int mode)
2624{
2625 /* not impremented */
2626 DEBUG(0,printk("AWE32: [volmethod mode=%d]\n", mode));
2627}
2628
2629
2630/* pitch wheel change: 0-16384 */
2631static void
2632awe_bender(int dev, int voice, int value)
2633{
2634 awe_chan_info *cinfo;
2635
2636 if (! voice_in_range(voice))
2637 return;
2638
2639 if (playing_mode == AWE_PLAY_MULTI2) {
2640 voice = voice_alloc->map[voice] >> 8;
2641 if (voice < 0 || voice >= AWE_MAX_CHANNELS)
2642 return;
2643 }
2644
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);
2650}
2651
2652
2653/*
2654 * load a sound patch:
2655 * three types of patches are accepted: AWE, GUS, and SYSEX.
2656 */
2657
2658static int
2659awe_load_patch(int dev, int format, const char __user *addr,
2660 int offs, int count, int pmgr_flag)
2661{
2662 awe_patch_info patch;
2663 int rc = 0;
2664
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;
2676 }
2677
2678 if (count < AWE_PATCH_INFO_SIZE) {
2679 printk(KERN_WARNING "AWE32 Error: Patch header too short\n");
2680 return -EINVAL;
2681 }
2682 if (copy_from_user(((char*)&patch) + offs, addr + offs,
2683 AWE_PATCH_INFO_SIZE - offs))
2684 return -EFAULT;
2685
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;
2691 }
2692
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;
2730
2731 default:
2732 printk(KERN_WARNING "AWE32 Error: unknown patch format type %d\n",
2733 patch.type);
2734 rc = -EINVAL;
2735 }
2736
2737 return rc;
2738}
2739
2740
2741/* create an sf list record */
2742static int
2743awe_create_sf(int type, char *name)
2744{
2745 sf_list *rec;
2746
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;
2761
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++;
2771
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;
2787 }
2788 }
2789 }
2790 }
2791#endif /* allow sharing */
2792
2793 return 0;
2794}
2795
2796
2797#ifdef AWE_ALLOW_SAMPLE_SHARING
2798
2799/* check if the given name is a valid shared name */
2800#define ASC_TO_KEY(c) ((c) - 'A' + 1)
2801static int is_shared_sf(unsigned char *name)
2802{
2803 static unsigned char id_head[4] = {
2804 ASC_TO_KEY('A'), ASC_TO_KEY('W'), ASC_TO_KEY('E'),
2805 AWE_MAJOR_VERSION,
2806 };
2807 if (memcmp(name, id_head, 4) == 0)
2808 return TRUE;
2809 return FALSE;
2810}
2811
2812/* check if the given name matches to the existing list */
2813static int is_identical_name(unsigned char *name, sf_list *p)
2814{
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;
2819}
2820
2821/* check if the given voice info exists */
2822static int info_duplicated(sf_list *sf, awe_voice_list *rec)
2823{
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;
2835 }
2836 }
2837 return FALSE;
2838}
2839
2840#endif /* AWE_ALLOW_SAMPLE_SHARING */
2841
2842
2843/* free sf_list record */
2844/* linked-list in this function is not cared */
2845static void
2846awe_free_sf(sf_list *sf)
2847{
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);
2853 }
2854 }
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);
2860 }
2861 }
2862 kfree(sf);
2863}
2864
2865
2866/* open patch; create sf list and set opened flag */
2867static int
2868awe_open_patch(awe_patch_info *patch, const char __user *addr, int count)
2869{
2870 awe_open_parm parm;
2871 int shared;
2872
2873 if (copy_from_user(&parm, addr + AWE_PATCH_INFO_SIZE, sizeof(parm)))
2874 return -EFAULT;
2875 shared = FALSE;
2876
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;
2886 }
2887 }
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;
2893 }
2894 }
2895 patch_opened = TRUE;
2896 return current_sf_id;
2897}
2898
2899/* check if the patch is already opened */
2900static sf_list *
2901check_patch_opened(int type, char *name)
2902{
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;
2907 }
2908 patch_opened = TRUE;
2909 return sftail;
2910 }
2911 return sftail;
2912}
2913
2914/* close the patch; if no voice is loaded, remove the patch */
2915static int
2916awe_close_patch(awe_patch_info *patch, const char __user *addr, int count)
2917{
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);
2923 }
2924 }
2925 patch_opened = 0;
2926 return 0;
2927}
2928
2929
2930/* remove the latest patch */
2931static int
2932awe_unload_patch(awe_patch_info *patch, const char __user *addr, int count)
2933{
2934 if (current_sf_id > 0 && current_sf_id > locked_sf_id) {
2935 awe_reset(0);
2936 awe_remove_samples(current_sf_id - 1);
2937 }
2938 return 0;
2939}
2940
2941/* allocate voice info list records */
2942static awe_voice_list *
2943alloc_new_info(void)
2944{
2945 awe_voice_list *newlist;
2946
2947 newlist = (awe_voice_list *)kmalloc(sizeof(*newlist), GFP_KERNEL);
2948 if (newlist == NULL) {
2949 printk(KERN_ERR "AWE32: can't alloc info table\n");
2950 return NULL;
2951 }
2952 return newlist;
2953}
2954
2955/* allocate sample info list records */
2956static awe_sample_list *
2957alloc_new_sample(void)
2958{
2959 awe_sample_list *newlist;
2960
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;
2965 }
2966 return newlist;
2967}
2968
2969/* load voice map */
2970static int
2971awe_load_map(awe_patch_info *patch, const char __user *addr, int count)
2972{
2973 awe_voice_map map;
2974 awe_voice_list *rec, *p;
2975 sf_list *sf;
2976
2977 /* get the link info */
2978 if (count < sizeof(map)) {
2979 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
2980 return -EINVAL;
2981 }
2982 if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
2983 return -EFAULT;
2984
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! */
2993 }
2994
2995 if ((sf = check_patch_opened(AWE_PAT_TYPE_MAP, NULL)) == NULL)
2996 return -ENOMEM;
2997
2998 if ((rec = alloc_new_info()) == NULL)
2999 return -ENOMEM;
3000
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;
3009 }
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);
3015
3016 return 0;
3017}
3018
3019#if 0
3020/* probe preset in the current list -- nothing to be loaded */
3021static int
3022awe_probe_info(awe_patch_info *patch, const char __user *addr, int count)
3023{
3024#ifdef AWE_ALLOW_SAMPLE_SHARING
3025 awe_voice_map map;
3026 awe_voice_list *p;
3027
3028 if (! patch_opened)
3029 return -EINVAL;
3030
3031 /* get the link info */
3032 if (count < sizeof(map)) {
3033 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3034 return -EINVAL;
3035 }
3036 if (copy_from_user(&map, addr + AWE_PATCH_INFO_SIZE, sizeof(map)))
3037 return -EFAULT;
3038
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! */
3049 }
3050#endif /* allow sharing */
3051 return -EINVAL;
3052}
3053#endif
3054
3055/* probe sample in the current list -- nothing to be loaded */
3056static int
3057awe_probe_data(awe_patch_info *patch, const char __user *addr, int count)
3058{
3059#ifdef AWE_ALLOW_SAMPLE_SHARING
3060 if (! patch_opened)
3061 return -EINVAL;
3062
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;
3068}
3069
3070
3071/* remove the present instrument layers */
3072static int
3073remove_info(sf_list *sf, int bank, int instr)
3074{
3075 awe_voice_list *prev, *next, *p;
3076 int removed = 0;
3077
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;
3095 }
3096 if (removed)
3097 rebuild_preset_list();
3098 return removed;
3099}
3100
3101/* load voice information data */
3102static int
3103awe_load_info(awe_patch_info *patch, const char __user *addr, int count)
3104{
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;
3111
3112 if (count < AWE_VOICE_REC_SIZE) {
3113 printk(KERN_WARNING "AWE32 Error: invalid patch info length\n");
3114 return -EINVAL;
3115 }
3116
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;
3121
3122 if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
3123 printk(KERN_WARNING "AWE32 Error: Invalid voice number %d\n", hdr.nvoices);
3124 return -EINVAL;
3125 }
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;
3131 }
3132
3133 if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
3134 return -ENOMEM;
3135
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;
3145 }
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;
3151 }
3152
3153 /* append new layers */
3154 for (i = 0; i < hdr.nvoices; i++) {
3155 rec = alloc_new_info();
3156 if (rec == NULL)
3157 return -ENOMEM;
3158
3159 rec->bank = hdr.bank;
3160 rec->instr = hdr.instr;
3161 rec->type = V_ST_NORMAL;
3162 rec->disabled = FALSE;
3163
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;
3168 }
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;
3175 }
3176 }
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);
3183 }
3184
3185 return 0;
3186}
3187
3188
3189/* remove instrument layers */
3190static int
3191awe_remove_info(awe_patch_info *patch, const char __user *addr, int count)
3192{
3193 unsigned char bank, instr;
3194 sf_list *sf;
3195
3196 if (! patch_opened || (sf = sftail) == NULL) {
3197 printk(KERN_WARNING "AWE32: remove_info: patch not opened\n");
3198 return -EINVAL;
3199 }
3200
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;
3206}
3207
3208
3209/* load wave sample data */
3210static int
3211awe_load_data(awe_patch_info *patch, const char __user *addr, int count)
3212{
3213 int offset, size;
3214 int rc;
3215 awe_sample_info tmprec;
3216 awe_sample_list *rec;
3217 sf_list *sf;
3218
3219 if ((sf = check_patch_opened(AWE_PAT_TYPE_MISC, NULL)) == NULL)
3220 return -ENOMEM;
3221
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;
3231 }
3232
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;
3241 }
3242
3243 if ((rec = alloc_new_sample()) == NULL)
3244 return -ENOMEM;
3245
3246 memcpy(&rec->v, &tmprec, sizeof(tmprec));
3247
3248 if (rec->v.size > 0) {
3249 if ((rc = awe_write_wave_data(addr, offset, rec, -1)) < 0) {
3250 kfree(rec);
3251 return rc;
3252 }
3253 sf->mem_ptr += rc;
3254 }
3255
3256 add_sf_sample(sf, rec);
3257 return 0;
3258}
3259
3260
3261/* replace wave sample data */
3262static int
3263awe_replace_data(awe_patch_info *patch, const char __user *addr, int count)
3264{
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;
3273
3274 if (! patch_opened || (sf = sftail) == NULL) {
3275 printk(KERN_WARNING "AWE32: replace: patch not opened\n");
3276 return -EINVAL;
3277 }
3278
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;
3288 }
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;
3293 }
3294
3295 for (rec = sf->samples; rec; rec = rec->next) {
3296 if (rec->v.sample == cursmp.sample)
3297 break;
3298 }
3299 if (rec == NULL) {
3300 printk(KERN_WARNING "AWE32: replace: cannot find existing sample data %d\n",
3301 cursmp.sample);
3302 return -EINVAL;
3303 }
3304
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;
3309 }
3310
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;
3318
3319 return 0;
3320}
3321
3322
3323/*----------------------------------------------------------------*/
3324
3325static const char __user *readbuf_addr;
3326static int readbuf_offs;
3327static int readbuf_flags;
3328
3329/* initialize read buffer */
3330static int
3331readbuf_init(const char __user *addr, int offset, awe_sample_info *sp)
3332{
3333 readbuf_addr = addr;
3334 readbuf_offs = offset;
3335 readbuf_flags = sp->mode_flags;
3336 return 0;
3337}
3338
3339/* read directly from user buffer */
3340static unsigned short
3341readbuf_word(int pos)
3342{
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));
3351 }
3352 if (readbuf_flags & AWE_SAMPLE_UNSIGNED)
3353 c ^= 0x8000; /* unsigned -> signed */
3354 return c;
3355}
3356
3357#define readbuf_word_cache readbuf_word
3358#define readbuf_end() /**/
3359
3360/*----------------------------------------------------------------*/
3361
3362#define BLANK_LOOP_START 8
3363#define BLANK_LOOP_END 40
3364#define BLANK_LOOP_SIZE 48
3365
3366/* loading onto memory - return the actual written size */
3367static int
3368awe_write_wave_data(const char __user *addr, int offset, awe_sample_list *list, int channels)
3369{
3370 int i, truesize, dram_offset;
3371 awe_sample_info *sp = &list->v;
3372 int rc;
3373
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;
3379 }
3380
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;
3390 }
3391
3392 /* recalculate address offset */
3393 sp->end -= sp->start;
3394 sp->loopstart -= sp->start;
3395 sp->loopend -= sp->start;
3396
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;
3402
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;
3408
3409 if ((rc = awe_open_dram_for_write(dram_offset, channels)) != 0)
3410 return rc;
3411
3412 if (readbuf_init(addr, offset, sp) < 0)
3413 return -ENOSPC;
3414
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);
3427 }
3428 if (sp->mode_flags & AWE_SAMPLE_BIDIR_LOOP) {
3429 sp->end += looplen;
3430 } else {
3431 sp->start += looplen;
3432 sp->end += looplen;
3433 }
3434 }
3435 }
3436 readbuf_end();
3437
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;
3445 }
3446 }
3447
3448 awe_close_dram();
3449
3450 /* initialize FM */
3451 awe_init_fm();
3452
3453 return truesize;
3454}
3455
3456
3457/*----------------------------------------------------------------*/
3458
3459#ifdef AWE_HAS_GUS_COMPATIBILITY
3460
3461/* calculate GUS envelope time:
3462 * is this correct? i have no idea..
3463 */
3464static int
3465calc_gus_envelope_time(int rate, int start, int end)
3466{
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);
3477}
3478
3479#define calc_gus_sustain(val) (0x7f - vol_table[(val)/2])
3480#define calc_gus_attenuation(val) vol_table[(val)/2]
3481
3482/* load GUS patch */
3483static int
3484awe_load_guspatch(const char __user *addr, int offs, int size, int pmgr_flag)
3485{
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;
3494
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;
3499 }
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;
3507 }
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;
3515 }
3516
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;
3524
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;
3538
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;
3546 }
3547 smp->checksum_flag = 0;
3548 smp->checksum = 0;
3549
3550 if ((rc = awe_write_wave_data(addr, sizeof_patch, smprec, -1)) < 0)
3551 return rc;
3552 sf->mem_ptr += rc;
3553 add_sf_sample(sf, smprec);
3554
3555 /* set up voice info */
3556 rec = &vrec->v;
3557 awe_init_voice_info(rec);
3558 rec->sample = sf->num_info; /* the last sample */
3559 rec->rate_offset = calc_rate_offset(patch.base_freq);
3560 note = freq_to_note(patch.base_note);
3561 rec->root = note / 100;
3562 rec->tune = -(note % 100);
3563 rec->low = freq_to_note(patch.low_note) / 100;
3564 rec->high = freq_to_note(patch.high_note) / 100;
3565 DEBUG(1,printk("AWE32: [gus base offset=%d, note=%d, range=%d-%d(%d-%d)]\n",
3566 rec->rate_offset, note,
3567 rec->low, rec->high,
3568 patch.low_note, patch.high_note));
3569 /* panning position; -128 - 127 => 0-127 */
3570 rec->pan = (patch.panning + 128) / 2;
3571
3572 /* detuning is ignored */
3573 /* 6points volume envelope */
3574 if (patch.mode & WAVE_ENVELOPES) {
3575 int attack, hold, decay, release;
3576 attack = calc_gus_envelope_time
3577 (patch.env_rate[0], 0, patch.env_offset[0]);
3578 hold = calc_gus_envelope_time
3579 (patch.env_rate[1], patch.env_offset[0],
3580 patch.env_offset[1]);
3581 decay = calc_gus_envelope_time
3582 (patch.env_rate[2], patch.env_offset[1],
3583 patch.env_offset[2]);
3584 release = calc_gus_envelope_time
3585 (patch.env_rate[3], patch.env_offset[1],
3586 patch.env_offset[4]);
3587 release += calc_gus_envelope_time
3588 (patch.env_rate[4], patch.env_offset[3],
3589 patch.env_offset[4]);
3590 release += calc_gus_envelope_time
3591 (patch.env_rate[5], patch.env_offset[4],
3592 patch.env_offset[5]);
3593 rec->parm.volatkhld = (calc_parm_hold(hold) << 8) |
3594 calc_parm_attack(attack);
3595 rec->parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
3596 calc_parm_decay(decay);
3597 rec->parm.volrelease = 0x8000 | calc_parm_decay(release);
3598 DEBUG(2,printk("AWE32: [gusenv atk=%d, hld=%d, dcy=%d, rel=%d]\n", attack, hold, decay, release));
3599 rec->attenuation = calc_gus_attenuation(patch.env_offset[0]);
3600 }
3601
3602 /* tremolo effect */
3603 if (patch.mode & WAVE_TREMOLO) {
3604 int rate = (patch.tremolo_rate * 1000 / 38) / 42;
3605 rec->parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
3606 DEBUG(2,printk("AWE32: [gusenv tremolo rate=%d, dep=%d, tremfrq=%x]\n",
3607 patch.tremolo_rate, patch.tremolo_depth,
3608 rec->parm.tremfrq));
3609 }
3610 /* vibrato effect */
3611 if (patch.mode & WAVE_VIBRATO) {
3612 int rate = (patch.vibrato_rate * 1000 / 38) / 42;
3613 rec->parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
3614 DEBUG(2,printk("AWE32: [gusenv vibrato rate=%d, dep=%d, tremfrq=%x]\n",
3615 patch.tremolo_rate, patch.tremolo_depth,
3616 rec->parm.tremfrq));
3617 }
3618
3619 /* scale_freq, scale_factor, volume, and fractions not implemented */
3620
3621 /* append to the tail of the list */
3622 vrec->bank = ctrls[AWE_MD_GUS_BANK];
3623 vrec->instr = patch.instr_no;
3624 vrec->disabled = FALSE;
3625 vrec->type = V_ST_NORMAL;
3626
3627 add_sf_info(sf, vrec);
3628 add_info_list(vrec);
3629
3630 /* set the voice index */
3631 awe_set_sample(vrec);
3632
3633 return 0;
3634}
3635
3636#endif /* AWE_HAS_GUS_COMPATIBILITY */
3637
3638/*
3639 * sample and voice list handlers
3640 */
3641
3642/* append this to the current sf list */
3643static void add_sf_info(sf_list *sf, awe_voice_list *rec)
3644{
3645 if (sf == NULL)
3646 return;
3647 rec->holder = sf;
3648 rec->v.sf_id = sf->sf_id;
3649 if (sf->last_infos)
3650 sf->last_infos->next = rec;
3651 else
3652 sf->infos = rec;
3653 sf->last_infos = rec;
3654 rec->next = NULL;
3655 sf->num_info++;
3656}
3657
3658/* prepend this sample to sf list */
3659static void add_sf_sample(sf_list *sf, awe_sample_list *rec)
3660{
3661 if (sf == NULL)
3662 return;
3663 rec->holder = sf;
3664 rec->v.sf_id = sf->sf_id;
3665 if (sf->last_samples)
3666 sf->last_samples->next = rec;
3667 else
3668 sf->samples = rec;
3669 sf->last_samples = rec;
3670 rec->next = NULL;
3671 sf->num_sample++;
3672}
3673
3674/* purge the old records which don't belong with the same file id */
3675static void purge_old_list(awe_voice_list *rec, awe_voice_list *next)
3676{
3677 rec->next_instr = next;
3678 if (rec->bank == AWE_DRUM_BANK) {
3679 /* remove samples with the same note range */
3680 awe_voice_list *cur, *prev = rec;
3681 int low = rec->v.low;
3682 int high = rec->v.high;
3683 for (cur = next; cur; cur = cur->next_instr) {
3684 if (cur->v.low == low &&
3685 cur->v.high == high &&
3686 ! is_identical_holder(cur->holder, rec->holder))
3687 prev->next_instr = cur->next_instr;
3688 else
3689 prev = cur;
3690 }
3691 } else {
3692 if (! is_identical_holder(next->holder, rec->holder))
3693 /* remove all samples */
3694 rec->next_instr = NULL;
3695 }
3696}
3697
3698/* prepend to top of the preset table */
3699static void add_info_list(awe_voice_list *rec)
3700{
3701 awe_voice_list *prev, *cur;
3702 int key;
3703
3704 if (rec->disabled)
3705 return;
3706
3707 key = awe_search_key(rec->bank, rec->instr, rec->v.low);
3708 prev = NULL;
3709 for (cur = preset_table[key]; cur; cur = cur->next_bank) {
3710 /* search the first record with the same bank number */
3711 if (cur->instr == rec->instr && cur->bank == rec->bank) {
3712 /* replace the list with the new record */
3713 rec->next_bank = cur->next_bank;
3714 if (prev)
3715 prev->next_bank = rec;
3716 else
3717 preset_table[key] = rec;
3718 purge_old_list(rec, cur);
3719 return;
3720 }
3721 prev = cur;
3722 }
3723
3724 /* this is the first bank record.. just add this */
3725 rec->next_instr = NULL;
3726 rec->next_bank = preset_table[key];
3727 preset_table[key] = rec;
3728}
3729
3730/* remove samples later than the specified sf_id */
3731static void
3732awe_remove_samples(int sf_id)
3733{
3734 sf_list *p, *prev;
3735
3736 if (sf_id <= 0) {
3737 awe_reset_samples();
3738 return;
3739 }
3740 /* already removed? */
3741 if (current_sf_id <= sf_id)
3742 return;
3743
3744 for (p = sftail; p; p = prev) {
3745 if (p->sf_id <= sf_id)
3746 break;
3747 prev = p->prev;
3748 awe_free_sf(p);
3749 }
3750 sftail = p;
3751 if (sftail) {
3752 sf_id = sftail->sf_id;
3753 sftail->next = NULL;
3754 } else {
3755 sf_id = 0;
3756 sfhead = NULL;
3757 }
3758 current_sf_id = sf_id;
3759 if (locked_sf_id > sf_id)
3760 locked_sf_id = sf_id;
3761
3762 rebuild_preset_list();
3763}
3764
3765/* rebuild preset search list */
3766static void rebuild_preset_list(void)
3767{
3768 sf_list *p;
3769 awe_voice_list *rec;
3770
3771 memset(preset_table, 0, sizeof(preset_table));
3772
3773 for (p = sfhead; p; p = p->next) {
3774 for (rec = p->infos; rec; rec = rec->next)
3775 add_info_list(rec);
3776 }
3777}
3778
3779/* compare the given sf_id pair */
3780static int is_identical_holder(sf_list *sf1, sf_list *sf2)
3781{
3782 if (sf1 == NULL || sf2 == NULL)
3783 return FALSE;
3784 if (sf1 == sf2)
3785 return TRUE;
3786#ifdef AWE_ALLOW_SAMPLE_SHARING
3787 {
3788 /* compare with the sharing id */
3789 sf_list *p;
3790 int counter = 0;
3791 if (sf1->sf_id < sf2->sf_id) { /* make sure id1 > id2 */
3792 sf_list *tmp; tmp = sf1; sf1 = sf2; sf2 = tmp;
3793 }
3794 for (p = sf1->shared; p; p = p->shared) {
3795 if (counter++ > current_sf_id)
3796 break; /* strange sharing loop.. quit */
3797 if (p == sf2)
3798 return TRUE;
3799 }
3800 }
3801#endif /* allow sharing */
3802 return FALSE;
3803}
3804
3805/* search the sample index matching with the given sample id */
3806static awe_sample_list *
3807search_sample_index(sf_list *sf, int sample)
3808{
3809 awe_sample_list *p;
3810#ifdef AWE_ALLOW_SAMPLE_SHARING
3811 int counter = 0;
3812 while (sf) {
3813 for (p = sf->samples; p; p = p->next) {
3814 if (p->v.sample == sample)
3815 return p;
3816 }
3817 sf = sf->shared;
3818 if (counter++ > current_sf_id)
3819 break; /* strange sharing loop.. quit */
3820 }
3821#else
3822 if (sf) {
3823 for (p = sf->samples; p; p = p->next) {
3824 if (p->v.sample == sample)
3825 return p;
3826 }
3827 }
3828#endif
3829 return NULL;
3830}
3831
3832/* search the specified sample */
3833/* non-zero = found */
3834static short
3835awe_set_sample(awe_voice_list *rec)
3836{
3837 awe_sample_list *smp;
3838 awe_voice_info *vp = &rec->v;
3839
3840 vp->index = 0;
3841 if ((smp = search_sample_index(rec->holder, vp->sample)) == NULL)
3842 return 0;
3843
3844 /* set the actual sample offsets */
3845 vp->start += smp->v.start;
3846 vp->end += smp->v.end;
3847 vp->loopstart += smp->v.loopstart;
3848 vp->loopend += smp->v.loopend;
3849 /* copy mode flags */
3850 vp->mode = smp->v.mode_flags;
3851 /* set flag */
3852 vp->index = 1;
3853
3854 return 1;
3855}
3856
3857
3858/*
3859 * voice allocation
3860 */
3861
3862/* look for all voices associated with the specified note & velocity */
3863static int
3864awe_search_multi_voices(awe_voice_list *rec, int note, int velocity,
3865 awe_voice_info **vlist)
3866{
3867 int nvoices;
3868
3869 nvoices = 0;
3870 for (; rec; rec = rec->next_instr) {
3871 if (note >= rec->v.low &&
3872 note <= rec->v.high &&
3873 velocity >= rec->v.vellow &&
3874 velocity <= rec->v.velhigh) {
3875 if (rec->type == V_ST_MAPPED) {
3876 /* mapper */
3877 vlist[0] = &rec->v;
3878 return -1;
3879 }
3880 vlist[nvoices++] = &rec->v;
3881 if (nvoices >= AWE_MAX_VOICES)
3882 break;
3883 }
3884 }
3885 return nvoices;
3886}
3887
3888/* store the voice list from the specified note and velocity.
3889 if the preset is mapped, seek for the destination preset, and rewrite
3890 the note number if necessary.
3891 */
3892static int
3893really_alloc_voices(int bank, int instr, int *note, int velocity, awe_voice_info **vlist)
3894{
3895 int nvoices;
3896 awe_voice_list *vrec;
3897 int level = 0;
3898
3899 for (;;) {
3900 vrec = awe_search_instr(bank, instr, *note);
3901 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3902 if (nvoices == 0) {
3903 if (bank == AWE_DRUM_BANK)
3904 /* search default drumset */
3905 vrec = awe_search_instr(bank, ctrls[AWE_MD_DEF_DRUM], *note);
3906 else
3907 /* search default preset */
3908 vrec = awe_search_instr(ctrls[AWE_MD_DEF_BANK], instr, *note);
3909 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3910 }
3911 if (nvoices == 0) {
3912 if (bank == AWE_DRUM_BANK && ctrls[AWE_MD_DEF_DRUM] != 0)
3913 /* search default drumset */
3914 vrec = awe_search_instr(bank, 0, *note);
3915 else if (bank != AWE_DRUM_BANK && ctrls[AWE_MD_DEF_BANK] != 0)
3916 /* search default preset */
3917 vrec = awe_search_instr(0, instr, *note);
3918 nvoices = awe_search_multi_voices(vrec, *note, velocity, vlist);
3919 }
3920 if (nvoices < 0) { /* mapping */
3921 int key = vlist[0]->fixkey;
3922 instr = vlist[0]->start;
3923 bank = vlist[0]->end;
3924 if (level++ > 5) {
3925 printk(KERN_ERR "AWE32: too deep mapping level\n");
3926 return 0;
3927 }
3928 if (key >= 0)
3929 *note = key;
3930 } else
3931 break;
3932 }
3933
3934 return nvoices;
3935}
3936
3937/* allocate voices corresponding note and velocity; supports multiple insts. */
3938static void
3939awe_alloc_multi_voices(int ch, int note, int velocity, int key)
3940{
3941 int i, v, nvoices, bank;
3942 awe_voice_info *vlist[AWE_MAX_VOICES];
3943
3944 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(ch))
3945 bank = AWE_DRUM_BANK; /* always search drumset */
3946 else
3947 bank = channels[ch].bank;
3948
3949 /* check the possible voices; note may be changeable if mapped */
3950 nvoices = really_alloc_voices(bank, channels[ch].instr,
3951 &note, velocity, vlist);
3952
3953 /* set the voices */
3954 current_alloc_time++;
3955 for (i = 0; i < nvoices; i++) {
3956 v = awe_clear_voice();
3957 voices[v].key = key;
3958 voices[v].ch = ch;
3959 voices[v].note = note;
3960 voices[v].velocity = velocity;
3961 voices[v].time = current_alloc_time;
3962 voices[v].cinfo = &channels[ch];
3963 voices[v].sample = vlist[i];
3964 voices[v].state = AWE_ST_MARK;
3965 voices[v].layer = nvoices - i - 1; /* in reverse order */
3966 }
3967
3968 /* clear the mark in allocated voices */
3969 for (i = 0; i < awe_max_voices; i++) {
3970 if (voices[i].state == AWE_ST_MARK)
3971 voices[i].state = AWE_ST_OFF;
3972
3973 }
3974}
3975
3976
3977/* search an empty voice.
3978 if no empty voice is found, at least terminate a voice
3979 */
3980static int
3981awe_clear_voice(void)
3982{
3983 enum {
3984 OFF=0, RELEASED, SUSTAINED, PLAYING, END
3985 };
3986 struct voice_candidate_t {
3987 int best;
3988 int time;
3989 int vtarget;
3990 } candidate[END];
3991 int i, type, vtarget;
3992
3993 vtarget = 0xffff;
3994 for (type = OFF; type < END; type++) {
3995 candidate[type].best = -1;
3996 candidate[type].time = current_alloc_time + 1;
3997 candidate[type].vtarget = vtarget;
3998 }
3999
4000 for (i = 0; i < awe_max_voices; i++) {
4001 if (voices[i].state & AWE_ST_OFF)
4002 type = OFF;
4003 else if (voices[i].state & AWE_ST_RELEASED)
4004 type = RELEASED;
4005 else if (voices[i].state & AWE_ST_SUSTAINED)
4006 type = SUSTAINED;
4007 else if (voices[i].state & ~AWE_ST_MARK)
4008 type = PLAYING;
4009 else
4010 continue;
4011#ifdef AWE_CHECK_VTARGET
4012 /* get current volume */
4013 vtarget = (awe_peek_dw(AWE_VTFT(i)) >> 16) & 0xffff;
4014#endif
4015 if (candidate[type].best < 0 ||
4016 vtarget < candidate[type].vtarget ||
4017 (vtarget == candidate[type].vtarget &&
4018 voices[i].time < candidate[type].time)) {
4019 candidate[type].best = i;
4020 candidate[type].time = voices[i].time;
4021 candidate[type].vtarget = vtarget;
4022 }
4023 }
4024
4025 for (type = OFF; type < END; type++) {
4026 if ((i = candidate[type].best) >= 0) {
4027 if (voices[i].state != AWE_ST_OFF)
4028 awe_terminate(i);
4029 awe_voice_init(i, TRUE);
4030 return i;
4031 }
4032 }
4033 return 0;
4034}
4035
4036
4037/* search sample for the specified note & velocity and set it on the voice;
4038 * note that voice is the voice index (not channel index)
4039 */
4040static void
4041awe_alloc_one_voice(int voice, int note, int velocity)
4042{
4043 int ch, nvoices, bank;
4044 awe_voice_info *vlist[AWE_MAX_VOICES];
4045
4046 ch = voices[voice].ch;
4047 if (MULTI_LAYER_MODE() && IS_DRUM_CHANNEL(voice))
4048 bank = AWE_DRUM_BANK; /* always search drumset */
4049 else
4050 bank = voices[voice].cinfo->bank;
4051
4052 nvoices = really_alloc_voices(bank, voices[voice].cinfo->instr,
4053 &note, velocity, vlist);
4054 if (nvoices > 0) {
4055 voices[voice].time = ++current_alloc_time;
4056 voices[voice].sample = vlist[0]; /* use the first one */
4057 voices[voice].layer = 0;
4058 voices[voice].note = note;
4059 voices[voice].velocity = velocity;
4060 }
4061}
4062
4063
4064/*
4065 * sequencer2 functions
4066 */
4067
4068/* search an empty voice; used by sequencer2 */
4069static int
4070awe_alloc(int dev, int chn, int note, struct voice_alloc_info *alloc)
4071{
4072 playing_mode = AWE_PLAY_MULTI2;
4073 awe_info.nr_voices = AWE_MAX_CHANNELS;
4074 return awe_clear_voice();
4075}
4076
4077
4078/* set up voice; used by sequencer2 */
4079static void
4080awe_setup_voice(int dev, int voice, int chn)
4081{
4082 struct channel_info *info;
4083 if (synth_devs[dev] == NULL ||
4084 (info = &synth_devs[dev]->chn_info[chn]) == NULL)
4085 return;
4086
4087 if (voice < 0 || voice >= awe_max_voices)
4088 return;
4089
4090 DEBUG(2,printk("AWE32: [setup(%d) ch=%d]\n", voice, chn));
4091 channels[chn].expression_vol = info->controllers[CTL_EXPRESSION];
4092 channels[chn].main_vol = info->controllers[CTL_MAIN_VOLUME];
4093 channels[chn].panning =
4094 info->controllers[CTL_PAN] * 2 - 128; /* signed 8bit */
4095 channels[chn].bender = info->bender_value; /* zero center */
4096 channels[chn].bank = info->controllers[CTL_BANK_SELECT];
4097 channels[chn].sustained = info->controllers[CTL_SUSTAIN];
4098 if (info->controllers[CTL_EXT_EFF_DEPTH]) {
4099 FX_SET(&channels[chn].fx, AWE_FX_REVERB,
4100 info->controllers[CTL_EXT_EFF_DEPTH] * 2);
4101 }
4102 if (info->controllers[CTL_CHORUS_DEPTH]) {
4103 FX_SET(&channels[chn].fx, AWE_FX_CHORUS,
4104 info->controllers[CTL_CHORUS_DEPTH] * 2);
4105 }
4106 awe_set_instr(dev, chn, info->pgm_num);
4107}
4108
4109
4110#ifdef CONFIG_AWE32_MIXER
4111/*
4112 * AWE32 mixer device control
4113 */
4114
4115static int awe_mixer_ioctl(int dev, unsigned int cmd, void __user *arg);
4116
4117static int my_mixerdev = -1;
4118
4119static struct mixer_operations awe_mixer_operations = {
4120 .owner = THIS_MODULE,
4121 .id = "AWE",
4122 .name = "AWE32 Equalizer",
4123 .ioctl = awe_mixer_ioctl,
4124};
4125
4126static void __init attach_mixer(void)
4127{
4128 if ((my_mixerdev = sound_alloc_mixerdev()) >= 0) {
4129 mixer_devs[my_mixerdev] = &awe_mixer_operations;
4130 }
4131}
4132
4133static void unload_mixer(void)
4134{
4135 if (my_mixerdev >= 0)
4136 sound_unload_mixerdev(my_mixerdev);
4137}
4138
4139static int
4140awe_mixer_ioctl(int dev, unsigned int cmd, void __user * arg)
4141{
4142 int i, level, value;
4143
4144 if (((cmd >> 8) & 0xff) != 'M')
4145 return -EINVAL;
4146
4147 if (get_user(level, (int __user *)arg))
4148 return -EFAULT;
4149 level = ((level & 0xff) + (level >> 8)) / 2;
4150 DEBUG(0,printk("AWEMix: cmd=%x val=%d\n", cmd & 0xff, level));
4151
4152 if (_SIOC_DIR(cmd) & _SIOC_WRITE) {
4153 switch (cmd & 0xff) {
4154 case SOUND_MIXER_BASS:
4155 value = level * 12 / 100;
4156 if (value >= 12)
4157 value = 11;
4158 ctrls[AWE_MD_BASS_LEVEL] = value;
4159 awe_update_equalizer();
4160 break;
4161 case SOUND_MIXER_TREBLE:
4162 value = level * 12 / 100;
4163 if (value >= 12)
4164 value = 11;
4165 ctrls[AWE_MD_TREBLE_LEVEL] = value;
4166 awe_update_equalizer();
4167 break;
4168 case SOUND_MIXER_VOLUME:
4169 level = level * 127 / 100;
4170 if (level >= 128) level = 127;
4171 atten_relative = FALSE;
4172 atten_offset = vol_table[level];
4173 awe_update_volume();
4174 break;
4175 }
4176 }
4177 switch (cmd & 0xff) {
4178 case SOUND_MIXER_BASS:
4179 level = ctrls[AWE_MD_BASS_LEVEL] * 100 / 24;
4180 level = (level << 8) | level;
4181 break;
4182 case SOUND_MIXER_TREBLE:
4183 level = ctrls[AWE_MD_TREBLE_LEVEL] * 100 / 24;
4184 level = (level << 8) | level;
4185 break;
4186 case SOUND_MIXER_VOLUME:
4187 value = atten_offset;
4188 if (atten_relative)
4189 value += ctrls[AWE_MD_ZERO_ATTEN];
4190 for (i = 127; i > 0; i--) {
4191 if (value <= vol_table[i])
4192 break;
4193 }
4194 level = i * 100 / 127;
4195 level = (level << 8) | level;
4196 break;
4197 case SOUND_MIXER_DEVMASK:
4198 level = SOUND_MASK_BASS|SOUND_MASK_TREBLE|SOUND_MASK_VOLUME;
4199 break;
4200 default:
4201 level = 0;
4202 break;
4203 }
4204 if (put_user(level, (int __user *)arg))
4205 return -EFAULT;
4206 return level;
4207}
4208#endif /* CONFIG_AWE32_MIXER */
4209
4210
4211/*
4212 * initialization of Emu8000
4213 */
4214
4215/* intiailize audio channels */
4216static void
4217awe_init_audio(void)
4218{
4219 int ch;
4220
4221 /* turn off envelope engines */
4222 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4223 awe_poke(AWE_DCYSUSV(ch), 0x80);
4224 }
4225
4226 /* reset all other parameters to zero */
4227 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4228 awe_poke(AWE_ENVVOL(ch), 0);
4229 awe_poke(AWE_ENVVAL(ch), 0);
4230 awe_poke(AWE_DCYSUS(ch), 0);
4231 awe_poke(AWE_ATKHLDV(ch), 0);
4232 awe_poke(AWE_LFO1VAL(ch), 0);
4233 awe_poke(AWE_ATKHLD(ch), 0);
4234 awe_poke(AWE_LFO2VAL(ch), 0);
4235 awe_poke(AWE_IP(ch), 0);
4236 awe_poke(AWE_IFATN(ch), 0);
4237 awe_poke(AWE_PEFE(ch), 0);
4238 awe_poke(AWE_FMMOD(ch), 0);
4239 awe_poke(AWE_TREMFRQ(ch), 0);
4240 awe_poke(AWE_FM2FRQ2(ch), 0);
4241 awe_poke_dw(AWE_PTRX(ch), 0);
4242 awe_poke_dw(AWE_VTFT(ch), 0);
4243 awe_poke_dw(AWE_PSST(ch), 0);
4244 awe_poke_dw(AWE_CSL(ch), 0);
4245 awe_poke_dw(AWE_CCCA(ch), 0);
4246 }
4247
4248 for (ch = 0; ch < AWE_MAX_VOICES; ch++) {
4249 awe_poke_dw(AWE_CPF(ch), 0);
4250 awe_poke_dw(AWE_CVCF(ch), 0);
4251 }
4252}
4253
4254
4255/* initialize DMA address */
4256static void
4257awe_init_dma(void)
4258{
4259 awe_poke_dw(AWE_SMALR, 0);
4260 awe_poke_dw(AWE_SMARR, 0);
4261 awe_poke_dw(AWE_SMALW, 0);
4262 awe_poke_dw(AWE_SMARW, 0);
4263}
4264
4265
4266/* initialization arrays; from ADIP */
4267
4268static unsigned short init1[128] = {
4269 0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330,
4270 0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730,
4271 0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30,
4272 0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30,
4273
4274 0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330,
4275 0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730,
4276 0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30,
4277 0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30,
4278
4279 0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330,
4280 0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730,
4281 0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30,
4282 0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30,
4283
4284 0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330,
4285 0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730,
4286 0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30,
4287 0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30,
4288};
4289
4290static unsigned short init2[128] = {
4291 0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
4292 0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
4293 0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
4294 0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
4295
4296 0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
4297 0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
4298 0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
4299 0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
4300
4301 0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
4302 0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
4303 0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
4304 0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
4305
4306 0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
4307 0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
4308 0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
4309 0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
4310};
4311
4312static unsigned short init3[128] = {
4313 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4314 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
4315 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
4316 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
4317
4318 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
4319 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
4320 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
4321 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
4322
4323 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
4324 0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
4325 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
4326 0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
4327
4328 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
4329 0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
4330 0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
4331 0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
4332};
4333
4334static unsigned short init4[128] = {
4335 0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
4336 0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
4337 0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
4338 0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
4339
4340 0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
4341 0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
4342 0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
4343 0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
4344
4345 0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
4346 0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
4347 0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
4348 0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
4349
4350 0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
4351 0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
4352 0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
4353 0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
4354};
4355
4356
4357/* send initialization arrays to start up */
4358static void
4359awe_init_array(void)
4360{
4361 awe_send_array(init1);
4362 awe_wait(1024);
4363 awe_send_array(init2);
4364 awe_send_array(init3);
4365 awe_poke_dw(AWE_HWCF4, 0);
4366 awe_poke_dw(AWE_HWCF5, 0x83);
4367 awe_poke_dw(AWE_HWCF6, 0x8000);
4368 awe_send_array(init4);
4369}
4370
4371/* send an initialization array */
4372static void
4373awe_send_array(unsigned short *data)
4374{
4375 int i;
4376 unsigned short *p;
4377
4378 p = data;
4379 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4380 awe_poke(AWE_INIT1(i), *p);
4381 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4382 awe_poke(AWE_INIT2(i), *p);
4383 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4384 awe_poke(AWE_INIT3(i), *p);
4385 for (i = 0; i < AWE_MAX_VOICES; i++, p++)
4386 awe_poke(AWE_INIT4(i), *p);
4387}
4388
4389
4390/*
4391 * set up awe32 channels to some known state.
4392 */
4393
4394/* set the envelope & LFO parameters to the default values; see ADIP */
4395static void
4396awe_tweak_voice(int i)
4397{
4398 /* set all mod/vol envelope shape to minimum */
4399 awe_poke(AWE_ENVVOL(i), 0x8000);
4400 awe_poke(AWE_ENVVAL(i), 0x8000);
4401 awe_poke(AWE_DCYSUS(i), 0x7F7F);
4402 awe_poke(AWE_ATKHLDV(i), 0x7F7F);
4403 awe_poke(AWE_ATKHLD(i), 0x7F7F);
4404 awe_poke(AWE_PEFE(i), 0); /* mod envelope height to zero */
4405 awe_poke(AWE_LFO1VAL(i), 0x8000); /* no delay for LFO1 */
4406 awe_poke(AWE_LFO2VAL(i), 0x8000);
4407 awe_poke(AWE_IP(i), 0xE000); /* no pitch shift */
4408 awe_poke(AWE_IFATN(i), 0xFF00); /* volume to minimum */
4409 awe_poke(AWE_FMMOD(i), 0);
4410 awe_poke(AWE_TREMFRQ(i), 0);
4411 awe_poke(AWE_FM2FRQ2(i), 0);
4412}
4413
4414static void
4415awe_tweak(void)
4416{
4417 int i;
4418 /* reset all channels */
4419 for (i = 0; i < awe_max_voices; i++)
4420 awe_tweak_voice(i);
4421}
4422
4423
4424/*
4425 * initializes the FM section of AWE32;
4426 * see Vince Vu's unofficial AWE32 programming guide
4427 */
4428
4429static void
4430awe_init_fm(void)
4431{
4432#ifndef AWE_ALWAYS_INIT_FM
4433 /* if no extended memory is on board.. */
4434 if (memsize <= 0)
4435 return;
4436#endif
4437 DEBUG(3,printk("AWE32: initializing FM\n"));
4438
4439 /* Initialize the last two channels for DRAM refresh and producing
4440 the reverb and chorus effects for Yamaha OPL-3 synthesizer */
4441
4442 /* 31: FM left channel, 0xffffe0-0xffffe8 */
4443 awe_poke(AWE_DCYSUSV(30), 0x80);
4444 awe_poke_dw(AWE_PSST(30), 0xFFFFFFE0); /* full left */
4445 awe_poke_dw(AWE_CSL(30), 0x00FFFFE8 |
4446 (DEF_FM_CHORUS_DEPTH << 24));
4447 awe_poke_dw(AWE_PTRX(30), (DEF_FM_REVERB_DEPTH << 8));
4448 awe_poke_dw(AWE_CPF(30), 0);
4449 awe_poke_dw(AWE_CCCA(30), 0x00FFFFE3);
4450
4451 /* 32: FM right channel, 0xfffff0-0xfffff8 */
4452 awe_poke(AWE_DCYSUSV(31), 0x80);
4453 awe_poke_dw(AWE_PSST(31), 0x00FFFFF0); /* full right */
4454 awe_poke_dw(AWE_CSL(31), 0x00FFFFF8 |
4455 (DEF_FM_CHORUS_DEPTH << 24));
4456 awe_poke_dw(AWE_PTRX(31), (DEF_FM_REVERB_DEPTH << 8));
4457 awe_poke_dw(AWE_CPF(31), 0x8000);
4458 awe_poke_dw(AWE_CCCA(31), 0x00FFFFF3);
4459
4460 /* skew volume & cutoff */
4461 awe_poke_dw(AWE_VTFT(30), 0x8000FFFF);
4462 awe_poke_dw(AWE_VTFT(31), 0x8000FFFF);
4463
4464 voices[30].state = AWE_ST_FM;
4465 voices[31].state = AWE_ST_FM;
4466
4467 /* change maximum channels to 30 */
4468 awe_max_voices = AWE_NORMAL_VOICES;
4469 if (playing_mode == AWE_PLAY_DIRECT)
4470 awe_info.nr_voices = awe_max_voices;
4471 else
4472 awe_info.nr_voices = AWE_MAX_CHANNELS;
4473 voice_alloc->max_voice = awe_max_voices;
4474}
4475
4476/*
4477 * AWE32 DRAM access routines
4478 */
4479
4480/* open DRAM write accessing mode */
4481static int
4482awe_open_dram_for_write(int offset, int channels)
4483{
4484 int vidx[AWE_NORMAL_VOICES];
4485 int i;
4486
4487 if (channels < 0 || channels >= AWE_NORMAL_VOICES) {
4488 channels = AWE_NORMAL_VOICES;
4489 for (i = 0; i < AWE_NORMAL_VOICES; i++)
4490 vidx[i] = i;
4491 } else {
4492 for (i = 0; i < channels; i++) {
4493 vidx[i] = awe_clear_voice();
4494 voices[vidx[i]].state = AWE_ST_MARK;
4495 }
4496 }
4497
4498 /* use all channels for DMA transfer */
4499 for (i = 0; i < channels; i++) {
4500 if (vidx[i] < 0) continue;
4501 awe_poke(AWE_DCYSUSV(vidx[i]), 0x80);
4502 awe_poke_dw(AWE_VTFT(vidx[i]), 0);
4503 awe_poke_dw(AWE_CVCF(vidx[i]), 0);
4504 awe_poke_dw(AWE_PTRX(vidx[i]), 0x40000000);
4505 awe_poke_dw(AWE_CPF(vidx[i]), 0x40000000);
4506 awe_poke_dw(AWE_PSST(vidx[i]), 0);
4507 awe_poke_dw(AWE_CSL(vidx[i]), 0);
4508 awe_poke_dw(AWE_CCCA(vidx[i]), 0x06000000);
4509 voices[vidx[i]].state = AWE_ST_DRAM;
4510 }
4511 /* point channels 31 & 32 to ROM samples for DRAM refresh */
4512 awe_poke_dw(AWE_VTFT(30), 0);
4513 awe_poke_dw(AWE_PSST(30), 0x1d8);
4514 awe_poke_dw(AWE_CSL(30), 0x1e0);
4515 awe_poke_dw(AWE_CCCA(30), 0x1d8);
4516 awe_poke_dw(AWE_VTFT(31), 0);
4517 awe_poke_dw(AWE_PSST(31), 0x1d8);
4518 awe_poke_dw(AWE_CSL(31), 0x1e0);
4519 awe_poke_dw(AWE_CCCA(31), 0x1d8);
4520 voices[30].state = AWE_ST_FM;
4521 voices[31].state = AWE_ST_FM;
4522
4523 /* if full bit is on, not ready to write on */
4524 if (awe_peek_dw(AWE_SMALW) & 0x80000000) {
4525 for (i = 0; i < channels; i++) {
4526 awe_poke_dw(AWE_CCCA(vidx[i]), 0);
4527 voices[vidx[i]].state = AWE_ST_OFF;
4528 }
4529 printk("awe: not ready to write..\n");
4530 return -EPERM;
4531 }
4532
4533 /* set address to write */
4534 awe_poke_dw(AWE_SMALW, offset);
4535
4536 return 0;
4537}
4538
4539/* open DRAM for RAM size detection */
4540static void
4541awe_open_dram_for_check(void)
4542{
4543 int i;
4544 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4545 awe_poke(AWE_DCYSUSV(i), 0x80);
4546 awe_poke_dw(AWE_VTFT(i), 0);
4547 awe_poke_dw(AWE_CVCF(i), 0);
4548 awe_poke_dw(AWE_PTRX(i), 0x40000000);
4549 awe_poke_dw(AWE_CPF(i), 0x40000000);
4550 awe_poke_dw(AWE_PSST(i), 0);
4551 awe_poke_dw(AWE_CSL(i), 0);
4552 if (i & 1) /* DMA write */
4553 awe_poke_dw(AWE_CCCA(i), 0x06000000);
4554 else /* DMA read */
4555 awe_poke_dw(AWE_CCCA(i), 0x04000000);
4556 voices[i].state = AWE_ST_DRAM;
4557 }
4558}
4559
4560
4561/* close dram access */
4562static void
4563awe_close_dram(void)
4564{
4565 int i;
4566 /* wait until FULL bit in SMAxW register be false */
4567 for (i = 0; i < 10000; i++) {
4568 if (!(awe_peek_dw(AWE_SMALW) & 0x80000000))
4569 break;
4570 awe_wait(10);
4571 }
4572
4573 for (i = 0; i < AWE_NORMAL_VOICES; i++) {
4574 if (voices[i].state == AWE_ST_DRAM) {
4575 awe_poke_dw(AWE_CCCA(i), 0);
4576 awe_poke(AWE_DCYSUSV(i), 0x807F);
4577 voices[i].state = AWE_ST_OFF;
4578 }
4579 }
4580}
4581
4582
4583/*
4584 * check dram size on AWE board
4585 */
4586
4587/* any three numbers you like */
4588#define UNIQUE_ID1 0x1234
4589#define UNIQUE_ID2 0x4321
4590#define UNIQUE_ID3 0xABCD
4591
4592static void __init
4593awe_check_dram(void)
4594{
4595 if (awe_present) /* already initialized */
4596 return;
4597
4598 if (memsize >= 0) { /* given by config file or module option */
4599 memsize *= 1024; /* convert to Kbytes */
4600 return;
4601 }
4602
4603 awe_open_dram_for_check();
4604
4605 memsize = 0;
4606
4607 /* set up unique two id numbers */
4608 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET);
4609 awe_poke(AWE_SMLD, UNIQUE_ID1);
4610 awe_poke(AWE_SMLD, UNIQUE_ID2);
4611
4612 while (memsize < AWE_MAX_DRAM_SIZE) {
4613 awe_wait(5);
4614 /* read a data on the DRAM start address */
4615 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET);
4616 awe_peek(AWE_SMLD); /* discard stale data */
4617 if (awe_peek(AWE_SMLD) != UNIQUE_ID1)
4618 break;
4619 if (awe_peek(AWE_SMLD) != UNIQUE_ID2)
4620 break;
4621 memsize += 512; /* increment 512kbytes */
4622 /* Write a unique data on the test address;
4623 * if the address is out of range, the data is written on
4624 * 0x200000(=AWE_DRAM_OFFSET). Then the two id words are
4625 * broken by this data.
4626 */
4627 awe_poke_dw(AWE_SMALW, AWE_DRAM_OFFSET + memsize*512L);
4628 awe_poke(AWE_SMLD, UNIQUE_ID3);
4629 awe_wait(5);
4630 /* read a data on the just written DRAM address */
4631 awe_poke_dw(AWE_SMALR, AWE_DRAM_OFFSET + memsize*512L);
4632 awe_peek(AWE_SMLD); /* discard stale data */
4633 if (awe_peek(AWE_SMLD) != UNIQUE_ID3)
4634 break;
4635 }
4636 awe_close_dram();
4637
4638 DEBUG(0,printk("AWE32: %d Kbytes memory detected\n", memsize));
4639
4640 /* convert to Kbytes */
4641 memsize *= 1024;
4642}
4643
4644
4645/*----------------------------------------------------------------*/
4646
4647/*
4648 * chorus and reverb controls; from VV's guide
4649 */
4650
4651/* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
4652static char chorus_defined[AWE_CHORUS_NUMBERS];
4653static awe_chorus_fx_rec chorus_parm[AWE_CHORUS_NUMBERS] = {
4654 {0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
4655 {0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
4656 {0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
4657 {0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
4658 {0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
4659 {0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
4660 {0xE600, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay */
4661 {0xE6C0, 0x0B06, 0xBC00, 0x0000E000, 0x00000083}, /* short delay + feedback */
4662};
4663
4664static int
4665awe_load_chorus_fx(awe_patch_info *patch, const char __user *addr, int count)
4666{
4667 if (patch->optarg < AWE_CHORUS_PREDEFINED || patch->optarg >= AWE_CHORUS_NUMBERS) {
4668 printk(KERN_WARNING "AWE32 Error: invalid chorus mode %d for uploading\n", patch->optarg);
4669 return -EINVAL;
4670 }
4671 if (count < sizeof(awe_chorus_fx_rec)) {
4672 printk(KERN_WARNING "AWE32 Error: too short chorus fx parameters\n");
4673 return -EINVAL;
4674 }
4675 if (copy_from_user(&chorus_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
4676 sizeof(awe_chorus_fx_rec)))
4677 return -EFAULT;
4678 chorus_defined[patch->optarg] = TRUE;
4679 return 0;
4680}
4681
4682static void
4683awe_set_chorus_mode(int effect)
4684{
4685 if (effect < 0 || effect >= AWE_CHORUS_NUMBERS ||
4686 (effect >= AWE_CHORUS_PREDEFINED && !chorus_defined[effect]))
4687 return;
4688 awe_poke(AWE_INIT3(9), chorus_parm[effect].feedback);
4689 awe_poke(AWE_INIT3(12), chorus_parm[effect].delay_offset);
4690 awe_poke(AWE_INIT4(3), chorus_parm[effect].lfo_depth);
4691 awe_poke_dw(AWE_HWCF4, chorus_parm[effect].delay);
4692 awe_poke_dw(AWE_HWCF5, chorus_parm[effect].lfo_freq);
4693 awe_poke_dw(AWE_HWCF6, 0x8000);
4694 awe_poke_dw(AWE_HWCF7, 0x0000);
4695}
4696
4697static void
4698awe_update_chorus_mode(void)
4699{
4700 awe_set_chorus_mode(ctrls[AWE_MD_CHORUS_MODE]);
4701}
4702
4703/*----------------------------------------------------------------*/
4704
4705/* reverb mode settings; write the following 28 data of 16 bit length
4706 * on the corresponding ports in the reverb_cmds array
4707 */
4708static char reverb_defined[AWE_CHORUS_NUMBERS];
4709static awe_reverb_fx_rec reverb_parm[AWE_REVERB_NUMBERS] = {
4710{{ /* room 1 */
4711 0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
4712 0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
4713 0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4714 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4715}},
4716{{ /* room 2 */
4717 0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4718 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4719 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4720 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4721}},
4722{{ /* room 3 */
4723 0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4724 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
4725 0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
4726 0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
4727}},
4728{{ /* hall 1 */
4729 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
4730 0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
4731 0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
4732 0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
4733}},
4734{{ /* hall 2 */
4735 0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
4736 0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
4737 0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4738 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4739}},
4740{{ /* plate */
4741 0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
4742 0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
4743 0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
4744 0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
4745}},
4746{{ /* delay */
4747 0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
4748 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4749 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4750 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4751}},
4752{{ /* panning delay */
4753 0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
4754 0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
4755 0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
4756 0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
4757}},
4758};
4759
4760static struct ReverbCmdPair {
4761 unsigned short cmd, port;
4762} reverb_cmds[28] = {
4763 {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
4764 {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
4765 {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
4766 {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
4767 {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
4768 {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
4769 {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
4770};
4771
4772static int
4773awe_load_reverb_fx(awe_patch_info *patch, const char __user *addr, int count)
4774{
4775 if (patch->optarg < AWE_REVERB_PREDEFINED || patch->optarg >= AWE_REVERB_NUMBERS) {
4776 printk(KERN_WARNING "AWE32 Error: invalid reverb mode %d for uploading\n", patch->optarg);
4777 return -EINVAL;
4778 }
4779 if (count < sizeof(awe_reverb_fx_rec)) {
4780 printk(KERN_WARNING "AWE32 Error: too short reverb fx parameters\n");
4781 return -EINVAL;
4782 }
4783 if (copy_from_user(&reverb_parm[patch->optarg], addr + AWE_PATCH_INFO_SIZE,
4784 sizeof(awe_reverb_fx_rec)))
4785 return -EFAULT;
4786 reverb_defined[patch->optarg] = TRUE;
4787 return 0;
4788}
4789
4790static void
4791awe_set_reverb_mode(int effect)
4792{
4793 int i;
4794 if (effect < 0 || effect >= AWE_REVERB_NUMBERS ||
4795 (effect >= AWE_REVERB_PREDEFINED && !reverb_defined[effect]))
4796 return;
4797 for (i = 0; i < 28; i++)
4798 awe_poke(reverb_cmds[i].cmd, reverb_cmds[i].port,
4799 reverb_parm[effect].parms[i]);
4800}
4801
4802static void
4803awe_update_reverb_mode(void)
4804{
4805 awe_set_reverb_mode(ctrls[AWE_MD_REVERB_MODE]);
4806}
4807
4808/*
4809 * treble/bass equalizer control
4810 */
4811
4812static unsigned short bass_parm[12][3] = {
4813 {0xD26A, 0xD36A, 0x0000}, /* -12 dB */
4814 {0xD25B, 0xD35B, 0x0000}, /* -8 */
4815 {0xD24C, 0xD34C, 0x0000}, /* -6 */
4816 {0xD23D, 0xD33D, 0x0000}, /* -4 */
4817 {0xD21F, 0xD31F, 0x0000}, /* -2 */
4818 {0xC208, 0xC308, 0x0001}, /* 0 (HW default) */
4819 {0xC219, 0xC319, 0x0001}, /* +2 */
4820 {0xC22A, 0xC32A, 0x0001}, /* +4 */
4821 {0xC24C, 0xC34C, 0x0001}, /* +6 */
4822 {0xC26E, 0xC36E, 0x0001}, /* +8 */
4823 {0xC248, 0xC348, 0x0002}, /* +10 */
4824 {0xC26A, 0xC36A, 0x0002}, /* +12 dB */
4825};
4826
4827static unsigned short treble_parm[12][9] = {
4828 {0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
4829 {0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4830 {0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4831 {0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4832 {0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
4833 {0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
4834 {0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
4835 {0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
4836 {0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
4837 {0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
4838 {0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
4839 {0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +12 dB */
4840};
4841
4842
4843/*
4844 * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
4845 */
4846static void
4847awe_equalizer(int bass, int treble)
4848{
4849 unsigned short w;
4850
4851 if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
4852 return;
4853 awe_poke(AWE_INIT4(0x01), bass_parm[bass][0]);
4854 awe_poke(AWE_INIT4(0x11), bass_parm[bass][1]);
4855 awe_poke(AWE_INIT3(0x11), treble_parm[treble][0]);
4856 awe_poke(AWE_INIT3(0x13), treble_parm[treble][1]);
4857 awe_poke(AWE_INIT3(0x1B), treble_parm[treble][2]);
4858 awe_poke(AWE_INIT4(0x07), treble_parm[treble][3]);
4859 awe_poke(AWE_INIT4(0x0B), treble_parm[treble][4]);
4860 awe_poke(AWE_INIT4(0x0D), treble_parm[treble][5]);
4861 awe_poke(AWE_INIT4(0x17), treble_parm[treble][6]);
4862 awe_poke(AWE_INIT4(0x19), treble_parm[treble][7]);
4863 w = bass_parm[bass][2] + treble_parm[treble][8];
4864 awe_poke(AWE_INIT4(0x15), (unsigned short)(w + 0x0262));
4865 awe_poke(AWE_INIT4(0x1D), (unsigned short)(w + 0x8362));
4866}
4867
4868static void awe_update_equalizer(void)
4869{
4870 awe_equalizer(ctrls[AWE_MD_BASS_LEVEL], ctrls[AWE_MD_TREBLE_LEVEL]);
4871}
4872
4873
4874/*----------------------------------------------------------------*/
4875
4876#ifdef CONFIG_AWE32_MIDIEMU
4877
4878/*
4879 * Emu8000 MIDI Emulation
4880 */
4881
4882/*
4883 * midi queue record
4884 */
4885
4886/* queue type */
4887enum { Q_NONE, Q_VARLEN, Q_READ, Q_SYSEX, };
4888
4889#define MAX_MIDIBUF 64
4890
4891/* midi status */
4892typedef struct MidiStatus {
4893 int queue; /* queue type */
4894 int qlen; /* queue length */
4895 int read; /* chars read */
4896 int status; /* current status */
4897 int chan; /* current channel */
4898 unsigned char buf[MAX_MIDIBUF];
4899} MidiStatus;
4900
4901/* MIDI mode type */
4902enum { MODE_GM, MODE_GS, MODE_XG, };
4903
4904/* NRPN / CC -> Emu8000 parameter converter */
4905typedef struct {
4906 int control;
4907 int awe_effect;
4908 unsigned short (*convert)(int val);
4909} ConvTable;
4910
4911
4912/*
4913 * prototypes
4914 */
4915
4916static int awe_midi_open(int dev, int mode, void (*input)(int,unsigned char), void (*output)(int));
4917static void awe_midi_close(int dev);
4918static int awe_midi_ioctl(int dev, unsigned cmd, void __user * arg);
4919static int awe_midi_outputc(int dev, unsigned char midi_byte);
4920
4921static void init_midi_status(MidiStatus *st);
4922static void clear_rpn(void);
4923static void get_midi_char(MidiStatus *st, int c);
4924/*static void queue_varlen(MidiStatus *st, int c);*/
4925static void special_event(MidiStatus *st, int c);
4926static void queue_read(MidiStatus *st, int c);
4927static void midi_note_on(MidiStatus *st);
4928static void midi_note_off(MidiStatus *st);
4929static void midi_key_pressure(MidiStatus *st);
4930static void midi_channel_pressure(MidiStatus *st);
4931static void midi_pitch_wheel(MidiStatus *st);
4932static void midi_program_change(MidiStatus *st);
4933static void midi_control_change(MidiStatus *st);
4934static void midi_select_bank(MidiStatus *st, int val);
4935static void midi_nrpn_event(MidiStatus *st);
4936static void midi_rpn_event(MidiStatus *st);
4937static void midi_detune(int chan, int coarse, int fine);
4938static void midi_system_exclusive(MidiStatus *st);
4939static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
4940static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val);
4941static int xg_control_change(MidiStatus *st, int cmd, int val);
4942
4943#define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
4944
4945
4946/*
4947 * OSS Midi device record
4948 */
4949
4950static struct midi_operations awe_midi_operations =
4951{
4952 .owner = THIS_MODULE,
4953 .info = {"AWE Midi Emu", 0, 0, SNDCARD_SB},
4954 .in_info = {0},
4955 .open = awe_midi_open, /*open*/
4956 .close = awe_midi_close, /*close*/
4957 .ioctl = awe_midi_ioctl, /*ioctl*/
4958 .outputc = awe_midi_outputc, /*outputc*/
4959};
4960
4961static int my_mididev = -1;
4962
4963static void __init attach_midiemu(void)
4964{
4965 if ((my_mididev = sound_alloc_mididev()) < 0)
4966 printk ("Sound: Too many midi devices detected\n");
4967 else
4968 midi_devs[my_mididev] = &awe_midi_operations;
4969}
4970
4971static void unload_midiemu(void)
4972{
4973 if (my_mididev >= 0)
4974 sound_unload_mididev(my_mididev);
4975}
4976
4977
4978/*
4979 * open/close midi device
4980 */
4981
4982static int midi_opened = FALSE;
4983
4984static int midi_mode;
4985static int coarsetune, finetune;
4986
4987static int xg_mapping = TRUE;
4988static int xg_bankmode;
4989
4990/* effect sensitivity */
4991
4992#define FX_CUTOFF 0
4993#define FX_RESONANCE 1
4994#define FX_ATTACK 2
4995#define FX_RELEASE 3
4996#define FX_VIBRATE 4
4997#define FX_VIBDEPTH 5
4998#define FX_VIBDELAY 6
4999#define FX_NUMS 7
5000
5001#define DEF_FX_CUTOFF 170
5002#define DEF_FX_RESONANCE 6
5003#define DEF_FX_ATTACK 50
5004#define DEF_FX_RELEASE 50
5005#define DEF_FX_VIBRATE 30
5006#define DEF_FX_VIBDEPTH 4
5007#define DEF_FX_VIBDELAY 1500
5008
5009/* effect sense: */
5010static int gs_sense[] =
5011{
5012 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
5013 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
5014};
5015static int xg_sense[] =
5016{
5017 DEF_FX_CUTOFF, DEF_FX_RESONANCE, DEF_FX_ATTACK, DEF_FX_RELEASE,
5018 DEF_FX_VIBRATE, DEF_FX_VIBDEPTH, DEF_FX_VIBDELAY
5019};
5020
5021
5022/* current status */
5023static MidiStatus curst;
5024
5025
5026static int
5027awe_midi_open (int dev, int mode,
5028 void (*input)(int,unsigned char),
5029 void (*output)(int))
5030{
5031 if (midi_opened)
5032 return -EBUSY;
5033
5034 midi_opened = TRUE;
5035
5036 midi_mode = MODE_GM;
5037
5038 curst.queue = Q_NONE;
5039 curst.qlen = 0;
5040 curst.read = 0;
5041 curst.status = 0;
5042 curst.chan = 0;
5043 memset(curst.buf, 0, sizeof(curst.buf));
5044
5045 init_midi_status(&curst);
5046
5047 return 0;
5048}
5049
5050static void
5051awe_midi_close (int dev)
5052{
5053 midi_opened = FALSE;
5054}
5055
5056
5057static int
5058awe_midi_ioctl (int dev, unsigned cmd, void __user *arg)
5059{
5060 return -EPERM;
5061}
5062
5063static int
5064awe_midi_outputc (int dev, unsigned char midi_byte)
5065{
5066 if (! midi_opened)
5067 return 1;
5068
5069 /* force to change playing mode */
5070 playing_mode = AWE_PLAY_MULTI;
5071
5072 get_midi_char(&curst, midi_byte);
5073 return 1;
5074}
5075
5076
5077/*
5078 * initialize
5079 */
5080
5081static void init_midi_status(MidiStatus *st)
5082{
5083 clear_rpn();
5084 coarsetune = 0;
5085 finetune = 0;
5086}
5087
5088
5089/*
5090 * RPN & NRPN
5091 */
5092
5093#define MAX_MIDI_CHANNELS 16
5094
5095/* RPN & NRPN */
5096static unsigned char nrpn[MAX_MIDI_CHANNELS]; /* current event is NRPN? */
5097static int msb_bit; /* current event is msb for RPN/NRPN */
5098/* RPN & NRPN indeces */
5099static unsigned char rpn_msb[MAX_MIDI_CHANNELS], rpn_lsb[MAX_MIDI_CHANNELS];
5100/* RPN & NRPN values */
5101static int rpn_val[MAX_MIDI_CHANNELS];
5102
5103static void clear_rpn(void)
5104{
5105 int i;
5106 for (i = 0; i < MAX_MIDI_CHANNELS; i++) {
5107 nrpn[i] = 0;
5108 rpn_msb[i] = 127;
5109 rpn_lsb[i] = 127;
5110 rpn_val[i] = 0;
5111 }
5112 msb_bit = 0;
5113}
5114
5115
5116/*
5117 * process midi queue
5118 */
5119
5120/* status event types */
5121typedef void (*StatusEvent)(MidiStatus *st);
5122static struct StatusEventList {
5123 StatusEvent process;
5124 int qlen;
5125} status_event[8] = {
5126 {midi_note_off, 2},
5127 {midi_note_on, 2},
5128 {midi_key_pressure, 2},
5129 {midi_control_change, 2},
5130 {midi_program_change, 1},
5131 {midi_channel_pressure, 1},
5132 {midi_pitch_wheel, 2},
5133 {NULL, 0},
5134};
5135
5136
5137/* read a char from fifo and process it */
5138static void get_midi_char(MidiStatus *st, int c)
5139{
5140 if (c == 0xfe) {
5141 /* ignore active sense */
5142 st->queue = Q_NONE;
5143 return;
5144 }
5145
5146 switch (st->queue) {
5147 /* case Q_VARLEN: queue_varlen(st, c); break;*/
5148 case Q_READ:
5149 case Q_SYSEX:
5150 queue_read(st, c);
5151 break;
5152 case Q_NONE:
5153 st->read = 0;
5154 if ((c & 0xf0) == 0xf0) {
5155 special_event(st, c);
5156 } else if (c & 0x80) { /* status change */
5157 st->status = (c >> 4) & 0x07;
5158 st->chan = c & 0x0f;
5159 st->queue = Q_READ;
5160 st->qlen = status_event[st->status].qlen;
5161 if (st->qlen == 0)
5162 st->queue = Q_NONE;
5163 }
5164 break;
5165 }
5166}
5167
5168/* 0xfx events */
5169static void special_event(MidiStatus *st, int c)
5170{
5171 switch (c) {
5172 case 0xf0: /* system exclusive */
5173 st->queue = Q_SYSEX;
5174 st->qlen = 0;
5175 break;
5176 case 0xf1: /* MTC quarter frame */
5177 case 0xf3: /* song select */
5178 st->queue = Q_READ;
5179 st->qlen = 1;
5180 break;
5181 case 0xf2: /* song position */
5182 st->queue = Q_READ;
5183 st->qlen = 2;
5184 break;
5185 }
5186}
5187
5188#if 0
5189/* read variable length value */
5190static void queue_varlen(MidiStatus *st, int c)
5191{
5192 st->qlen += (c & 0x7f);
5193 if (c & 0x80) {
5194 st->qlen <<= 7;
5195 return;
5196 }
5197 if (st->qlen <= 0) {
5198 st->qlen = 0;
5199 st->queue = Q_NONE;
5200 }
5201 st->queue = Q_READ;
5202 st->read = 0;
5203}
5204#endif
5205
5206
5207/* read a char */
5208static void queue_read(MidiStatus *st, int c)
5209{
5210 if (st->read < MAX_MIDIBUF) {
5211 if (st->queue != Q_SYSEX)
5212 c &= 0x7f;
5213 st->buf[st->read] = (unsigned char)c;
5214 }
5215 st->read++;
5216 if (st->queue == Q_SYSEX && c == 0xf7) {
5217 midi_system_exclusive(st);
5218 st->queue = Q_NONE;
5219 } else if (st->queue == Q_READ && st->read >= st->qlen) {
5220 if (status_event[st->status].process)
5221 status_event[st->status].process(st);
5222 st->queue = Q_NONE;
5223 }
5224}
5225
5226
5227/*
5228 * status events
5229 */
5230
5231/* note on */
5232static void midi_note_on(MidiStatus *st)
5233{
5234 DEBUG(2,printk("midi: note_on (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
5235 if (st->buf[1] == 0)
5236 midi_note_off(st);
5237 else
5238 awe_start_note(0, st->chan, st->buf[0], st->buf[1]);
5239}
5240
5241/* note off */
5242static void midi_note_off(MidiStatus *st)
5243{
5244 DEBUG(2,printk("midi: note_off (%d) %d %d\n", st->chan, st->buf[0], st->buf[1]));
5245 awe_kill_note(0, st->chan, st->buf[0], st->buf[1]);
5246}
5247
5248/* key pressure change */
5249static void midi_key_pressure(MidiStatus *st)
5250{
5251 awe_key_pressure(0, st->chan, st->buf[0], st->buf[1]);
5252}
5253
5254/* channel pressure change */
5255static void midi_channel_pressure(MidiStatus *st)
5256{
5257 channels[st->chan].chan_press = st->buf[0];
5258 awe_modwheel_change(st->chan, st->buf[0]);
5259}
5260
5261/* pitch wheel change */
5262static void midi_pitch_wheel(MidiStatus *st)
5263{
5264 int val = (int)st->buf[1] * 128 + st->buf[0];
5265 awe_bender(0, st->chan, val);
5266}
5267
5268/* program change */
5269static void midi_program_change(MidiStatus *st)
5270{
5271 int preset;
5272 preset = st->buf[0];
5273 if (midi_mode == MODE_GS && IS_DRUM_CHANNEL(st->chan) && preset == 127)
5274 preset = 0;
5275 else if (midi_mode == MODE_XG && xg_mapping && IS_DRUM_CHANNEL(st->chan))
5276 preset += 64;
5277
5278 awe_set_instr(0, st->chan, preset);
5279}
5280
5281#define send_effect(chan,type,val) awe_send_effect(chan,-1,type,val)
5282#define add_effect(chan,type,val) awe_send_effect(chan,-1,(type)|0x80,val)
5283#define unset_effect(chan,type) awe_send_effect(chan,-1,(type)|0x40,0)
5284
5285/* midi control change */
5286static void midi_control_change(MidiStatus *st)
5287{
5288 int cmd = st->buf[0];
5289 int val = st->buf[1];
5290
5291 DEBUG(2,printk("midi: control (%d) %d %d\n", st->chan, cmd, val));
5292 if (midi_mode == MODE_XG) {
5293 if (xg_control_change(st, cmd, val))
5294 return;
5295 }
5296
5297 /* controls #31 - #64 are LSB of #0 - #31 */
5298 msb_bit = 1;
5299 if (cmd >= 0x20 && cmd < 0x40) {
5300 msb_bit = 0;
5301 cmd -= 0x20;
5302 }
5303
5304 switch (cmd) {
5305 case CTL_SOFT_PEDAL:
5306 if (val == 127)
5307 add_effect(st->chan, AWE_FX_CUTOFF, -160);
5308 else
5309 unset_effect(st->chan, AWE_FX_CUTOFF);
5310 break;
5311
5312 case CTL_BANK_SELECT:
5313 midi_select_bank(st, val);
5314 break;
5315
5316 /* set RPN/NRPN parameter */
5317 case CTL_REGIST_PARM_NUM_MSB:
5318 nrpn[st->chan]=0; rpn_msb[st->chan]=val;
5319 break;
5320 case CTL_REGIST_PARM_NUM_LSB:
5321 nrpn[st->chan]=0; rpn_lsb[st->chan]=val;
5322 break;
5323 case CTL_NONREG_PARM_NUM_MSB:
5324 nrpn[st->chan]=1; rpn_msb[st->chan]=val;
5325 break;
5326 case CTL_NONREG_PARM_NUM_LSB:
5327 nrpn[st->chan]=1; rpn_lsb[st->chan]=val;
5328 break;
5329
5330 /* send RPN/NRPN entry */
5331 case CTL_DATA_ENTRY:
5332 if (msb_bit)
5333 rpn_val[st->chan] = val * 128;
5334 else
5335 rpn_val[st->chan] |= val;
5336 if (nrpn[st->chan])
5337 midi_nrpn_event(st);
5338 else
5339 midi_rpn_event(st);
5340 break;
5341
5342 /* increase/decrease data entry */
5343 case CTL_DATA_INCREMENT:
5344 rpn_val[st->chan]++;
5345 midi_rpn_event(st);
5346 break;
5347 case CTL_DATA_DECREMENT:
5348 rpn_val[st->chan]--;
5349 midi_rpn_event(st);
5350 break;
5351
5352 /* default */
5353 default:
5354 awe_controller(0, st->chan, cmd, val);
5355 break;
5356 }
5357}
5358
5359/* tone bank change */
5360static void midi_select_bank(MidiStatus *st, int val)
5361{
5362 if (midi_mode == MODE_XG && msb_bit) {
5363 xg_bankmode = val;
5364 /* XG MSB value; not normal bank selection */
5365 switch (val) {
5366 case 127: /* remap to drum channel */
5367 awe_controller(0, st->chan, CTL_BANK_SELECT, 128);
5368 break;
5369 default: /* remap to normal channel */
5370 awe_controller(0, st->chan, CTL_BANK_SELECT, val);
5371 break;
5372 }
5373 return;
5374 } else if (midi_mode == MODE_GS && !msb_bit)
5375 /* ignore LSB bank in GS mode (used for mapping) */
5376 return;
5377
5378 /* normal bank controls; accept both MSB and LSB */
5379 if (! IS_DRUM_CHANNEL(st->chan)) {
5380 if (midi_mode == MODE_XG) {
5381 if (xg_bankmode) return;
5382 if (val == 64 || val == 126)
5383 val = 0;
5384 } else if (midi_mode == MODE_GS && val == 127)
5385 val = 0;
5386 awe_controller(0, st->chan, CTL_BANK_SELECT, val);
5387 }
5388}
5389
5390
5391/*
5392 * RPN events
5393 */
5394
5395static void midi_rpn_event(MidiStatus *st)
5396{
5397 int type;
5398 type = (rpn_msb[st->chan]<<8) | rpn_lsb[st->chan];
5399 switch (type) {
5400 case 0x0000: /* Pitch bend sensitivity */
5401 /* MSB only / 1 semitone per 128 */
5402 if (msb_bit) {
5403 channels[st->chan].bender_range =
5404 rpn_val[st->chan] * 100 / 128;
5405 }
5406 break;
5407
5408 case 0x0001: /* fine tuning: */
5409 /* MSB/LSB, 8192=center, 100/8192 cent step */
5410 finetune = rpn_val[st->chan] - 8192;
5411 midi_detune(st->chan, coarsetune, finetune);
5412 break;
5413
5414 case 0x0002: /* coarse tuning */
5415 /* MSB only / 8192=center, 1 semitone per 128 */
5416 if (msb_bit) {
5417 coarsetune = rpn_val[st->chan] - 8192;
5418 midi_detune(st->chan, coarsetune, finetune);
5419 }
5420 break;
5421
5422 case 0x7F7F: /* "lock-in" RPN */
5423 break;
5424 }
5425}
5426
5427
5428/* tuning:
5429 * coarse = -8192 to 8192 (100 cent per 128)
5430 * fine = -8192 to 8192 (max=100cent)
5431 */
5432static void midi_detune(int chan, int coarse, int fine)
5433{
5434 /* 4096 = 1200 cents in AWE parameter */
5435 int val;
5436 val = coarse * 4096 / (12 * 128);
5437 val += fine / 24;
5438 if (val)
5439 send_effect(chan, AWE_FX_INIT_PITCH, val);
5440 else
5441 unset_effect(chan, AWE_FX_INIT_PITCH);
5442}
5443
5444
5445/*
5446 * system exclusive message
5447 * GM/GS/XG macros are accepted
5448 */
5449
5450static void midi_system_exclusive(MidiStatus *st)
5451{
5452 /* GM on */
5453 static unsigned char gm_on_macro[] = {
5454 0x7e,0x7f,0x09,0x01,
5455 };
5456 /* XG on */
5457 static unsigned char xg_on_macro[] = {
5458 0x43,0x10,0x4c,0x00,0x00,0x7e,0x00,
5459 };
5460 /* GS prefix
5461 * drum channel: XX=0x1?(channel), YY=0x15, ZZ=on/off
5462 * reverb mode: XX=0x01, YY=0x30, ZZ=0-7
5463 * chorus mode: XX=0x01, YY=0x38, ZZ=0-7
5464 */
5465 static unsigned char gs_pfx_macro[] = {
5466 0x41,0x10,0x42,0x12,0x40,/*XX,YY,ZZ*/
5467 };
5468
5469#if 0
5470 /* SC88 system mode set
5471 * single module mode: XX=1
5472 * double module mode: XX=0
5473 */
5474 static unsigned char gs_mode_macro[] = {
5475 0x41,0x10,0x42,0x12,0x00,0x00,0x7F,/*ZZ*/
5476 };
5477 /* SC88 display macro: XX=01:bitmap, 00:text
5478 */
5479 static unsigned char gs_disp_macro[] = {
5480 0x41,0x10,0x45,0x12,0x10,/*XX,00*/
5481 };
5482#endif
5483
5484 /* GM on */
5485 if (memcmp(st->buf, gm_on_macro, sizeof(gm_on_macro)) == 0) {
5486 if (midi_mode != MODE_GS && midi_mode != MODE_XG)
5487 midi_mode = MODE_GM;
5488 init_midi_status(st);
5489 }
5490
5491 /* GS macros */
5492 else if (memcmp(st->buf, gs_pfx_macro, sizeof(gs_pfx_macro)) == 0) {
5493 if (midi_mode != MODE_GS && midi_mode != MODE_XG)
5494 midi_mode = MODE_GS;
5495
5496 if (st->buf[5] == 0x00 && st->buf[6] == 0x7f && st->buf[7] == 0x00) {
5497 /* GS reset */
5498 init_midi_status(st);
5499 }
5500
5501 else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x15) {
5502 /* drum pattern */
5503 int p = st->buf[5] & 0x0f;
5504 if (p == 0) p = 9;
5505 else if (p < 10) p--;
5506 if (st->buf[7] == 0)
5507 DRUM_CHANNEL_OFF(p);
5508 else
5509 DRUM_CHANNEL_ON(p);
5510
5511 } else if ((st->buf[5] & 0xf0) == 0x10 && st->buf[6] == 0x21) {
5512 /* program */
5513 int p = st->buf[5] & 0x0f;
5514 if (p == 0) p = 9;
5515 else if (p < 10) p--;
5516 if (! IS_DRUM_CHANNEL(p))
5517 awe_set_instr(0, p, st->buf[7]);
5518
5519 } else if (st->buf[5] == 0x01 && st->buf[6] == 0x30) {
5520 /* reverb mode */
5521 awe_set_reverb_mode(st->buf[7]);
5522
5523 } else if (st->buf[5] == 0x01 && st->buf[6] == 0x38) {
5524 /* chorus mode */
5525 awe_set_chorus_mode(st->buf[7]);
5526
5527 } else if (st->buf[5] == 0x00 && st->buf[6] == 0x04) {
5528 /* master volume */
5529 awe_change_master_volume(st->buf[7]);
5530
5531 }
5532 }
5533
5534 /* XG on */
5535 else if (memcmp(st->buf, xg_on_macro, sizeof(xg_on_macro)) == 0) {
5536 midi_mode = MODE_XG;
5537 xg_mapping = TRUE;
5538 xg_bankmode = 0;
5539 }
5540}
5541
5542
5543/*----------------------------------------------------------------*/
5544
5545/*
5546 * convert NRPN/control values
5547 */
5548
5549static int send_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
5550{
5551 int i, cval;
5552 for (i = 0; i < num_tables; i++) {
5553 if (table[i].control == type) {
5554 cval = table[i].convert(val);
5555 send_effect(st->chan, table[i].awe_effect, cval);
5556 return TRUE;
5557 }
5558 }
5559 return FALSE;
5560}
5561
5562static int add_converted_effect(ConvTable *table, int num_tables, MidiStatus *st, int type, int val)
5563{
5564 int i, cval;
5565 for (i = 0; i < num_tables; i++) {
5566 if (table[i].control == type) {
5567 cval = table[i].convert(val);
5568 add_effect(st->chan, table[i].awe_effect|0x80, cval);
5569 return TRUE;
5570 }
5571 }
5572 return FALSE;
5573}
5574
5575
5576/*
5577 * AWE32 NRPN effects
5578 */
5579
5580static unsigned short fx_delay(int val);
5581static unsigned short fx_attack(int val);
5582static unsigned short fx_hold(int val);
5583static unsigned short fx_decay(int val);
5584static unsigned short fx_the_value(int val);
5585static unsigned short fx_twice_value(int val);
5586static unsigned short fx_conv_pitch(int val);
5587static unsigned short fx_conv_Q(int val);
5588
5589/* function for each NRPN */ /* [range] units */
5590#define fx_env1_delay fx_delay /* [0,5900] 4msec */
5591#define fx_env1_attack fx_attack /* [0,5940] 1msec */
5592#define fx_env1_hold fx_hold /* [0,8191] 1msec */
5593#define fx_env1_decay fx_decay /* [0,5940] 4msec */
5594#define fx_env1_release fx_decay /* [0,5940] 4msec */
5595#define fx_env1_sustain fx_the_value /* [0,127] 0.75dB */
5596#define fx_env1_pitch fx_the_value /* [-127,127] 9.375cents */
5597#define fx_env1_cutoff fx_the_value /* [-127,127] 56.25cents */
5598
5599#define fx_env2_delay fx_delay /* [0,5900] 4msec */
5600#define fx_env2_attack fx_attack /* [0,5940] 1msec */
5601#define fx_env2_hold fx_hold /* [0,8191] 1msec */
5602#define fx_env2_decay fx_decay /* [0,5940] 4msec */
5603#define fx_env2_release fx_decay /* [0,5940] 4msec */
5604#define fx_env2_sustain fx_the_value /* [0,127] 0.75dB */
5605
5606#define fx_lfo1_delay fx_delay /* [0,5900] 4msec */
5607#define fx_lfo1_freq fx_twice_value /* [0,127] 84mHz */
5608#define fx_lfo1_volume fx_twice_value /* [0,127] 0.1875dB */
5609#define fx_lfo1_pitch fx_the_value /* [-127,127] 9.375cents */
5610#define fx_lfo1_cutoff fx_twice_value /* [-64,63] 56.25cents */
5611
5612#define fx_lfo2_delay fx_delay /* [0,5900] 4msec */
5613#define fx_lfo2_freq fx_twice_value /* [0,127] 84mHz */
5614#define fx_lfo2_pitch fx_the_value /* [-127,127] 9.375cents */
5615
5616#define fx_init_pitch fx_conv_pitch /* [-8192,8192] cents */
5617#define fx_chorus fx_the_value /* [0,255] -- */
5618#define fx_reverb fx_the_value /* [0,255] -- */
5619#define fx_cutoff fx_twice_value /* [0,127] 62Hz */
5620#define fx_filterQ fx_conv_Q /* [0,127] -- */
5621
5622static unsigned short fx_delay(int val)
5623{
5624 return (unsigned short)calc_parm_delay(val);
5625}
5626
5627static unsigned short fx_attack(int val)
5628{
5629 return (unsigned short)calc_parm_attack(val);
5630}
5631
5632static unsigned short fx_hold(int val)
5633{
5634 return (unsigned short)calc_parm_hold(val);
5635}
5636
5637static unsigned short fx_decay(int val)
5638{
5639 return (unsigned short)calc_parm_decay(val);
5640}
5641
5642static unsigned short fx_the_value(int val)
5643{
5644 return (unsigned short)(val & 0xff);
5645}
5646
5647static unsigned short fx_twice_value(int val)
5648{
5649 return (unsigned short)((val * 2) & 0xff);
5650}
5651
5652static unsigned short fx_conv_pitch(int val)
5653{
5654 return (short)(val * 4096 / 1200);
5655}
5656
5657static unsigned short fx_conv_Q(int val)
5658{
5659 return (unsigned short)((val / 8) & 0xff);
5660}
5661
5662
5663static ConvTable awe_effects[] =
5664{
5665 { 0, AWE_FX_LFO1_DELAY, fx_lfo1_delay},
5666 { 1, AWE_FX_LFO1_FREQ, fx_lfo1_freq},
5667 { 2, AWE_FX_LFO2_DELAY, fx_lfo2_delay},
5668 { 3, AWE_FX_LFO2_FREQ, fx_lfo2_freq},
5669
5670 { 4, AWE_FX_ENV1_DELAY, fx_env1_delay},
5671 { 5, AWE_FX_ENV1_ATTACK,fx_env1_attack},
5672 { 6, AWE_FX_ENV1_HOLD, fx_env1_hold},
5673 { 7, AWE_FX_ENV1_DECAY, fx_env1_decay},
5674 { 8, AWE_FX_ENV1_SUSTAIN, fx_env1_sustain},
5675 { 9, AWE_FX_ENV1_RELEASE, fx_env1_release},
5676
5677 {10, AWE_FX_ENV2_DELAY, fx_env2_delay},
5678 {11, AWE_FX_ENV2_ATTACK, fx_env2_attack},
5679 {12, AWE_FX_ENV2_HOLD, fx_env2_hold},
5680 {13, AWE_FX_ENV2_DECAY, fx_env2_decay},
5681 {14, AWE_FX_ENV2_SUSTAIN, fx_env2_sustain},
5682 {15, AWE_FX_ENV2_RELEASE, fx_env2_release},
5683
5684 {16, AWE_FX_INIT_PITCH, fx_init_pitch},
5685 {17, AWE_FX_LFO1_PITCH, fx_lfo1_pitch},
5686 {18, AWE_FX_LFO2_PITCH, fx_lfo2_pitch},
5687 {19, AWE_FX_ENV1_PITCH, fx_env1_pitch},
5688 {20, AWE_FX_LFO1_VOLUME, fx_lfo1_volume},
5689 {21, AWE_FX_CUTOFF, fx_cutoff},
5690 {22, AWE_FX_FILTERQ, fx_filterQ},
5691 {23, AWE_FX_LFO1_CUTOFF, fx_lfo1_cutoff},
5692 {24, AWE_FX_ENV1_CUTOFF, fx_env1_cutoff},
5693 {25, AWE_FX_CHORUS, fx_chorus},
5694 {26, AWE_FX_REVERB, fx_reverb},
5695};
5696
5697static int num_awe_effects = numberof(awe_effects);
5698
5699
5700/*
5701 * GS(SC88) NRPN effects; still experimental
5702 */
5703
5704/* cutoff: quarter semitone step, max=255 */
5705static unsigned short gs_cutoff(int val)
5706{
5707 return (val - 64) * gs_sense[FX_CUTOFF] / 50;
5708}
5709
5710/* resonance: 0 to 15(max) */
5711static unsigned short gs_filterQ(int val)
5712{
5713 return (val - 64) * gs_sense[FX_RESONANCE] / 50;
5714}
5715
5716/* attack: */
5717static unsigned short gs_attack(int val)
5718{
5719 return -(val - 64) * gs_sense[FX_ATTACK] / 50;
5720}
5721
5722/* decay: */
5723static unsigned short gs_decay(int val)
5724{
5725 return -(val - 64) * gs_sense[FX_RELEASE] / 50;
5726}
5727
5728/* release: */
5729static unsigned short gs_release(int val)
5730{
5731 return -(val - 64) * gs_sense[FX_RELEASE] / 50;
5732}
5733
5734/* vibrato freq: 0.042Hz step, max=255 */
5735static unsigned short gs_vib_rate(int val)
5736{
5737 return (val - 64) * gs_sense[FX_VIBRATE] / 50;
5738}
5739
5740/* vibrato depth: max=127, 1 octave */
5741static unsigned short gs_vib_depth(int val)
5742{
5743 return (val - 64) * gs_sense[FX_VIBDEPTH] / 50;
5744}
5745
5746/* vibrato delay: -0.725msec step */
5747static unsigned short gs_vib_delay(int val)
5748{
5749 return -(val - 64) * gs_sense[FX_VIBDELAY] / 50;
5750}
5751
5752static ConvTable gs_effects[] =
5753{
5754 {32, AWE_FX_CUTOFF, gs_cutoff},
5755 {33, AWE_FX_FILTERQ, gs_filterQ},
5756 {99, AWE_FX_ENV2_ATTACK, gs_attack},
5757 {100, AWE_FX_ENV2_DECAY, gs_decay},
5758 {102, AWE_FX_ENV2_RELEASE, gs_release},
5759 {8, AWE_FX_LFO1_FREQ, gs_vib_rate},
5760 {9, AWE_FX_LFO1_VOLUME, gs_vib_depth},
5761 {10, AWE_FX_LFO1_DELAY, gs_vib_delay},
5762};
5763
5764static int num_gs_effects = numberof(gs_effects);
5765
5766
5767/*
5768 * NRPN events: accept as AWE32/SC88 specific controls
5769 */
5770
5771static void midi_nrpn_event(MidiStatus *st)
5772{
5773 if (rpn_msb[st->chan] == 127 && rpn_lsb[st->chan] <= 26) {
5774 if (! msb_bit) /* both MSB/LSB necessary */
5775 send_converted_effect(awe_effects, num_awe_effects,
5776 st, rpn_lsb[st->chan],
5777 rpn_val[st->chan] - 8192);
5778 } else if (rpn_msb[st->chan] == 1) {
5779 if (msb_bit) /* only MSB is valid */
5780 add_converted_effect(gs_effects, num_gs_effects,
5781 st, rpn_lsb[st->chan],
5782 rpn_val[st->chan] / 128);
5783 }
5784}
5785
5786
5787/*
5788 * XG control effects; still experimental
5789 */
5790
5791/* cutoff: quarter semitone step, max=255 */
5792static unsigned short xg_cutoff(int val)
5793{
5794 return (val - 64) * xg_sense[FX_CUTOFF] / 64;
5795}
5796
5797/* resonance: 0(open) to 15(most nasal) */
5798static unsigned short xg_filterQ(int val)
5799{
5800 return (val - 64) * xg_sense[FX_RESONANCE] / 64;
5801}
5802
5803/* attack: */
5804static unsigned short xg_attack(int val)
5805{
5806 return -(val - 64) * xg_sense[FX_ATTACK] / 64;
5807}
5808
5809/* release: */
5810static unsigned short xg_release(int val)
5811{
5812 return -(val - 64) * xg_sense[FX_RELEASE] / 64;
5813}
5814
5815static ConvTable xg_effects[] =
5816{
5817 {71, AWE_FX_CUTOFF, xg_cutoff},
5818 {74, AWE_FX_FILTERQ, xg_filterQ},
5819 {72, AWE_FX_ENV2_RELEASE, xg_release},
5820 {73, AWE_FX_ENV2_ATTACK, xg_attack},
5821};
5822
5823static int num_xg_effects = numberof(xg_effects);
5824
5825static int xg_control_change(MidiStatus *st, int cmd, int val)
5826{
5827 return add_converted_effect(xg_effects, num_xg_effects, st, cmd, val);
5828}
5829
5830#endif /* CONFIG_AWE32_MIDIEMU */
5831
5832
5833/*----------------------------------------------------------------*/
5834
5835
5836/*
5837 * initialization of AWE driver
5838 */
5839
5840static void
5841awe_initialize(void)
5842{
5843 DEBUG(0,printk("AWE32: initializing..\n"));
5844
5845 /* initialize hardware configuration */
5846 awe_poke(AWE_HWCF1, 0x0059);
5847 awe_poke(AWE_HWCF2, 0x0020);
5848
5849 /* disable audio; this seems to reduce a clicking noise a bit.. */
5850 awe_poke(AWE_HWCF3, 0);
5851
5852 /* initialize audio channels */
5853 awe_init_audio();
5854
5855 /* initialize DMA */
5856 awe_init_dma();
5857
5858 /* initialize init array */
5859 awe_init_array();
5860
5861 /* check DRAM memory size */
5862 awe_check_dram();
5863
5864 /* initialize the FM section of the AWE32 */
5865 awe_init_fm();
5866
5867 /* set up voice envelopes */
5868 awe_tweak();
5869
5870 /* enable audio */
5871 awe_poke(AWE_HWCF3, 0x0004);
5872
5873 /* set default values */
5874 awe_init_ctrl_parms(TRUE);
5875
5876 /* set equalizer */
5877 awe_update_equalizer();
5878
5879 /* set reverb & chorus modes */
5880 awe_update_reverb_mode();
5881 awe_update_chorus_mode();
5882}
5883
5884
5885/*
5886 * Core Device Management Functions
5887 */
5888
5889/* store values to i/o port array */
5890static void setup_ports(int port1, int port2, int port3)
5891{
5892 awe_ports[0] = port1;
5893 if (port2 == 0)
5894 port2 = port1 + 0x400;
5895 awe_ports[1] = port2;
5896 awe_ports[2] = port2 + 2;
5897 if (port3 == 0)
5898 port3 = port1 + 0x800;
5899 awe_ports[3] = port3;
5900 awe_ports[4] = port3 + 2;
5901
5902 port_setuped = TRUE;
5903}
5904
5905/*
5906 * port request
5907 * 0x620-623, 0xA20-A23, 0xE20-E23
5908 */
5909
5910static int
5911awe_request_region(void)
5912{
5913 if (! port_setuped)
5914 return 0;
5915 if (! request_region(awe_ports[0], 4, "sound driver (AWE32)"))
5916 return 0;
5917 if (! request_region(awe_ports[1], 4, "sound driver (AWE32)"))
5918 goto err_out;
5919 if (! request_region(awe_ports[3], 4, "sound driver (AWE32)"))
5920 goto err_out1;
5921 return 1;
5922err_out1:
5923 release_region(awe_ports[1], 4);
5924err_out:
5925 release_region(awe_ports[0], 4);
5926 return 0;
5927}
5928
5929static void
5930awe_release_region(void)
5931{
5932 if (! port_setuped) return;
5933 release_region(awe_ports[0], 4);
5934 release_region(awe_ports[1], 4);
5935 release_region(awe_ports[3], 4);
5936}
5937
5938static int awe_attach_device(void)
5939{
5940 if (awe_present) return 0; /* for OSS38.. called twice? */
5941
5942 /* reserve I/O ports for awedrv */
5943 if (! awe_request_region()) {
5944 printk(KERN_ERR "AWE32: I/O area already used.\n");
5945 return 0;
5946 }
5947
5948 /* set buffers to NULL */
5949 sfhead = sftail = NULL;
5950
5951 my_dev = sound_alloc_synthdev();
5952 if (my_dev == -1) {
5953 printk(KERN_ERR "AWE32 Error: too many synthesizers\n");
5954 awe_release_region();
5955 return 0;
5956 }
5957
5958 voice_alloc = &awe_operations.alloc;
5959 voice_alloc->max_voice = awe_max_voices;
5960 synth_devs[my_dev] = &awe_operations;
5961
5962#ifdef CONFIG_AWE32_MIXER
5963 attach_mixer();
5964#endif
5965#ifdef CONFIG_AWE32_MIDIEMU
5966 attach_midiemu();
5967#endif
5968
5969 /* clear all samples */
5970 awe_reset_samples();
5971
5972 /* initialize AWE32 hardware */
5973 awe_initialize();
5974
5975 sprintf(awe_info.name, "AWE32-%s (RAM%dk)",
5976 AWEDRV_VERSION, memsize/1024);
5977 printk(KERN_INFO "<SoundBlaster EMU8000 (RAM%dk)>\n", memsize/1024);
5978
5979 awe_present = TRUE;
5980
5981 return 1;
5982}
5983
5984static void awe_dettach_device(void)
5985{
5986 if (awe_present) {
5987 awe_reset_samples();
5988 awe_release_region();
5989 free_tables();
5990#ifdef CONFIG_AWE32_MIXER
5991 unload_mixer();
5992#endif
5993#ifdef CONFIG_AWE32_MIDIEMU
5994 unload_midiemu();
5995#endif
5996 sound_unload_synthdev(my_dev);
5997 awe_present = FALSE;
5998 }
5999}
6000
6001
6002/*
6003 * Legacy device Probing
6004 */
6005
6006/* detect emu8000 chip on the specified address; from VV's guide */
6007
6008static int __init
6009awe_detect_base(int addr)
6010{
6011 setup_ports(addr, 0, 0);
6012 if ((awe_peek(AWE_U1) & 0x000F) != 0x000C)
6013 return 0;
6014 if ((awe_peek(AWE_HWCF1) & 0x007E) != 0x0058)
6015 return 0;
6016 if ((awe_peek(AWE_HWCF2) & 0x0003) != 0x0003)
6017 return 0;
6018 DEBUG(0,printk("AWE32 found at %x\n", addr));
6019 return 1;
6020}
6021
6022static int __init awe_detect_legacy_devices(void)
6023{
6024 int base;
6025 for (base = 0x620; base <= 0x680; base += 0x20)
6026 if (awe_detect_base(base)) {
6027 awe_attach_device();
6028 return 1;
6029 }
6030 DEBUG(0,printk("AWE32 Legacy detection failed\n"));
6031 return 0;
6032}
6033
6034
6035/*
6036 * PnP device Probing
6037 */
6038
6039static struct pnp_device_id awe_pnp_ids[] = {
6040 {.id = "CTL0021", .driver_data = 0}, /* AWE32 WaveTable */
6041 {.id = "CTL0022", .driver_data = 0}, /* AWE64 WaveTable */
6042 {.id = "CTL0023", .driver_data = 0}, /* AWE64 Gold WaveTable */
6043 { } /* terminator */
6044};
6045
6046MODULE_DEVICE_TABLE(pnp, awe_pnp_ids);
6047
6048static int awe_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
6049{
6050 int io1, io2, io3;
6051
6052 if (awe_present) {
6053 printk(KERN_ERR "AWE32: This driver only supports one AWE32 device, skipping.\n");
6054 }
6055
6056 if (!pnp_port_valid(dev,0) ||
6057 !pnp_port_valid(dev,1) ||
6058 !pnp_port_valid(dev,2)) {
6059 printk(KERN_ERR "AWE32: The PnP device does not have the required resources.\n");
6060 return -EINVAL;
6061 }
6062 io1 = pnp_port_start(dev,0);
6063 io2 = pnp_port_start(dev,1);
6064 io3 = pnp_port_start(dev,2);
6065 printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x\n.",
6066 io1, io2, io3);
6067 setup_ports(io1, io2, io3);
6068
6069 awe_attach_device();
6070 return 0;
6071}
6072
6073static void awe_pnp_remove(struct pnp_dev *dev)
6074{
6075 awe_dettach_device();
6076}
6077
6078static struct pnp_driver awe_pnp_driver = {
6079 .name = "AWE32",
6080 .id_table = awe_pnp_ids,
6081 .probe = awe_pnp_probe,
6082 .remove = awe_pnp_remove,
6083};
6084
6085static int __init awe_detect_pnp_devices(void)
6086{
6087 int ret;
6088
6089 ret = pnp_register_driver(&awe_pnp_driver);
6090 if (ret<0)
6091 printk(KERN_ERR "AWE32: PnP support is unavailable.\n");
6092 return ret;
6093}
6094
6095
6096/*
6097 * device / lowlevel (module) interface
6098 */
6099
6100static int __init
6101awe_detect(void)
6102{
6103 printk(KERN_INFO "AWE32: Probing for WaveTable...\n");
6104 if (isapnp) {
6105 if (awe_detect_pnp_devices()>=0)
6106 return 1;
6107 } else
6108 printk(KERN_INFO "AWE32: Skipping PnP detection.\n");
6109
6110 if (awe_detect_legacy_devices())
6111 return 1;
6112
6113 return 0;
6114}
6115
6116static int __init attach_awe(void)
6117{
6118 return awe_detect() ? 0 : -ENODEV;
6119}
6120
6121static void __exit unload_awe(void)
6122{
6123 pnp_unregister_driver(&awe_pnp_driver);
6124 awe_dettach_device();
6125}
6126
6127
6128module_init(attach_awe);
6129module_exit(unload_awe);
6130
6131#ifndef MODULE
6132static int __init setup_awe(char *str)
6133{
6134 /* io, memsize, isapnp */
6135 int ints[4];
6136
6137 str = get_options(str, ARRAY_SIZE(ints), ints);
6138
6139 io = ints[1];
6140 memsize = ints[2];
6141 isapnp = ints[3];
6142
6143 return 1;
6144}
6145
6146__setup("awe=", setup_awe);
6147#endif