2 * Soundfont generic routines.
3 * It is intended that these should be used by any driver that is willing
4 * to accept soundfont patches.
6 * Copyright (C) 1999 Steve Ratcliffe
7 * Copyright (c) 1999-2000 Takashi Iwai <tiwai@suse.de>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * Deal with reading in of a soundfont. Code follows the OSS way
25 * of doing things so that the old sfxload utility can be used.
26 * Everything may change when there is an alsa way of doing things.
28 #include <asm/uaccess.h>
29 #include <linux/slab.h>
30 #include <sound/core.h>
31 #include <sound/soundfont.h>
32 #include <sound/seq_oss_legacy.h>
34 /* Prototypes for static functions */
36 static int open_patch(struct snd_sf_list *sflist, const char __user *data,
37 int count, int client);
38 static struct snd_soundfont *newsf(struct snd_sf_list *sflist, int type, char *name);
39 static int is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name);
40 static int close_patch(struct snd_sf_list *sflist);
41 static int probe_data(struct snd_sf_list *sflist, int sample_id);
42 static void set_zone_counter(struct snd_sf_list *sflist,
43 struct snd_soundfont *sf, struct snd_sf_zone *zp);
44 static struct snd_sf_zone *sf_zone_new(struct snd_sf_list *sflist,
45 struct snd_soundfont *sf);
46 static void set_sample_counter(struct snd_sf_list *sflist,
47 struct snd_soundfont *sf, struct snd_sf_sample *sp);
48 static struct snd_sf_sample *sf_sample_new(struct snd_sf_list *sflist,
49 struct snd_soundfont *sf);
50 static void sf_sample_delete(struct snd_sf_list *sflist,
51 struct snd_soundfont *sf, struct snd_sf_sample *sp);
52 static int load_map(struct snd_sf_list *sflist, const void __user *data, int count);
53 static int load_info(struct snd_sf_list *sflist, const void __user *data, long count);
54 static int remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
56 static void init_voice_info(struct soundfont_voice_info *avp);
57 static void init_voice_parm(struct soundfont_voice_parm *pp);
58 static struct snd_sf_sample *set_sample(struct snd_soundfont *sf,
59 struct soundfont_voice_info *avp);
60 static struct snd_sf_sample *find_sample(struct snd_soundfont *sf, int sample_id);
61 static int load_data(struct snd_sf_list *sflist, const void __user *data, long count);
62 static void rebuild_presets(struct snd_sf_list *sflist);
63 static void add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur);
64 static void delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp);
65 static struct snd_sf_zone *search_first_zone(struct snd_sf_list *sflist,
66 int bank, int preset, int key);
67 static int search_zones(struct snd_sf_list *sflist, int *notep, int vel,
68 int preset, int bank, struct snd_sf_zone **table,
69 int max_layers, int level);
70 static int get_index(int bank, int instr, int key);
71 static void snd_sf_init(struct snd_sf_list *sflist);
72 static void snd_sf_clear(struct snd_sf_list *sflist);
75 * lock access to sflist
78 lock_preset(struct snd_sf_list *sflist)
81 mutex_lock(&sflist->presets_mutex);
82 spin_lock_irqsave(&sflist->lock, flags);
83 sflist->presets_locked = 1;
84 spin_unlock_irqrestore(&sflist->lock, flags);
92 unlock_preset(struct snd_sf_list *sflist)
95 spin_lock_irqsave(&sflist->lock, flags);
96 sflist->presets_locked = 0;
97 spin_unlock_irqrestore(&sflist->lock, flags);
98 mutex_unlock(&sflist->presets_mutex);
103 * close the patch if the patch was opened by this client.
106 snd_soundfont_close_check(struct snd_sf_list *sflist, int client)
109 spin_lock_irqsave(&sflist->lock, flags);
110 if (sflist->open_client == client) {
111 spin_unlock_irqrestore(&sflist->lock, flags);
112 return close_patch(sflist);
114 spin_unlock_irqrestore(&sflist->lock, flags);
120 * Deal with a soundfont patch. Any driver could use these routines
121 * although it was designed for the AWE64.
123 * The sample_write and callargs pararameters allow a callback into
124 * the actual driver to write sample data to the board or whatever
125 * it wants to do with it.
128 snd_soundfont_load(struct snd_sf_list *sflist, const void __user *data,
129 long count, int client)
131 struct soundfont_patch_info patch;
135 if (count < (long)sizeof(patch)) {
136 snd_printk(KERN_ERR "patch record too small %ld\n", count);
139 if (copy_from_user(&patch, data, sizeof(patch)))
142 count -= sizeof(patch);
143 data += sizeof(patch);
145 if (patch.key != SNDRV_OSS_SOUNDFONT_PATCH) {
146 snd_printk(KERN_ERR "The wrong kind of patch %x\n", patch.key);
149 if (count < patch.len) {
150 snd_printk(KERN_ERR "Patch too short %ld, need %d\n",
155 snd_printk(KERN_ERR "poor length %d\n", patch.len);
159 if (patch.type == SNDRV_SFNT_OPEN_PATCH) {
160 /* grab sflist to open */
162 rc = open_patch(sflist, data, count, client);
163 unlock_preset(sflist);
167 /* check if other client already opened patch */
168 spin_lock_irqsave(&sflist->lock, flags);
169 if (sflist->open_client != client) {
170 spin_unlock_irqrestore(&sflist->lock, flags);
173 spin_unlock_irqrestore(&sflist->lock, flags);
177 switch (patch.type) {
178 case SNDRV_SFNT_LOAD_INFO:
179 rc = load_info(sflist, data, count);
181 case SNDRV_SFNT_LOAD_DATA:
182 rc = load_data(sflist, data, count);
184 case SNDRV_SFNT_CLOSE_PATCH:
185 rc = close_patch(sflist);
187 case SNDRV_SFNT_REPLACE_DATA:
188 /*rc = replace_data(&patch, data, count);*/
190 case SNDRV_SFNT_MAP_PRESET:
191 rc = load_map(sflist, data, count);
193 case SNDRV_SFNT_PROBE_DATA:
194 rc = probe_data(sflist, patch.optarg);
196 case SNDRV_SFNT_REMOVE_INFO:
197 /* patch must be opened */
198 if (!sflist->currsf) {
199 snd_printk(KERN_ERR "soundfont: remove_info: "
200 "patch not opened\n");
204 bank = ((unsigned short)patch.optarg >> 8) & 0xff;
205 instr = (unsigned short)patch.optarg & 0xff;
206 if (! remove_info(sflist, sflist->currsf, bank, instr))
213 unlock_preset(sflist);
219 /* check if specified type is special font (GUS or preset-alias) */
221 is_special_type(int type)
224 return (type == SNDRV_SFNT_PAT_TYPE_GUS ||
225 type == SNDRV_SFNT_PAT_TYPE_MAP);
229 /* open patch; create sf list */
231 open_patch(struct snd_sf_list *sflist, const char __user *data,
232 int count, int client)
234 struct soundfont_open_parm parm;
235 struct snd_soundfont *sf;
238 spin_lock_irqsave(&sflist->lock, flags);
239 if (sflist->open_client >= 0 || sflist->currsf) {
240 spin_unlock_irqrestore(&sflist->lock, flags);
243 spin_unlock_irqrestore(&sflist->lock, flags);
245 if (copy_from_user(&parm, data, sizeof(parm)))
248 if (is_special_type(parm.type)) {
249 parm.type |= SNDRV_SFNT_PAT_SHARED;
250 sf = newsf(sflist, parm.type, NULL);
252 sf = newsf(sflist, parm.type, parm.name);
257 spin_lock_irqsave(&sflist->lock, flags);
258 sflist->open_client = client;
260 spin_unlock_irqrestore(&sflist->lock, flags);
266 * Allocate a new soundfont structure.
268 static struct snd_soundfont *
269 newsf(struct snd_sf_list *sflist, int type, char *name)
271 struct snd_soundfont *sf;
273 /* check the shared fonts */
274 if (type & SNDRV_SFNT_PAT_SHARED) {
275 for (sf = sflist->fonts; sf; sf = sf->next) {
276 if (is_identical_font(sf, type, name)) {
282 /* not found -- create a new one */
283 sf = kzalloc(sizeof(*sf), GFP_KERNEL);
286 sf->id = sflist->fonts_size;
287 sflist->fonts_size++;
289 /* prepend this record */
290 sf->next = sflist->fonts;
297 memcpy(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN);
302 /* check if the given name matches to the existing list */
304 is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name)
306 return ((sf->type & SNDRV_SFNT_PAT_SHARED) &&
307 (sf->type & 0x0f) == (type & 0x0f) &&
309 memcmp(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN) == 0));
313 * Close the current patch.
316 close_patch(struct snd_sf_list *sflist)
320 spin_lock_irqsave(&sflist->lock, flags);
321 sflist->currsf = NULL;
322 sflist->open_client = -1;
323 spin_unlock_irqrestore(&sflist->lock, flags);
325 rebuild_presets(sflist);
331 /* probe sample in the current list -- nothing to be loaded */
333 probe_data(struct snd_sf_list *sflist, int sample_id)
335 /* patch must be opened */
336 if (sflist->currsf) {
337 /* search the specified sample by optarg */
338 if (find_sample(sflist->currsf, sample_id))
345 * increment zone counter
348 set_zone_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
349 struct snd_sf_zone *zp)
351 zp->counter = sflist->zone_counter++;
352 if (sf->type & SNDRV_SFNT_PAT_LOCKED)
353 sflist->zone_locked = sflist->zone_counter;
357 * allocate a new zone record
359 static struct snd_sf_zone *
360 sf_zone_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
362 struct snd_sf_zone *zp;
364 if ((zp = kzalloc(sizeof(*zp), GFP_KERNEL)) == NULL)
366 zp->next = sf->zones;
369 init_voice_info(&zp->v);
371 set_zone_counter(sflist, sf, zp);
377 * increment sample couter
380 set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
381 struct snd_sf_sample *sp)
383 sp->counter = sflist->sample_counter++;
384 if (sf->type & SNDRV_SFNT_PAT_LOCKED)
385 sflist->sample_locked = sflist->sample_counter;
389 * allocate a new sample list record
391 static struct snd_sf_sample *
392 sf_sample_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
394 struct snd_sf_sample *sp;
396 if ((sp = kzalloc(sizeof(*sp), GFP_KERNEL)) == NULL)
399 sp->next = sf->samples;
402 set_sample_counter(sflist, sf, sp);
407 * delete sample list -- this is an exceptional job.
408 * only the last allocated sample can be deleted.
411 sf_sample_delete(struct snd_sf_list *sflist, struct snd_soundfont *sf,
412 struct snd_sf_sample *sp)
414 /* only last sample is accepted */
415 if (sp == sf->samples) {
416 sf->samples = sp->next;
424 load_map(struct snd_sf_list *sflist, const void __user *data, int count)
426 struct snd_sf_zone *zp, *prevp;
427 struct snd_soundfont *sf;
428 struct soundfont_voice_map map;
430 /* get the link info */
431 if (count < (int)sizeof(map))
433 if (copy_from_user(&map, data, sizeof(map)))
436 if (map.map_instr < 0 || map.map_instr >= SF_MAX_INSTRUMENTS)
439 sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_MAP|SNDRV_SFNT_PAT_SHARED, NULL);
444 for (zp = sf->zones; zp; prevp = zp, zp = zp->next) {
446 zp->instr == map.map_instr &&
447 zp->bank == map.map_bank &&
448 zp->v.low == map.map_key &&
449 zp->v.start == map.src_instr &&
450 zp->v.end == map.src_bank &&
451 zp->v.fixkey == map.src_key) {
452 /* the same mapping is already present */
453 /* relink this record to the link head */
455 prevp->next = zp->next;
456 zp->next = sf->zones;
459 /* update the counter */
460 set_zone_counter(sflist, sf, zp);
465 /* create a new zone */
466 if ((zp = sf_zone_new(sflist, sf)) == NULL)
469 zp->bank = map.map_bank;
470 zp->instr = map.map_instr;
472 if (map.map_key >= 0) {
473 zp->v.low = map.map_key;
474 zp->v.high = map.map_key;
476 zp->v.start = map.src_instr;
477 zp->v.end = map.src_bank;
478 zp->v.fixkey = map.src_key;
479 zp->v.sf_id = sf->id;
481 add_preset(sflist, zp);
487 /* remove the present instrument layers */
489 remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
492 struct snd_sf_zone *prev, *next, *p;
496 for (p = sf->zones; p; p = next) {
499 p->bank == bank && p->instr == instr) {
500 /* remove this layer */
511 rebuild_presets(sflist);
517 * Read an info record from the user buffer and save it on the current
521 load_info(struct snd_sf_list *sflist, const void __user *data, long count)
523 struct snd_soundfont *sf;
524 struct snd_sf_zone *zone;
525 struct soundfont_voice_rec_hdr hdr;
528 /* patch must be opened */
529 if ((sf = sflist->currsf) == NULL)
532 if (is_special_type(sf->type))
535 if (count < (long)sizeof(hdr)) {
536 printk(KERN_ERR "Soundfont error: invalid patch zone length\n");
539 if (copy_from_user((char*)&hdr, data, sizeof(hdr)))
543 count -= sizeof(hdr);
545 if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
546 printk(KERN_ERR "Soundfont error: Illegal voice number %d\n",
551 if (count < (long)sizeof(struct soundfont_voice_info) * hdr.nvoices) {
552 printk(KERN_ERR "Soundfont Error: "
553 "patch length(%ld) is smaller than nvoices(%d)\n",
558 switch (hdr.write_mode) {
559 case SNDRV_SFNT_WR_EXCLUSIVE:
560 /* exclusive mode - if the instrument already exists,
562 for (zone = sf->zones; zone; zone = zone->next) {
564 zone->bank == hdr.bank &&
565 zone->instr == hdr.instr)
569 case SNDRV_SFNT_WR_REPLACE:
570 /* replace mode - remove the instrument if it already exists */
571 remove_info(sflist, sf, hdr.bank, hdr.instr);
575 for (i = 0; i < hdr.nvoices; i++) {
576 struct snd_sf_zone tmpzone;
578 /* copy awe_voice_info parameters */
579 if (copy_from_user(&tmpzone.v, data, sizeof(tmpzone.v))) {
583 data += sizeof(tmpzone.v);
584 count -= sizeof(tmpzone.v);
586 tmpzone.bank = hdr.bank;
587 tmpzone.instr = hdr.instr;
589 tmpzone.v.sf_id = sf->id;
590 if (tmpzone.v.mode & SNDRV_SFNT_MODE_INIT_PARM)
591 init_voice_parm(&tmpzone.v.parm);
593 /* create a new zone */
594 if ((zone = sf_zone_new(sflist, sf)) == NULL) {
598 /* copy the temporary data */
599 zone->bank = tmpzone.bank;
600 zone->instr = tmpzone.instr;
603 /* look up the sample */
604 zone->sample = set_sample(sf, &zone->v);
611 /* initialize voice_info record */
613 init_voice_info(struct soundfont_voice_info *avp)
615 memset(avp, 0, sizeof(*avp));
624 avp->amplitude = 127;
625 avp->scaleTuning = 100;
627 init_voice_parm(&avp->parm);
630 /* initialize voice_parm record:
631 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
632 * Vibrato and Tremolo effects are zero.
634 * Chorus and Reverb effects are zero.
637 init_voice_parm(struct soundfont_voice_parm *pp)
639 memset(pp, 0, sizeof(*pp));
641 pp->moddelay = 0x8000;
642 pp->modatkhld = 0x7f7f;
643 pp->moddcysus = 0x7f7f;
644 pp->modrelease = 0x807f;
646 pp->voldelay = 0x8000;
647 pp->volatkhld = 0x7f7f;
648 pp->voldcysus = 0x7f7f;
649 pp->volrelease = 0x807f;
651 pp->lfo1delay = 0x8000;
652 pp->lfo2delay = 0x8000;
657 /* search the specified sample */
658 static struct snd_sf_sample *
659 set_sample(struct snd_soundfont *sf, struct soundfont_voice_info *avp)
661 struct snd_sf_sample *sample;
663 sample = find_sample(sf, avp->sample);
667 /* add in the actual sample offsets:
668 * The voice_info addresses define only the relative offset
669 * from sample pointers. Here we calculate the actual DRAM
670 * offset from sample pointers.
672 avp->start += sample->v.start;
673 avp->end += sample->v.end;
674 avp->loopstart += sample->v.loopstart;
675 avp->loopend += sample->v.loopend;
677 /* copy mode flags */
678 avp->sample_mode = sample->v.mode_flags;
683 /* find the sample pointer with the given id in the soundfont */
684 static struct snd_sf_sample *
685 find_sample(struct snd_soundfont *sf, int sample_id)
687 struct snd_sf_sample *p;
692 for (p = sf->samples; p; p = p->next) {
693 if (p->v.sample == sample_id)
701 * Load sample information, this can include data to be loaded onto
702 * the soundcard. It can also just be a pointer into soundcard ROM.
703 * If there is data it will be written to the soundcard via the callback
707 load_data(struct snd_sf_list *sflist, const void __user *data, long count)
709 struct snd_soundfont *sf;
710 struct soundfont_sample_info sample_info;
711 struct snd_sf_sample *sp;
714 /* patch must be opened */
715 if ((sf = sflist->currsf) == NULL)
718 if (is_special_type(sf->type))
721 if (copy_from_user(&sample_info, data, sizeof(sample_info)))
724 off = sizeof(sample_info);
726 if (sample_info.size != (count-off)/2)
730 if (find_sample(sf, sample_info.sample)) {
731 /* if shared sample, skip this data */
732 if (sf->type & SNDRV_SFNT_PAT_SHARED)
737 /* Allocate a new sample structure */
738 if ((sp = sf_sample_new(sflist, sf)) == NULL)
742 sp->v.sf_id = sf->id;
744 sp->v.truesize = sp->v.size;
747 * If there is wave data then load it.
749 if (sp->v.size > 0) {
751 rc = sflist->callback.sample_new
752 (sflist->callback.private_data, sp, sflist->memhdr,
753 data + off, count - off);
755 sf_sample_delete(sflist, sf, sp);
758 sflist->mem_used += sp->v.truesize;
765 /* log2_tbl[i] = log2(i+128) * 0x10000 */
766 static int log_tbl[129] = {
767 0x70000, 0x702df, 0x705b9, 0x7088e, 0x70b5d, 0x70e26, 0x710eb, 0x713aa,
768 0x71663, 0x71918, 0x71bc8, 0x71e72, 0x72118, 0x723b9, 0x72655, 0x728ed,
769 0x72b80, 0x72e0e, 0x73098, 0x7331d, 0x7359e, 0x7381b, 0x73a93, 0x73d08,
770 0x73f78, 0x741e4, 0x7444c, 0x746b0, 0x74910, 0x74b6c, 0x74dc4, 0x75019,
771 0x75269, 0x754b6, 0x75700, 0x75946, 0x75b88, 0x75dc7, 0x76002, 0x7623a,
772 0x7646e, 0x766a0, 0x768cd, 0x76af8, 0x76d1f, 0x76f43, 0x77164, 0x77382,
773 0x7759d, 0x777b4, 0x779c9, 0x77bdb, 0x77dea, 0x77ff5, 0x781fe, 0x78404,
774 0x78608, 0x78808, 0x78a06, 0x78c01, 0x78df9, 0x78fef, 0x791e2, 0x793d2,
775 0x795c0, 0x797ab, 0x79993, 0x79b79, 0x79d5d, 0x79f3e, 0x7a11d, 0x7a2f9,
776 0x7a4d3, 0x7a6ab, 0x7a880, 0x7aa53, 0x7ac24, 0x7adf2, 0x7afbe, 0x7b188,
777 0x7b350, 0x7b515, 0x7b6d8, 0x7b899, 0x7ba58, 0x7bc15, 0x7bdd0, 0x7bf89,
778 0x7c140, 0x7c2f5, 0x7c4a7, 0x7c658, 0x7c807, 0x7c9b3, 0x7cb5e, 0x7cd07,
779 0x7ceae, 0x7d053, 0x7d1f7, 0x7d398, 0x7d538, 0x7d6d6, 0x7d872, 0x7da0c,
780 0x7dba4, 0x7dd3b, 0x7ded0, 0x7e063, 0x7e1f4, 0x7e384, 0x7e512, 0x7e69f,
781 0x7e829, 0x7e9b3, 0x7eb3a, 0x7ecc0, 0x7ee44, 0x7efc7, 0x7f148, 0x7f2c8,
782 0x7f446, 0x7f5c2, 0x7f73d, 0x7f8b7, 0x7fa2f, 0x7fba5, 0x7fd1a, 0x7fe8d,
786 /* convert from linear to log value
788 * conversion: value = log2(amount / base) * ratio
791 * amount = linear value (unsigned, 32bit max)
792 * offset = base offset (:= log2(base) * 0x10000)
793 * ratio = division ratio
797 snd_sf_linear_to_log(unsigned int amount, int offset, int ratio)
804 for (bit = 0; ! (amount & 0x80000000L); bit++)
806 s = (amount >> 24) & 0x7f;
807 low = (amount >> 16) & 0xff;
808 /* linear approxmimation by lower 8 bit */
809 v = (log_tbl[s + 1] * low + log_tbl[s] * (0x100 - low)) >> 8;
811 v = (v * ratio) >> 16;
812 v += (24 - bit) * ratio;
816 EXPORT_SYMBOL(snd_sf_linear_to_log);
819 #define OFFSET_MSEC 653117 /* base = 1000 */
820 #define OFFSET_ABSCENT 851781 /* base = 8176 */
821 #define OFFSET_SAMPLERATE 1011119 /* base = 44100 */
823 #define ABSCENT_RATIO 1200
824 #define TIMECENT_RATIO 1200
825 #define SAMPLERATE_RATIO 4096
829 * conversion: abscent = log2(MHz / 8176) * 1200
832 freq_to_note(int mhz)
834 return snd_sf_linear_to_log(mhz, OFFSET_ABSCENT, ABSCENT_RATIO);
837 /* convert Hz to AWE32 rate offset:
838 * sample pitch offset for the specified sample rate
839 * rate=44100 is no offset, each 4096 is 1 octave (twice).
840 * eg, when rate is 22050, this offset becomes -4096.
842 * conversion: offset = log2(Hz / 44100) * 4096
845 calc_rate_offset(int hz)
847 return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);
851 /* calculate GUS envelope time */
853 calc_gus_envelope_time(int rate, int start, int end)
856 r = (3 - ((rate >> 6) & 3)) * 3;
864 return (t * 10) / (p * 441);
867 /* convert envelope time parameter to soundfont parameters */
869 /* attack & decay/release time table (msec) */
870 static short attack_time_tbl[128] = {
871 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
872 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
873 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
874 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
875 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
876 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
877 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
878 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
881 static short decay_time_tbl[128] = {
882 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
883 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
884 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
885 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
886 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
887 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
888 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
889 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
892 /* delay time = 0x8000 - msec/92 */
894 snd_sf_calc_parm_hold(int msec)
896 int val = (0x7f * 92 - msec) / 92;
897 if (val < 1) val = 1;
898 if (val >= 126) val = 126;
902 /* search an index for specified time from given time table */
904 calc_parm_search(int msec, short *table)
906 int left = 1, right = 127, mid;
907 while (left < right) {
908 mid = (left + right) / 2;
909 if (msec < (int)table[mid])
917 /* attack time: search from time table */
919 snd_sf_calc_parm_attack(int msec)
921 return calc_parm_search(msec, attack_time_tbl);
924 /* decay/release time: search from time table */
926 snd_sf_calc_parm_decay(int msec)
928 return calc_parm_search(msec, decay_time_tbl);
931 int snd_sf_vol_table[128] = {
932 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
933 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
934 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
935 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
936 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
937 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
938 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
939 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
943 #define calc_gus_sustain(val) (0x7f - snd_sf_vol_table[(val)/2])
944 #define calc_gus_attenuation(val) snd_sf_vol_table[(val)/2]
948 load_guspatch(struct snd_sf_list *sflist, const char __user *data,
949 long count, int client)
951 struct patch_info patch;
952 struct snd_soundfont *sf;
953 struct snd_sf_zone *zone;
954 struct snd_sf_sample *smp;
958 if (count < (long)sizeof(patch)) {
959 snd_printk(KERN_ERR "patch record too small %ld\n", count);
962 if (copy_from_user(&patch, data, sizeof(patch)))
965 count -= sizeof(patch);
966 data += sizeof(patch);
968 sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
971 if ((smp = sf_sample_new(sflist, sf)) == NULL)
973 sample_id = sflist->sample_counter;
974 smp->v.sample = sample_id;
976 smp->v.end = patch.len;
977 smp->v.loopstart = patch.loop_start;
978 smp->v.loopend = patch.loop_end;
979 smp->v.size = patch.len;
981 /* set up mode flags */
982 smp->v.mode_flags = 0;
983 if (!(patch.mode & WAVE_16_BITS))
984 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_8BITS;
985 if (patch.mode & WAVE_UNSIGNED)
986 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_UNSIGNED;
987 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_NO_BLANK;
988 if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
989 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_SINGLESHOT;
990 if (patch.mode & WAVE_BIDIR_LOOP)
991 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_BIDIR_LOOP;
992 if (patch.mode & WAVE_LOOP_BACK)
993 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_REVERSE_LOOP;
995 if (patch.mode & WAVE_16_BITS) {
996 /* convert to word offsets */
999 smp->v.loopstart /= 2;
1000 smp->v.loopend /= 2;
1002 /*smp->v.loopend++;*/
1005 smp->v.truesize = 0;
1006 smp->v.sf_id = sf->id;
1008 /* set up voice info */
1009 if ((zone = sf_zone_new(sflist, sf)) == NULL) {
1010 sf_sample_delete(sflist, sf, smp);
1017 if (sflist->callback.sample_new) {
1018 rc = sflist->callback.sample_new
1019 (sflist->callback.private_data, smp, sflist->memhdr,
1022 sf_sample_delete(sflist, sf, smp);
1025 /* memory offset is updated after */
1028 /* update the memory offset here */
1029 sflist->mem_used += smp->v.truesize;
1031 zone->v.sample = sample_id; /* the last sample */
1032 zone->v.rate_offset = calc_rate_offset(patch.base_freq);
1033 note = freq_to_note(patch.base_note);
1034 zone->v.root = note / 100;
1035 zone->v.tune = -(note % 100);
1036 zone->v.low = (freq_to_note(patch.low_note) + 99) / 100;
1037 zone->v.high = freq_to_note(patch.high_note) / 100;
1038 /* panning position; -128 - 127 => 0-127 */
1039 zone->v.pan = (patch.panning + 128) / 2;
1041 snd_printk(KERN_DEBUG
1042 "gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
1043 (int)patch.base_freq, zone->v.rate_offset,
1044 zone->v.root, zone->v.tune, zone->v.low, zone->v.high);
1047 /* detuning is ignored */
1048 /* 6points volume envelope */
1049 if (patch.mode & WAVE_ENVELOPES) {
1050 int attack, hold, decay, release;
1051 attack = calc_gus_envelope_time
1052 (patch.env_rate[0], 0, patch.env_offset[0]);
1053 hold = calc_gus_envelope_time
1054 (patch.env_rate[1], patch.env_offset[0],
1055 patch.env_offset[1]);
1056 decay = calc_gus_envelope_time
1057 (patch.env_rate[2], patch.env_offset[1],
1058 patch.env_offset[2]);
1059 release = calc_gus_envelope_time
1060 (patch.env_rate[3], patch.env_offset[1],
1061 patch.env_offset[4]);
1062 release += calc_gus_envelope_time
1063 (patch.env_rate[4], patch.env_offset[3],
1064 patch.env_offset[4]);
1065 release += calc_gus_envelope_time
1066 (patch.env_rate[5], patch.env_offset[4],
1067 patch.env_offset[5]);
1068 zone->v.parm.volatkhld =
1069 (snd_sf_calc_parm_hold(hold) << 8) |
1070 snd_sf_calc_parm_attack(attack);
1071 zone->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
1072 snd_sf_calc_parm_decay(decay);
1073 zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release);
1074 zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]);
1076 snd_printk(KERN_DEBUG
1077 "gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
1078 zone->v.parm.volatkhld,
1079 zone->v.parm.voldcysus,
1080 zone->v.parm.volrelease,
1081 zone->v.attenuation);
1086 if (patch.mode & WAVE_FAST_RELEASE) {
1087 zone->v.parm.volrelease = 0x807f;
1090 /* tremolo effect */
1091 if (patch.mode & WAVE_TREMOLO) {
1092 int rate = (patch.tremolo_rate * 1000 / 38) / 42;
1093 zone->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
1095 /* vibrato effect */
1096 if (patch.mode & WAVE_VIBRATO) {
1097 int rate = (patch.vibrato_rate * 1000 / 38) / 42;
1098 zone->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
1101 /* scale_freq, scale_factor, volume, and fractions not implemented */
1103 if (!(smp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT))
1104 zone->v.mode = SNDRV_SFNT_MODE_LOOPING;
1108 /* append to the tail of the list */
1109 /*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
1111 zone->instr = patch.instr_no;
1113 zone->v.sf_id = sf->id;
1115 zone->sample = set_sample(sf, &zone->v);
1117 /* rebuild preset now */
1118 add_preset(sflist, zone);
1123 /* load GUS patch */
1125 snd_soundfont_load_guspatch(struct snd_sf_list *sflist, const char __user *data,
1126 long count, int client)
1129 lock_preset(sflist);
1130 rc = load_guspatch(sflist, data, count, client);
1131 unlock_preset(sflist);
1137 * Rebuild the preset table. This is like a hash table in that it allows
1138 * quick access to the zone information. For each preset there are zone
1139 * structures linked by next_instr and by next_zone. Former is the whole
1140 * link for this preset, and latter is the link for zone (i.e. instrument/
1141 * bank/key combination).
1144 rebuild_presets(struct snd_sf_list *sflist)
1146 struct snd_soundfont *sf;
1147 struct snd_sf_zone *cur;
1149 /* clear preset table */
1150 memset(sflist->presets, 0, sizeof(sflist->presets));
1152 /* search all fonts and insert each font */
1153 for (sf = sflist->fonts; sf; sf = sf->next) {
1154 for (cur = sf->zones; cur; cur = cur->next) {
1155 if (! cur->mapped && cur->sample == NULL) {
1156 /* try again to search the corresponding sample */
1157 cur->sample = set_sample(sf, &cur->v);
1158 if (cur->sample == NULL)
1162 add_preset(sflist, cur);
1169 * add the given zone to preset table
1172 add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur)
1174 struct snd_sf_zone *zone;
1177 zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
1178 if (zone && zone->v.sf_id != cur->v.sf_id) {
1179 /* different instrument was already defined */
1180 struct snd_sf_zone *p;
1181 /* compare the allocated time */
1182 for (p = zone; p; p = p->next_zone) {
1183 if (p->counter > cur->counter)
1184 /* the current is older.. skipped */
1187 /* remove old zones */
1188 delete_preset(sflist, zone);
1189 zone = NULL; /* do not forget to clear this! */
1192 /* prepend this zone */
1193 if ((index = get_index(cur->bank, cur->instr, cur->v.low)) < 0)
1195 cur->next_zone = zone; /* zone link */
1196 cur->next_instr = sflist->presets[index]; /* preset table link */
1197 sflist->presets[index] = cur;
1201 * delete the given zones from preset_table
1204 delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp)
1207 struct snd_sf_zone *p;
1209 if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
1211 for (p = sflist->presets[index]; p; p = p->next_instr) {
1212 while (p->next_instr == zp) {
1213 p->next_instr = zp->next_instr;
1223 * Search matching zones from preset table.
1224 * The note can be rewritten by preset mapping (alias).
1225 * The found zones are stored on 'table' array. max_layers defines
1226 * the maximum number of elements in this array.
1227 * This function returns the number of found zones. 0 if not found.
1230 snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
1231 int preset, int bank,
1232 int def_preset, int def_bank,
1233 struct snd_sf_zone **table, int max_layers)
1236 unsigned long flags;
1238 /* this function is supposed to be called atomically,
1239 * so we check the lock. if it's busy, just returns 0 to
1240 * tell the caller the busy state
1242 spin_lock_irqsave(&sflist->lock, flags);
1243 if (sflist->presets_locked) {
1244 spin_unlock_irqrestore(&sflist->lock, flags);
1247 nvoices = search_zones(sflist, notep, vel, preset, bank,
1248 table, max_layers, 0);
1250 if (preset != def_preset || bank != def_bank)
1251 nvoices = search_zones(sflist, notep, vel,
1252 def_preset, def_bank,
1253 table, max_layers, 0);
1255 spin_unlock_irqrestore(&sflist->lock, flags);
1261 * search the first matching zone
1263 static struct snd_sf_zone *
1264 search_first_zone(struct snd_sf_list *sflist, int bank, int preset, int key)
1267 struct snd_sf_zone *zp;
1269 if ((index = get_index(bank, preset, key)) < 0)
1271 for (zp = sflist->presets[index]; zp; zp = zp->next_instr) {
1272 if (zp->instr == preset && zp->bank == bank)
1280 * search matching zones from sflist. can be called recursively.
1283 search_zones(struct snd_sf_list *sflist, int *notep, int vel,
1284 int preset, int bank, struct snd_sf_zone **table,
1285 int max_layers, int level)
1287 struct snd_sf_zone *zp;
1290 zp = search_first_zone(sflist, bank, preset, *notep);
1292 for (; zp; zp = zp->next_zone) {
1293 if (*notep >= zp->v.low && *notep <= zp->v.high &&
1294 vel >= zp->v.vellow && vel <= zp->v.velhigh) {
1296 /* search preset mapping (aliasing) */
1297 int key = zp->v.fixkey;
1298 preset = zp->v.start;
1301 if (level > 5) /* too deep alias level */
1305 nvoices = search_zones(sflist, &key, vel,
1306 preset, bank, table,
1307 max_layers, level + 1);
1312 table[nvoices++] = zp;
1313 if (nvoices >= max_layers)
1322 /* calculate the index of preset table:
1323 * drums are mapped from 128 to 255 according to its note key.
1324 * other instruments are mapped from 0 to 127.
1325 * if the index is out of range, return -1.
1328 get_index(int bank, int instr, int key)
1331 if (SF_IS_DRUM_BANK(bank))
1332 index = key + SF_MAX_INSTRUMENTS;
1335 index = index % SF_MAX_PRESETS;
1342 * Initialise the sflist structure.
1345 snd_sf_init(struct snd_sf_list *sflist)
1347 memset(sflist->presets, 0, sizeof(sflist->presets));
1349 sflist->mem_used = 0;
1350 sflist->currsf = NULL;
1351 sflist->open_client = -1;
1352 sflist->fonts = NULL;
1353 sflist->fonts_size = 0;
1354 sflist->zone_counter = 0;
1355 sflist->sample_counter = 0;
1356 sflist->zone_locked = 0;
1357 sflist->sample_locked = 0;
1361 * Release all list records
1364 snd_sf_clear(struct snd_sf_list *sflist)
1366 struct snd_soundfont *sf, *nextsf;
1367 struct snd_sf_zone *zp, *nextzp;
1368 struct snd_sf_sample *sp, *nextsp;
1370 for (sf = sflist->fonts; sf; sf = nextsf) {
1372 for (zp = sf->zones; zp; zp = nextzp) {
1376 for (sp = sf->samples; sp; sp = nextsp) {
1378 if (sflist->callback.sample_free)
1379 sflist->callback.sample_free(sflist->callback.private_data,
1380 sp, sflist->memhdr);
1386 snd_sf_init(sflist);
1391 * Create a new sflist structure
1393 struct snd_sf_list *
1394 snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr)
1396 struct snd_sf_list *sflist;
1398 if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL)
1401 mutex_init(&sflist->presets_mutex);
1402 spin_lock_init(&sflist->lock);
1403 sflist->memhdr = hdr;
1406 sflist->callback = *callback;
1408 snd_sf_init(sflist);
1414 * Free everything allocated off the sflist structure.
1417 snd_sf_free(struct snd_sf_list *sflist)
1422 lock_preset(sflist);
1423 if (sflist->callback.sample_reset)
1424 sflist->callback.sample_reset(sflist->callback.private_data);
1425 snd_sf_clear(sflist);
1426 unlock_preset(sflist);
1432 * Remove all samples
1433 * The soundcard should be silet before calling this function.
1436 snd_soundfont_remove_samples(struct snd_sf_list *sflist)
1438 lock_preset(sflist);
1439 if (sflist->callback.sample_reset)
1440 sflist->callback.sample_reset(sflist->callback.private_data);
1441 snd_sf_clear(sflist);
1442 unlock_preset(sflist);
1448 * Remove unlocked samples.
1449 * The soundcard should be silent before calling this function.
1452 snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
1454 struct snd_soundfont *sf;
1455 struct snd_sf_zone *zp, *nextzp;
1456 struct snd_sf_sample *sp, *nextsp;
1458 lock_preset(sflist);
1460 if (sflist->callback.sample_reset)
1461 sflist->callback.sample_reset(sflist->callback.private_data);
1464 memset(sflist->presets, 0, sizeof(sflist->presets));
1466 for (sf = sflist->fonts; sf; sf = sf->next) {
1467 for (zp = sf->zones; zp; zp = nextzp) {
1468 if (zp->counter < sflist->zone_locked)
1475 for (sp = sf->samples; sp; sp = nextsp) {
1476 if (sp->counter < sflist->sample_locked)
1479 sf->samples = nextsp;
1480 sflist->mem_used -= sp->v.truesize;
1481 if (sflist->callback.sample_free)
1482 sflist->callback.sample_free(sflist->callback.private_data,
1483 sp, sflist->memhdr);
1488 sflist->zone_counter = sflist->zone_locked;
1489 sflist->sample_counter = sflist->sample_locked;
1491 rebuild_presets(sflist);
1493 unlock_preset(sflist);