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("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("'The wrong kind of patch' %x\n", patch.key);
149 if (count < patch.len) {
150 snd_printk("Patch too short %ld, need %d\n", count, patch.len);
154 snd_printk("poor length %d\n", patch.len);
158 if (patch.type == SNDRV_SFNT_OPEN_PATCH) {
159 /* grab sflist to open */
161 rc = open_patch(sflist, data, count, client);
162 unlock_preset(sflist);
166 /* check if other client already opened patch */
167 spin_lock_irqsave(&sflist->lock, flags);
168 if (sflist->open_client != client) {
169 spin_unlock_irqrestore(&sflist->lock, flags);
172 spin_unlock_irqrestore(&sflist->lock, flags);
176 switch (patch.type) {
177 case SNDRV_SFNT_LOAD_INFO:
178 rc = load_info(sflist, data, count);
180 case SNDRV_SFNT_LOAD_DATA:
181 rc = load_data(sflist, data, count);
183 case SNDRV_SFNT_CLOSE_PATCH:
184 rc = close_patch(sflist);
186 case SNDRV_SFNT_REPLACE_DATA:
187 /*rc = replace_data(&patch, data, count);*/
189 case SNDRV_SFNT_MAP_PRESET:
190 rc = load_map(sflist, data, count);
192 case SNDRV_SFNT_PROBE_DATA:
193 rc = probe_data(sflist, patch.optarg);
195 case SNDRV_SFNT_REMOVE_INFO:
196 /* patch must be opened */
197 if (!sflist->currsf) {
198 snd_printk("soundfont: remove_info: patch not opened\n");
202 bank = ((unsigned short)patch.optarg >> 8) & 0xff;
203 instr = (unsigned short)patch.optarg & 0xff;
204 if (! remove_info(sflist, sflist->currsf, bank, instr))
211 unlock_preset(sflist);
217 /* check if specified type is special font (GUS or preset-alias) */
219 is_special_type(int type)
222 return (type == SNDRV_SFNT_PAT_TYPE_GUS ||
223 type == SNDRV_SFNT_PAT_TYPE_MAP);
227 /* open patch; create sf list */
229 open_patch(struct snd_sf_list *sflist, const char __user *data,
230 int count, int client)
232 struct soundfont_open_parm parm;
233 struct snd_soundfont *sf;
236 spin_lock_irqsave(&sflist->lock, flags);
237 if (sflist->open_client >= 0 || sflist->currsf) {
238 spin_unlock_irqrestore(&sflist->lock, flags);
241 spin_unlock_irqrestore(&sflist->lock, flags);
243 if (copy_from_user(&parm, data, sizeof(parm)))
246 if (is_special_type(parm.type)) {
247 parm.type |= SNDRV_SFNT_PAT_SHARED;
248 sf = newsf(sflist, parm.type, NULL);
250 sf = newsf(sflist, parm.type, parm.name);
255 spin_lock_irqsave(&sflist->lock, flags);
256 sflist->open_client = client;
258 spin_unlock_irqrestore(&sflist->lock, flags);
264 * Allocate a new soundfont structure.
266 static struct snd_soundfont *
267 newsf(struct snd_sf_list *sflist, int type, char *name)
269 struct snd_soundfont *sf;
271 /* check the shared fonts */
272 if (type & SNDRV_SFNT_PAT_SHARED) {
273 for (sf = sflist->fonts; sf; sf = sf->next) {
274 if (is_identical_font(sf, type, name)) {
280 /* not found -- create a new one */
281 sf = kzalloc(sizeof(*sf), GFP_KERNEL);
284 sf->id = sflist->fonts_size;
285 sflist->fonts_size++;
287 /* prepend this record */
288 sf->next = sflist->fonts;
295 memcpy(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN);
300 /* check if the given name matches to the existing list */
302 is_identical_font(struct snd_soundfont *sf, int type, unsigned char *name)
304 return ((sf->type & SNDRV_SFNT_PAT_SHARED) &&
305 (sf->type & 0x0f) == (type & 0x0f) &&
307 memcmp(sf->name, name, SNDRV_SFNT_PATCH_NAME_LEN) == 0));
311 * Close the current patch.
314 close_patch(struct snd_sf_list *sflist)
318 spin_lock_irqsave(&sflist->lock, flags);
319 sflist->currsf = NULL;
320 sflist->open_client = -1;
321 spin_unlock_irqrestore(&sflist->lock, flags);
323 rebuild_presets(sflist);
329 /* probe sample in the current list -- nothing to be loaded */
331 probe_data(struct snd_sf_list *sflist, int sample_id)
333 /* patch must be opened */
334 if (sflist->currsf) {
335 /* search the specified sample by optarg */
336 if (find_sample(sflist->currsf, sample_id))
343 * increment zone counter
346 set_zone_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
347 struct snd_sf_zone *zp)
349 zp->counter = sflist->zone_counter++;
350 if (sf->type & SNDRV_SFNT_PAT_LOCKED)
351 sflist->zone_locked = sflist->zone_counter;
355 * allocate a new zone record
357 static struct snd_sf_zone *
358 sf_zone_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
360 struct snd_sf_zone *zp;
362 if ((zp = kzalloc(sizeof(*zp), GFP_KERNEL)) == NULL)
364 zp->next = sf->zones;
367 init_voice_info(&zp->v);
369 set_zone_counter(sflist, sf, zp);
375 * increment sample couter
378 set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
379 struct snd_sf_sample *sp)
381 sp->counter = sflist->sample_counter++;
382 if (sf->type & SNDRV_SFNT_PAT_LOCKED)
383 sflist->sample_locked = sflist->sample_counter;
387 * allocate a new sample list record
389 static struct snd_sf_sample *
390 sf_sample_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
392 struct snd_sf_sample *sp;
394 if ((sp = kzalloc(sizeof(*sp), GFP_KERNEL)) == NULL)
397 sp->next = sf->samples;
400 set_sample_counter(sflist, sf, sp);
405 * delete sample list -- this is an exceptional job.
406 * only the last allocated sample can be deleted.
409 sf_sample_delete(struct snd_sf_list *sflist, struct snd_soundfont *sf,
410 struct snd_sf_sample *sp)
412 /* only last sample is accepted */
413 if (sp == sf->samples) {
414 sf->samples = sp->next;
422 load_map(struct snd_sf_list *sflist, const void __user *data, int count)
424 struct snd_sf_zone *zp, *prevp;
425 struct snd_soundfont *sf;
426 struct soundfont_voice_map map;
428 /* get the link info */
429 if (count < (int)sizeof(map))
431 if (copy_from_user(&map, data, sizeof(map)))
434 if (map.map_instr < 0 || map.map_instr >= SF_MAX_INSTRUMENTS)
437 sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_MAP|SNDRV_SFNT_PAT_SHARED, NULL);
442 for (zp = sf->zones; zp; prevp = zp, zp = zp->next) {
444 zp->instr == map.map_instr &&
445 zp->bank == map.map_bank &&
446 zp->v.low == map.map_key &&
447 zp->v.start == map.src_instr &&
448 zp->v.end == map.src_bank &&
449 zp->v.fixkey == map.src_key) {
450 /* the same mapping is already present */
451 /* relink this record to the link head */
453 prevp->next = zp->next;
454 zp->next = sf->zones;
457 /* update the counter */
458 set_zone_counter(sflist, sf, zp);
463 /* create a new zone */
464 if ((zp = sf_zone_new(sflist, sf)) == NULL)
467 zp->bank = map.map_bank;
468 zp->instr = map.map_instr;
470 if (map.map_key >= 0) {
471 zp->v.low = map.map_key;
472 zp->v.high = map.map_key;
474 zp->v.start = map.src_instr;
475 zp->v.end = map.src_bank;
476 zp->v.fixkey = map.src_key;
477 zp->v.sf_id = sf->id;
479 add_preset(sflist, zp);
485 /* remove the present instrument layers */
487 remove_info(struct snd_sf_list *sflist, struct snd_soundfont *sf,
490 struct snd_sf_zone *prev, *next, *p;
494 for (p = sf->zones; p; p = next) {
497 p->bank == bank && p->instr == instr) {
498 /* remove this layer */
509 rebuild_presets(sflist);
515 * Read an info record from the user buffer and save it on the current
519 load_info(struct snd_sf_list *sflist, const void __user *data, long count)
521 struct snd_soundfont *sf;
522 struct snd_sf_zone *zone;
523 struct soundfont_voice_rec_hdr hdr;
526 /* patch must be opened */
527 if ((sf = sflist->currsf) == NULL)
530 if (is_special_type(sf->type))
533 if (count < (long)sizeof(hdr)) {
534 printk("Soundfont error: invalid patch zone length\n");
537 if (copy_from_user((char*)&hdr, data, sizeof(hdr)))
541 count -= sizeof(hdr);
543 if (hdr.nvoices <= 0 || hdr.nvoices >= 100) {
544 printk("Soundfont error: Illegal voice number %d\n", hdr.nvoices);
548 if (count < (long)sizeof(struct soundfont_voice_info) * hdr.nvoices) {
549 printk("Soundfont Error: patch length(%ld) is smaller than nvoices(%d)\n",
554 switch (hdr.write_mode) {
555 case SNDRV_SFNT_WR_EXCLUSIVE:
556 /* exclusive mode - if the instrument already exists,
558 for (zone = sf->zones; zone; zone = zone->next) {
560 zone->bank == hdr.bank &&
561 zone->instr == hdr.instr)
565 case SNDRV_SFNT_WR_REPLACE:
566 /* replace mode - remove the instrument if it already exists */
567 remove_info(sflist, sf, hdr.bank, hdr.instr);
571 for (i = 0; i < hdr.nvoices; i++) {
572 struct snd_sf_zone tmpzone;
574 /* copy awe_voice_info parameters */
575 if (copy_from_user(&tmpzone.v, data, sizeof(tmpzone.v))) {
579 data += sizeof(tmpzone.v);
580 count -= sizeof(tmpzone.v);
582 tmpzone.bank = hdr.bank;
583 tmpzone.instr = hdr.instr;
585 tmpzone.v.sf_id = sf->id;
586 if (tmpzone.v.mode & SNDRV_SFNT_MODE_INIT_PARM)
587 init_voice_parm(&tmpzone.v.parm);
589 /* create a new zone */
590 if ((zone = sf_zone_new(sflist, sf)) == NULL) {
594 /* copy the temporary data */
595 zone->bank = tmpzone.bank;
596 zone->instr = tmpzone.instr;
599 /* look up the sample */
600 zone->sample = set_sample(sf, &zone->v);
607 /* initialize voice_info record */
609 init_voice_info(struct soundfont_voice_info *avp)
611 memset(avp, 0, sizeof(*avp));
620 avp->amplitude = 127;
621 avp->scaleTuning = 100;
623 init_voice_parm(&avp->parm);
626 /* initialize voice_parm record:
627 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
628 * Vibrato and Tremolo effects are zero.
630 * Chorus and Reverb effects are zero.
633 init_voice_parm(struct soundfont_voice_parm *pp)
635 memset(pp, 0, sizeof(*pp));
637 pp->moddelay = 0x8000;
638 pp->modatkhld = 0x7f7f;
639 pp->moddcysus = 0x7f7f;
640 pp->modrelease = 0x807f;
642 pp->voldelay = 0x8000;
643 pp->volatkhld = 0x7f7f;
644 pp->voldcysus = 0x7f7f;
645 pp->volrelease = 0x807f;
647 pp->lfo1delay = 0x8000;
648 pp->lfo2delay = 0x8000;
653 /* search the specified sample */
654 static struct snd_sf_sample *
655 set_sample(struct snd_soundfont *sf, struct soundfont_voice_info *avp)
657 struct snd_sf_sample *sample;
659 sample = find_sample(sf, avp->sample);
663 /* add in the actual sample offsets:
664 * The voice_info addresses define only the relative offset
665 * from sample pointers. Here we calculate the actual DRAM
666 * offset from sample pointers.
668 avp->start += sample->v.start;
669 avp->end += sample->v.end;
670 avp->loopstart += sample->v.loopstart;
671 avp->loopend += sample->v.loopend;
673 /* copy mode flags */
674 avp->sample_mode = sample->v.mode_flags;
679 /* find the sample pointer with the given id in the soundfont */
680 static struct snd_sf_sample *
681 find_sample(struct snd_soundfont *sf, int sample_id)
683 struct snd_sf_sample *p;
688 for (p = sf->samples; p; p = p->next) {
689 if (p->v.sample == sample_id)
697 * Load sample information, this can include data to be loaded onto
698 * the soundcard. It can also just be a pointer into soundcard ROM.
699 * If there is data it will be written to the soundcard via the callback
703 load_data(struct snd_sf_list *sflist, const void __user *data, long count)
705 struct snd_soundfont *sf;
706 struct soundfont_sample_info sample_info;
707 struct snd_sf_sample *sp;
710 /* patch must be opened */
711 if ((sf = sflist->currsf) == NULL)
714 if (is_special_type(sf->type))
717 if (copy_from_user(&sample_info, data, sizeof(sample_info)))
720 off = sizeof(sample_info);
722 if (sample_info.size != (count-off)/2)
726 if (find_sample(sf, sample_info.sample)) {
727 /* if shared sample, skip this data */
728 if (sf->type & SNDRV_SFNT_PAT_SHARED)
733 /* Allocate a new sample structure */
734 if ((sp = sf_sample_new(sflist, sf)) == NULL)
738 sp->v.sf_id = sf->id;
740 sp->v.truesize = sp->v.size;
743 * If there is wave data then load it.
745 if (sp->v.size > 0) {
747 rc = sflist->callback.sample_new
748 (sflist->callback.private_data, sp, sflist->memhdr,
749 data + off, count - off);
751 sf_sample_delete(sflist, sf, sp);
754 sflist->mem_used += sp->v.truesize;
761 /* log2_tbl[i] = log2(i+128) * 0x10000 */
762 static int log_tbl[129] = {
763 0x70000, 0x702df, 0x705b9, 0x7088e, 0x70b5d, 0x70e26, 0x710eb, 0x713aa,
764 0x71663, 0x71918, 0x71bc8, 0x71e72, 0x72118, 0x723b9, 0x72655, 0x728ed,
765 0x72b80, 0x72e0e, 0x73098, 0x7331d, 0x7359e, 0x7381b, 0x73a93, 0x73d08,
766 0x73f78, 0x741e4, 0x7444c, 0x746b0, 0x74910, 0x74b6c, 0x74dc4, 0x75019,
767 0x75269, 0x754b6, 0x75700, 0x75946, 0x75b88, 0x75dc7, 0x76002, 0x7623a,
768 0x7646e, 0x766a0, 0x768cd, 0x76af8, 0x76d1f, 0x76f43, 0x77164, 0x77382,
769 0x7759d, 0x777b4, 0x779c9, 0x77bdb, 0x77dea, 0x77ff5, 0x781fe, 0x78404,
770 0x78608, 0x78808, 0x78a06, 0x78c01, 0x78df9, 0x78fef, 0x791e2, 0x793d2,
771 0x795c0, 0x797ab, 0x79993, 0x79b79, 0x79d5d, 0x79f3e, 0x7a11d, 0x7a2f9,
772 0x7a4d3, 0x7a6ab, 0x7a880, 0x7aa53, 0x7ac24, 0x7adf2, 0x7afbe, 0x7b188,
773 0x7b350, 0x7b515, 0x7b6d8, 0x7b899, 0x7ba58, 0x7bc15, 0x7bdd0, 0x7bf89,
774 0x7c140, 0x7c2f5, 0x7c4a7, 0x7c658, 0x7c807, 0x7c9b3, 0x7cb5e, 0x7cd07,
775 0x7ceae, 0x7d053, 0x7d1f7, 0x7d398, 0x7d538, 0x7d6d6, 0x7d872, 0x7da0c,
776 0x7dba4, 0x7dd3b, 0x7ded0, 0x7e063, 0x7e1f4, 0x7e384, 0x7e512, 0x7e69f,
777 0x7e829, 0x7e9b3, 0x7eb3a, 0x7ecc0, 0x7ee44, 0x7efc7, 0x7f148, 0x7f2c8,
778 0x7f446, 0x7f5c2, 0x7f73d, 0x7f8b7, 0x7fa2f, 0x7fba5, 0x7fd1a, 0x7fe8d,
782 /* convert from linear to log value
784 * conversion: value = log2(amount / base) * ratio
787 * amount = linear value (unsigned, 32bit max)
788 * offset = base offset (:= log2(base) * 0x10000)
789 * ratio = division ratio
793 snd_sf_linear_to_log(unsigned int amount, int offset, int ratio)
800 for (bit = 0; ! (amount & 0x80000000L); bit++)
802 s = (amount >> 24) & 0x7f;
803 low = (amount >> 16) & 0xff;
804 /* linear approxmimation by lower 8 bit */
805 v = (log_tbl[s + 1] * low + log_tbl[s] * (0x100 - low)) >> 8;
807 v = (v * ratio) >> 16;
808 v += (24 - bit) * ratio;
812 EXPORT_SYMBOL(snd_sf_linear_to_log);
815 #define OFFSET_MSEC 653117 /* base = 1000 */
816 #define OFFSET_ABSCENT 851781 /* base = 8176 */
817 #define OFFSET_SAMPLERATE 1011119 /* base = 44100 */
819 #define ABSCENT_RATIO 1200
820 #define TIMECENT_RATIO 1200
821 #define SAMPLERATE_RATIO 4096
825 * conversion: abscent = log2(MHz / 8176) * 1200
828 freq_to_note(int mhz)
830 return snd_sf_linear_to_log(mhz, OFFSET_ABSCENT, ABSCENT_RATIO);
833 /* convert Hz to AWE32 rate offset:
834 * sample pitch offset for the specified sample rate
835 * rate=44100 is no offset, each 4096 is 1 octave (twice).
836 * eg, when rate is 22050, this offset becomes -4096.
838 * conversion: offset = log2(Hz / 44100) * 4096
841 calc_rate_offset(int hz)
843 return snd_sf_linear_to_log(hz, OFFSET_SAMPLERATE, SAMPLERATE_RATIO);
847 /* calculate GUS envelope time */
849 calc_gus_envelope_time(int rate, int start, int end)
852 r = (3 - ((rate >> 6) & 3)) * 3;
860 return (t * 10) / (p * 441);
863 /* convert envelope time parameter to soundfont parameters */
865 /* attack & decay/release time table (msec) */
866 static short attack_time_tbl[128] = {
867 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
868 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
869 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
870 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
871 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
872 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
873 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
874 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
877 static short decay_time_tbl[128] = {
878 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
879 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
880 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
881 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
882 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
883 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
884 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
885 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
888 /* delay time = 0x8000 - msec/92 */
890 snd_sf_calc_parm_hold(int msec)
892 int val = (0x7f * 92 - msec) / 92;
893 if (val < 1) val = 1;
894 if (val >= 126) val = 126;
898 /* search an index for specified time from given time table */
900 calc_parm_search(int msec, short *table)
902 int left = 1, right = 127, mid;
903 while (left < right) {
904 mid = (left + right) / 2;
905 if (msec < (int)table[mid])
913 /* attack time: search from time table */
915 snd_sf_calc_parm_attack(int msec)
917 return calc_parm_search(msec, attack_time_tbl);
920 /* decay/release time: search from time table */
922 snd_sf_calc_parm_decay(int msec)
924 return calc_parm_search(msec, decay_time_tbl);
927 int snd_sf_vol_table[128] = {
928 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
929 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
930 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
931 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
932 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
933 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
934 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
935 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
939 #define calc_gus_sustain(val) (0x7f - snd_sf_vol_table[(val)/2])
940 #define calc_gus_attenuation(val) snd_sf_vol_table[(val)/2]
944 load_guspatch(struct snd_sf_list *sflist, const char __user *data,
945 long count, int client)
947 struct patch_info patch;
948 struct snd_soundfont *sf;
949 struct snd_sf_zone *zone;
950 struct snd_sf_sample *smp;
954 if (count < (long)sizeof(patch)) {
955 snd_printk("patch record too small %ld\n", count);
958 if (copy_from_user(&patch, data, sizeof(patch)))
961 count -= sizeof(patch);
962 data += sizeof(patch);
964 sf = newsf(sflist, SNDRV_SFNT_PAT_TYPE_GUS|SNDRV_SFNT_PAT_SHARED, NULL);
967 if ((smp = sf_sample_new(sflist, sf)) == NULL)
969 sample_id = sflist->sample_counter;
970 smp->v.sample = sample_id;
972 smp->v.end = patch.len;
973 smp->v.loopstart = patch.loop_start;
974 smp->v.loopend = patch.loop_end;
975 smp->v.size = patch.len;
977 /* set up mode flags */
978 smp->v.mode_flags = 0;
979 if (!(patch.mode & WAVE_16_BITS))
980 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_8BITS;
981 if (patch.mode & WAVE_UNSIGNED)
982 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_UNSIGNED;
983 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_NO_BLANK;
984 if (!(patch.mode & (WAVE_LOOPING|WAVE_BIDIR_LOOP|WAVE_LOOP_BACK)))
985 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_SINGLESHOT;
986 if (patch.mode & WAVE_BIDIR_LOOP)
987 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_BIDIR_LOOP;
988 if (patch.mode & WAVE_LOOP_BACK)
989 smp->v.mode_flags |= SNDRV_SFNT_SAMPLE_REVERSE_LOOP;
991 if (patch.mode & WAVE_16_BITS) {
992 /* convert to word offsets */
995 smp->v.loopstart /= 2;
998 /*smp->v.loopend++;*/
1001 smp->v.truesize = 0;
1002 smp->v.sf_id = sf->id;
1004 /* set up voice info */
1005 if ((zone = sf_zone_new(sflist, sf)) == NULL) {
1006 sf_sample_delete(sflist, sf, smp);
1013 if (sflist->callback.sample_new) {
1014 rc = sflist->callback.sample_new
1015 (sflist->callback.private_data, smp, sflist->memhdr,
1018 sf_sample_delete(sflist, sf, smp);
1021 /* memory offset is updated after */
1024 /* update the memory offset here */
1025 sflist->mem_used += smp->v.truesize;
1027 zone->v.sample = sample_id; /* the last sample */
1028 zone->v.rate_offset = calc_rate_offset(patch.base_freq);
1029 note = freq_to_note(patch.base_note);
1030 zone->v.root = note / 100;
1031 zone->v.tune = -(note % 100);
1032 zone->v.low = (freq_to_note(patch.low_note) + 99) / 100;
1033 zone->v.high = freq_to_note(patch.high_note) / 100;
1034 /* panning position; -128 - 127 => 0-127 */
1035 zone->v.pan = (patch.panning + 128) / 2;
1037 snd_printk("gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
1038 (int)patch.base_freq, zone->v.rate_offset,
1039 zone->v.root, zone->v.tune, zone->v.low, zone->v.high);
1042 /* detuning is ignored */
1043 /* 6points volume envelope */
1044 if (patch.mode & WAVE_ENVELOPES) {
1045 int attack, hold, decay, release;
1046 attack = calc_gus_envelope_time
1047 (patch.env_rate[0], 0, patch.env_offset[0]);
1048 hold = calc_gus_envelope_time
1049 (patch.env_rate[1], patch.env_offset[0],
1050 patch.env_offset[1]);
1051 decay = calc_gus_envelope_time
1052 (patch.env_rate[2], patch.env_offset[1],
1053 patch.env_offset[2]);
1054 release = calc_gus_envelope_time
1055 (patch.env_rate[3], patch.env_offset[1],
1056 patch.env_offset[4]);
1057 release += calc_gus_envelope_time
1058 (patch.env_rate[4], patch.env_offset[3],
1059 patch.env_offset[4]);
1060 release += calc_gus_envelope_time
1061 (patch.env_rate[5], patch.env_offset[4],
1062 patch.env_offset[5]);
1063 zone->v.parm.volatkhld =
1064 (snd_sf_calc_parm_hold(hold) << 8) |
1065 snd_sf_calc_parm_attack(attack);
1066 zone->v.parm.voldcysus = (calc_gus_sustain(patch.env_offset[2]) << 8) |
1067 snd_sf_calc_parm_decay(decay);
1068 zone->v.parm.volrelease = 0x8000 | snd_sf_calc_parm_decay(release);
1069 zone->v.attenuation = calc_gus_attenuation(patch.env_offset[0]);
1071 snd_printk("gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
1072 zone->v.parm.volatkhld,
1073 zone->v.parm.voldcysus,
1074 zone->v.parm.volrelease,
1075 zone->v.attenuation);
1080 if (patch.mode & WAVE_FAST_RELEASE) {
1081 zone->v.parm.volrelease = 0x807f;
1084 /* tremolo effect */
1085 if (patch.mode & WAVE_TREMOLO) {
1086 int rate = (patch.tremolo_rate * 1000 / 38) / 42;
1087 zone->v.parm.tremfrq = ((patch.tremolo_depth / 2) << 8) | rate;
1089 /* vibrato effect */
1090 if (patch.mode & WAVE_VIBRATO) {
1091 int rate = (patch.vibrato_rate * 1000 / 38) / 42;
1092 zone->v.parm.fm2frq2 = ((patch.vibrato_depth / 6) << 8) | rate;
1095 /* scale_freq, scale_factor, volume, and fractions not implemented */
1097 if (!(smp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT))
1098 zone->v.mode = SNDRV_SFNT_MODE_LOOPING;
1102 /* append to the tail of the list */
1103 /*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
1105 zone->instr = patch.instr_no;
1107 zone->v.sf_id = sf->id;
1109 zone->sample = set_sample(sf, &zone->v);
1111 /* rebuild preset now */
1112 add_preset(sflist, zone);
1117 /* load GUS patch */
1119 snd_soundfont_load_guspatch(struct snd_sf_list *sflist, const char __user *data,
1120 long count, int client)
1123 lock_preset(sflist);
1124 rc = load_guspatch(sflist, data, count, client);
1125 unlock_preset(sflist);
1131 * Rebuild the preset table. This is like a hash table in that it allows
1132 * quick access to the zone information. For each preset there are zone
1133 * structures linked by next_instr and by next_zone. Former is the whole
1134 * link for this preset, and latter is the link for zone (i.e. instrument/
1135 * bank/key combination).
1138 rebuild_presets(struct snd_sf_list *sflist)
1140 struct snd_soundfont *sf;
1141 struct snd_sf_zone *cur;
1143 /* clear preset table */
1144 memset(sflist->presets, 0, sizeof(sflist->presets));
1146 /* search all fonts and insert each font */
1147 for (sf = sflist->fonts; sf; sf = sf->next) {
1148 for (cur = sf->zones; cur; cur = cur->next) {
1149 if (! cur->mapped && cur->sample == NULL) {
1150 /* try again to search the corresponding sample */
1151 cur->sample = set_sample(sf, &cur->v);
1152 if (cur->sample == NULL)
1156 add_preset(sflist, cur);
1163 * add the given zone to preset table
1166 add_preset(struct snd_sf_list *sflist, struct snd_sf_zone *cur)
1168 struct snd_sf_zone *zone;
1171 zone = search_first_zone(sflist, cur->bank, cur->instr, cur->v.low);
1172 if (zone && zone->v.sf_id != cur->v.sf_id) {
1173 /* different instrument was already defined */
1174 struct snd_sf_zone *p;
1175 /* compare the allocated time */
1176 for (p = zone; p; p = p->next_zone) {
1177 if (p->counter > cur->counter)
1178 /* the current is older.. skipped */
1181 /* remove old zones */
1182 delete_preset(sflist, zone);
1183 zone = NULL; /* do not forget to clear this! */
1186 /* prepend this zone */
1187 if ((index = get_index(cur->bank, cur->instr, cur->v.low)) < 0)
1189 cur->next_zone = zone; /* zone link */
1190 cur->next_instr = sflist->presets[index]; /* preset table link */
1191 sflist->presets[index] = cur;
1195 * delete the given zones from preset_table
1198 delete_preset(struct snd_sf_list *sflist, struct snd_sf_zone *zp)
1201 struct snd_sf_zone *p;
1203 if ((index = get_index(zp->bank, zp->instr, zp->v.low)) < 0)
1205 for (p = sflist->presets[index]; p; p = p->next_instr) {
1206 while (p->next_instr == zp) {
1207 p->next_instr = zp->next_instr;
1217 * Search matching zones from preset table.
1218 * The note can be rewritten by preset mapping (alias).
1219 * The found zones are stored on 'table' array. max_layers defines
1220 * the maximum number of elements in this array.
1221 * This function returns the number of found zones. 0 if not found.
1224 snd_soundfont_search_zone(struct snd_sf_list *sflist, int *notep, int vel,
1225 int preset, int bank,
1226 int def_preset, int def_bank,
1227 struct snd_sf_zone **table, int max_layers)
1230 unsigned long flags;
1232 /* this function is supposed to be called atomically,
1233 * so we check the lock. if it's busy, just returns 0 to
1234 * tell the caller the busy state
1236 spin_lock_irqsave(&sflist->lock, flags);
1237 if (sflist->presets_locked) {
1238 spin_unlock_irqrestore(&sflist->lock, flags);
1241 nvoices = search_zones(sflist, notep, vel, preset, bank,
1242 table, max_layers, 0);
1244 if (preset != def_preset || bank != def_bank)
1245 nvoices = search_zones(sflist, notep, vel,
1246 def_preset, def_bank,
1247 table, max_layers, 0);
1249 spin_unlock_irqrestore(&sflist->lock, flags);
1255 * search the first matching zone
1257 static struct snd_sf_zone *
1258 search_first_zone(struct snd_sf_list *sflist, int bank, int preset, int key)
1261 struct snd_sf_zone *zp;
1263 if ((index = get_index(bank, preset, key)) < 0)
1265 for (zp = sflist->presets[index]; zp; zp = zp->next_instr) {
1266 if (zp->instr == preset && zp->bank == bank)
1274 * search matching zones from sflist. can be called recursively.
1277 search_zones(struct snd_sf_list *sflist, int *notep, int vel,
1278 int preset, int bank, struct snd_sf_zone **table,
1279 int max_layers, int level)
1281 struct snd_sf_zone *zp;
1284 zp = search_first_zone(sflist, bank, preset, *notep);
1286 for (; zp; zp = zp->next_zone) {
1287 if (*notep >= zp->v.low && *notep <= zp->v.high &&
1288 vel >= zp->v.vellow && vel <= zp->v.velhigh) {
1290 /* search preset mapping (aliasing) */
1291 int key = zp->v.fixkey;
1292 preset = zp->v.start;
1295 if (level > 5) /* too deep alias level */
1299 nvoices = search_zones(sflist, &key, vel,
1300 preset, bank, table,
1301 max_layers, level + 1);
1306 table[nvoices++] = zp;
1307 if (nvoices >= max_layers)
1316 /* calculate the index of preset table:
1317 * drums are mapped from 128 to 255 according to its note key.
1318 * other instruments are mapped from 0 to 127.
1319 * if the index is out of range, return -1.
1322 get_index(int bank, int instr, int key)
1325 if (SF_IS_DRUM_BANK(bank))
1326 index = key + SF_MAX_INSTRUMENTS;
1329 index = index % SF_MAX_PRESETS;
1336 * Initialise the sflist structure.
1339 snd_sf_init(struct snd_sf_list *sflist)
1341 memset(sflist->presets, 0, sizeof(sflist->presets));
1343 sflist->mem_used = 0;
1344 sflist->currsf = NULL;
1345 sflist->open_client = -1;
1346 sflist->fonts = NULL;
1347 sflist->fonts_size = 0;
1348 sflist->zone_counter = 0;
1349 sflist->sample_counter = 0;
1350 sflist->zone_locked = 0;
1351 sflist->sample_locked = 0;
1355 * Release all list records
1358 snd_sf_clear(struct snd_sf_list *sflist)
1360 struct snd_soundfont *sf, *nextsf;
1361 struct snd_sf_zone *zp, *nextzp;
1362 struct snd_sf_sample *sp, *nextsp;
1364 for (sf = sflist->fonts; sf; sf = nextsf) {
1366 for (zp = sf->zones; zp; zp = nextzp) {
1370 for (sp = sf->samples; sp; sp = nextsp) {
1372 if (sflist->callback.sample_free)
1373 sflist->callback.sample_free(sflist->callback.private_data,
1374 sp, sflist->memhdr);
1380 snd_sf_init(sflist);
1385 * Create a new sflist structure
1387 struct snd_sf_list *
1388 snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr)
1390 struct snd_sf_list *sflist;
1392 if ((sflist = kzalloc(sizeof(*sflist), GFP_KERNEL)) == NULL)
1395 mutex_init(&sflist->presets_mutex);
1396 spin_lock_init(&sflist->lock);
1397 sflist->memhdr = hdr;
1400 sflist->callback = *callback;
1402 snd_sf_init(sflist);
1408 * Free everything allocated off the sflist structure.
1411 snd_sf_free(struct snd_sf_list *sflist)
1416 lock_preset(sflist);
1417 if (sflist->callback.sample_reset)
1418 sflist->callback.sample_reset(sflist->callback.private_data);
1419 snd_sf_clear(sflist);
1420 unlock_preset(sflist);
1426 * Remove all samples
1427 * The soundcard should be silet before calling this function.
1430 snd_soundfont_remove_samples(struct snd_sf_list *sflist)
1432 lock_preset(sflist);
1433 if (sflist->callback.sample_reset)
1434 sflist->callback.sample_reset(sflist->callback.private_data);
1435 snd_sf_clear(sflist);
1436 unlock_preset(sflist);
1442 * Remove unlocked samples.
1443 * The soundcard should be silent before calling this function.
1446 snd_soundfont_remove_unlocked(struct snd_sf_list *sflist)
1448 struct snd_soundfont *sf;
1449 struct snd_sf_zone *zp, *nextzp;
1450 struct snd_sf_sample *sp, *nextsp;
1452 lock_preset(sflist);
1454 if (sflist->callback.sample_reset)
1455 sflist->callback.sample_reset(sflist->callback.private_data);
1458 memset(sflist->presets, 0, sizeof(sflist->presets));
1460 for (sf = sflist->fonts; sf; sf = sf->next) {
1461 for (zp = sf->zones; zp; zp = nextzp) {
1462 if (zp->counter < sflist->zone_locked)
1469 for (sp = sf->samples; sp; sp = nextsp) {
1470 if (sp->counter < sflist->sample_locked)
1473 sf->samples = nextsp;
1474 sflist->mem_used -= sp->v.truesize;
1475 if (sflist->callback.sample_free)
1476 sflist->callback.sample_free(sflist->callback.private_data,
1477 sp, sflist->memhdr);
1482 sflist->zone_counter = sflist->zone_locked;
1483 sflist->sample_counter = sflist->sample_locked;
1485 rebuild_presets(sflist);
1487 unlock_preset(sflist);