OSDN Git Service

Changed Jaroslav Kysela's e-mail from perex@suse.cz to perex@perex.cz
[android-x86/external-alsa-lib.git] / src / instr / iwffff.c
1 /**
2  * \file src/instr/iwffff.c
3  * \brief InterWave FFFF Format Support
4  * \author Jaroslav Kysela <perex@perex.cz>
5  * \date 1999-2001
6  */
7 /*
8  *  InterWave FFFF Format Support
9  *  Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
10  *
11  *
12  *   This library is free software; you can redistribute it and/or modify
13  *   it under the terms of the GNU Lesser General Public License as
14  *   published by the Free Software Foundation; either version 2.1 of
15  *   the License, or (at your option) any later version.
16  *
17  *   This program is distributed in the hope that it will be useful,
18  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *   GNU Lesser General Public License for more details.
21  *
22  *   You should have received a copy of the GNU Lesser General Public
23  *   License along with this library; if not, write to the Free Software
24  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
25  *
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/stat.h>
32 #include <stdio.h>
33 #include "local.h"
34 #include <sound/ainstr_iw.h>
35
36 /*
37  *  defines
38  */
39
40 #ifndef DOC_HIDDEN
41
42 #define IW_RAM_FILE             "/proc/asound/card%i/gus-ram-%i"
43 #define IW_ROM_FILE             "/proc/asound/card%i/gus-rom-%i"
44
45 #undef IW_ROM_DEBUG
46
47 #define IW_ROM_PROGRAM_VERSION_MAJOR    1
48 #define IW_ROM_PROGRAM_VERSION_MINOR    0
49
50 #define IW_FORMAT_8BIT          0x01
51 #define IW_FORMAT_SIGNED        0x02
52 #define IW_FORMAT_FORWARD       0x04
53 #define IW_FORMAT_LOOP          0x08
54 #define IW_FORMAT_BIDIR         0x10
55 #define IW_FORMAT_ULAW          0x20
56 #define IW_FORMAT_ROM           0x80
57
58 /*
59  *  structures
60  */
61
62 typedef __u32 ID;
63
64 struct header {
65         ID id;
66         __u32 length;
67 };
68
69 struct program {
70         /* 00 */ ID id;
71         /* 04 */ ID version;
72 };
73
74 #define PATCH_SIZE 20
75
76 struct patch {
77         /* 00 */ ID id;
78         /* 04 */ __u16 nlayers;
79         /* 06 */ __u8 layer_mode;
80         /* 07 */ __u8 exclusion_mode;
81         /* 08 */ __u16 exclusion_group;
82         /* 10 */ __u8 effect1;
83         /* 11 */ __u8 effect1_depth;
84         /* 12 */ __u8 effect2;
85         /* 13 */ __u8 effect2_depth;
86         /* 14 */ __u8 bank;
87         /* 15 */ __u8 program;
88         /* 16 */ char *__layer;         /* don't use */
89 };
90
91 #define LFO_SIZE 8
92
93 struct LFO {
94         /* 00 */ __u16 freq;
95         /* 02 */ __s16 depth;
96         /* 04 */ __s16 sweep;
97         /* 06 */ __u8 shape;
98         /* 07 */ __u8 delay;
99 };
100
101 #define LAYER_SIZE 42
102
103 struct layer {
104         /* 00 */ ID id;
105         /* 04 */ __u8 nwaves;
106         /* 05 */ __u8 flags;
107         /* 06 */ __u8 high_range;
108         /* 07 */ __u8 low_range;
109         /* 08 */ __u8 pan;
110         /* 09 */ __u8 pan_freq_scale;
111         /* 10 */ struct LFO tremolo;
112         /* 18 */ struct LFO vibrato;
113         /* 26 */ __u8 velocity_mode;
114         /* 27 */ __u8 attenuation;
115         /* 28 */ __u16 freq_scale;
116         /* 30 */ __u8 freq_center;
117         /* 31 */ __u8 layer_event;
118         /* 32 */ ID penv;
119         /* 34 */ ID venv;
120         /* 38 */ char *wave;
121 };
122
123 #define WAVE_SIZE 37
124
125 struct wave {
126         /* 00 */ ID id;
127         /* 04 */ __u32 size;
128         /* 08 */ __u32 start;
129         /* 12 */ __u32 loopstart;
130         /* 16 */ __u32 loopend;
131         /* 20 */ __u32 m_start;
132         /* 24 */ __u32 sample_ratio;
133         /* 28 */ __u8 attenuation;
134         /* 29 */ __u8 low_note;
135         /* 30 */ __u8 high_note;
136         /* 31 */ __u8 format;
137         /* 32 */ __u8 m_format;
138         /* 33 */ ID data_id;
139 };
140
141 #define ENVELOPE_SIZE 8
142
143 struct envelope {
144         /* 00 */ ID id;
145         /* 04 */ __u8 num_envelopes;
146         /* 05 */ __u8 flags;
147         /* 06 */ __u8 mode;
148         /* 07 */ __u8 index_type;
149 };
150
151 #define ENVELOPE_RECORD_SIZE 12
152
153 struct envelope_record {
154         /* 00 */ __u16 nattack;
155         /* 02 */ __u16 nrelease;
156         /* 04 */ __u16 sustain_offset;
157         /* 06 */ __u16 sustain_rate;
158         /* 08 */ __u16 release_rate;
159         /* 10 */ __u8 hirange;
160         /* 11 */ __u8 pad;
161 };
162
163 /*
164  *  variables
165  */
166
167 #define IW_ID_VALUE(a, b, c, d) (a|(b<<8)|(c<<16)|(d<<24))
168
169 #define file_header     IW_ID_VALUE('F', 'F', 'F', 'F')
170 #define patch_header    IW_ID_VALUE('P', 'T', 'C', 'H')
171 #define program_header  IW_ID_VALUE('P', 'R', 'O', 'G')
172 #define layer_header    IW_ID_VALUE('L', 'A', 'Y', 'R')
173 #define wave_header     IW_ID_VALUE('W', 'A', 'V', 'E')
174 #define envp_header     IW_ID_VALUE('E', 'N', 'V', 'P')
175 #if 0
176 #define text_header     IW_ID_VALUE('T', 'E', 'X', 'T')
177 #define data_header     IW_ID_VALUE('D', 'A', 'T', 'A')
178 #define copyright_header IW_ID_VALUE('C', 'P', 'R', 'T')
179 #endif
180
181 struct _snd_iwffff_handle {
182         int rom;
183         unsigned char *fff_data;
184         size_t fff_size;
185         char *fff_filename;
186         char *dat_filename;
187         unsigned int start_addr;
188         unsigned int share_id1;
189         unsigned int share_id2;
190         unsigned int share_id3;
191 };
192
193 #endif /* DOC_HIDDEN */
194
195 /*
196  *  local functions
197  */
198
199 static int iwffff_get_rom_header(int card, int bank, iwffff_rom_header_t *header)
200 {
201         int fd;
202         char filename[128];
203         
204         sprintf(filename, IW_ROM_FILE, card, bank);
205         if ((fd = open(filename, O_RDONLY)) < 0)
206                 return -errno;
207         if (read(fd, header, sizeof(*header)) != sizeof(*header)) {
208                 close(fd);
209                 return -EIO;
210         }
211         if (lseek(fd, IWFFFF_ROM_HDR_SIZE, SEEK_SET) < 0) {
212                 close(fd);
213                 return -errno;
214         }
215         return fd;
216 }
217
218 /**
219  * \brief Open IWFFFF files
220  * \param handle IWFFFF handle
221  * \param name_fff filename of an FFF (header) file
222  * \param name_dat filename of an DAT (data) file
223  * \return 0 on success otherwise a negative error code
224  */
225 int snd_instr_iwffff_open(snd_iwffff_handle_t **handle, const char *name_fff, const char *name_dat)
226 {
227         snd_iwffff_handle_t *iwf;
228         struct stat info;
229         struct header ffff;
230         int fd;
231
232         if (handle == NULL)
233                 return -EINVAL;
234         *handle = NULL;
235         if (stat(name_fff, &info) < 0)
236                 return -ENOENT;
237         if (stat(name_dat, &info) < 0)
238                 return -ENOENT;
239         /* ok.. at first - look for FFFF ROM */
240         if ((fd = open(name_fff, O_RDONLY)) < 0)
241                 return -errno;
242         if (read(fd, &ffff, sizeof(ffff)) != sizeof(ffff)) {
243                 close(fd);
244                 return -EIO;
245         }
246         if ((iwf = malloc(sizeof(*iwf))) == NULL) {
247                 close(fd);
248                 return -ENOMEM;
249         }
250         memset(iwf, 0, sizeof(*iwf));
251         iwf->fff_size = snd_LE_to_host_32(ffff.length);
252         iwf->fff_filename = strdup(name_fff);
253         iwf->dat_filename = strdup(name_dat);
254         iwf->fff_data = malloc(iwf->fff_size);
255         if (iwf->fff_data == NULL) {
256                 free(iwf);
257                 close(fd);
258                 return -ENOMEM;
259         }
260         if (read(fd, iwf->fff_data, iwf->fff_size) != (ssize_t) iwf->fff_size) {
261                 free(iwf->fff_data);
262                 free(iwf);
263                 close(fd);
264                 return -EIO;
265         }
266         iwf->share_id1 = IWFFFF_SHARE_FILE;
267 #ifdef __alpha__
268         iwf->share_id2 = (info.st_dev << 16) /* | ((info.st_ino >> 32) & 0xffff) */;
269 #else
270         iwf->share_id2 = info.st_dev << 16;
271 #endif
272         iwf->share_id3 = info.st_ino;   /* can be 64-bit -> overflow */
273         *handle = iwf;
274         return 0;
275 }
276
277 /**
278  * \brief Open IWFFFF ROM
279  * \param handle IWFFFF handle
280  * \param card card number
281  * \param bank ROM bank number (0-3)
282  * \param file ROM file number
283  * \return 0 on success otherwise a negative \c errno code
284  *
285  * Opens \a file in \a bank in the ROM image of card \a card, and
286  * writes a handle pointer into \a *handle. 
287  */
288 int snd_instr_iwffff_open_rom(snd_iwffff_handle_t **handle, int card, int bank, int file)
289 {
290         unsigned int next_ffff;
291         struct header ffff;
292         snd_iwffff_handle_t *iwf;
293         iwffff_rom_header_t header;
294         int fd, idx;
295
296         if (handle == NULL)
297                 return -EINVAL;
298         *handle = NULL;
299         idx = 0;
300         if (bank > 3 || file > 255)
301                 return -ENOENT;
302         fd = iwffff_get_rom_header(card, bank, &header);
303         if (fd < 0)
304                 return fd;
305         while (read(fd, (char *)&ffff, sizeof(ffff)) == sizeof(ffff)) {
306                 if (ffff.id != file_header)
307                         break;
308                 ffff.length = snd_LE_to_host_32(ffff.length);
309                 next_ffff = lseek(fd, 0, SEEK_CUR) + ffff.length;
310                 if (file == idx) {
311 #ifdef IW_ROM_DEBUG
312                         SNDERR("file header at 0x%x size 0x%x\n", rom_pos - sizeof(ffff), ffff.length);
313 #endif
314                         iwf = malloc(sizeof(*iwf));
315                         if (iwf == NULL) {
316                                 close(fd);
317                                 return -ENOMEM;
318                         }
319                         memset(iwf, 0, sizeof(*iwf));
320                         iwf->fff_data = malloc(iwf->fff_size = ffff.length);
321                         if (iwf->fff_data == NULL) {
322                                 free(iwf);
323                                 close(fd);
324                                 return -ENOMEM;
325                         }
326                         if (read(fd, iwf->fff_data, ffff.length) != (ssize_t) ffff.length) {
327                                 free(iwf->fff_data);
328                                 free(iwf);
329                                 close(fd);
330                                 return -ENOMEM;
331                         }
332                         close(fd);
333                         iwf->start_addr = bank*4L*1024L*1024L;
334                         iwf->rom = 1;
335                         *handle = iwf;
336                         return 0;
337                 }
338                 idx++;
339                 lseek(fd, SEEK_CUR, next_ffff);
340         }
341         close(fd);
342         return -ENOENT;
343 }
344
345 /**
346  * \brief Open IWFFFF ROM file
347  * \param handle IWFFFF handle
348  * \param name IWFFFF ROM filename
349  * \param bank ROM bank number (0-3)
350  * \param file ROM file number
351  * \return 0 on success otherwise a negative error code
352  */
353 #ifndef DOXYGEN
354 int snd_instr_iwffff_open_rom_file(snd_iwffff_handle_t **handle ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED, int bank ATTRIBUTE_UNUSED, int file ATTRIBUTE_UNUSED)
355 #else
356 int snd_instr_iwffff_open_rom_file(snd_iwffff_handle_t **handle, const char *name, int bank, int file)
357 #endif
358 {
359         /* TODO */
360         return -ENXIO;
361 }
362
363 /**
364  * \brief Close and free IWFFFF handle
365  * \param handle IWFFFF handle
366  * \return 0 on success otherwise a negative error code
367  */
368 int snd_instr_iwffff_close(snd_iwffff_handle_t *handle)
369 {
370         if (handle == NULL)
371                 return -EINVAL;
372         free(handle->dat_filename);
373         free(handle->fff_filename);
374         free(handle->fff_data);
375         free(handle);
376         return 0;
377 }
378
379 static void free_wave(iwffff_wave_t *wave)
380 {
381         if (wave == NULL)
382                 return;
383         free(wave->address.ptr);
384         free(wave);
385 }
386
387 static void free_envelope(iwffff_env_t *envp)
388 {
389         iwffff_env_record_t *rec, *nrec;
390         
391         if (envp == NULL)
392                 return;
393         rec = envp->record;
394         while (rec != NULL) {
395                 nrec = rec->next;
396                 free(rec);
397                 rec = nrec;
398         }
399 }
400
401 static void free_layer(iwffff_layer_t *layer)
402 {
403         iwffff_wave_t *wave, *nwave;
404
405         if (layer == NULL)
406                 return;
407
408         free_envelope(&layer->penv);
409         free_envelope(&layer->venv);
410         
411         wave = layer->wave;
412         while (wave != NULL) {
413                 nwave = wave->next;
414                 free_wave(wave);
415                 wave = nwave;
416         }
417         
418         free(layer);
419 }
420
421 /**
422  * \brief Free IWFFFF instrument
423  * \param __instr IWFFFF instrument handle
424  * \return 0 on success otherwise a negative error code
425  */
426 int snd_instr_iwffff_free(snd_instr_iwffff_t *__instr)
427 {
428         iwffff_instrument_t *instr = (iwffff_instrument_t *)__instr; 
429         iwffff_layer_t *layer, *nlayer;
430         
431         if (instr == NULL)
432                 return -EINVAL;
433         layer = instr->layer;
434         while (layer != NULL) {
435                 nlayer = layer->next;
436                 free_layer(layer);
437                 layer = nlayer;
438         }
439         free(instr);
440         return 0;
441 }
442
443 static char *look_for_id(snd_iwffff_handle_t *iwf ATTRIBUTE_UNUSED, unsigned char *start,
444                          unsigned char *end, ID id)
445 {
446         if (!start)
447                 return NULL;
448         while ((long)start < (long)end) {
449                 if (((struct header *)start)->id == id)
450                         return (char *)start;
451                 start += sizeof(struct header) + snd_LE_to_host_32(((struct header *)start)->length);
452         }
453         return NULL;
454 }
455
456 static void copy_modulation(iwffff_lfo_t *glfo, unsigned char *buffer)
457 {
458         glfo->freq  = snd_LE_to_host_16(*(((unsigned short *)buffer) + 0/2));
459         glfo->depth = snd_LE_to_host_16(*(((unsigned short *)buffer) + 2/2));
460         glfo->sweep = snd_LE_to_host_16(*(((unsigned short *)buffer) + 4/2));
461         glfo->shape = buffer[6];
462         glfo->delay = buffer[7];
463 }
464
465 static int copy_envelope(snd_iwffff_handle_t *iwf, iwffff_env_t *genv, ID eid)
466 {
467         int idx, idx1;
468         unsigned char *ptr, *end;
469         unsigned char *envelope, *record;
470         iwffff_env_record_t *grecord, *precord;
471         unsigned short nattack, nrelease, *points;
472         iwffff_env_point_t *rpoints;
473   
474         if (eid == 0)
475                 return -EINVAL;
476         ptr = iwf->fff_data;
477         end = iwf->fff_data + iwf->fff_size;
478         while (1) {
479                 ptr = (unsigned char *)look_for_id(iwf, ptr, end, envp_header);
480                 if (ptr == NULL)
481                         return -ENOENT;
482                 envelope = ptr + sizeof(struct header);
483                 if (*((ID *)envelope) == eid) {
484                         genv->flags = envelope[5];
485                         genv->mode = envelope[6];
486                         genv->index = envelope[7];
487                         genv->record = precord = NULL;
488                         record = envelope + ENVELOPE_SIZE;
489                         for (idx = 0; idx < envelope[4]; idx++) {
490                                 nattack = snd_LE_to_host_16(*(((unsigned short *)record) + 0/2));
491                                 nrelease = snd_LE_to_host_16(*(((unsigned short*)record) + 2/2));
492                                 grecord = calloc(1, sizeof(*grecord) + (nattack + nrelease) * sizeof(iwffff_env_point_t));
493                                 if (grecord == NULL)
494                                         return -ENOMEM;
495                                 grecord->nattack = nattack;
496                                 grecord->nrelease = nrelease;
497                                 grecord->sustain_offset = snd_LE_to_host_16(*(((unsigned short*)record) + 4/2));
498                                 grecord->sustain_rate = snd_LE_to_host_16(*(((unsigned short *)record) + 6/2));
499                                 grecord->release_rate = snd_LE_to_host_16(*(((unsigned short *)record) + 8/2));
500                                 grecord->hirange = record[10];
501                                 points = (unsigned short *)(record + ENVELOPE_RECORD_SIZE);
502                                 rpoints = (iwffff_env_point_t *)(grecord + 1);
503                                 for (idx1 = 0; idx1 < grecord->nattack + grecord->nrelease; idx1++) {
504                                         rpoints[idx1].offset = *points++;
505                                         rpoints[idx1].rate = *points++;
506                                 }
507                                 grecord->next = NULL;
508                                 if (genv->record == NULL) {
509                                         genv->record = grecord;
510                                 } else {
511                                         precord->next = grecord;
512                                 }
513                                 precord = grecord;
514                                 record += ENVELOPE_RECORD_SIZE + 2 * sizeof(short) * (grecord->nattack + grecord->nrelease);
515                         }
516                         return 0;
517                 }
518                 ptr += sizeof(struct header) + snd_LE_to_host_32(((struct header *)ptr)->length);
519         }
520 }
521
522 static int load_iw_wave(snd_iwffff_handle_t *file,
523                         unsigned int start,
524                         unsigned int size,
525                         unsigned char **result)
526 {
527         int fd, res;
528   
529         *result = NULL;
530         if ((fd = open(file->dat_filename, O_RDONLY)) < 0)
531                 return -errno;
532         if (lseek(fd, start, SEEK_SET) < 0) {
533                 res = -errno;
534                 close(fd);
535                 return res;
536         }
537         *result = malloc(size);
538         if (*result == NULL) {
539                 close(fd);
540                 return -ENOMEM;
541         }
542         if (read(fd, result, size) != (ssize_t) size) {
543                 free(*result);
544                 *result = NULL;
545                 close(fd);
546                 return -errno;
547         }
548         close(fd);
549         return 0;
550 }
551
552 static int load_iw_patch(snd_iwffff_handle_t *iwf, iwffff_instrument_t *instr,
553                          unsigned char *patch)
554 {
555         unsigned char *layer, *wave;
556         iwffff_layer_t *glayer, *player;
557         iwffff_wave_t *gwave, *pwave;
558         int idx_layer, idx_wave, result;
559         unsigned char *current;
560
561 #ifdef IW_ROM_DEBUG
562         SNDERR("load_iw_patch - nlayers = %i\n", snd_LE_to_host_16(*(((unsigned short *)patch) + 8/2));
563 #endif
564         instr->layer_type = patch[6];
565         instr->exclusion = patch[7];
566         instr->exclusion_group = snd_LE_to_host_16(*(((unsigned short *)patch) + 8/2));
567         instr->effect1 = patch[10];
568         instr->effect1_depth = patch[11];
569         instr->effect2 = patch[12];
570         instr->effect2_depth = patch[13];
571         current = (unsigned char *)patch + sizeof(struct patch);
572         instr->layer = player = NULL;
573         for (idx_layer = 0; idx_layer < snd_LE_to_host_16(*(((unsigned short *)patch) + 4/2)); idx_layer++) {
574                 if (((struct header *)current)->id != layer_header) {
575                         return -EIO;
576                 }
577                 layer = current + sizeof(struct header);
578                 glayer = calloc(1, sizeof(*glayer));
579                 glayer->flags = layer[5];
580                 glayer->high_range = layer[6];
581                 glayer->low_range = layer[7];
582                 glayer->pan = layer[8];
583                 glayer->pan_freq_scale = layer[9];
584                 copy_modulation(&glayer->tremolo, layer + 10);
585                 copy_modulation(&glayer->vibrato, layer + 18);
586                 glayer->velocity_mode = layer[26];
587                 glayer->attenuation = layer[27];
588                 glayer->freq_scale = snd_LE_to_host_16(*(((unsigned short *)layer) + 28/2));
589                 glayer->freq_center = layer[30];
590                 glayer->layer_event = layer[31];
591                 if (copy_envelope(iwf, &glayer->penv, *((ID *)(layer + 32))) < 0) {
592                         free_layer(glayer);
593                         return -EIO;
594                 }
595                 if (copy_envelope(iwf, &glayer->venv, *((ID *)(layer + 36))) < 0) {
596                         free_layer(glayer);
597                         return -EIO;
598                 }
599                 current += sizeof(struct header) + snd_LE_to_host_32(((struct header *)current)->length);
600                 glayer->wave = pwave = NULL;
601                 for (idx_wave = 0; idx_wave < layer[4]; idx_wave++) {
602                         unsigned char format;
603                         int w_16;
604         
605                         if (((struct header *)current)->id != wave_header) {
606                                 free_layer(glayer);
607                                 return -EIO;
608                         }
609                         wave = current + sizeof(struct header);
610                         format = wave[31];
611                         w_16 = format & IW_FORMAT_8BIT ? 1 : 2; 
612                         gwave = calloc(1, sizeof(*gwave));
613                         gwave->size = snd_LE_to_host_32(*(((unsigned int *)wave) + 4/4)) * w_16;
614                         gwave->start = iwf->start_addr;
615                         gwave->loop_start = snd_LE_to_host_32(*(((unsigned int *)wave) + 12/4)) * w_16;
616                         gwave->loop_end = snd_LE_to_host_32(*(((unsigned int *)wave) + 16/4)) * w_16;
617                         gwave->sample_ratio = snd_LE_to_host_32(*(((unsigned int *)wave) + 24/4));
618                         gwave->attenuation = wave[28];
619                         gwave->low_note = wave[29];
620                         gwave->high_note = wave[30];
621                         if (!(format & IW_FORMAT_8BIT))
622                                 gwave->format |= IWFFFF_WAVE_16BIT;
623                         if (!(format & IW_FORMAT_SIGNED))
624                                 gwave->format |= IWFFFF_WAVE_UNSIGNED;
625                         if (!(format & IW_FORMAT_FORWARD))
626                                 gwave->format |= IWFFFF_WAVE_BACKWARD;
627                         if (format & IW_FORMAT_LOOP)
628                                 gwave->format |= IWFFFF_WAVE_LOOP;
629                         if (format & IW_FORMAT_BIDIR)
630                                 gwave->format |= IWFFFF_WAVE_BIDIR;
631                         if (format & IW_FORMAT_ULAW)
632                                 gwave->format |= IWFFFF_WAVE_ULAW;
633                         if (format & IW_FORMAT_ROM) {
634                                 gwave->format |= IWFFFF_WAVE_ROM;
635                                 gwave->address.memory = snd_LE_to_host_32(*(((unsigned int *)wave) + 8/4));
636                         } else {
637                                 gwave->share_id[0] = iwf->share_id1;
638                                 gwave->share_id[1] = iwf->share_id2;
639                                 gwave->share_id[2] = iwf->share_id3;
640                                 gwave->share_id[3] = snd_LE_to_host_32(*(((unsigned int *)wave) + 8/4));
641                                 result = load_iw_wave(iwf, gwave->share_id[2], gwave->size, &gwave->address.ptr);
642                                 if (result < 0) {
643                                         free_wave(gwave);
644                                         return result;
645                                 }
646                         }
647                         if (glayer->wave == NULL) {
648                                 glayer->wave = gwave;
649                         } else {
650                                 pwave->next = gwave;
651                         }
652                         pwave = gwave;
653                         current += sizeof(struct header) + snd_LE_to_host_32(((struct header *)current)->length);
654                 }
655                 if (instr->layer == NULL) {
656                         instr->layer = glayer;
657                 } else {
658                         player->next = glayer;
659                 }
660                 player = glayer;
661         }
662         return 0;
663 }
664
665 /**
666  * \brief Load IWFFFF instrument
667  * \param iwf IWFFFF handle
668  * \param bank program bank number
669  * \param prg program number
670  * \param __iwffff allocated IWFFFF instrument
671  * \return 0 on success otherwise a negative error code
672  */
673 int snd_instr_iwffff_load(snd_iwffff_handle_t *iwf, int bank, int prg, snd_instr_iwffff_t **__iwffff)
674 {
675         unsigned char *ptr, *end;
676         unsigned char *program, *patch;
677         struct header *header;
678         iwffff_instrument_t *iwffff;
679         int result;
680
681         if (iwf == NULL || __iwffff == NULL)
682                 return -EINVAL;
683         __iwffff = NULL;
684         if (bank < 0 || bank > 255 || prg < 0 || prg > 255)
685                 return -EINVAL;
686         iwffff = (iwffff_instrument_t *)__iwffff;
687         ptr = iwf->fff_data;
688         end = iwf->fff_data + iwf->fff_size;
689         while (1) {
690                 ptr = (unsigned char *)look_for_id(iwf, ptr, end, program_header);
691                 if (ptr == NULL)
692                         break;
693                 program = ptr + sizeof(struct header);
694                 if (snd_LE_to_host_16(*(((unsigned short *)program) + 4/2)) != IW_ROM_PROGRAM_VERSION_MAJOR ||
695                     snd_LE_to_host_16(*(((unsigned short *)program) + 6/2)) != IW_ROM_PROGRAM_VERSION_MINOR)
696                         return -EINVAL;
697                 header = (struct header *)(ptr + sizeof(struct header) + sizeof(struct program));
698                 if (header->id == patch_header) {
699                         patch = ptr + sizeof(struct header) + sizeof(struct program) + sizeof(struct header);
700                         if (patch[14] == bank && patch[15] == prg) {
701                                 iwffff = (iwffff_instrument_t *)malloc(sizeof(*iwffff));
702                                 if (iwffff == NULL)
703                                         return -ENOMEM;
704                                 result = load_iw_patch(iwf, iwffff, patch);
705                                 if (result < 0) {
706                                         snd_instr_iwffff_free(iwffff);
707                                 } else {
708                                         *__iwffff = iwffff;
709                                 }
710                                 return result;
711                         }
712                 }
713                 ptr += sizeof(struct header) + snd_LE_to_host_32(((struct header *)ptr)->length);
714         }
715         return -ENOENT;
716 }
717
718 static int iwffff_evp_record_size(iwffff_env_t *env)
719 {
720         iwffff_env_record_t *rec;
721         int size;
722
723         if (env == NULL)
724                 return 0;
725         size = 0;
726         for (rec = env->record; rec; rec = rec->next) {
727                 size += sizeof(iwffff_xenv_record_t);
728                 size += sizeof(iwffff_xenv_point_t) *
729                         (rec->nattack + rec->nrelease);
730         }
731         return size;
732 }
733
734 static int iwffff_size(iwffff_instrument_t *instr)
735 {
736         int size;
737         iwffff_layer_t *layer;
738         iwffff_wave_t *wave;
739         
740         if (instr == NULL)
741                 return 0;
742         size = sizeof(iwffff_xinstrument_t);
743         for (layer = instr->layer; layer; layer = layer->next) {
744                 size += sizeof(iwffff_xlayer_t);
745                 size += iwffff_evp_record_size(&layer->penv);
746                 size += iwffff_evp_record_size(&layer->venv);
747                 for (wave = layer->wave; wave; wave = wave->next) {
748                         size += sizeof(iwffff_xwave_t);
749                         if (!(wave->format & IWFFFF_WAVE_ROM))
750                                 size += wave->size;
751                 }
752         }
753         return size;
754 }
755
756 static void copy_lfo_to_stream(iwffff_xlfo_t *xlfo, iwffff_lfo_t *lfo)
757 {
758         xlfo->freq = __cpu_to_le16(lfo->freq);
759         xlfo->depth = __cpu_to_le16(lfo->depth);
760         xlfo->sweep = __cpu_to_le16(lfo->sweep);
761         xlfo->shape = lfo->shape;
762         xlfo->delay = lfo->delay;
763         
764 }
765
766 static int copy_env_to_stream(iwffff_xenv_t *xenv, iwffff_env_t *env, __u32 stype)
767 {
768         int size, idx;
769         char *ptr;
770         iwffff_xenv_record_t *xrec;
771         iwffff_env_record_t *rec;
772         iwffff_xenv_point_t *xpoint;
773         iwffff_env_point_t *point;
774
775         xenv->flags = env->flags;
776         xenv->mode = env->mode;
777         xenv->index = env->index;
778         size = 0;
779         ptr = (char *)(xenv + 1);
780         for (rec = env->record; rec; rec = rec->next) {
781                 xrec = (iwffff_xenv_record_t *)ptr;
782                 ptr += sizeof(*xrec);
783                 size += sizeof(*xrec);
784                 xrec->stype = stype;
785                 xrec->nattack = __cpu_to_le16(rec->nattack);
786                 xrec->nrelease = __cpu_to_le16(rec->nrelease);
787                 xrec->sustain_offset = __cpu_to_le16(rec->sustain_offset);
788                 xrec->sustain_rate = __cpu_to_le16(rec->sustain_rate);
789                 xrec->release_rate = __cpu_to_le16(rec->release_rate);
790                 xrec->hirange = rec->hirange;
791                 point = (iwffff_env_point_t *)(rec + 1);
792                 for (idx = 0; idx < xrec->nattack + xrec->nrelease; idx++) {
793                         xpoint = (iwffff_xenv_point_t *)ptr;
794                         ptr += sizeof(*xpoint);
795                         size += sizeof(*xpoint);
796                         xpoint->offset = __cpu_to_le16(point->offset);
797                         xpoint->rate = __cpu_to_le16(point->rate);
798                         point++;
799                 }
800         }
801         return size;
802 }
803
804 /**
805  * \brief Convert the IWFFFF instrument to byte stream
806  * \param iwffff IWFFFF instrument handle
807  * \param name instrument name
808  * \param __data Result - allocated byte stream
809  * \param __size Result - size of allocated byte stream
810  * \return 0 on success otherwise a negative error code
811  */
812 int snd_instr_iwffff_convert_to_stream(snd_instr_iwffff_t *iwffff,
813                                        const char *name,
814                                        snd_instr_header_t **__data,
815                                        size_t *__size)
816 {
817         snd_instr_header_t *put;
818         int size;
819         char *ptr;
820         iwffff_instrument_t *instr;
821         iwffff_xinstrument_t *xinstr;
822         iwffff_layer_t *layer;
823         iwffff_xlayer_t *xlayer;
824         iwffff_wave_t *wave;
825         iwffff_xwave_t *xwave;
826         
827         if (iwffff == NULL || __data == NULL)
828                 return -EINVAL;
829         instr = (iwffff_instrument_t *)iwffff;
830         *__data = NULL;
831         *__size = 0;
832         size = iwffff_size(iwffff);
833         if (snd_instr_header_malloc(&put, size) < 0)
834                 return -ENOMEM;
835         /* build header */
836         if (name)
837                 snd_instr_header_set_name(put, name);
838         snd_instr_header_set_type(put, SND_SEQ_INSTR_ATYPE_DATA);
839         snd_instr_header_set_format(put, SND_SEQ_INSTR_ID_INTERWAVE);
840         /* build data section */
841         xinstr = (iwffff_xinstrument_t *)snd_instr_header_get_data(put);
842         xinstr->stype = IWFFFF_STRU_INSTR;
843         xinstr->exclusion = __cpu_to_le16(instr->exclusion);
844         xinstr->layer_type = __cpu_to_le16(instr->layer_type);
845         xinstr->exclusion_group = __cpu_to_le16(instr->exclusion_group);
846         xinstr->effect1 = instr->effect1;
847         xinstr->effect1_depth = instr->effect1_depth;
848         xinstr->effect2 = instr->effect2;
849         xinstr->effect2_depth = instr->effect2_depth;
850         ptr = (char *)(xinstr + 1);
851         for (layer = instr->layer; layer; layer = layer->next) {
852                 xlayer = (iwffff_xlayer_t *)ptr;
853                 ptr += sizeof(*xlayer);
854                 xlayer->stype = IWFFFF_STRU_LAYER;
855                 xlayer->flags = layer->flags;
856                 xlayer->velocity_mode = layer->velocity_mode;
857                 xlayer->layer_event = layer->layer_event;
858                 xlayer->low_range = layer->low_range;
859                 xlayer->high_range = layer->high_range;
860                 xlayer->pan = layer->pan;
861                 xlayer->pan_freq_scale = layer->pan_freq_scale;
862                 xlayer->attenuation = layer->attenuation;
863                 copy_lfo_to_stream(&xlayer->tremolo, &layer->tremolo);
864                 copy_lfo_to_stream(&xlayer->vibrato, &layer->vibrato);
865                 xlayer->freq_scale = __cpu_to_le16(layer->freq_scale);
866                 xlayer->freq_center = layer->freq_center;
867                 ptr += copy_env_to_stream(&xlayer->penv, &layer->penv, IWFFFF_STRU_ENV_RECP);
868                 ptr += copy_env_to_stream(&xlayer->venv, &layer->venv, IWFFFF_STRU_ENV_RECV);
869                 for (wave = layer->wave; wave; wave = wave->next) {
870                         xwave = (iwffff_xwave_t *)ptr;
871                         ptr += sizeof(*xwave);
872                         xwave->stype = IWFFFF_STRU_WAVE;
873                         xwave->share_id[0] = __cpu_to_le32(wave->share_id[0]);
874                         xwave->share_id[1] = __cpu_to_le32(wave->share_id[1]);
875                         xwave->share_id[2] = __cpu_to_le32(wave->share_id[2]);
876                         xwave->share_id[3] = __cpu_to_le32(wave->share_id[3]);
877                         xwave->format = __cpu_to_le32(wave->format);
878                         xwave->size = __cpu_to_le32(wave->size);
879                         xwave->start = __cpu_to_le32(wave->start);
880                         xwave->loop_start = __cpu_to_le32(wave->loop_start);
881                         xwave->loop_end = __cpu_to_le32(wave->loop_end);
882                         xwave->loop_repeat = __cpu_to_le32(wave->loop_repeat);
883                         xwave->sample_ratio = __cpu_to_le32(wave->sample_ratio);
884                         xwave->attenuation = wave->attenuation;
885                         xwave->low_note = wave->low_note;
886                         xwave->high_note = wave->high_note;
887                         if (!(xwave->format & IWFFFF_WAVE_ROM)) {
888                                 memcpy(ptr, wave->address.ptr, wave->size);
889                                 ptr += wave->size;
890                         } else {
891                                 xwave->offset = __cpu_to_le32(wave->address.memory);
892                         }
893                 }
894         }
895         /* write result */
896         *__data = put;
897         *__size = sizeof(*put) + size;
898         return 0;
899 }
900
901 /**
902  * \brief Convert the byte stream to IWFFFF instrument
903  * \param data Input - byte stream
904  * \param size Input - size of byte stream
905  * \param iwffff Result - allocated IWFFFF instrument handle
906  * \return 0 on success otherwise a negative error code
907  */
908 #ifndef DOXYGEN
909 int snd_instr_iwffff_convert_from_stream(snd_instr_header_t *data ATTRIBUTE_UNUSED,
910                                          size_t size ATTRIBUTE_UNUSED,
911                                          snd_instr_iwffff_t **iwffff ATTRIBUTE_UNUSED)
912 #else
913 int snd_instr_iwffff_convert_from_stream(snd_instr_header_t *data,
914                                          size_t size,
915                                          snd_instr_iwffff_t **iwffff)
916 #endif
917 {
918         /* TODO */
919         return -ENXIO;
920 }