File Index
Files and directories
Sign in
FILE

emux_synth.c

File preview with syntax highlighting.

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