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 __user
*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
)
71 down(&sflist
->presets_mutex
);
72 spin_lock_irqsave(&sflist
->lock
, flags
);
73 sflist
->presets_locked
= 1;
74 spin_unlock_irqrestore(&sflist
->lock
, flags
);
82 unlock_preset(snd_sf_list_t
*sflist
)
85 spin_lock_irqsave(&sflist
->lock
, flags
);
86 sflist
->presets_locked
= 0;
87 spin_unlock_irqrestore(&sflist
->lock
, flags
);
88 up(&sflist
->presets_mutex
);
93 * close the patch if the patch was opened by this client.
96 snd_soundfont_close_check(snd_sf_list_t
*sflist
, int client
)
99 spin_lock_irqsave(&sflist
->lock
, flags
);
100 if (sflist
->open_client
== client
) {
101 spin_unlock_irqrestore(&sflist
->lock
, flags
);
102 return close_patch(sflist
);
104 spin_unlock_irqrestore(&sflist
->lock
, flags
);
110 * Deal with a soundfont patch. Any driver could use these routines
111 * although it was designed for the AWE64.
113 * The sample_write and callargs pararameters allow a callback into
114 * the actual driver to write sample data to the board or whatever
115 * it wants to do with it.
118 snd_soundfont_load(snd_sf_list_t
*sflist
, const void __user
*data
, long count
, int client
)
120 soundfont_patch_info_t patch
;
124 if (count
< (long)sizeof(patch
)) {
125 snd_printk("patch record too small %ld\n", count
);
128 if (copy_from_user(&patch
, data
, sizeof(patch
)))
131 count
-= sizeof(patch
);
132 data
+= sizeof(patch
);
134 if (patch
.key
!= SNDRV_OSS_SOUNDFONT_PATCH
) {
135 snd_printk("'The wrong kind of patch' %x\n", patch
.key
);
138 if (count
< patch
.len
) {
139 snd_printk("Patch too short %ld, need %d\n", count
, patch
.len
);
143 snd_printk("poor length %d\n", patch
.len
);
147 if (patch
.type
== SNDRV_SFNT_OPEN_PATCH
) {
148 /* grab sflist to open */
150 rc
= open_patch(sflist
, data
, count
, client
);
151 unlock_preset(sflist
);
155 /* check if other client already opened patch */
156 spin_lock_irqsave(&sflist
->lock
, flags
);
157 if (sflist
->open_client
!= client
) {
158 spin_unlock_irqrestore(&sflist
->lock
, flags
);
161 spin_unlock_irqrestore(&sflist
->lock
, flags
);
165 switch (patch
.type
) {
166 case SNDRV_SFNT_LOAD_INFO
:
167 rc
= load_info(sflist
, data
, count
);
169 case SNDRV_SFNT_LOAD_DATA
:
170 rc
= load_data(sflist
, data
, count
);
172 case SNDRV_SFNT_CLOSE_PATCH
:
173 rc
= close_patch(sflist
);
175 case SNDRV_SFNT_REPLACE_DATA
:
176 /*rc = replace_data(&patch, data, count);*/
178 case SNDRV_SFNT_MAP_PRESET
:
179 rc
= load_map(sflist
, data
, count
);
181 case SNDRV_SFNT_PROBE_DATA
:
182 rc
= probe_data(sflist
, patch
.optarg
);
184 case SNDRV_SFNT_REMOVE_INFO
:
185 /* patch must be opened */
186 if (sflist
->currsf
) {
187 snd_printk("soundfont: remove_info: patch not opened\n");
191 bank
= ((unsigned short)patch
.optarg
>> 8) & 0xff;
192 instr
= (unsigned short)patch
.optarg
& 0xff;
193 if (! remove_info(sflist
, sflist
->currsf
, bank
, instr
))
200 unlock_preset(sflist
);
206 /* check if specified type is special font (GUS or preset-alias) */
208 is_special_type(int type
)
211 return (type
== SNDRV_SFNT_PAT_TYPE_GUS
||
212 type
== SNDRV_SFNT_PAT_TYPE_MAP
);
216 /* open patch; create sf list */
218 open_patch(snd_sf_list_t
*sflist
, const char __user
*data
, int count
, int client
)
220 soundfont_open_parm_t parm
;
224 spin_lock_irqsave(&sflist
->lock
, flags
);
225 if (sflist
->open_client
>= 0 || sflist
->currsf
) {
226 spin_unlock_irqrestore(&sflist
->lock
, flags
);
229 spin_unlock_irqrestore(&sflist
->lock
, flags
);
231 if (copy_from_user(&parm
, data
, sizeof(parm
)))
234 if (is_special_type(parm
.type
)) {
235 parm
.type
|= SNDRV_SFNT_PAT_SHARED
;
236 sf
= newsf(sflist
, parm
.type
, NULL
);
238 sf
= newsf(sflist
, parm
.type
, parm
.name
);
243 spin_lock_irqsave(&sflist
->lock
, flags
);
244 sflist
->open_client
= client
;
246 spin_unlock_irqrestore(&sflist
->lock
, flags
);
252 * Allocate a new soundfont structure.
254 static snd_soundfont_t
*
255 newsf(snd_sf_list_t
*sflist
, int type
, char *name
)
259 /* check the shared fonts */
260 if (type
& SNDRV_SFNT_PAT_SHARED
) {
261 for (sf
= sflist
->fonts
; sf
; sf
= sf
->next
) {
262 if (is_identical_font(sf
, type
, name
)) {
268 /* not found -- create a new one */
269 sf
= kcalloc(1, sizeof(*sf
), GFP_KERNEL
);
272 sf
->id
= sflist
->fonts_size
;
273 sflist
->fonts_size
++;
275 /* prepend this record */
276 sf
->next
= sflist
->fonts
;
283 memcpy(sf
->name
, name
, SNDRV_SFNT_PATCH_NAME_LEN
);
288 /* check if the given name matches to the existing list */
290 is_identical_font(snd_soundfont_t
*sf
, int type
, unsigned char *name
)
292 return ((sf
->type
& SNDRV_SFNT_PAT_SHARED
) &&
293 (sf
->type
& 0x0f) == (type
& 0x0f) &&
295 memcmp(sf
->name
, name
, SNDRV_SFNT_PATCH_NAME_LEN
) == 0));
299 * Close the current patch.
302 close_patch(snd_sf_list_t
*sflist
)
306 spin_lock_irqsave(&sflist
->lock
, flags
);
307 sflist
->currsf
= NULL
;
308 sflist
->open_client
= -1;
309 spin_unlock_irqrestore(&sflist
->lock
, flags
);
311 rebuild_presets(sflist
);
317 /* probe sample in the current list -- nothing to be loaded */
319 probe_data(snd_sf_list_t
*sflist
, int sample_id
)
321 /* patch must be opened */
322 if (sflist
->currsf
) {
323 /* search the specified sample by optarg */
324 if (find_sample(sflist
->currsf
, sample_id
))
331 * increment zone counter
334 set_zone_counter(snd_sf_list_t
*sflist
, snd_soundfont_t
*sf
, snd_sf_zone_t
*zp
)
336 zp
->counter
= sflist
->zone_counter
++;
337 if (sf
->type
& SNDRV_SFNT_PAT_LOCKED
)
338 sflist
->zone_locked
= sflist
->zone_counter
;
342 * allocate a new zone record
344 static snd_sf_zone_t
*
345 sf_zone_new(snd_sf_list_t
*sflist
, snd_soundfont_t
*sf
)
349 if ((zp
= kcalloc(1, sizeof(*zp
), GFP_KERNEL
)) == NULL
)
351 zp
->next
= sf
->zones
;
354 init_voice_info(&zp
->v
);
356 set_zone_counter(sflist
, sf
, zp
);
362 * increment sample couter
365 set_sample_counter(snd_sf_list_t
*sflist
, snd_soundfont_t
*sf
, snd_sf_sample_t
*sp
)
367 sp
->counter
= sflist
->sample_counter
++;
368 if (sf
->type
& SNDRV_SFNT_PAT_LOCKED
)
369 sflist
->sample_locked
= sflist
->sample_counter
;
373 * allocate a new sample list record
375 static snd_sf_sample_t
*
376 sf_sample_new(snd_sf_list_t
*sflist
, snd_soundfont_t
*sf
)
380 if ((sp
= kcalloc(1, sizeof(*sp
), GFP_KERNEL
)) == NULL
)
383 sp
->next
= sf
->samples
;
386 set_sample_counter(sflist
, sf
, sp
);
391 * delete sample list -- this is an exceptional job.
392 * only the last allocated sample can be deleted.
395 sf_sample_delete(snd_sf_list_t
*sflist
, snd_soundfont_t
*sf
, snd_sf_sample_t
*sp
)
397 /* only last sample is accepted */
398 if (sp
== sf
->samples
) {
399 sf
->samples
= sp
->next
;
407 load_map(snd_sf_list_t
*sflist
, const void __user
*data
, int count
)
409 snd_sf_zone_t
*zp
, *prevp
;
411 soundfont_voice_map_t map
;
413 /* get the link info */
414 if (count
< (int)sizeof(map
))
416 if (copy_from_user(&map
, data
, sizeof(map
)))
419 if (map
.map_instr
< 0 || map
.map_instr
>= SF_MAX_INSTRUMENTS
)
422 sf
= newsf(sflist
, SNDRV_SFNT_PAT_TYPE_MAP
|SNDRV_SFNT_PAT_SHARED
, NULL
);
427 for (zp
= sf
->zones
; zp
; prevp
= zp
, zp
= zp
->next
) {
429 zp
->instr
== map
.map_instr
&&
430 zp
->bank
== map
.map_bank
&&
431 zp
->v
.low
== map
.map_key
&&
432 zp
->v
.start
== map
.src_instr
&&
433 zp
->v
.end
== map
.src_bank
&&
434 zp
->v
.fixkey
== map
.src_key
) {
435 /* the same mapping is already present */
436 /* relink this record to the link head */
438 prevp
->next
= zp
->next
;
439 zp
->next
= sf
->zones
;
442 /* update the counter */
443 set_zone_counter(sflist
, sf
, zp
);
448 /* create a new zone */
449 if ((zp
= sf_zone_new(sflist
, sf
)) == NULL
)
452 zp
->bank
= map
.map_bank
;
453 zp
->instr
= map
.map_instr
;
455 if (map
.map_key
>= 0) {
456 zp
->v
.low
= map
.map_key
;
457 zp
->v
.high
= map
.map_key
;
459 zp
->v
.start
= map
.src_instr
;
460 zp
->v
.end
= map
.src_bank
;
461 zp
->v
.fixkey
= map
.src_key
;
462 zp
->v
.sf_id
= sf
->id
;
464 add_preset(sflist
, zp
);
470 /* remove the present instrument layers */
472 remove_info(snd_sf_list_t
*sflist
, snd_soundfont_t
*sf
, int bank
, int instr
)
474 snd_sf_zone_t
*prev
, *next
, *p
;
478 for (p
= sf
->zones
; p
; p
= next
) {
481 p
->bank
== bank
&& p
->instr
== instr
) {
482 /* remove this layer */
493 rebuild_presets(sflist
);
499 * Read an info record from the user buffer and save it on the current
503 load_info(snd_sf_list_t
*sflist
, const void __user
*data
, long count
)
507 soundfont_voice_rec_hdr_t hdr
;
510 /* patch must be opened */
511 if ((sf
= sflist
->currsf
) == NULL
)
514 if (is_special_type(sf
->type
))
517 if (count
< (long)sizeof(hdr
)) {
518 printk("Soundfont error: invalid patch zone length\n");
521 if (copy_from_user((char*)&hdr
, data
, sizeof(hdr
)))
525 count
-= sizeof(hdr
);
527 if (hdr
.nvoices
<= 0 || hdr
.nvoices
>= 100) {
528 printk("Soundfont error: Illegal voice number %d\n", hdr
.nvoices
);
532 if (count
< (long)sizeof(soundfont_voice_info_t
)*hdr
.nvoices
) {
533 printk("Soundfont Error: patch length(%ld) is smaller than nvoices(%d)\n",
538 switch (hdr
.write_mode
) {
539 case SNDRV_SFNT_WR_EXCLUSIVE
:
540 /* exclusive mode - if the instrument already exists,
542 for (zone
= sf
->zones
; zone
; zone
= zone
->next
) {
544 zone
->bank
== hdr
.bank
&&
545 zone
->instr
== hdr
.instr
)
549 case SNDRV_SFNT_WR_REPLACE
:
550 /* replace mode - remove the instrument if it already exists */
551 remove_info(sflist
, sf
, hdr
.bank
, hdr
.instr
);
555 for (i
= 0; i
< hdr
.nvoices
; i
++) {
556 snd_sf_zone_t tmpzone
;
558 /* copy awe_voice_info parameters */
559 if (copy_from_user(&tmpzone
.v
, data
, sizeof(tmpzone
.v
))) {
563 data
+= sizeof(tmpzone
.v
);
564 count
-= sizeof(tmpzone
.v
);
566 tmpzone
.bank
= hdr
.bank
;
567 tmpzone
.instr
= hdr
.instr
;
569 tmpzone
.v
.sf_id
= sf
->id
;
570 if (tmpzone
.v
.mode
& SNDRV_SFNT_MODE_INIT_PARM
)
571 init_voice_parm(&tmpzone
.v
.parm
);
573 /* create a new zone */
574 if ((zone
= sf_zone_new(sflist
, sf
)) == NULL
) {
578 /* copy the temporary data */
579 zone
->bank
= tmpzone
.bank
;
580 zone
->instr
= tmpzone
.instr
;
583 /* look up the sample */
584 zone
->sample
= set_sample(sf
, &zone
->v
);
591 /* initialize voice_info record */
593 init_voice_info(soundfont_voice_info_t
*avp
)
595 memset(avp
, 0, sizeof(*avp
));
604 avp
->amplitude
= 127;
605 avp
->scaleTuning
= 100;
607 init_voice_parm(&avp
->parm
);
610 /* initialize voice_parm record:
611 * Env1/2: delay=0, attack=0, hold=0, sustain=0, decay=0, release=0.
612 * Vibrato and Tremolo effects are zero.
614 * Chorus and Reverb effects are zero.
617 init_voice_parm(soundfont_voice_parm_t
*pp
)
619 memset(pp
, 0, sizeof(*pp
));
621 pp
->moddelay
= 0x8000;
622 pp
->modatkhld
= 0x7f7f;
623 pp
->moddcysus
= 0x7f7f;
624 pp
->modrelease
= 0x807f;
626 pp
->voldelay
= 0x8000;
627 pp
->volatkhld
= 0x7f7f;
628 pp
->voldcysus
= 0x7f7f;
629 pp
->volrelease
= 0x807f;
631 pp
->lfo1delay
= 0x8000;
632 pp
->lfo2delay
= 0x8000;
637 /* search the specified sample */
638 static snd_sf_sample_t
*
639 set_sample(snd_soundfont_t
*sf
, soundfont_voice_info_t
*avp
)
641 snd_sf_sample_t
*sample
;
643 sample
= find_sample(sf
, avp
->sample
);
647 /* add in the actual sample offsets:
648 * The voice_info addresses define only the relative offset
649 * from sample pointers. Here we calculate the actual DRAM
650 * offset from sample pointers.
652 avp
->start
+= sample
->v
.start
;
653 avp
->end
+= sample
->v
.end
;
654 avp
->loopstart
+= sample
->v
.loopstart
;
655 avp
->loopend
+= sample
->v
.loopend
;
657 /* copy mode flags */
658 avp
->sample_mode
= sample
->v
.mode_flags
;
663 /* find the sample pointer with the given id in the soundfont */
664 static snd_sf_sample_t
*
665 find_sample(snd_soundfont_t
*sf
, int sample_id
)
672 for (p
= sf
->samples
; p
; p
= p
->next
) {
673 if (p
->v
.sample
== sample_id
)
681 * Load sample information, this can include data to be loaded onto
682 * the soundcard. It can also just be a pointer into soundcard ROM.
683 * If there is data it will be written to the soundcard via the callback
687 load_data(snd_sf_list_t
*sflist
, const void __user
*data
, long count
)
690 soundfont_sample_info_t sample_info
;
694 /* patch must be opened */
695 if ((sf
= sflist
->currsf
) == NULL
)
698 if (is_special_type(sf
->type
))
701 if (copy_from_user(&sample_info
, data
, sizeof(sample_info
)))
704 off
= sizeof(sample_info
);
706 if (sample_info
.size
!= (count
-off
)/2)
710 if (find_sample(sf
, sample_info
.sample
)) {
711 /* if shared sample, skip this data */
712 if (sf
->type
& SNDRV_SFNT_PAT_SHARED
)
717 /* Allocate a new sample structure */
718 if ((sp
= sf_sample_new(sflist
, sf
)) == NULL
)
722 sp
->v
.sf_id
= sf
->id
;
724 sp
->v
.truesize
= sp
->v
.size
;
727 * If there is wave data then load it.
729 if (sp
->v
.size
> 0) {
731 rc
= sflist
->callback
.sample_new
732 (sflist
->callback
.private_data
, sp
, sflist
->memhdr
,
733 data
+ off
, count
- off
);
735 sf_sample_delete(sflist
, sf
, sp
);
738 sflist
->mem_used
+= sp
->v
.truesize
;
745 /* log2_tbl[i] = log2(i+128) * 0x10000 */
746 static int log_tbl
[129] = {
747 0x70000, 0x702df, 0x705b9, 0x7088e, 0x70b5d, 0x70e26, 0x710eb, 0x713aa,
748 0x71663, 0x71918, 0x71bc8, 0x71e72, 0x72118, 0x723b9, 0x72655, 0x728ed,
749 0x72b80, 0x72e0e, 0x73098, 0x7331d, 0x7359e, 0x7381b, 0x73a93, 0x73d08,
750 0x73f78, 0x741e4, 0x7444c, 0x746b0, 0x74910, 0x74b6c, 0x74dc4, 0x75019,
751 0x75269, 0x754b6, 0x75700, 0x75946, 0x75b88, 0x75dc7, 0x76002, 0x7623a,
752 0x7646e, 0x766a0, 0x768cd, 0x76af8, 0x76d1f, 0x76f43, 0x77164, 0x77382,
753 0x7759d, 0x777b4, 0x779c9, 0x77bdb, 0x77dea, 0x77ff5, 0x781fe, 0x78404,
754 0x78608, 0x78808, 0x78a06, 0x78c01, 0x78df9, 0x78fef, 0x791e2, 0x793d2,
755 0x795c0, 0x797ab, 0x79993, 0x79b79, 0x79d5d, 0x79f3e, 0x7a11d, 0x7a2f9,
756 0x7a4d3, 0x7a6ab, 0x7a880, 0x7aa53, 0x7ac24, 0x7adf2, 0x7afbe, 0x7b188,
757 0x7b350, 0x7b515, 0x7b6d8, 0x7b899, 0x7ba58, 0x7bc15, 0x7bdd0, 0x7bf89,
758 0x7c140, 0x7c2f5, 0x7c4a7, 0x7c658, 0x7c807, 0x7c9b3, 0x7cb5e, 0x7cd07,
759 0x7ceae, 0x7d053, 0x7d1f7, 0x7d398, 0x7d538, 0x7d6d6, 0x7d872, 0x7da0c,
760 0x7dba4, 0x7dd3b, 0x7ded0, 0x7e063, 0x7e1f4, 0x7e384, 0x7e512, 0x7e69f,
761 0x7e829, 0x7e9b3, 0x7eb3a, 0x7ecc0, 0x7ee44, 0x7efc7, 0x7f148, 0x7f2c8,
762 0x7f446, 0x7f5c2, 0x7f73d, 0x7f8b7, 0x7fa2f, 0x7fba5, 0x7fd1a, 0x7fe8d,
766 /* convert from linear to log value
768 * conversion: value = log2(amount / base) * ratio
771 * amount = linear value (unsigned, 32bit max)
772 * offset = base offset (:= log2(base) * 0x10000)
773 * ratio = division ratio
777 snd_sf_linear_to_log(unsigned int amount
, int offset
, int ratio
)
784 for (bit
= 0; ! (amount
& 0x80000000L
); bit
++)
786 s
= (amount
>> 24) & 0x7f;
787 low
= (amount
>> 16) & 0xff;
788 /* linear approxmimation by lower 8 bit */
789 v
= (log_tbl
[s
+ 1] * low
+ log_tbl
[s
] * (0x100 - low
)) >> 8;
791 v
= (v
* ratio
) >> 16;
792 v
+= (24 - bit
) * ratio
;
796 #define OFFSET_MSEC 653117 /* base = 1000 */
797 #define OFFSET_ABSCENT 851781 /* base = 8176 */
798 #define OFFSET_SAMPLERATE 1011119 /* base = 44100 */
800 #define ABSCENT_RATIO 1200
801 #define TIMECENT_RATIO 1200
802 #define SAMPLERATE_RATIO 4096
806 * conversion: abscent = log2(MHz / 8176) * 1200
809 freq_to_note(int mhz
)
811 return snd_sf_linear_to_log(mhz
, OFFSET_ABSCENT
, ABSCENT_RATIO
);
814 /* convert Hz to AWE32 rate offset:
815 * sample pitch offset for the specified sample rate
816 * rate=44100 is no offset, each 4096 is 1 octave (twice).
817 * eg, when rate is 22050, this offset becomes -4096.
819 * conversion: offset = log2(Hz / 44100) * 4096
822 calc_rate_offset(int hz
)
824 return snd_sf_linear_to_log(hz
, OFFSET_SAMPLERATE
, SAMPLERATE_RATIO
);
828 /* calculate GUS envelope time */
830 calc_gus_envelope_time(int rate
, int start
, int end
)
833 r
= (3 - ((rate
>> 6) & 3)) * 3;
841 return (t
* 10) / (p
* 441);
844 /* convert envelope time parameter to soundfont parameters */
846 /* attack & decay/release time table (msec) */
847 static short attack_time_tbl
[128] = {
848 32767, 32767, 5989, 4235, 2994, 2518, 2117, 1780, 1497, 1373, 1259, 1154, 1058, 970, 890, 816,
849 707, 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377,
850 361, 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188,
851 180, 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94,
852 90, 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47,
853 45, 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23,
854 22, 21, 20, 19, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
855 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 6, 0,
858 static short decay_time_tbl
[128] = {
859 32767, 32767, 22614, 15990, 11307, 9508, 7995, 6723, 5653, 5184, 4754, 4359, 3997, 3665, 3361, 3082,
860 2828, 2765, 2648, 2535, 2428, 2325, 2226, 2132, 2042, 1955, 1872, 1793, 1717, 1644, 1574, 1507,
861 1443, 1382, 1324, 1267, 1214, 1162, 1113, 1066, 978, 936, 897, 859, 822, 787, 754, 722,
862 691, 662, 634, 607, 581, 557, 533, 510, 489, 468, 448, 429, 411, 393, 377, 361,
863 345, 331, 317, 303, 290, 278, 266, 255, 244, 234, 224, 214, 205, 196, 188, 180,
864 172, 165, 158, 151, 145, 139, 133, 127, 122, 117, 112, 107, 102, 98, 94, 90,
865 86, 82, 79, 75, 72, 69, 66, 63, 61, 58, 56, 53, 51, 49, 47, 45,
866 43, 41, 39, 37, 36, 34, 33, 31, 30, 29, 28, 26, 25, 24, 23, 22,
869 /* delay time = 0x8000 - msec/92 */
871 snd_sf_calc_parm_hold(int msec
)
873 int val
= (0x7f * 92 - msec
) / 92;
874 if (val
< 1) val
= 1;
875 if (val
>= 126) val
= 126;
879 /* search an index for specified time from given time table */
881 calc_parm_search(int msec
, short *table
)
883 int left
= 1, right
= 127, mid
;
884 while (left
< right
) {
885 mid
= (left
+ right
) / 2;
886 if (msec
< (int)table
[mid
])
894 /* attack time: search from time table */
896 snd_sf_calc_parm_attack(int msec
)
898 return calc_parm_search(msec
, attack_time_tbl
);
901 /* decay/release time: search from time table */
903 snd_sf_calc_parm_decay(int msec
)
905 return calc_parm_search(msec
, decay_time_tbl
);
908 int snd_sf_vol_table
[128] = {
909 255,111,95,86,79,74,70,66,63,61,58,56,54,52,50,49,
910 47,46,45,43,42,41,40,39,38,37,36,35,34,34,33,32,
911 31,31,30,29,29,28,27,27,26,26,25,24,24,23,23,22,
912 22,21,21,21,20,20,19,19,18,18,18,17,17,16,16,16,
913 15,15,15,14,14,14,13,13,13,12,12,12,11,11,11,10,
914 10,10,10,9,9,9,8,8,8,8,7,7,7,7,6,6,
915 6,6,5,5,5,5,5,4,4,4,4,3,3,3,3,3,
916 2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,0,
920 #define calc_gus_sustain(val) (0x7f - snd_sf_vol_table[(val)/2])
921 #define calc_gus_attenuation(val) snd_sf_vol_table[(val)/2]
925 load_guspatch(snd_sf_list_t
*sflist
, const char __user
*data
, long count
, int client
)
927 struct patch_info patch
;
930 snd_sf_sample_t
*smp
;
934 if (count
< (long)sizeof(patch
)) {
935 snd_printk("patch record too small %ld\n", count
);
938 if (copy_from_user(&patch
, data
, sizeof(patch
)))
941 count
-= sizeof(patch
);
942 data
+= sizeof(patch
);
944 sf
= newsf(sflist
, SNDRV_SFNT_PAT_TYPE_GUS
|SNDRV_SFNT_PAT_SHARED
, NULL
);
947 if ((smp
= sf_sample_new(sflist
, sf
)) == NULL
)
949 sample_id
= sflist
->sample_counter
;
950 smp
->v
.sample
= sample_id
;
952 smp
->v
.end
= patch
.len
;
953 smp
->v
.loopstart
= patch
.loop_start
;
954 smp
->v
.loopend
= patch
.loop_end
;
955 smp
->v
.size
= patch
.len
;
957 /* set up mode flags */
958 smp
->v
.mode_flags
= 0;
959 if (!(patch
.mode
& WAVE_16_BITS
))
960 smp
->v
.mode_flags
|= SNDRV_SFNT_SAMPLE_8BITS
;
961 if (patch
.mode
& WAVE_UNSIGNED
)
962 smp
->v
.mode_flags
|= SNDRV_SFNT_SAMPLE_UNSIGNED
;
963 smp
->v
.mode_flags
|= SNDRV_SFNT_SAMPLE_NO_BLANK
;
964 if (!(patch
.mode
& (WAVE_LOOPING
|WAVE_BIDIR_LOOP
|WAVE_LOOP_BACK
)))
965 smp
->v
.mode_flags
|= SNDRV_SFNT_SAMPLE_SINGLESHOT
;
966 if (patch
.mode
& WAVE_BIDIR_LOOP
)
967 smp
->v
.mode_flags
|= SNDRV_SFNT_SAMPLE_BIDIR_LOOP
;
968 if (patch
.mode
& WAVE_LOOP_BACK
)
969 smp
->v
.mode_flags
|= SNDRV_SFNT_SAMPLE_REVERSE_LOOP
;
971 if (patch
.mode
& WAVE_16_BITS
) {
972 /* convert to word offsets */
975 smp
->v
.loopstart
/= 2;
978 /*smp->v.loopend++;*/
982 smp
->v
.sf_id
= sf
->id
;
984 /* set up voice info */
985 if ((zone
= sf_zone_new(sflist
, sf
)) == NULL
) {
986 sf_sample_delete(sflist
, sf
, smp
);
993 if (sflist
->callback
.sample_new
) {
994 rc
= sflist
->callback
.sample_new
995 (sflist
->callback
.private_data
, smp
, sflist
->memhdr
, data
, count
);
997 sf_sample_delete(sflist
, sf
, smp
);
1000 /* memory offset is updated after */
1003 /* update the memory offset here */
1004 sflist
->mem_used
+= smp
->v
.truesize
;
1006 zone
->v
.sample
= sample_id
; /* the last sample */
1007 zone
->v
.rate_offset
= calc_rate_offset(patch
.base_freq
);
1008 note
= freq_to_note(patch
.base_note
);
1009 zone
->v
.root
= note
/ 100;
1010 zone
->v
.tune
= -(note
% 100);
1011 zone
->v
.low
= (freq_to_note(patch
.low_note
) + 99) / 100;
1012 zone
->v
.high
= freq_to_note(patch
.high_note
) / 100;
1013 /* panning position; -128 - 127 => 0-127 */
1014 zone
->v
.pan
= (patch
.panning
+ 128) / 2;
1016 snd_printk("gus: basefrq=%d (ofs=%d) root=%d,tune=%d, range:%d-%d\n",
1017 (int)patch
.base_freq
, zone
->v
.rate_offset
,
1018 zone
->v
.root
, zone
->v
.tune
, zone
->v
.low
, zone
->v
.high
);
1021 /* detuning is ignored */
1022 /* 6points volume envelope */
1023 if (patch
.mode
& WAVE_ENVELOPES
) {
1024 int attack
, hold
, decay
, release
;
1025 attack
= calc_gus_envelope_time
1026 (patch
.env_rate
[0], 0, patch
.env_offset
[0]);
1027 hold
= calc_gus_envelope_time
1028 (patch
.env_rate
[1], patch
.env_offset
[0],
1029 patch
.env_offset
[1]);
1030 decay
= calc_gus_envelope_time
1031 (patch
.env_rate
[2], patch
.env_offset
[1],
1032 patch
.env_offset
[2]);
1033 release
= calc_gus_envelope_time
1034 (patch
.env_rate
[3], patch
.env_offset
[1],
1035 patch
.env_offset
[4]);
1036 release
+= calc_gus_envelope_time
1037 (patch
.env_rate
[4], patch
.env_offset
[3],
1038 patch
.env_offset
[4]);
1039 release
+= calc_gus_envelope_time
1040 (patch
.env_rate
[5], patch
.env_offset
[4],
1041 patch
.env_offset
[5]);
1042 zone
->v
.parm
.volatkhld
=
1043 (snd_sf_calc_parm_hold(hold
) << 8) |
1044 snd_sf_calc_parm_attack(attack
);
1045 zone
->v
.parm
.voldcysus
= (calc_gus_sustain(patch
.env_offset
[2]) << 8) |
1046 snd_sf_calc_parm_decay(decay
);
1047 zone
->v
.parm
.volrelease
= 0x8000 | snd_sf_calc_parm_decay(release
);
1048 zone
->v
.attenuation
= calc_gus_attenuation(patch
.env_offset
[0]);
1050 snd_printk("gus: atkhld=%x, dcysus=%x, volrel=%x, att=%d\n",
1051 zone
->v
.parm
.volatkhld
,
1052 zone
->v
.parm
.voldcysus
,
1053 zone
->v
.parm
.volrelease
,
1054 zone
->v
.attenuation
);
1059 if (patch
.mode
& WAVE_FAST_RELEASE
) {
1060 zone
->v
.parm
.volrelease
= 0x807f;
1063 /* tremolo effect */
1064 if (patch
.mode
& WAVE_TREMOLO
) {
1065 int rate
= (patch
.tremolo_rate
* 1000 / 38) / 42;
1066 zone
->v
.parm
.tremfrq
= ((patch
.tremolo_depth
/ 2) << 8) | rate
;
1068 /* vibrato effect */
1069 if (patch
.mode
& WAVE_VIBRATO
) {
1070 int rate
= (patch
.vibrato_rate
* 1000 / 38) / 42;
1071 zone
->v
.parm
.fm2frq2
= ((patch
.vibrato_depth
/ 6) << 8) | rate
;
1074 /* scale_freq, scale_factor, volume, and fractions not implemented */
1076 if (!(smp
->v
.mode_flags
& SNDRV_SFNT_SAMPLE_SINGLESHOT
))
1077 zone
->v
.mode
= SNDRV_SFNT_MODE_LOOPING
;
1081 /* append to the tail of the list */
1082 /*zone->bank = ctrls[AWE_MD_GUS_BANK];*/
1084 zone
->instr
= patch
.instr_no
;
1086 zone
->v
.sf_id
= sf
->id
;
1088 zone
->sample
= set_sample(sf
, &zone
->v
);
1090 /* rebuild preset now */
1091 add_preset(sflist
, zone
);
1096 /* load GUS patch */
1098 snd_soundfont_load_guspatch(snd_sf_list_t
*sflist
, const char __user
*data
,
1099 long count
, int client
)
1102 lock_preset(sflist
);
1103 rc
= load_guspatch(sflist
, data
, count
, client
);
1104 unlock_preset(sflist
);
1110 * Rebuild the preset table. This is like a hash table in that it allows
1111 * quick access to the zone information. For each preset there are zone
1112 * structures linked by next_instr and by next_zone. Former is the whole
1113 * link for this preset, and latter is the link for zone (i.e. instrument/
1114 * bank/key combination).
1117 rebuild_presets(snd_sf_list_t
*sflist
)
1119 snd_soundfont_t
*sf
;
1122 /* clear preset table */
1123 memset(sflist
->presets
, 0, sizeof(sflist
->presets
));
1125 /* search all fonts and insert each font */
1126 for (sf
= sflist
->fonts
; sf
; sf
= sf
->next
) {
1127 for (cur
= sf
->zones
; cur
; cur
= cur
->next
) {
1128 if (! cur
->mapped
&& cur
->sample
== NULL
) {
1129 /* try again to search the corresponding sample */
1130 cur
->sample
= set_sample(sf
, &cur
->v
);
1131 if (cur
->sample
== NULL
)
1135 add_preset(sflist
, cur
);
1142 * add the given zone to preset table
1145 add_preset(snd_sf_list_t
*sflist
, snd_sf_zone_t
*cur
)
1147 snd_sf_zone_t
*zone
;
1150 zone
= search_first_zone(sflist
, cur
->bank
, cur
->instr
, cur
->v
.low
);
1151 if (zone
&& zone
->v
.sf_id
!= cur
->v
.sf_id
) {
1152 /* different instrument was already defined */
1154 /* compare the allocated time */
1155 for (p
= zone
; p
; p
= p
->next_zone
) {
1156 if (p
->counter
> cur
->counter
)
1157 /* the current is older.. skipped */
1160 /* remove old zones */
1161 delete_preset(sflist
, zone
);
1162 zone
= NULL
; /* do not forget to clear this! */
1165 /* prepend this zone */
1166 if ((index
= get_index(cur
->bank
, cur
->instr
, cur
->v
.low
)) < 0)
1168 cur
->next_zone
= zone
; /* zone link */
1169 cur
->next_instr
= sflist
->presets
[index
]; /* preset table link */
1170 sflist
->presets
[index
] = cur
;
1174 * delete the given zones from preset_table
1177 delete_preset(snd_sf_list_t
*sflist
, snd_sf_zone_t
*zp
)
1182 if ((index
= get_index(zp
->bank
, zp
->instr
, zp
->v
.low
)) < 0)
1184 for (p
= sflist
->presets
[index
]; p
; p
= p
->next_instr
) {
1185 while (p
->next_instr
== zp
) {
1186 p
->next_instr
= zp
->next_instr
;
1196 * Search matching zones from preset table.
1197 * The note can be rewritten by preset mapping (alias).
1198 * The found zones are stored on 'table' array. max_layers defines
1199 * the maximum number of elements in this array.
1200 * This function returns the number of found zones. 0 if not found.
1203 snd_soundfont_search_zone(snd_sf_list_t
*sflist
, int *notep
, int vel
,
1204 int preset
, int bank
,
1205 int def_preset
, int def_bank
,
1206 snd_sf_zone_t
**table
, int max_layers
)
1209 unsigned long flags
;
1211 /* this function is supposed to be called atomically,
1212 * so we check the lock. if it's busy, just returns 0 to
1213 * tell the caller the busy state
1215 spin_lock_irqsave(&sflist
->lock
, flags
);
1216 if (sflist
->presets_locked
) {
1217 spin_unlock_irqrestore(&sflist
->lock
, flags
);
1220 nvoices
= search_zones(sflist
, notep
, vel
, preset
, bank
, table
, max_layers
, 0);
1222 if (preset
!= def_preset
|| bank
!= def_bank
)
1223 nvoices
= search_zones(sflist
, notep
, vel
, def_preset
, def_bank
, table
, max_layers
, 0);
1225 spin_unlock_irqrestore(&sflist
->lock
, flags
);
1231 * search the first matching zone
1233 static snd_sf_zone_t
*
1234 search_first_zone(snd_sf_list_t
*sflist
, int bank
, int preset
, int key
)
1239 if ((index
= get_index(bank
, preset
, key
)) < 0)
1241 for (zp
= sflist
->presets
[index
]; zp
; zp
= zp
->next_instr
) {
1242 if (zp
->instr
== preset
&& zp
->bank
== bank
)
1250 * search matching zones from sflist. can be called recursively.
1253 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
)
1258 zp
= search_first_zone(sflist
, bank
, preset
, *notep
);
1260 for (; zp
; zp
= zp
->next_zone
) {
1261 if (*notep
>= zp
->v
.low
&& *notep
<= zp
->v
.high
&&
1262 vel
>= zp
->v
.vellow
&& vel
<= zp
->v
.velhigh
) {
1264 /* search preset mapping (aliasing) */
1265 int key
= zp
->v
.fixkey
;
1266 preset
= zp
->v
.start
;
1269 if (level
> 5) /* too deep alias level */
1273 nvoices
= search_zones(sflist
, &key
, vel
,
1274 preset
, bank
, table
,
1275 max_layers
, level
+ 1);
1280 table
[nvoices
++] = zp
;
1281 if (nvoices
>= max_layers
)
1290 /* calculate the index of preset table:
1291 * drums are mapped from 128 to 255 according to its note key.
1292 * other instruments are mapped from 0 to 127.
1293 * if the index is out of range, return -1.
1296 get_index(int bank
, int instr
, int key
)
1299 if (SF_IS_DRUM_BANK(bank
))
1300 index
= key
+ SF_MAX_INSTRUMENTS
;
1303 index
= index
% SF_MAX_PRESETS
;
1310 * Initialise the sflist structure.
1313 snd_sf_init(snd_sf_list_t
*sflist
)
1315 memset(sflist
->presets
, 0, sizeof(sflist
->presets
));
1317 sflist
->mem_used
= 0;
1318 sflist
->currsf
= NULL
;
1319 sflist
->open_client
= -1;
1320 sflist
->fonts
= NULL
;
1321 sflist
->fonts_size
= 0;
1322 sflist
->zone_counter
= 0;
1323 sflist
->sample_counter
= 0;
1324 sflist
->zone_locked
= 0;
1325 sflist
->sample_locked
= 0;
1329 * Release all list records
1332 snd_sf_clear(snd_sf_list_t
*sflist
)
1334 snd_soundfont_t
*sf
, *nextsf
;
1335 snd_sf_zone_t
*zp
, *nextzp
;
1336 snd_sf_sample_t
*sp
, *nextsp
;
1338 for (sf
= sflist
->fonts
; sf
; sf
= nextsf
) {
1340 for (zp
= sf
->zones
; zp
; zp
= nextzp
) {
1344 for (sp
= sf
->samples
; sp
; sp
= nextsp
) {
1346 if (sflist
->callback
.sample_free
)
1347 sflist
->callback
.sample_free(sflist
->callback
.private_data
, sp
, sflist
->memhdr
);
1353 snd_sf_init(sflist
);
1358 * Create a new sflist structure
1361 snd_sf_new(snd_sf_callback_t
*callback
, snd_util_memhdr_t
*hdr
)
1363 snd_sf_list_t
*sflist
;
1365 if ((sflist
= kcalloc(1, sizeof(*sflist
), GFP_KERNEL
)) == NULL
)
1368 init_MUTEX(&sflist
->presets_mutex
);
1369 spin_lock_init(&sflist
->lock
);
1370 sflist
->memhdr
= hdr
;
1373 sflist
->callback
= *callback
;
1375 snd_sf_init(sflist
);
1381 * Free everything allocated off the sflist structure.
1384 snd_sf_free(snd_sf_list_t
*sflist
)
1389 lock_preset(sflist
);
1390 if (sflist
->callback
.sample_reset
)
1391 sflist
->callback
.sample_reset(sflist
->callback
.private_data
);
1392 snd_sf_clear(sflist
);
1393 unlock_preset(sflist
);
1399 * Remove all samples
1400 * The soundcard should be silet before calling this function.
1403 snd_soundfont_remove_samples(snd_sf_list_t
*sflist
)
1405 lock_preset(sflist
);
1406 if (sflist
->callback
.sample_reset
)
1407 sflist
->callback
.sample_reset(sflist
->callback
.private_data
);
1408 snd_sf_clear(sflist
);
1409 unlock_preset(sflist
);
1415 * Remove unlocked samples.
1416 * The soundcard should be silent before calling this function.
1419 snd_soundfont_remove_unlocked(snd_sf_list_t
*sflist
)
1421 snd_soundfont_t
*sf
;
1422 snd_sf_zone_t
*zp
, *nextzp
;
1423 snd_sf_sample_t
*sp
, *nextsp
;
1425 lock_preset(sflist
);
1427 if (sflist
->callback
.sample_reset
)
1428 sflist
->callback
.sample_reset(sflist
->callback
.private_data
);
1431 memset(sflist
->presets
, 0, sizeof(sflist
->presets
));
1433 for (sf
= sflist
->fonts
; sf
; sf
= sf
->next
) {
1434 for (zp
= sf
->zones
; zp
; zp
= nextzp
) {
1435 if (zp
->counter
< sflist
->zone_locked
)
1442 for (sp
= sf
->samples
; sp
; sp
= nextsp
) {
1443 if (sp
->counter
< sflist
->sample_locked
)
1446 sf
->samples
= nextsp
;
1447 sflist
->mem_used
-= sp
->v
.truesize
;
1448 if (sflist
->callback
.sample_free
)
1449 sflist
->callback
.sample_free(sflist
->callback
.private_data
, sp
, sflist
->memhdr
);
1454 sflist
->zone_counter
= sflist
->zone_locked
;
1455 sflist
->sample_counter
= sflist
->sample_locked
;
1457 rebuild_presets(sflist
);
1459 unlock_preset(sflist
);