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 <sound/driver.h>
29 #include <asm/uaccess.h>
30 #include <linux/slab.h>
31 #include <sound/core.h>
32 #include <sound/soundfont.h>
33 #include <sound/seq_oss_legacy.h>
35 /* Prototypes for static functions */
37 static int open_patch(snd_sf_list_t *sflist, const char *data, int count, int client);
38 static snd_soundfont_t *newsf(snd_sf_list_t *sflist, int type, char *name);
39 static int is_identical_font(snd_soundfont_t *sf, int type, unsigned char *name);
40 static int close_patch(snd_sf_list_t *sflist);
41 static int probe_data(snd_sf_list_t *sflist, int sample_id);
42 static void set_zone_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_zone_t *zp);
43 static snd_sf_zone_t *sf_zone_new(snd_sf_list_t *sflist, snd_soundfont_t *sf);
44 static void set_sample_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp);
45 static snd_sf_sample_t *sf_sample_new(snd_sf_list_t *sflist, snd_soundfont_t *sf);
46 static void sf_sample_delete(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp);
47 static int load_map(snd_sf_list_t *sflist, const void __user *data, int count);
48 static int load_info(snd_sf_list_t *sflist, const void __user *data, long count);
49 static int remove_info(snd_sf_list_t *sflist, snd_soundfont_t *sf, int bank, int instr);
50 static void init_voice_info(soundfont_voice_info_t *avp);
51 static void init_voice_parm(soundfont_voice_parm_t *pp);
52 static snd_sf_sample_t *set_sample(snd_soundfont_t *sf, soundfont_voice_info_t *avp);
53 static snd_sf_sample_t *find_sample(snd_soundfont_t *sf, int sample_id);
54 static int load_data(snd_sf_list_t *sflist, const void __user *data, long count);
55 static void rebuild_presets(snd_sf_list_t *sflist);
56 static void add_preset(snd_sf_list_t *sflist, snd_sf_zone_t *cur);
57 static void delete_preset(snd_sf_list_t *sflist, snd_sf_zone_t *zp);
58 static snd_sf_zone_t *search_first_zone(snd_sf_list_t *sflist, int bank, int preset, int key);
59 static int search_zones(snd_sf_list_t *sflist, int *notep, int vel, int preset, int bank, snd_sf_zone_t **table, int max_layers, int level);
60 static int get_index(int bank, int instr, int key);
61 static void snd_sf_init(snd_sf_list_t *sflist);
62 static void snd_sf_clear(snd_sf_list_t *sflist);
65 * lock access to sflist
68 lock_preset(snd_sf_list_t *sflist, int nonblock)
71 if (down_trylock(&sflist->presets_mutex))
74 down(&sflist->presets_mutex);
83 unlock_preset(snd_sf_list_t *sflist)
85 up(&sflist->presets_mutex);
90 * close the patch if the patch was opened by this client.
93 snd_soundfont_close_check(snd_sf_list_t *sflist, int client)
96 spin_lock_irqsave(&sflist->lock, flags);
97 if (sflist->open_client == client) {
98 spin_unlock_irqrestore(&sflist->lock, flags);
99 return close_patch(sflist);
101 spin_unlock_irqrestore(&sflist->lock, flags);
107 * Deal with a soundfont patch. Any driver could use these routines
108 * although it was designed for the AWE64.
110 * The sample_write and callargs pararameters allow a callback into
111 * the actual driver to write sample data to the board or whatever
112 * it wants to do with it.
115 snd_soundfont_load(snd_sf_list_t *sflist, const void __user *data, long count, int client)
117 soundfont_patch_info_t patch;
121 if (count < (long)sizeof(patch)) {
122 snd_printk("patch record too small %ld\n", count);
125 if (copy_from_user(&patch, data, sizeof(patch)))
128 count -= sizeof(patch);
129 data += sizeof(patch);
131 if (patch.key != SNDRV_OSS_SOUNDFONT_PATCH) {
132 snd_printk("'The wrong kind of patch' %x\n", patch.key);
135 if (count < patch.len) {
136 snd_printk("Patch too short %ld, need %d\n", count, patch.len);
140 snd_printk("poor length %d\n", patch.len);
144 if (patch.type == SNDRV_SFNT_OPEN_PATCH) {
145 /* grab sflist to open */
146 lock_preset(sflist, 0);
147 rc = open_patch(sflist, data, count, client);
148 unlock_preset(sflist);
152 /* check if other client already opened patch */
153 spin_lock_irqsave(&sflist->lock, flags);
154 if (sflist->open_client != client) {
155 spin_unlock_irqrestore(&sflist->lock, flags);
158 spin_unlock_irqrestore(&sflist->lock, flags);
160 lock_preset(sflist, 0);
162 switch (patch.type) {
163 case SNDRV_SFNT_LOAD_INFO:
164 rc = load_info(sflist, data, count);
166 case SNDRV_SFNT_LOAD_DATA:
167 rc = load_data(sflist, data, count);
169 case SNDRV_SFNT_CLOSE_PATCH:
170 rc = close_patch(sflist);
172 case SNDRV_SFNT_REPLACE_DATA:
173 /*rc = replace_data(&patch, data, count);*/
175 case SNDRV_SFNT_MAP_PRESET:
176 rc = load_map(sflist, data, count);
178 case SNDRV_SFNT_PROBE_DATA:
179 rc = probe_data(sflist, patch.optarg);
181 case SNDRV_SFNT_REMOVE_INFO:
182 /* patch must be opened */
183 if (sflist->currsf) {
184 snd_printk("soundfont: remove_info: patch not opened\n");
188 bank = ((unsigned short)patch.optarg >> 8) & 0xff;
189 instr = (unsigned short)patch.optarg & 0xff;
190 if (! remove_info(sflist, sflist->currsf, bank, instr))
197 unlock_preset(sflist);
203 /* check if specified type is special font (GUS or preset-alias) */
205 is_special_type(int type)
208 return (type == SNDRV_SFNT_PAT_TYPE_GUS ||
209 type == SNDRV_SFNT_PAT_TYPE_MAP);
213 /* open patch; create sf list */
215 open_patch(snd_sf_list_t *sflist, const char __user *data, int count, int client)
217 soundfont_open_parm_t parm;
221 spin_lock_irqsave(&sflist->lock, flags);
222 if (sflist->open_client >= 0 || sflist->currsf) {
223 spin_unlock_irqrestore(&sflist->lock, flags);
226 spin_unlock_irqrestore(&sflist->lock, flags);
228 if (copy_from_user(&parm, data, sizeof(parm)))
231 if (is_special_type(parm.type)) {
232 parm.type |= SNDRV_SFNT_PAT_SHARED;
233 sf = newsf(sflist, parm.type, NULL);
235 sf = newsf(sflist, parm.type, parm.name);
240 sflist->open_client = client;
247 * Allocate a new soundfont structure.
249 static snd_soundfont_t *
250 newsf(snd_sf_list_t *sflist, int type, char *name)
254 /* check the shared fonts */
255 if (type & SNDRV_SFNT_PAT_SHARED) {
256 for (sf = sflist->fonts; sf; sf = sf->next) {
257 if (is_identical_font(sf, type, name)) {
263 /* not found -- create a new one */
264 sf = (snd_soundfont_t*)snd_kcalloc(sizeof(*sf), GFP_KERNEL);
267 sf->id = sflist->fonts_size;
268 sflist->fonts_size++;
270 /* prepend this record */
271 sf->next = sflist->fonts;
278 memcpy(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN);
283 /* check if the given name matches to the existing list */
285 is_identical_font(snd_soundfont_t *sf, int type, unsigned char *name)
287 return ((sf->type & SNDRV_SFNT_PAT_SHARED) &&
288 (sf->type & 0x0f) == (type & 0x0f) &&
290 memcmp(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN) == 0));
294 * Close the current patch.
297 close_patch(snd_sf_list_t *sflist)
299 sflist->currsf = NULL;
300 sflist->open_client = -1;
302 rebuild_presets(sflist);
308 /* probe sample in the current list -- nothing to be loaded */
310 probe_data(snd_sf_list_t *sflist, int sample_id)
312 /* patch must be opened */
313 if (sflist->currsf) {
314 /* search the specified sample by optarg */
315 if (find_sample(sflist->currsf, sample_id))
322 * increment zone counter
325 set_zone_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_zone_t *zp)
327 zp->counter = sflist->zone_counter++;
328 if (sf->type & SNDRV_SFNT_PAT_LOCKED)
329 sflist->zone_locked = sflist->zone_counter;
333 * allocate a new zone record
335 static snd_sf_zone_t *
336 sf_zone_new(snd_sf_list_t *sflist, snd_soundfont_t *sf)
340 if ((zp = snd_kcalloc(sizeof(*zp), GFP_KERNEL)) == NULL)
342 zp->next = sf->zones;
345 init_voice_info(&zp->v);
347 set_zone_counter(sflist, sf, zp);
353 * increment sample couter
356 set_sample_counter(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp)
358 sp->counter = sflist->sample_counter++;
359 if (sf->type & SNDRV_SFNT_PAT_LOCKED)
360 sflist->sample_locked = sflist->sample_counter;
364 * allocate a new sample list record
366 static snd_sf_sample_t *
367 sf_sample_new(snd_sf_list_t *sflist, snd_soundfont_t *sf)
371 if ((sp = snd_kcalloc(sizeof(*sp), GFP_KERNEL)) == NULL)
374 sp->next = sf->samples;
377 set_sample_counter(sflist, sf, sp);
382 * delete sample list -- this is an exceptional job.
383 * only the last allocated sample can be deleted.
386 sf_sample_delete(snd_sf_list_t *sflist, snd_soundfont_t *sf, snd_sf_sample_t *sp)
388 /* only last sample is accepted */
389 if (sp == sf->samples) {
390 sf->samples = sp->next;
398 load_map(snd_sf_list_t *sflist, const void __user *data, int count)
400 snd_sf_zone_t *zp, *prevp;
402 soundfont_voice_map_t map;
404 /* get the link info */
405 if (count < (int)sizeof(map))
407 if (copy_from_user(&map, data, sizeof(map)))
410 if (map.map_instr < 0 || map.map_instr >= SF_MAX_INSTRUMENTS)
413 sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_MAP|SNDRV_SFNT_PAT_SHARED, NULL);
418 for (zp = sf->zones; zp; prevp = zp, zp = zp->next) {
420 zp->instr == map.map_instr &&
421 zp->bank == map.map_bank &&
422 zp->v.low == map.map_key &&
423 zp->v.start == map.src_instr &&
424 zp->v.end == map.src_bank &&
425 zp->v.fixkey == map.src_key) {
426 /* the same mapping is already present */
427 /* relink this record to the link head */
429 prevp->next = zp->next;
430 zp->next = sf->zones;
433 /* update the counter */
434 set_zone_counter(sflist, sf, zp);
439 /* create a new zone */
440 if ((zp = sf_zone_new(sflist, sf)) == NULL)
443 zp->bank = map.map_bank;
444 zp->instr = map.map_instr;
446 if (map.map_key >= 0) {
447 zp->v.low = map.map_key;
448 zp->v.high = map.map_key;
450 zp->v.start = map.src_instr;
451 zp->v.end = map.src_bank;
452 zp->v.fixkey = map.src_key;
453 zp->v.sf_id = sf->id;
455 add_preset(sflist, zp);
461 /* remove the present instrument layers */
463 remove_info(snd_sf_list_t *sflist, snd_soundfont_t *sf, int bank, int instr)
465 snd_sf_zone_t *prev, *next, *p;
469 for (p = sf->zones; p; p = next) {
472 p->bank == bank && p->instr == instr) {
473 /* remove this layer */
484 rebuild_presets(sflist);
490 * Read an info record from the user buffer and save it on the current
494 load_info(snd_sf_list_t *sflist, const void __user *data, long count)
498 soundfont_voice_rec_hdr_t hdr;
501 /* patch must be opened */
502 if ((sf = sflist->currsf) == NULL)
505 if (is_special_type(sf->type))
508 if (count < (long)sizeof(hdr)) {
509 printk("Soundfont error: invalid patch zone length\n");
512 if (copy_from_user((char*)&hdr, data, sizeof(hdr)))
516 count -= sizeof(hdr);
518 if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
519 printk("Soundfont error: Illegal voice number %d\n", hdr.nvoices);
523 if (count < (long)sizeof(soundfont_voice_info_t)*hdr.nvoices) {
524 printk("Soundfont Error: patch length(%ld) is smaller than nvoices(%d)\n",
529 switch (hdr.write_mode) {
530 case SNDRV_SFNT_WR_EXCLUSIVE:
531 /* exclusive mode - if the instrument already exists,
533 for (zone = sf->zones; zone; zone = zone->next) {
535 zone->bank == hdr.bank &&
536 zone->instr == hdr.instr)
540 case SNDRV_SFNT_WR_REPLACE:
541 /* replace mode - remove the instrument if it already exists */
542 remove_info(sflist, sf, hdr.bank, hdr.instr);
546 for (i = 0; i < hdr.nvoices; i++) {
547 snd_sf_zone_t tmpzone;
549 /* copy awe_voice_info parameters */
550 if (copy_from_user(&tmpzone.v, data, sizeof(tmpzone.v))) {
554 data += sizeof(tmpzone.v);
555 count -= sizeof(tmpzone.v);
557 tmpzone.bank = hdr.bank;
558 tmpzone.instr = hdr.instr;
560 tmpzone.v.sf_id = sf->id;
561 if (tmpzone.v.mode & SNDRV_SFNT_MODE_INIT_PARM)
562 init_voice_parm(&tmpzone.v.parm);
564 /* create a new zone */
565 if ((zone = sf_zone_new(sflist, sf)) == NULL) {
569 /* copy the temporary data */
570 zone->bank = tmpzone.bank;
571 zone->instr = tmpzone.instr;
574 /* look up the sample */
575 zone->sample = set_sample(sf, &zone->v);
582 /* initialize voice_info record */
584 init_voice_info(soundfont_voice_info_t *avp)
586 memset(avp, 0, sizeof(*avp));
595 avp->amplitude = 127;
596 avp->scaleTuning = 100;
598 init_voice_parm(&avp->parm);
601 /* initialize voice_parm record:
602 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
603 * Vibrato and Tremolo effects are zero.
605 * Chorus and Reverb effects are zero.
608 init_voice_parm(soundfont_voice_parm_t *pp)
610 memset(pp, 0, sizeof(*pp));
612 pp->moddelay = 0x8000;
613 pp->modatkhld = 0x7f7f;
614 pp->moddcysus = 0x7f7f;
615 pp->modrelease = 0x807f;
617 pp->voldelay = 0x8000;
618 pp->volatkhld = 0x7f7f;
619 pp->voldcysus = 0x7f7f;
620 pp->volrelease = 0x807f;
622 pp->lfo1delay = 0x8000;
623 pp->lfo2delay = 0x8000;
628 /* search the specified sample */
629 static snd_sf_sample_t *
630 set_sample(snd_soundfont_t *sf, soundfont_voice_info_t *avp)
632 snd_sf_sample_t *sample;
634 sample = find_sample(sf, avp->sample);
638 /* add in the actual sample offsets:
639 * The voice_info addresses define only the relative offset
640 * from sample pointers. Here we calculate the actual DRAM
641 * offset from sample pointers.
643 avp->start += sample->v.start;
644 avp->end += sample->v.end;
645 avp->loopstart += sample->v.loopstart;
646 avp->loopend += sample->v.loopend;
648 /* copy mode flags */
649 avp->sample_mode = sample->v.mode_flags;
654 /* find the sample pointer with the given id in the soundfont */
655 static snd_sf_sample_t *
656 find_sample(snd_soundfont_t *sf, int sample_id)
663 for (p = sf->samples; p; p = p->next) {
664 if (p->v.sample == sample_id)
672 * Load sample information, this can include data to be loaded onto
673 * the soundcard. It can also just be a pointer into soundcard ROM.
674 * If there is data it will be written to the soundcard via the callback
678 load_data(snd_sf_list_t *sflist, const void __user *data, long count)
681 soundfont_sample_info_t sample_info;
685 /* patch must be opened */
686 if ((sf = sflist->currsf) == NULL)
689 if (is_special_type(sf->type))
692 if (copy_from_user(&sample_info, data, sizeof(sample_info)))
695 off = sizeof(sample_info);
697 if (sample_info.size != (count-off)/2)
701 if (find_sample(sf, sample_info.sample)) {
702 /* if shared sample, skip this data */
703 if (sf->type & SNDRV_SFNT_PAT_SHARED)
708 /* Allocate a new sample structure */
709 if ((sp = sf_sample_new(sflist, sf)) == NULL)
713 sp->v.sf_id = sf->id;
715 sp->v.truesize = sp->v.size;
718 * If there is wave data then load it.
720 if (sp->v.size > 0) {
722 rc = sflist->callback.sample_new
723 (sflist->callback.private_data, sp, sflist->memhdr,
724 data + off, count - off);
726 sf_sample_delete(sflist, sf, sp);
729 sflist->mem_used += sp->v.truesize;
736 /* log2_tbl[i] = log2(i+128) * 0x10000 */
737 static int log_tbl[129] = {
738 0x70000, 0x702df, 0x705b9, 0x7088e, 0x70b5d, 0x70e26, 0x710eb, 0x713aa,
739 0x71663, 0x71918, 0x71bc8, 0x71e72, 0x72118, 0x723b9, 0x72655, 0x728ed,
740 0x72b80, 0x72e0e, 0x73098, 0x7331d, 0x7359e, 0x7381b, 0x73a93, 0x73d08,
741 0x73f78, 0x741e4, 0x7444c, 0x746b0, 0x74910, 0x74b6c, 0x74dc4, 0x75019,
742 0x75269, 0x754b6, 0x75700, 0x75946, 0x75b88, 0x75dc7, 0x76002, 0x7623a,
743 0x7646e, 0x766a0, 0x768cd, 0x76af8, 0x76d1f, 0x76f43, 0x77164, 0x77382,
744 0x7759d, 0x777b4, 0x779c9, 0x77bdb, 0x77dea, 0x77ff5, 0x781fe, 0x78404,
745 0x78608, 0x78808, 0x78a06, 0x78c01, 0x78df9, 0x78fef, 0x791e2, 0x793d2,
746 0x795c0, 0x797ab, 0x79993, 0x79b79, 0x79d5d, 0x79f3e, 0x7a11d, 0x7a2f9,
747 0x7a4d3, 0x7a6ab, 0x7a880, 0x7aa53, 0x7ac24, 0x7adf2, 0x7afbe, 0x7b188,
748 0x7b350, 0x7b515, 0x7b6d8, 0x7b899, 0x7ba58, 0x7bc15, 0x7bdd0, 0x7bf89,
749 0x7c140, 0x7c2f5, 0x7c4a7, 0x7c658, 0x7c807, 0x7c9b3, 0x7cb5e, 0x7cd07,
750 0x7ceae, 0x7d053, 0x7d1f7, 0x7d398, 0x7d538, 0x7d6d6, 0x7d872, 0x7da0c,
751 0x7dba4, 0x7dd3b, 0x7ded0, 0x7e063, 0x7e1f4, 0x7e384, 0x7e512, 0x7e69f,
752 0x7e829, 0x7e9b3, 0x7eb3a, 0x7ecc0, 0x7ee44, 0x7efc7, 0x7f148, 0x7f2c8,
753 0x7f446, 0x7f5c2, 0x7f73d, 0x7f8b7, 0x7fa2f, 0x7fba5, 0x7fd1a, 0x7fe8d,
757 /* convert from linear to log value
759 * conversion: value = log2(amount / base) * ratio
762 * amount = linear value (unsigned, 32bit max)
763 * offset = base offset (:= log2(base) * 0x10000)
764 * ratio = division ratio
768 snd_sf_linear_to_log(unsigned int amount, int offset, int ratio)
775 for (bit = 0; ! (amount & 0x80000000L); bit++)
777 s = (amount >> 24) & 0x7f;
778 low = (amount >> 16) & 0xff;
779 /* linear approxmimation by lower 8 bit */
780 v = (log_tbl[s + 1] * low + log_tbl[s] * (0x100 - low)) >> 8;
782 v = (v * ratio) >> 16;
783 v += (24 - bit) * ratio;
787 #define OFFSET_MSEC 653117 /* base = 1000 */
788 #define OFFSET_ABSCENT 851781 /* base = 8176 */
789 #define OFFSET_SAMPLERATE 1011119 /* base = 44100 */
791 #define ABSCENT_RATIO 1200
792 #define TIMECENT_RATIO 1200
793 #define SAMPLERATE_RATIO 4096
797 * conversion: abscent = log2(MHz / 8176) * 1200
800 freq_to_note(int mhz)
802 return snd_sf_linear_to_log(mhz, OFFSET_ABSCENT, ABSCENT_RATIO);
805 /* convert Hz to AWE32 rate offset:
806 * sample pitch offset for the specified sample rate
807 * rate=44100 is no offset, each 4096 is 1 octave (twice).
808 * eg, when rate is 22050, this offset becomes -4096.
810 * conversion: offset = log2(Hz / 44100) * 4096
813 calc_rate_offset(int hz)
815 return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);
819 /* calculate GUS envelope time */
821 calc_gus_envelope_time(int rate, int start, int end)
824 r = (3 - ((rate >> 6) & 3)) * 3;
832 return (t * 10) / (p * 441);
835 /* convert envelope time parameter to soundfont parameters */
837 /* attack & decay/release time table (msec) */
838 static short attack_time_tbl[128] = {
839 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
840 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
841 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
842 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
843 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
844 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
845 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
846 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
849 static short decay_time_tbl[128] = {
850 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
851 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
852 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
853 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
854 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
855 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
856 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
857 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
860 /* delay time = 0x8000 - msec/92 */
862 snd_sf_calc_parm_hold(int msec)
864 int val = (0x7f * 92 - msec) / 92;
865 if (val < 1) val = 1;
866 if (val >= 126) val = 126;
870 /* search an index for specified time from given time table */
872 calc_parm_search(int msec, short *table)
874 int left = 1, right = 127, mid;
875 while (left < right) {
876 mid = (left + right) / 2;
877 if (msec < (int)table[mid])
885 /* attack time: search from time table */
887 snd_sf_calc_parm_attack(int msec)
889 return calc_parm_search(msec, attack_time_tbl);
892 /* decay/release time: search from time table */
894 snd_sf_calc_parm_decay(int msec)
896 return calc_parm_search(msec, decay_time_tbl);
899 int snd_sf_vol_table[128] = {
900 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
901 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
902 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
903 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
904 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
905 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
906 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
907 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
911 #define calc_gus_sustain(val) (0x7f - snd_sf_vol_table[(val)/2])
912 #define calc_gus_attenuation(val) snd_sf_vol_table[(val)/2]
916 load_guspatch(snd_sf_list_t *sflist, const char __user *data, long count, int client)
918 struct patch_info patch;
921 snd_sf_sample_t *smp;
925 if (count < (long)sizeof(patch)) {
926 snd_printk("patch record too small %ld\n", count);
929 if (copy_from_user(&patch, data, sizeof(patch)))
932 count -= sizeof(patch);
933 data += sizeof(patch);
935 sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
938 if ((smp = sf_sample_new(sflist, sf)) == NULL)
940 sample_id = sflist->sample_counter;
941 smp->v.sample = sample_id;
943 smp->v.end = patch.len;
944 smp->v.loopstart = patch.loop_start;
945 smp->v.loopend = patch.loop_end;
946 smp->v.size = patch.len;
948 /* set up mode flags */
949 smp->v.mode_flags = 0;
950 if (!(patch.mode & WAVE_16_BITS))
951 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_8BITS;
952 if (patch.mode & WAVE_UNSIGNED)
953 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_UNSIGNED;
954 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_NO_BLANK;
955 if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
956 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_SINGLESHOT;
957 if (patch.mode & WAVE_BIDIR_LOOP)
958 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_BIDIR_LOOP;
959 if (patch.mode & WAVE_LOOP_BACK)
960 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_REVERSE_LOOP;
962 if (patch.mode & WAVE_16_BITS) {
963 /* convert to word offsets */
966 smp->v.loopstart /= 2;
969 /*smp->v.loopend++;*/
973 smp->v.sf_id = sf->id;
975 /* set up voice info */
976 if ((zone = sf_zone_new(sflist, sf)) == NULL) {
977 sf_sample_delete(sflist, sf, smp);
984 if (sflist->callback.sample_new) {
985 rc = sflist->callback.sample_new
986 (sflist->callback.private_data, smp, sflist->memhdr, data, count);
988 sf_sample_delete(sflist, sf, smp);
991 /* memory offset is updated after */
994 /* update the memory offset here */
995 sflist->mem_used += smp->v.truesize;
997 zone->v.sample = sample_id; /* the last sample */
998 zone->v.rate_offset = calc_rate_offset(patch.base_freq);
999 note = freq_to_note(patch.base_note);
1000 zone->v.root = note / 100;
1001 zone->v.tune = -(note % 100);
1002 zone->v.low = (freq_to_note(patch.low_note) + 99) / 100;
1003 zone->v.high = freq_to_note(patch.high_note) / 100;
1004 /* panning position; -128 - 127 => 0-127 */
1005 zone->v.pan = (patch.panning + 128) / 2;
1007 snd_printk("gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
1008 (int)patch.base_freq, zone->v.rate_offset,
1009 zone->v.root, zone->v.tune, zone->v.low, zone->v.high);
1012 /* detuning is ignored */
1013 /* 6points volume envelope */
1014 if (patch.mode & WAVE_ENVELOPES) {
1015 int attack, hold, decay, release;
1016 attack = calc_gus_envelope_time
1017 (patch.env_rate[0], 0, patch.env_offset[0]);
1018 hold = calc_gus_envelope_time
1019 (patch.env_rate[1], patch.env_offset[0],
1020 patch.env_offset[1]);
1021 decay = calc_gus_envelope_time
1022 (patch.env_rate[2], patch.env_offset[1],
1023 patch.env_offset[2]);
1024 release = calc_gus_envelope_time
1025 (patch.env_rate[3], patch.env_offset[1],
1026 patch.env_offset[4]);
1027 release += calc_gus_envelope_time
1028 (patch.env_rate[4], patch.env_offset[3],
1029 patch.env_offset[4]);
1030 release += calc_gus_envelope_time
1031 (patch.env_rate[5], patch.env_offset[4],
1032 patch.env_offset[5]);
1033 zone->v.parm.volatkhld =
1034 (snd_sf_calc_parm_hold(hold) << 8) |
1035 snd_sf_calc_parm_attack(attack);
1036 zone->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
1037 snd_sf_calc_parm_decay(decay);
1038 zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release);
1039 zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]);
1041 snd_printk("gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
1042 zone->v.parm.volatkhld,
1043 zone->v.parm.voldcysus,
1044 zone->v.parm.volrelease,
1045 zone->v.attenuation);
1050 if (patch.mode & WAVE_FAST_RELEASE) {
1051 zone->v.parm.volrelease = 0x807f;
1054 /* tremolo effect */
1055 if (patch.mode & WAVE_TREMOLO) {
1056 int rate = (patch.tremolo_rate * 1000 / 38) / 42;
1057 zone->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
1059 /* vibrato effect */
1060 if (patch.mode & WAVE_VIBRATO) {
1061 int rate = (patch.vibrato_rate * 1000 / 38) / 42;
1062 zone->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
1065 /* scale_freq, scale_factor, volume, and fractions not implemented */
1067 if (!(smp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT))
1068 zone->v.mode = SNDRV_SFNT_MODE_LOOPING;
1072 /* append to the tail of the list */
1073 /*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
1075 zone->instr = patch.instr_no;
1077 zone->v.sf_id = sf->id;
1079 zone->sample = set_sample(sf, &zone->v);
1081 /* rebuild preset now */
1082 add_preset(sflist, zone);
1087 /* load GUS patch */
1089 snd_soundfont_load_guspatch(snd_sf_list_t *sflist, const char __user *data,
1090 long count, int client)
1093 lock_preset(sflist, 0);
1094 rc = load_guspatch(sflist, data, count, client);
1095 unlock_preset(sflist);
1101 * Rebuild the preset table. This is like a hash table in that it allows
1102 * quick access to the zone information. For each preset there are zone
1103 * structures linked by next_instr and by next_zone. Former is the whole
1104 * link for this preset, and latter is the link for zone (i.e. instrument/
1105 * bank/key combination).
1108 rebuild_presets(snd_sf_list_t *sflist)
1110 snd_soundfont_t *sf;
1113 /* clear preset table */
1114 memset(sflist->presets, 0, sizeof(sflist->presets));
1116 /* search all fonts and insert each font */
1117 for (sf = sflist->fonts; sf; sf = sf->next) {
1118 for (cur = sf->zones; cur; cur = cur->next) {
1119 if (! cur->mapped && cur->sample == NULL) {
1120 /* try again to search the corresponding sample */
1121 cur->sample = set_sample(sf, &cur->v);
1122 if (cur->sample == NULL)
1126 add_preset(sflist, cur);
1133 * add the given zone to preset table
1136 add_preset(snd_sf_list_t *sflist, snd_sf_zone_t *cur)
1138 snd_sf_zone_t *zone;
1141 zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
1142 if (zone && zone->v.sf_id != cur->v.sf_id) {
1143 /* different instrument was already defined */
1145 /* compare the allocated time */
1146 for (p = zone; p; p = p->next_zone) {
1147 if (p->counter > cur->counter)
1148 /* the current is older.. skipped */
1151 /* remove old zones */
1152 delete_preset(sflist, zone);
1153 zone = NULL; /* do not forget to clear this! */
1156 /* prepend this zone */
1157 if ((index = get_index(cur->bank, cur->instr, cur->v.low)) < 0)
1159 cur->next_zone = zone; /* zone link */
1160 cur->next_instr = sflist->presets[index]; /* preset table link */
1161 sflist->presets[index] = cur;
1165 * delete the given zones from preset_table
1168 delete_preset(snd_sf_list_t *sflist, snd_sf_zone_t *zp)
1173 if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
1175 for (p = sflist->presets[index]; p; p = p->next_instr) {
1176 while (p->next_instr == zp) {
1177 p->next_instr = zp->next_instr;
1187 * Search matching zones from preset table.
1188 * The note can be rewritten by preset mapping (alias).
1189 * The found zones are stored on 'table' array. max_layers defines
1190 * the maximum number of elements in this array.
1191 * This function returns the number of found zones. 0 if not found.
1194 snd_soundfont_search_zone(snd_sf_list_t *sflist, int *notep, int vel,
1195 int preset, int bank,
1196 int def_preset, int def_bank,
1197 snd_sf_zone_t **table, int max_layers)
1201 if (lock_preset(sflist, 1))
1204 nvoices = search_zones(sflist, notep, vel, preset, bank, table, max_layers, 0);
1206 if (preset != def_preset || bank != def_bank)
1207 nvoices = search_zones(sflist, notep, vel, def_preset, def_bank, table, max_layers, 0);
1209 unlock_preset(sflist);
1216 * search the first matching zone
1218 static snd_sf_zone_t *
1219 search_first_zone(snd_sf_list_t *sflist, int bank, int preset, int key)
1224 if ((index = get_index(bank, preset, key)) < 0)
1226 for (zp = sflist->presets[index]; zp; zp = zp->next_instr) {
1227 if (zp->instr == preset && zp->bank == bank)
1235 * search matching zones from sflist. can be called recursively.
1238 search_zones(snd_sf_list_t *sflist, int *notep, int vel, int preset, int bank, snd_sf_zone_t **table, int max_layers, int level)
1243 zp = search_first_zone(sflist, bank, preset, *notep);
1245 for (; zp; zp = zp->next_zone) {
1246 if (*notep >= zp->v.low && *notep <= zp->v.high &&
1247 vel >= zp->v.vellow && vel <= zp->v.velhigh) {
1249 /* search preset mapping (aliasing) */
1250 int key = zp->v.fixkey;
1251 preset = zp->v.start;
1254 if (level > 5) /* too deep alias level */
1258 nvoices = search_zones(sflist, &key, vel,
1259 preset, bank, table,
1260 max_layers, level + 1);
1265 table[nvoices++] = zp;
1266 if (nvoices >= max_layers)
1275 /* calculate the index of preset table:
1276 * drums are mapped from 128 to 255 according to its note key.
1277 * other instruments are mapped from 0 to 127.
1278 * if the index is out of range, return -1.
1281 get_index(int bank, int instr, int key)
1284 if (SF_IS_DRUM_BANK(bank))
1285 index = key + SF_MAX_INSTRUMENTS;
1288 index = index % SF_MAX_PRESETS;
1295 * Initialise the sflist structure.
1298 snd_sf_init(snd_sf_list_t *sflist)
1300 memset(sflist->presets, 0, sizeof(sflist->presets));
1302 sflist->mem_used = 0;
1303 sflist->currsf = NULL;
1304 sflist->open_client = -1;
1305 sflist->fonts = NULL;
1306 sflist->fonts_size = 0;
1307 sflist->zone_counter = 0;
1308 sflist->sample_counter = 0;
1309 sflist->zone_locked = 0;
1310 sflist->sample_locked = 0;
1314 * Release all list records
1317 snd_sf_clear(snd_sf_list_t *sflist)
1319 snd_soundfont_t *sf, *nextsf;
1320 snd_sf_zone_t *zp, *nextzp;
1321 snd_sf_sample_t *sp, *nextsp;
1323 for (sf = sflist->fonts; sf; sf = nextsf) {
1325 for (zp = sf->zones; zp; zp = nextzp) {
1329 for (sp = sf->samples; sp; sp = nextsp) {
1331 if (sflist->callback.sample_free)
1332 sflist->callback.sample_free(sflist->callback.private_data, sp, sflist->memhdr);
1338 snd_sf_init(sflist);
1343 * Create a new sflist structure
1346 snd_sf_new(snd_sf_callback_t *callback, snd_util_memhdr_t *hdr)
1348 snd_sf_list_t *sflist;
1350 if ((sflist = snd_kcalloc(sizeof(snd_sf_list_t), GFP_KERNEL)) == NULL)
1353 init_MUTEX(&sflist->presets_mutex);
1354 spin_lock_init(&sflist->lock);
1355 sflist->memhdr = hdr;
1358 sflist->callback = *callback;
1360 snd_sf_init(sflist);
1366 * Free everything allocated off the sflist structure.
1369 snd_sf_free(snd_sf_list_t *sflist)
1374 lock_preset(sflist, 0);
1375 if (sflist->callback.sample_reset)
1376 sflist->callback.sample_reset(sflist->callback.private_data);
1377 snd_sf_clear(sflist);
1378 unlock_preset(sflist);
1384 * Remove all samples
1385 * The soundcard should be silet before calling this function.
1388 snd_soundfont_remove_samples(snd_sf_list_t *sflist)
1390 lock_preset(sflist, 0);
1391 if (sflist->callback.sample_reset)
1392 sflist->callback.sample_reset(sflist->callback.private_data);
1393 snd_sf_clear(sflist);
1394 unlock_preset(sflist);
1400 * Remove unlocked samples.
1401 * The soundcard should be silent before calling this function.
1404 snd_soundfont_remove_unlocked(snd_sf_list_t *sflist)
1406 snd_soundfont_t *sf;
1407 snd_sf_zone_t *zp, *nextzp;
1408 snd_sf_sample_t *sp, *nextsp;
1410 if (lock_preset(sflist, 1))
1413 if (sflist->callback.sample_reset)
1414 sflist->callback.sample_reset(sflist->callback.private_data);
1417 memset(sflist->presets, 0, sizeof(sflist->presets));
1419 for (sf = sflist->fonts; sf; sf = sf->next) {
1420 for (zp = sf->zones; zp; zp = nextzp) {
1421 if (zp->counter < sflist->zone_locked)
1428 for (sp = sf->samples; sp; sp = nextsp) {
1429 if (sp->counter < sflist->sample_locked)
1432 sf->samples = nextsp;
1433 sflist->mem_used -= sp->v.truesize;
1434 if (sflist->callback.sample_free)
1435 sflist->callback.sample_free(sflist->callback.private_data, sp, sflist->memhdr);
1440 sflist->zone_counter = sflist->zone_locked;
1441 sflist->sample_counter = sflist->sample_locked;
1443 rebuild_presets(sflist);
1445 unlock_preset(sflist);
1450 * Return the used memory size (in words)
1453 snd_soundfont_mem_used(snd_sf_list_t *sflist)
1455 return sflist->mem_used;