Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/synth/emux/emux_synth.c
10817 views
1
/*
2
* Midi synth routines for the Emu8k/Emu10k1
3
*
4
* Copyright (C) 1999 Steve Ratcliffe
5
* Copyright (c) 1999-2000 Takashi Iwai <[email protected]>
6
*
7
* Contains code based on awe_wave.c by 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
*
23
*/
24
25
#include "emux_voice.h"
26
#include <sound/asoundef.h>
27
28
/*
29
* Prototypes
30
*/
31
32
/*
33
* Ensure a value is between two points
34
* macro evaluates its args more than once, so changed to upper-case.
35
*/
36
#define LIMITVALUE(x, a, b) do { if ((x) < (a)) (x) = (a); else if ((x) > (b)) (x) = (b); } while (0)
37
#define LIMITMAX(x, a) do {if ((x) > (a)) (x) = (a); } while (0)
38
39
static int get_zone(struct snd_emux *emu, struct snd_emux_port *port,
40
int *notep, int vel, struct snd_midi_channel *chan,
41
struct snd_sf_zone **table);
42
static int get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan);
43
static void terminate_note1(struct snd_emux *emu, int note,
44
struct snd_midi_channel *chan, int free);
45
static void exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port,
46
int exclass);
47
static void terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free);
48
static void update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update);
49
static void setup_voice(struct snd_emux_voice *vp);
50
static int calc_pan(struct snd_emux_voice *vp);
51
static int calc_volume(struct snd_emux_voice *vp);
52
static int calc_pitch(struct snd_emux_voice *vp);
53
54
55
/*
56
* Start a note.
57
*/
58
void
59
snd_emux_note_on(void *p, int note, int vel, struct snd_midi_channel *chan)
60
{
61
struct snd_emux *emu;
62
int i, key, nvoices;
63
struct snd_emux_voice *vp;
64
struct snd_sf_zone *table[SNDRV_EMUX_MAX_MULTI_VOICES];
65
unsigned long flags;
66
struct snd_emux_port *port;
67
68
port = p;
69
if (snd_BUG_ON(!port || !chan))
70
return;
71
72
emu = port->emu;
73
if (snd_BUG_ON(!emu || !emu->ops.get_voice || !emu->ops.trigger))
74
return;
75
76
key = note; /* remember the original note */
77
nvoices = get_zone(emu, port, &note, vel, chan, table);
78
if (! nvoices)
79
return;
80
81
/* exclusive note off */
82
for (i = 0; i < nvoices; i++) {
83
struct snd_sf_zone *zp = table[i];
84
if (zp && zp->v.exclusiveClass)
85
exclusive_note_off(emu, port, zp->v.exclusiveClass);
86
}
87
88
#if 0 // seems not necessary
89
/* Turn off the same note on the same channel. */
90
terminate_note1(emu, key, chan, 0);
91
#endif
92
93
spin_lock_irqsave(&emu->voice_lock, flags);
94
for (i = 0; i < nvoices; i++) {
95
96
/* set up each voice parameter */
97
/* at this stage, we don't trigger the voice yet. */
98
99
if (table[i] == NULL)
100
continue;
101
102
vp = emu->ops.get_voice(emu, port);
103
if (vp == NULL || vp->ch < 0)
104
continue;
105
if (STATE_IS_PLAYING(vp->state))
106
emu->ops.terminate(vp);
107
108
vp->time = emu->use_time++;
109
vp->chan = chan;
110
vp->port = port;
111
vp->key = key;
112
vp->note = note;
113
vp->velocity = vel;
114
vp->zone = table[i];
115
if (vp->zone->sample)
116
vp->block = vp->zone->sample->block;
117
else
118
vp->block = NULL;
119
120
setup_voice(vp);
121
122
vp->state = SNDRV_EMUX_ST_STANDBY;
123
if (emu->ops.prepare) {
124
vp->state = SNDRV_EMUX_ST_OFF;
125
if (emu->ops.prepare(vp) >= 0)
126
vp->state = SNDRV_EMUX_ST_STANDBY;
127
}
128
}
129
130
/* start envelope now */
131
for (i = 0; i < emu->max_voices; i++) {
132
vp = &emu->voices[i];
133
if (vp->state == SNDRV_EMUX_ST_STANDBY &&
134
vp->chan == chan) {
135
emu->ops.trigger(vp);
136
vp->state = SNDRV_EMUX_ST_ON;
137
vp->ontime = jiffies; /* remember the trigger timing */
138
}
139
}
140
spin_unlock_irqrestore(&emu->voice_lock, flags);
141
142
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
143
if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
144
/* clear voice position for the next note on this channel */
145
struct snd_emux_effect_table *fx = chan->private;
146
if (fx) {
147
fx->flag[EMUX_FX_SAMPLE_START] = 0;
148
fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0;
149
}
150
}
151
#endif
152
}
153
154
/*
155
* Release a note in response to a midi note off.
156
*/
157
void
158
snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
159
{
160
int ch;
161
struct snd_emux *emu;
162
struct snd_emux_voice *vp;
163
unsigned long flags;
164
struct snd_emux_port *port;
165
166
port = p;
167
if (snd_BUG_ON(!port || !chan))
168
return;
169
170
emu = port->emu;
171
if (snd_BUG_ON(!emu || !emu->ops.release))
172
return;
173
174
spin_lock_irqsave(&emu->voice_lock, flags);
175
for (ch = 0; ch < emu->max_voices; ch++) {
176
vp = &emu->voices[ch];
177
if (STATE_IS_PLAYING(vp->state) &&
178
vp->chan == chan && vp->key == note) {
179
vp->state = SNDRV_EMUX_ST_RELEASED;
180
if (vp->ontime == jiffies) {
181
/* if note-off is sent too shortly after
182
* note-on, emuX engine cannot produce the sound
183
* correctly. so we'll release this note
184
* a bit later via timer callback.
185
*/
186
vp->state = SNDRV_EMUX_ST_PENDING;
187
if (! emu->timer_active) {
188
emu->tlist.expires = jiffies + 1;
189
add_timer(&emu->tlist);
190
emu->timer_active = 1;
191
}
192
} else
193
/* ok now release the note */
194
emu->ops.release(vp);
195
}
196
}
197
spin_unlock_irqrestore(&emu->voice_lock, flags);
198
}
199
200
/*
201
* timer callback
202
*
203
* release the pending note-offs
204
*/
205
void snd_emux_timer_callback(unsigned long data)
206
{
207
struct snd_emux *emu = (struct snd_emux *) data;
208
struct snd_emux_voice *vp;
209
unsigned long flags;
210
int ch, do_again = 0;
211
212
spin_lock_irqsave(&emu->voice_lock, flags);
213
for (ch = 0; ch < emu->max_voices; ch++) {
214
vp = &emu->voices[ch];
215
if (vp->state == SNDRV_EMUX_ST_PENDING) {
216
if (vp->ontime == jiffies)
217
do_again++; /* release this at the next interrupt */
218
else {
219
emu->ops.release(vp);
220
vp->state = SNDRV_EMUX_ST_RELEASED;
221
}
222
}
223
}
224
if (do_again) {
225
emu->tlist.expires = jiffies + 1;
226
add_timer(&emu->tlist);
227
emu->timer_active = 1;
228
} else
229
emu->timer_active = 0;
230
spin_unlock_irqrestore(&emu->voice_lock, flags);
231
}
232
233
/*
234
* key pressure change
235
*/
236
void
237
snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
238
{
239
int ch;
240
struct snd_emux *emu;
241
struct snd_emux_voice *vp;
242
unsigned long flags;
243
struct snd_emux_port *port;
244
245
port = p;
246
if (snd_BUG_ON(!port || !chan))
247
return;
248
249
emu = port->emu;
250
if (snd_BUG_ON(!emu || !emu->ops.update))
251
return;
252
253
spin_lock_irqsave(&emu->voice_lock, flags);
254
for (ch = 0; ch < emu->max_voices; ch++) {
255
vp = &emu->voices[ch];
256
if (vp->state == SNDRV_EMUX_ST_ON &&
257
vp->chan == chan && vp->key == note) {
258
vp->velocity = vel;
259
update_voice(emu, vp, SNDRV_EMUX_UPDATE_VOLUME);
260
}
261
}
262
spin_unlock_irqrestore(&emu->voice_lock, flags);
263
}
264
265
266
/*
267
* Modulate the voices which belong to the channel
268
*/
269
void
270
snd_emux_update_channel(struct snd_emux_port *port, struct snd_midi_channel *chan, int update)
271
{
272
struct snd_emux *emu;
273
struct snd_emux_voice *vp;
274
int i;
275
unsigned long flags;
276
277
if (! update)
278
return;
279
280
emu = port->emu;
281
if (snd_BUG_ON(!emu || !emu->ops.update))
282
return;
283
284
spin_lock_irqsave(&emu->voice_lock, flags);
285
for (i = 0; i < emu->max_voices; i++) {
286
vp = &emu->voices[i];
287
if (vp->chan == chan)
288
update_voice(emu, vp, update);
289
}
290
spin_unlock_irqrestore(&emu->voice_lock, flags);
291
}
292
293
/*
294
* Modulate all the voices which belong to the port.
295
*/
296
void
297
snd_emux_update_port(struct snd_emux_port *port, int update)
298
{
299
struct snd_emux *emu;
300
struct snd_emux_voice *vp;
301
int i;
302
unsigned long flags;
303
304
if (! update)
305
return;
306
307
emu = port->emu;
308
if (snd_BUG_ON(!emu || !emu->ops.update))
309
return;
310
311
spin_lock_irqsave(&emu->voice_lock, flags);
312
for (i = 0; i < emu->max_voices; i++) {
313
vp = &emu->voices[i];
314
if (vp->port == port)
315
update_voice(emu, vp, update);
316
}
317
spin_unlock_irqrestore(&emu->voice_lock, flags);
318
}
319
320
321
/*
322
* Deal with a controller type event. This includes all types of
323
* control events, not just the midi controllers
324
*/
325
void
326
snd_emux_control(void *p, int type, struct snd_midi_channel *chan)
327
{
328
struct snd_emux_port *port;
329
330
port = p;
331
if (snd_BUG_ON(!port || !chan))
332
return;
333
334
switch (type) {
335
case MIDI_CTL_MSB_MAIN_VOLUME:
336
case MIDI_CTL_MSB_EXPRESSION:
337
snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_VOLUME);
338
break;
339
340
case MIDI_CTL_MSB_PAN:
341
snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PAN);
342
break;
343
344
case MIDI_CTL_SOFT_PEDAL:
345
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
346
/* FIXME: this is an emulation */
347
if (chan->control[type] >= 64)
348
snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, -160,
349
EMUX_FX_FLAG_ADD);
350
else
351
snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, 0,
352
EMUX_FX_FLAG_OFF);
353
#endif
354
break;
355
356
case MIDI_CTL_PITCHBEND:
357
snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PITCH);
358
break;
359
360
case MIDI_CTL_MSB_MODWHEEL:
361
case MIDI_CTL_CHAN_PRESSURE:
362
snd_emux_update_channel(port, chan,
363
SNDRV_EMUX_UPDATE_FMMOD |
364
SNDRV_EMUX_UPDATE_FM2FRQ2);
365
break;
366
367
}
368
369
if (port->chset.midi_mode == SNDRV_MIDI_MODE_XG) {
370
snd_emux_xg_control(port, chan, type);
371
}
372
}
373
374
375
/*
376
* terminate note - if free flag is true, free the terminated voice
377
*/
378
static void
379
terminate_note1(struct snd_emux *emu, int note, struct snd_midi_channel *chan, int free)
380
{
381
int i;
382
struct snd_emux_voice *vp;
383
unsigned long flags;
384
385
spin_lock_irqsave(&emu->voice_lock, flags);
386
for (i = 0; i < emu->max_voices; i++) {
387
vp = &emu->voices[i];
388
if (STATE_IS_PLAYING(vp->state) && vp->chan == chan &&
389
vp->key == note)
390
terminate_voice(emu, vp, free);
391
}
392
spin_unlock_irqrestore(&emu->voice_lock, flags);
393
}
394
395
396
/*
397
* terminate note - exported for midi emulation
398
*/
399
void
400
snd_emux_terminate_note(void *p, int note, struct snd_midi_channel *chan)
401
{
402
struct snd_emux *emu;
403
struct snd_emux_port *port;
404
405
port = p;
406
if (snd_BUG_ON(!port || !chan))
407
return;
408
409
emu = port->emu;
410
if (snd_BUG_ON(!emu || !emu->ops.terminate))
411
return;
412
413
terminate_note1(emu, note, chan, 1);
414
}
415
416
417
/*
418
* Terminate all the notes
419
*/
420
void
421
snd_emux_terminate_all(struct snd_emux *emu)
422
{
423
int i;
424
struct snd_emux_voice *vp;
425
unsigned long flags;
426
427
spin_lock_irqsave(&emu->voice_lock, flags);
428
for (i = 0; i < emu->max_voices; i++) {
429
vp = &emu->voices[i];
430
if (STATE_IS_PLAYING(vp->state))
431
terminate_voice(emu, vp, 0);
432
if (vp->state == SNDRV_EMUX_ST_OFF) {
433
if (emu->ops.free_voice)
434
emu->ops.free_voice(vp);
435
if (emu->ops.reset)
436
emu->ops.reset(emu, i);
437
}
438
vp->time = 0;
439
}
440
/* initialize allocation time */
441
emu->use_time = 0;
442
spin_unlock_irqrestore(&emu->voice_lock, flags);
443
}
444
445
EXPORT_SYMBOL(snd_emux_terminate_all);
446
447
/*
448
* Terminate all voices associated with the given port
449
*/
450
void
451
snd_emux_sounds_off_all(struct snd_emux_port *port)
452
{
453
int i;
454
struct snd_emux *emu;
455
struct snd_emux_voice *vp;
456
unsigned long flags;
457
458
if (snd_BUG_ON(!port))
459
return;
460
emu = port->emu;
461
if (snd_BUG_ON(!emu || !emu->ops.terminate))
462
return;
463
464
spin_lock_irqsave(&emu->voice_lock, flags);
465
for (i = 0; i < emu->max_voices; i++) {
466
vp = &emu->voices[i];
467
if (STATE_IS_PLAYING(vp->state) &&
468
vp->port == port)
469
terminate_voice(emu, vp, 0);
470
if (vp->state == SNDRV_EMUX_ST_OFF) {
471
if (emu->ops.free_voice)
472
emu->ops.free_voice(vp);
473
if (emu->ops.reset)
474
emu->ops.reset(emu, i);
475
}
476
}
477
spin_unlock_irqrestore(&emu->voice_lock, flags);
478
}
479
480
481
/*
482
* Terminate all voices that have the same exclusive class. This
483
* is mainly for drums.
484
*/
485
static void
486
exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port, int exclass)
487
{
488
struct snd_emux_voice *vp;
489
int i;
490
unsigned long flags;
491
492
spin_lock_irqsave(&emu->voice_lock, flags);
493
for (i = 0; i < emu->max_voices; i++) {
494
vp = &emu->voices[i];
495
if (STATE_IS_PLAYING(vp->state) && vp->port == port &&
496
vp->reg.exclusiveClass == exclass) {
497
terminate_voice(emu, vp, 0);
498
}
499
}
500
spin_unlock_irqrestore(&emu->voice_lock, flags);
501
}
502
503
/*
504
* terminate a voice
505
* if free flag is true, call free_voice after termination
506
*/
507
static void
508
terminate_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int free)
509
{
510
emu->ops.terminate(vp);
511
vp->time = emu->use_time++;
512
vp->chan = NULL;
513
vp->port = NULL;
514
vp->zone = NULL;
515
vp->block = NULL;
516
vp->state = SNDRV_EMUX_ST_OFF;
517
if (free && emu->ops.free_voice)
518
emu->ops.free_voice(vp);
519
}
520
521
522
/*
523
* Modulate the voice
524
*/
525
static void
526
update_voice(struct snd_emux *emu, struct snd_emux_voice *vp, int update)
527
{
528
if (!STATE_IS_PLAYING(vp->state))
529
return;
530
531
if (vp->chan == NULL || vp->port == NULL)
532
return;
533
if (update & SNDRV_EMUX_UPDATE_VOLUME)
534
calc_volume(vp);
535
if (update & SNDRV_EMUX_UPDATE_PITCH)
536
calc_pitch(vp);
537
if (update & SNDRV_EMUX_UPDATE_PAN) {
538
if (! calc_pan(vp) && (update == SNDRV_EMUX_UPDATE_PAN))
539
return;
540
}
541
emu->ops.update(vp, update);
542
}
543
544
545
#if 0 // not used
546
/* table for volume target calculation */
547
static unsigned short voltarget[16] = {
548
0xEAC0, 0xE0C8, 0xD740, 0xCE20, 0xC560, 0xBD08, 0xB500, 0xAD58,
549
0xA5F8, 0x9EF0, 0x9830, 0x91C0, 0x8B90, 0x85A8, 0x8000, 0x7A90
550
};
551
#endif
552
553
#define LO_BYTE(v) ((v) & 0xff)
554
#define HI_BYTE(v) (((v) >> 8) & 0xff)
555
556
/*
557
* Sets up the voice structure by calculating some values that
558
* will be needed later.
559
*/
560
static void
561
setup_voice(struct snd_emux_voice *vp)
562
{
563
struct soundfont_voice_parm *parm;
564
int pitch;
565
566
/* copy the original register values */
567
vp->reg = vp->zone->v;
568
569
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
570
snd_emux_setup_effect(vp);
571
#endif
572
573
/* reset status */
574
vp->apan = -1;
575
vp->avol = -1;
576
vp->apitch = -1;
577
578
calc_volume(vp);
579
calc_pitch(vp);
580
calc_pan(vp);
581
582
parm = &vp->reg.parm;
583
584
/* compute filter target and correct modulation parameters */
585
if (LO_BYTE(parm->modatkhld) >= 0x80 && parm->moddelay >= 0x8000) {
586
parm->moddelay = 0xbfff;
587
pitch = (HI_BYTE(parm->pefe) << 4) + vp->apitch;
588
if (pitch > 0xffff)
589
pitch = 0xffff;
590
/* calculate filter target */
591
vp->ftarget = parm->cutoff + LO_BYTE(parm->pefe);
592
LIMITVALUE(vp->ftarget, 0, 255);
593
vp->ftarget <<= 8;
594
} else {
595
vp->ftarget = parm->cutoff;
596
vp->ftarget <<= 8;
597
pitch = vp->apitch;
598
}
599
600
/* compute pitch target */
601
if (pitch != 0xffff) {
602
vp->ptarget = 1 << (pitch >> 12);
603
if (pitch & 0x800) vp->ptarget += (vp->ptarget*0x102e)/0x2710;
604
if (pitch & 0x400) vp->ptarget += (vp->ptarget*0x764)/0x2710;
605
if (pitch & 0x200) vp->ptarget += (vp->ptarget*0x389)/0x2710;
606
vp->ptarget += (vp->ptarget >> 1);
607
if (vp->ptarget > 0xffff) vp->ptarget = 0xffff;
608
} else
609
vp->ptarget = 0xffff;
610
611
if (LO_BYTE(parm->modatkhld) >= 0x80) {
612
parm->modatkhld &= ~0xff;
613
parm->modatkhld |= 0x7f;
614
}
615
616
/* compute volume target and correct volume parameters */
617
vp->vtarget = 0;
618
#if 0 /* FIXME: this leads to some clicks.. */
619
if (LO_BYTE(parm->volatkhld) >= 0x80 && parm->voldelay >= 0x8000) {
620
parm->voldelay = 0xbfff;
621
vp->vtarget = voltarget[vp->avol % 0x10] >> (vp->avol >> 4);
622
}
623
#endif
624
625
if (LO_BYTE(parm->volatkhld) >= 0x80) {
626
parm->volatkhld &= ~0xff;
627
parm->volatkhld |= 0x7f;
628
}
629
}
630
631
/*
632
* calculate pitch parameter
633
*/
634
static unsigned char pan_volumes[256] = {
635
0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a,
636
0x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52,
637
0x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,
638
0x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92,
639
0x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab,
640
0xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0,
641
0xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,
642
0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf,
643
0xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9,
644
0xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1,
645
0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
646
0xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,
647
0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
648
0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
649
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
650
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
651
};
652
653
static int
654
calc_pan(struct snd_emux_voice *vp)
655
{
656
struct snd_midi_channel *chan = vp->chan;
657
int pan;
658
659
/* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
660
if (vp->reg.fixpan > 0) /* 0-127 */
661
pan = 255 - (int)vp->reg.fixpan * 2;
662
else {
663
pan = chan->control[MIDI_CTL_MSB_PAN] - 64;
664
if (vp->reg.pan >= 0) /* 0-127 */
665
pan += vp->reg.pan - 64;
666
pan = 127 - (int)pan * 2;
667
}
668
LIMITVALUE(pan, 0, 255);
669
670
if (vp->emu->linear_panning) {
671
/* assuming linear volume */
672
if (pan != vp->apan) {
673
vp->apan = pan;
674
if (pan == 0)
675
vp->aaux = 0xff;
676
else
677
vp->aaux = (-pan) & 0xff;
678
return 1;
679
} else
680
return 0;
681
} else {
682
/* using volume table */
683
if (vp->apan != (int)pan_volumes[pan]) {
684
vp->apan = pan_volumes[pan];
685
vp->aaux = pan_volumes[255 - pan];
686
return 1;
687
}
688
return 0;
689
}
690
}
691
692
693
/*
694
* calculate volume attenuation
695
*
696
* Voice volume is controlled by volume attenuation parameter.
697
* So volume becomes maximum when avol is 0 (no attenuation), and
698
* minimum when 255 (-96dB or silence).
699
*/
700
701
/* tables for volume->attenuation calculation */
702
static unsigned char voltab1[128] = {
703
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
704
0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
705
0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
706
0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
707
0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
708
0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
709
0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
710
0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
711
0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
712
0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
713
0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
714
0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
715
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
716
};
717
718
static unsigned char voltab2[128] = {
719
0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
720
0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
721
0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
722
0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
723
0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
724
0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
725
0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
726
0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
727
0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
728
0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
729
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
730
0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
731
0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
732
};
733
734
static unsigned char expressiontab[128] = {
735
0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
736
0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
737
0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
738
0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
739
0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
740
0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
741
0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
742
0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
743
0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
744
0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
745
0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
746
0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
747
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
748
};
749
750
/*
751
* Magic to calculate the volume (actually attenuation) from all the
752
* voice and channels parameters.
753
*/
754
static int
755
calc_volume(struct snd_emux_voice *vp)
756
{
757
int vol;
758
int main_vol, expression_vol, master_vol;
759
struct snd_midi_channel *chan = vp->chan;
760
struct snd_emux_port *port = vp->port;
761
762
expression_vol = chan->control[MIDI_CTL_MSB_EXPRESSION];
763
LIMITMAX(vp->velocity, 127);
764
LIMITVALUE(expression_vol, 0, 127);
765
if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
766
/* 0 - 127 */
767
main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME];
768
vol = (vp->velocity * main_vol * expression_vol) / (127*127);
769
vol = vol * vp->reg.amplitude / 127;
770
771
LIMITVALUE(vol, 0, 127);
772
773
/* calc to attenuation */
774
vol = snd_sf_vol_table[vol];
775
776
} else {
777
main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME] * vp->reg.amplitude / 127;
778
LIMITVALUE(main_vol, 0, 127);
779
780
vol = voltab1[main_vol] + voltab2[vp->velocity];
781
vol = (vol * 8) / 3;
782
vol += vp->reg.attenuation;
783
vol += ((0x100 - vol) * expressiontab[expression_vol])/128;
784
}
785
786
master_vol = port->chset.gs_master_volume;
787
LIMITVALUE(master_vol, 0, 127);
788
vol += snd_sf_vol_table[master_vol];
789
vol += port->volume_atten;
790
791
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
792
if (chan->private) {
793
struct snd_emux_effect_table *fx = chan->private;
794
vol += fx->val[EMUX_FX_ATTEN];
795
}
796
#endif
797
798
LIMITVALUE(vol, 0, 255);
799
if (vp->avol == vol)
800
return 0; /* value unchanged */
801
802
vp->avol = vol;
803
if (!SF_IS_DRUM_BANK(get_bank(port, chan))
804
&& LO_BYTE(vp->reg.parm.volatkhld) < 0x7d) {
805
int atten;
806
if (vp->velocity < 70)
807
atten = 70;
808
else
809
atten = vp->velocity;
810
vp->acutoff = (atten * vp->reg.parm.cutoff + 0xa0) >> 7;
811
} else {
812
vp->acutoff = vp->reg.parm.cutoff;
813
}
814
815
return 1; /* value changed */
816
}
817
818
/*
819
* calculate pitch offset
820
*
821
* 0xE000 is no pitch offset at 44100Hz sample.
822
* Every 4096 is one octave.
823
*/
824
825
static int
826
calc_pitch(struct snd_emux_voice *vp)
827
{
828
struct snd_midi_channel *chan = vp->chan;
829
int offset;
830
831
/* calculate offset */
832
if (vp->reg.fixkey >= 0) {
833
offset = (vp->reg.fixkey - vp->reg.root) * 4096 / 12;
834
} else {
835
offset = (vp->note - vp->reg.root) * 4096 / 12;
836
}
837
offset = (offset * vp->reg.scaleTuning) / 100;
838
offset += vp->reg.tune * 4096 / 1200;
839
if (chan->midi_pitchbend != 0) {
840
/* (128 * 8192: 1 semitone) ==> (4096: 12 semitones) */
841
offset += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 3072;
842
}
843
844
/* tuning via RPN:
845
* coarse = -8192 to 8192 (100 cent per 128)
846
* fine = -8192 to 8192 (max=100cent)
847
*/
848
/* 4096 = 1200 cents in emu8000 parameter */
849
offset += chan->gm_rpn_coarse_tuning * 4096 / (12 * 128);
850
offset += chan->gm_rpn_fine_tuning / 24;
851
852
#ifdef SNDRV_EMUX_USE_RAW_EFFECT
853
/* add initial pitch correction */
854
if (chan->private) {
855
struct snd_emux_effect_table *fx = chan->private;
856
if (fx->flag[EMUX_FX_INIT_PITCH])
857
offset += fx->val[EMUX_FX_INIT_PITCH];
858
}
859
#endif
860
861
/* 0xe000: root pitch */
862
offset += 0xe000 + vp->reg.rate_offset;
863
offset += vp->emu->pitch_shift;
864
LIMITVALUE(offset, 0, 0xffff);
865
if (offset == vp->apitch)
866
return 0; /* unchanged */
867
vp->apitch = offset;
868
return 1; /* value changed */
869
}
870
871
/*
872
* Get the bank number assigned to the channel
873
*/
874
static int
875
get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan)
876
{
877
int val;
878
879
switch (port->chset.midi_mode) {
880
case SNDRV_MIDI_MODE_XG:
881
val = chan->control[MIDI_CTL_MSB_BANK];
882
if (val == 127)
883
return 128; /* return drum bank */
884
return chan->control[MIDI_CTL_LSB_BANK];
885
886
case SNDRV_MIDI_MODE_GS:
887
if (chan->drum_channel)
888
return 128;
889
/* ignore LSB (bank map) */
890
return chan->control[MIDI_CTL_MSB_BANK];
891
892
default:
893
if (chan->drum_channel)
894
return 128;
895
return chan->control[MIDI_CTL_MSB_BANK];
896
}
897
}
898
899
900
/* Look for the zones matching with the given note and velocity.
901
* The resultant zones are stored on table.
902
*/
903
static int
904
get_zone(struct snd_emux *emu, struct snd_emux_port *port,
905
int *notep, int vel, struct snd_midi_channel *chan,
906
struct snd_sf_zone **table)
907
{
908
int preset, bank, def_preset, def_bank;
909
910
bank = get_bank(port, chan);
911
preset = chan->midi_program;
912
913
if (SF_IS_DRUM_BANK(bank)) {
914
def_preset = port->ctrls[EMUX_MD_DEF_DRUM];
915
def_bank = bank;
916
} else {
917
def_preset = preset;
918
def_bank = port->ctrls[EMUX_MD_DEF_BANK];
919
}
920
921
return snd_soundfont_search_zone(emu->sflist, notep, vel, preset, bank,
922
def_preset, def_bank,
923
table, SNDRV_EMUX_MAX_MULTI_VOICES);
924
}
925
926
/*
927
*/
928
void
929
snd_emux_init_voices(struct snd_emux *emu)
930
{
931
struct snd_emux_voice *vp;
932
int i;
933
unsigned long flags;
934
935
spin_lock_irqsave(&emu->voice_lock, flags);
936
for (i = 0; i < emu->max_voices; i++) {
937
vp = &emu->voices[i];
938
vp->ch = -1; /* not used */
939
vp->state = SNDRV_EMUX_ST_OFF;
940
vp->chan = NULL;
941
vp->port = NULL;
942
vp->time = 0;
943
vp->emu = emu;
944
vp->hw = emu->hw;
945
}
946
spin_unlock_irqrestore(&emu->voice_lock, flags);
947
}
948
949
/*
950
*/
951
void snd_emux_lock_voice(struct snd_emux *emu, int voice)
952
{
953
unsigned long flags;
954
955
spin_lock_irqsave(&emu->voice_lock, flags);
956
if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF)
957
emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED;
958
else
959
snd_printk(KERN_WARNING
960
"invalid voice for lock %d (state = %x)\n",
961
voice, emu->voices[voice].state);
962
spin_unlock_irqrestore(&emu->voice_lock, flags);
963
}
964
965
EXPORT_SYMBOL(snd_emux_lock_voice);
966
967
/*
968
*/
969
void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
970
{
971
unsigned long flags;
972
973
spin_lock_irqsave(&emu->voice_lock, flags);
974
if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED)
975
emu->voices[voice].state = SNDRV_EMUX_ST_OFF;
976
else
977
snd_printk(KERN_WARNING
978
"invalid voice for unlock %d (state = %x)\n",
979
voice, emu->voices[voice].state);
980
spin_unlock_irqrestore(&emu->voice_lock, flags);
981
}
982
983
EXPORT_SYMBOL(snd_emux_unlock_voice);
984
985