ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/PDL-Audio/sndlib/headers.c
Revision: 1.1
Committed: Tue Dec 28 01:05:17 2004 UTC (19 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-1_1, rel-1_2, HEAD
Log Message:
*** empty log message ***

File Contents

# Content
1 /* readers/writers for various sound file headers
2 *
3 * TODO: avi, asf, and soundfont code seriously incomplete
4 * avr doesn't match actual files
5 * quicktime is just a guess
6 * esignal not tackled yet (need an example file)
7 * check resource info on Mac (for SoundEdit)
8 * get example of little endian DEC header
9 *
10 * --------------------------------
11 * int mus_read_header (char *name): reads file's header
12 * int mus_write_header (char *name, int type, int in_srate, int in_chans, int loc, int size, int format, char *comment, int len): writes file's header
13 * int mus_update_header (char *name, int type, int size, int srate, int format, int chans, int loc): update file's header (unset fields should be 0)
14 * int mus_create_header_buffer (void): initialize (allocate) various buffers -- should be called before using mus_read_header and others
15 *
16 * Once mus_read_header has been called, the data in it can be accessed through:
17 *
18 * int mus_header_samples (void): samples
19 * int mus_header_data_location (void) location of data (bytes)
20 * int mus_header_chans (void) channels
21 * int mus_header_srate (void) srate
22 * int mus_header_type (void) header type (i.e. aiff, wave, etc) (see sndlib.h)
23 * int mus_header_format (void) data format (see sndlib.h)
24 * int mus_header_distributed (void) true if header info is scattered around in the file
25 * int mus_header_comment_start (void) comment start location (if any) (bytes)
26 * int mus_header_comment_end (void) comment end location
27 * int mus_header_aux_comment_start (int n) if multiple comments, nth start location
28 * int mus_header_aux_comment_end (int n) if multiple comments, nth end location
29 * int mus_header_type_specifier (void) original (header-specific) type ID
30 * int mus_header_bits_per_sample (void) sample width in bits
31 * int mus_true_file_length (void) true (lseek) file length
32 * int mus_header_format2bytes (void) sample width in bytes
33 *
34 * int mus_header_aiff_p(void) is header actually old-style AIFF, not AIFC
35 * int mus_header_writable(int type, int format)
36 * --------------------------------
37 *
38 * "Linear" below means 2's complement integer.
39 *
40 * Currently supported read/write (in standard data formats):
41 * NeXT/Sun/DEC/AFsp
42 * AIFF/AIFC
43 * RIFF (microsoft wave)
44 * IRCAM (old style)
45 * NIST-sphere
46 * no header
47 *
48 * Currently supported read-only (in selected data formats):
49 * 8SVX (IFF), IRCAM Vax float, EBICSF, INRS, ESPS, SPPACK, ADC (OGI), AVR, VOC,
50 * Sound Tools, Turtle Beach SMP, SoundFont 2.0, Sound Designer I and II, PSION alaw, MAUD,
51 * Tandy DeskMate new and old style, Gravis Ultrasound, Comdisco SPW, Goldwave sample, OMF,
52 * Sonic Foundry, SBStudio II, Delusion digital, Digiplayer ST3, Farandole Composer WaveSample,
53 * Ultratracker WaveSample, Sample Dump exchange, Yamaha SY85 and SY99 (buggy), Yamaha TX16,
54 * Covox v8, SPL, AVI, Kurzweil 2000
55 *
56 * for a few of these I'm still trying to get documentation -- best sources of info
57 * are ftp.cwi.nl:pub/audio (info files), the AFsp sources, and the SOX sources.
58 * sox and gsm are at ftp.cwi.nl, AFsp is from kabal@Polaris.EE.McGill.CA (Peter Kabal) as
59 * ftp.TSP.EE.McGill.CA:/pub/AFsp/AFsp-V3R2.tar.Z. The Sound Designer formats are described
60 * in the "Developer Documentation" from Digidesign. Other useful sources can be found at
61 * ftp.x.org:/contrib/audio/nas, svr-ftp.eng.cam.ac.uk:/comp.speech/tools, and
62 * at http://www.wotsit.org/music.htm. I put many of my test cases in
63 * ccrma-ftp.stanford.edu:/pub/Lisp/sf.tar.gz. The RIFF format is described in the
64 * Microsoft Multimedia Programmer's Reference Manual at ftp.microsoft.com:/SoftLib/MSLFILES/MDRK.EXE.
65 * AVI format is described in http://www.rahul.net/jfm/avi.html.
66 *
67 * The main problem with compressed sound files is that you can't do reliable
68 * random access to the data, can't easily read backwards, and most of the compression
69 * schemes are proprietary (and appalling), but to translate Mus10/Sam, HCOM, IEEE text,
70 * IBM CVSD, MIDI sample dumps, various adpcm cases, NIST shortpack files, and AVI see snd-trans.c
71 * in the sound editor (snd-3.tar.gz).
72 *
73 * If anyone has information on any other header or data formats, I would be most interested in it,
74 * but only if it can be included in this file.
75 */
76
77 #if defined(HAVE_CONFIG_H)
78 #include "config.h"
79 #endif
80
81 #include <math.h>
82 #include <stdio.h>
83 #if (!defined(HAVE_CONFIG_H)) || (defined(HAVE_FCNTL_H))
84 #include <fcntl.h>
85 #endif
86 #include <signal.h>
87 #if (!defined(HAVE_CONFIG_H)) || (defined(HAVE_LIMITS_H))
88 #include <limits.h>
89 #endif
90 #include <errno.h>
91 #include <stdlib.h>
92 #if (!defined(HAVE_CONFIG_H)) || (defined(HAVE_STRING_H))
93 #include <string.h>
94 #endif
95
96 #if (defined(NEXT) || (defined(HAVE_LIBC_H) && (!defined(HAVE_UNISTD_H))))
97 #include <libc.h>
98 #else
99 #if (!(defined(_MSC_VER))) && (!(defined(MPW_C)))
100 #include <unistd.h>
101 #endif
102 #endif
103
104 #include "sndlib.h"
105
106 static int hdrbuf_is_inited = 0;
107
108 #define HDRBUFSIZ 256
109 #ifndef MACOS
110 static unsigned char *hdrbuf;
111 #else
112 static char *hdrbuf;
113 #endif
114
115 #define INITIAL_READ_SIZE 32
116
117 /* AIFF files can have any number of ANNO chunks, so we'll grab at least 4 of them */
118 #define AUX_COMMENTS 4
119 static int *aux_comment_start = NULL, *aux_comment_end = NULL;
120
121 #define LOOPS 2
122 static int *loop_modes = NULL,*loop_starts = NULL,*loop_ends = NULL;
123 static int markers = 0;
124 static int *marker_ids = NULL,*marker_positions = NULL;
125
126 #ifdef CLM
127 void reset_headers_c(void)
128 {
129 hdrbuf_is_inited = 0;
130 markers = 0;
131 }
132 #endif
133
134 int mus_create_header_buffer (void)
135 {
136 if (hdrbuf_is_inited == 0)
137 {
138 hdrbuf_is_inited = 1;
139 #ifndef MACOS
140 hdrbuf = (unsigned char *)CALLOC(HDRBUFSIZ,sizeof(unsigned char));
141 #else
142 hdrbuf = (char *)CALLOC(HDRBUFSIZ,sizeof(unsigned char));
143 #endif
144 aux_comment_start = (int *)CALLOC(AUX_COMMENTS,sizeof(int));
145 aux_comment_end = (int *)CALLOC(AUX_COMMENTS,sizeof(int));
146 loop_modes = (int *)CALLOC(LOOPS,sizeof(int));
147 loop_starts = (int *)CALLOC(LOOPS,sizeof(int));
148 loop_ends = (int *)CALLOC(LOOPS,sizeof(int));
149 if ((hdrbuf == NULL) || (aux_comment_start == NULL) || (aux_comment_end == NULL) ||
150 (loop_modes == NULL) || (loop_starts == NULL) || (loop_ends == NULL))
151 {
152 mus_error(MUS_MEMORY_ALLOCATION_FAILED,"header buffer allocation trouble");
153 return(-1);
154 }
155 }
156 return(0);
157 }
158
159
160 static const unsigned char I_DSND[4] = {'.','s','n','d'}; /* NeXT/Sun/Dec/SGI/AFsp first word */
161 static const unsigned char I_FORM[4] = {'F','O','R','M'}; /* AIFF first word */
162 static const unsigned char I_AIFF[4] = {'A','I','F','F'}; /* AIFF second word */
163 static const unsigned char I_AIFC[4] = {'A','I','F','C'}; /* ditto but might be compressed data */
164 static const unsigned char I_COMM[4] = {'C','O','M','M'};
165 static const unsigned char I_COMT[4] = {'C','O','M','T'};
166 static const unsigned char I_INFO[4] = {'I','N','F','O'};
167 static const unsigned char I_INST[4] = {'I','N','S','T'};
168 static const unsigned char I_inst[4] = {'i','n','s','t'}; /* RIFF wants lower case, just to be different */
169 static const unsigned char I_MARK[4] = {'M','A','R','K'};
170 static const unsigned char I_SSND[4] = {'S','S','N','D'};
171 static const unsigned char I_FVER[4] = {'F','V','E','R'};
172 static const unsigned char I_NONE[4] = {'N','O','N','E'};
173 static const unsigned char I_ULAW[4] = {'U','L','A','W'}; /* AIFC compression types that we can handle */
174 static const unsigned char I_ulaw[4] = {'u','l','a','w'}; /* or maybe it's lowercase (Apple) ... */
175 static const unsigned char I_ima4[4] = {'i','m','a','4'}; /* AIFC IMA adpcm apparently */
176 static const unsigned char I_raw_[4] = {'r','a','w',' '}; /* AIFC offset binary OS 8.5 (others are 'MAC3' 'MAC6' 'cdx4' 'cdx2' 'str4') */
177 static const unsigned char I_sowt[4] = {'s','o','w','t'}; /* AIFC little endian? */
178 static const unsigned char I_fl32[4] = {'f','l','3','2'}; /* AIFC 32-bit float? */
179 static const unsigned char I_fl64[4] = {'f','l','6','4'}; /* AIFC 64-bit float? */
180 static const unsigned char I_twos[4] = {'t','w','o','s'}; /* AIFC big endian? */
181 static const unsigned char I_ALAW[4] = {'A','L','A','W'};
182 static const unsigned char I_alaw[4] = {'a','l','a','w'}; /* apple */
183 static const unsigned char I_APPL[4] = {'A','P','P','L'};
184 static const unsigned char I_MUS_[4] = {'C','L','M',' '}; /* I hereby claim this AIFF chunk name */
185 static const unsigned char I_RIFF[4] = {'R','I','F','F'}; /* RIFF first word */
186 static const unsigned char I_RIFX[4] = {'R','I','F','X'}; /* RIFX first word (big-endian RIFF file) */
187 static const unsigned char I_WAVE[4] = {'W','A','V','E'};
188 static const unsigned char I_fmt_[4] = {'f','m','t',' '};
189 static const unsigned char I_data[4] = {'d','a','t','a'};
190 static const unsigned char I_fact[4] = {'f','a','c','t'}; /* used by compressed RIFF files */
191 static const unsigned char I_clm_[4] = {'c','l','m',' '};
192 static const unsigned char I_NIST[4] = {'N','I','S','T'}; /* first word of NIST SPHERE files */
193 static const unsigned char I_8SVX[4] = {'8','S','V','X'}; /* AIFF other choice */
194 static const unsigned char I_VOC0[4] = {'C','r','e','a'}; /* Actual text is "Creative Voice File" */
195 static const unsigned char I_VOC1[4] = {'t','i','v','e'};
196 static const unsigned char I_SOUN[4] = {'S','O','U','N'}; /* Sound Tools first word="SOUND" -- not unique as SMP files start with "SOUND SAMPLE" */
197 static const unsigned char I_SMP1[4] = {'D',' ','S','A'};
198 static const unsigned char I_SMP2[4] = {'M','P','L','E'};
199 static const unsigned char I_BODY[4] = {'B','O','D','Y'}; /* next 4 for 8svx chunk names */
200 static const unsigned char I_VHDR[4] = {'V','H','D','R'};
201 static const unsigned char I_CHAN[4] = {'C','H','A','N'};
202 static const unsigned char I_ANNO[4] = {'A','N','N','O'};
203 static const unsigned char I_NAME[4] = {'N','A','M','E'};
204 static const unsigned char I_AVR_[4] = {'2','B','I','T'}; /* first word of AVR files */
205 static const unsigned char I_HCOM[4] = {'H','C','O','M'};
206 static const unsigned char I_FSSD[4] = {'F','S','S','D'};
207 static const unsigned char I_SPIB[4] = {'%','/','/','\n'}; /* first word of IEEE spib text sound files */
208 static const unsigned char I_S___[4] = {'%','-','-','-'}; /* first word of other IEEE spib text sound files */
209 static const unsigned char I_ALaw[4] = {'A','L','a','w'}; /* first word of PSION alaw files */
210 static const unsigned char I_Soun[4] = {'S','o','u','n'}; /* second */
211 static const unsigned char I_MAUD[4] = {'M','A','U','D'}; /* MAUD specialization of AIFF */
212 static const unsigned char I_MHDR[4] = {'M','H','D','R'};
213 static const unsigned char I_MDAT[4] = {'M','D','A','T'};
214 static const unsigned char I_mdat[4] = {'m','d','a','t'}; /* quicktime */
215 static const unsigned char I_AFsp[4] = {'A','F','s','p'};
216 static const unsigned char I_MThd[4] = {'M','T','h','d'}; /* sigh -- the M word */
217 static const unsigned char I_DVSM[4] = {'D','V','S','M'}; /* first word of DVSM files */
218 static const unsigned char I_DECN[4] = {'.','s','d','\0'}; /* first word of DEC files (?) */
219 static const unsigned char I_Esig[4] = {'E','s','i','g'}; /* first word of Esignal files */
220 static const unsigned char I_nalc[4] = {'n','a','l','\n'}; /* second word of Esignal files */
221 static const unsigned char I_sfbk[4] = {'s','f','b','k'}; /* SoundFont 2.0 */
222 static const unsigned char I_sdta[4] = {'s','d','t','a'};
223 static const unsigned char I_shdr[4] = {'s','h','d','r'};
224 static const unsigned char I_smpl[4] = {'s','m','p','l'};
225 static const unsigned char I_pdta[4] = {'p','d','t','a'};
226 static const unsigned char I_LIST[4] = {'L','I','S','T'};
227 static const unsigned char I_GF1P[4] = {'G','F','1','P'}; /* first word of Gravis Ultrsound patch files */
228 static const unsigned char I_ATCH[4] = {'A','T','C','H'}; /* second word */
229 static const unsigned char I_DSIG[4] = {'$','S','I','G'}; /* first word of Comdisco SPW file */
230 static const unsigned char I_NAL_[4] = {'N','A','L','_'}; /* second word */
231 static const unsigned char I_GOLD[4] = {'G','O','L','D'}; /* first word Goldwave(?) sample file */
232 static const unsigned char I__WAV[4] = {' ','S','A','M'}; /* second word */
233 static const unsigned char I_SRFS[4] = {'S','R','F','S'}; /* first word Sonic Resource Foundry file(?) */
234 static const unsigned char I_Diam[4] = {'D','i','a','m'}; /* first word DiamondWare file */
235 static const unsigned char I_ondW[4] = {'o','n','d','W'}; /* second word */
236 static const unsigned char I_Drat[4] = {'.','r','a','\xfd'}; /* first word real audio file */
237 static const unsigned char I_CSRE[4] = {'C','S','R','E'}; /* adf first word -- second starts with "40" */
238 static const unsigned char I_SND_[4] = {'S','N','D',' '}; /* SBStudio II */
239 static const unsigned char I_SNIN[4] = {'S','N','I','N'};
240 static const unsigned char I_SNDT[4] = {'S','N','D','T'};
241 static const unsigned char I_DDSF[4] = {'D','D','S','F'}; /* Delusion Digital Sound File */
242 static const unsigned char I_FSMt[4] = {'F','S','M','\376'}; /* Farandole Composer WaveSample */
243 static const unsigned char I_SDXc[4] = {'S','D','X',':'}; /* Sample dump exchange format */
244 static const unsigned char I_UWFD[4] = {'U','W','F','D'}; /* Ultratracker Wavesample */
245 static const unsigned char I_LM89[4] = {'L','M','8','9'}; /* Yamaha TX-16 */
246 static const unsigned char I_SY80[4] = {'S','Y','8','0'}; /* Yamaha SY-99 */
247 static const unsigned char I_SY85[4] = {'S','Y','8','5'}; /* Yamaha SY-85 */
248 static const unsigned char I_SCRS[4] = {'S','C','R','S'}; /* Digiplayer ST3 */
249 static const unsigned char I_covox[4] = {'\377','\125','\377','\252'};
250 static const unsigned char I_DSPL[4] = {'D','S','P','L'}; /* Digitracker SPL (now obsolete) */
251 static const unsigned char I_AVI_[4] = {'A','V','I',' '}; /* RIFF AVI */
252 static const unsigned char I_strf[4] = {'s','t','r','f'};
253 static const unsigned char I_movi[4] = {'m','o','v','i'};
254 static const unsigned char I_PRAM[4] = {'P','R','A','M'}; /* Kurzweil 2000 */
255 static const unsigned char I_ones[4] = {'\377','\377','\377','\377'};
256 static const unsigned char I_zeros[4] = {'\0','\0','\0','\0'};
257 static const unsigned char I_asf0[4] = {'\321','\051','\342','\326'};
258 static const unsigned char I_asf1[4] = {'\332','\065','\321','\021'};
259 static const unsigned char I_asf2[4] = {'\220','\064','\000','\240'};
260 static const unsigned char I_asf3[4] = {'\311','\003','\111','\276'};
261
262 /* .glt and .shp -> Perry Cook's SPASM data files */
263
264 #define I_IRCAM_VAX 0x0001a364
265 #define I_IRCAM_SUN 0x0002a364
266 #define I_IRCAM_MIPS 0x0003a364
267 #define I_IRCAM_NEXT 0x0004a364
268
269 #define NINRS 7
270 static const unsigned int I_INRS[NINRS]={0xcb460020,0xd0465555,0xfa460000,0x1c470040,0x3b470080,0x7a470000,0x9c470040};
271
272 static int data_size=0, data_location=0, srate=0, chans=0, header_type=0, data_format=0, original_data_format=0, true_file_length=0;
273 static int comment_start=0, comment_end=0, header_distributed=0, type_specifier=0, bits_per_sample=0, fact_samples=0, block_align=0;
274 static int base_detune = 0, base_note = 0;
275
276 int mus_header_samples (void) {return(data_size);}
277 int mus_header_data_location (void) {return(data_location);}
278 int mus_header_chans (void) {return(chans);}
279 int mus_header_srate (void) {return(srate);}
280 int mus_header_type (void) {return(header_type);}
281 int mus_header_format (void) {return(data_format);}
282 int mus_header_distributed (void) {return(header_distributed);}
283 int mus_header_comment_start (void) {return(comment_start);}
284 int mus_header_comment_end (void) {return(comment_end);}
285 int mus_header_aux_comment_start (int n) {return(aux_comment_start[n]);}
286 int mus_header_aux_comment_end (int n) {return(aux_comment_end[n]);}
287 int mus_header_type_specifier (void) {return(type_specifier);}
288 int mus_header_bits_per_sample (void) {return(bits_per_sample);}
289 int mus_header_fact_samples (void) {return(fact_samples);}
290 int mus_header_block_align (void) {return(block_align);}
291 int mus_true_file_length (void) {return(true_file_length);}
292 int mus_header_original_format (void) {return(original_data_format);}
293 int mus_header_loop_mode(int which) {if (loop_modes) return(loop_modes[which]); else return(-1);}
294 int mus_header_loop_start(int which) {if (loop_starts) return(loop_starts[which]); else return(-1);}
295 int mus_header_loop_end(int which) {if (loop_ends) return(loop_ends[which]); else return(-1);}
296 int mus_header_mark_position(int id) {int i; for (i=0;i<markers;i++) {if (marker_ids[i] == id) return(marker_positions[i]);} return(-1);}
297 int mus_header_base_detune(void) {return(base_detune);}
298 int mus_header_base_note(void) {return(base_note);}
299
300 int mus_format2bytes (int format)
301 {
302 switch (format)
303 {
304 case SNDLIB_8_LINEAR: return(1); break;
305 case SNDLIB_16_LINEAR: return(2); break;
306 case SNDLIB_8_UNSIGNED: return(1); break;
307 case SNDLIB_8_MULAW: return(1); break;
308 case SNDLIB_8_ALAW: return(1); break;
309 case SNDLIB_32_LINEAR: return(4); break;
310 case SNDLIB_32_FLOAT: return(4); break;
311 case SNDLIB_24_LINEAR: return(3); break;
312 case SNDLIB_64_DOUBLE: return(8); break;
313 case SNDLIB_16_LINEAR_LITTLE_ENDIAN: return(2); break;
314 case SNDLIB_32_LINEAR_LITTLE_ENDIAN: return(4); break;
315 case SNDLIB_32_FLOAT_LITTLE_ENDIAN: return(4); break;
316 case SNDLIB_64_DOUBLE_LITTLE_ENDIAN: return(8); break;
317 case SNDLIB_24_LINEAR_LITTLE_ENDIAN: return(3); break;
318 case SNDLIB_16_UNSIGNED: return(2); break;
319 case SNDLIB_16_UNSIGNED_LITTLE_ENDIAN: return(2); break;
320 case SNDLIB_32_VAX_FLOAT: return(4); break;
321 default: return(1); break; /* we divide by this number, so 0 is not safe */
322 }
323 }
324
325 int mus_header_format2bytes (void) {return(mus_format2bytes(data_format));}
326 int mus_samples2bytes (int format, int size) {return(size*(mus_format2bytes(format)));}
327 int mus_bytes2samples (int format, int size) {return((int)(size/(mus_format2bytes(format))));}
328
329 void mus_set_snd_header (int in_srate, int in_chans, int in_format)
330 {
331 srate = in_srate;
332 chans = in_chans;
333 data_format = in_format;
334 data_size = mus_bytes2samples(in_format,true_file_length);
335 }
336
337
338 static int equal_big_or_little_endian(unsigned char *n1, const unsigned int n2)
339 {
340 return((mus_big_endian_unsigned_int(n1) == n2) || (mus_little_endian_unsigned_int(n1) == n2));
341 }
342
343 static short big_or_little_endian_short (unsigned char *n, int little)
344 {
345 if (little) return(mus_little_endian_short(n));
346 return(mus_big_endian_short(n));
347 }
348
349 static int big_or_little_endian_int (unsigned char *n, int little)
350 {
351 if (little) return(mus_little_endian_int(n));
352 return(mus_big_endian_int(n));
353 }
354
355 static float big_or_little_endian_float (unsigned char *n, int little)
356 {
357 if (little) return(mus_little_endian_float(n));
358 return(mus_big_endian_float(n));
359 }
360
361 static int match_four_chars(unsigned char *head, const unsigned char *match)
362 {
363 int i;
364 for (i=0;i<4;i++) if (head[i] != match[i]) return(0);
365 return(1);
366 }
367
368 static void write_four_chars(unsigned char *head, const unsigned char *match)
369 {
370 int i;
371 for (i=0;i<4;i++) head[i] = match[i];
372 }
373
374 char *mus_header_type2string(int type)
375 {
376 switch (type)
377 {
378 case NeXT_sound_file: return("Sun"); break;
379 case AIFC_sound_file: return("AIFC"); break;
380 case RIFF_sound_file: return("RIFF"); break;
381 case BICSF_sound_file: return("BICSF"); break;
382 case NIST_sound_file: return("NIST"); break;
383 case INRS_sound_file: return("INRS"); break;
384 case ESPS_sound_file: return("ESPS"); break;
385 case SVX_sound_file: return("SVX8"); break;
386 case VOC_sound_file: return("VOC"); break;
387 case SNDT_sound_file: return("SNDT"); break;
388 case raw_sound_file: return("raw (no header)"); break;
389 case SMP_sound_file: return("SMP"); break;
390 case SD2_sound_file: return("Sound Designer 2"); break;
391 case AVR_sound_file: return("AVR"); break;
392 case IRCAM_sound_file: return("IRCAM"); break;
393 case SD1_sound_file: return("Sound Designer 1"); break;
394 case SPPACK_sound_file: return("SPPACK"); break;
395 case MUS10_sound_file: return("Mus10"); break;
396 case HCOM_sound_file: return("HCOM"); break;
397 case PSION_sound_file: return("PSION"); break;
398 case MAUD_sound_file: return("MAUD"); break;
399 case IEEE_sound_file: return("IEEE text"); break;
400 case DeskMate_sound_file: return("DeskMate"); break;
401 case DeskMate_2500_sound_file: return("DeskMate_2500"); break;
402 case Matlab_sound_file: return("Matlab"); break;
403 case ADC_sound_file: return("ADC/OGI"); break;
404 case SoundEdit_sound_file: return("SoundEdit"); break;
405 case SoundEdit_16_sound_file: return("SoundEdit 16"); break;
406 case DVSM_sound_file: return("DVSM"); break;
407 case MIDI_file: return("MIDI"); break;
408 case Esignal_file: return("Esignal"); break;
409 case soundfont_sound_file: return("SoundFont"); break;
410 case gravis_sound_file: return("Gravis Ultrasound patch"); break;
411 case comdisco_sound_file: return("Comdisco SPW signal"); break;
412 case goldwave_sound_file: return("Goldwave sample"); break;
413 case srfs_sound_file: return("SRFS"); break;
414 case MIDI_sample_dump: return("MIDI sample dump"); break;
415 case DiamondWare_sound_file: return("DiamondWare"); break;
416 case RealAudio_sound_file: return("RealAudio"); break;
417 case ADF_sound_file: return("CSRE adf"); break;
418 case SBStudioII_sound_file: return("SBStudioII"); break;
419 case Delusion_sound_file: return("Delusion"); break;
420 case Farandole_sound_file: return("Farandole"); break;
421 case Sample_dump_sound_file: return("Sample dump"); break;
422 case Ultratracker_sound_file: return("Ultratracker"); break;
423 case Yamaha_TX16_sound_file: return("TX-16"); break;
424 case Yamaha_SY85_sound_file: return("Sy-85"); break;
425 case Yamaha_SY99_sound_file: return("Sy-99"); break;
426 case Kurzweil_2000_sound_file: return("Kurzweil 2000"); break;
427 case digiplayer_sound_file: return("Digiplayer ST3"); break;
428 case Covox_sound_file: return("Covox V8"); break;
429 case SPL_sound_file: return("Digitracker SPL"); break;
430 case AVI_sound_file: return("AVI"); break;
431 case OMF_sound_file: return("OMF"); break;
432 case Quicktime_sound_file: return("Quicktime"); break;
433 case asf_sound_file: return("asf"); break;
434 case AIFF_sound_file: return("AIFF"); break;
435 default: return("unknown"); break;
436 }
437 }
438
439 char *mus_header_data_format2string(int format)
440 {
441 switch (format)
442 {
443 case SNDLIB_UNSUPPORTED: return("unsupported"); break;
444 case SNDLIB_NO_SND: return("no_snd"); break;
445 case SNDLIB_16_LINEAR: return("16-bit big endian"); break;
446 case SNDLIB_8_MULAW: return("mulaw"); break;
447 case SNDLIB_8_LINEAR: return("8-bit"); break;
448 case SNDLIB_32_FLOAT: return("32-bit big endian float"); break;
449 case SNDLIB_32_LINEAR: return("32-bit big endian"); break;
450 case SNDLIB_8_ALAW: return("alaw"); break;
451 case SNDLIB_8_UNSIGNED: return("8-bit unsigned"); break;
452 case SNDLIB_24_LINEAR: return("24-bit big endian"); break;
453 case SNDLIB_64_DOUBLE: return("64-bit big endian double"); break;
454 case SNDLIB_16_LINEAR_LITTLE_ENDIAN: return("16-bit little endian"); break;
455 case SNDLIB_32_LINEAR_LITTLE_ENDIAN: return("32-bit little endian"); break;
456 case SNDLIB_32_FLOAT_LITTLE_ENDIAN: return("32-bit little endian float"); break;
457 case SNDLIB_64_DOUBLE_LITTLE_ENDIAN: return("64-bit little endian double"); break;
458 case SNDLIB_16_UNSIGNED: return("16-bit big endian unsigned"); break;
459 case SNDLIB_16_UNSIGNED_LITTLE_ENDIAN: return("16-bit little endian unsigned"); break;
460 case SNDLIB_12_UNSIGNED: return("12-bit big endian unsigned"); break;
461 case SNDLIB_12_UNSIGNED_LITTLE_ENDIAN: return("12-bit little endian unsigned"); break;
462 case SNDLIB_12_LINEAR: return("12-bit big endian"); break;
463 case SNDLIB_12_LINEAR_LITTLE_ENDIAN: return("12-bit little endian"); break;
464 case SNDLIB_24_LINEAR_LITTLE_ENDIAN: return("24-bit little endian"); break;
465 case SNDLIB_32_VAX_FLOAT: return("vax float"); break;
466 default: return("unknown"); break;
467 }
468 }
469
470 static int read_bicsf_header (int chan);
471
472
473 /* ------------------------------------ NeXT (or Sun) --------------------------------
474 *
475 * 0: ".snd"
476 * 4: data_location (bytes) (not necessarily word aligned on Sun)
477 * 8: data_size (bytes) -- sometimes incorrect ("advisory")
478 * 12: data format indicator -- see below
479 * 16: srate (int)
480 * 20: chans
481 * 24: comment start
482 *
483 * in an AFsp file, the first 4 bytes of the comment are "AFsp",
484 * see headers.lisp for readers/writers of AFsp fields
485 * for bicsf, the integer at 28 is 107364 or 107415
486 *
487 * on NeXTStep, always big-endian. ".snd"==0x2e736e64 on big-endian machines.
488 *
489 * formats are:
490 * 0 unspecified, 1 mulaw_8, 2 linear_8, 3 linear_16, 4 linear_24, 5 linear_32, 6 float,
491 * 7 double, 8 indirect, 9 nested, 10 dsp_core, 11 dsp_data_8, 12 dsp_data_16, 13 dsp_data_24,
492 * 14 dsp_data_32, 16 display, 17 mulaw_squelch, 18 emphasized, 19 compressed, 20 compressed_emphasized
493 * 21 dsp_commands, 22 dsp_commands_samples, 23 adpcm_g721, 24 adpcm_g722, 25 adpcm_g723,
494 * 26 adpcm_g723_5, 27 alaw_8, 28 aes, 29 delat_mulaw_8 {internal Snd-secret format: 30=linear_32_little_endian}
495 *
496 */
497
498 /* according to the file /usr/share/magic, the DECN versions were little endian */
499
500 static int read_next_header (int chan)
501 {
502 int maybe_bicsf;
503 type_specifier = mus_uninterpreted_int((unsigned char *)hdrbuf);
504 data_location = mus_big_endian_int((unsigned char *)(hdrbuf+4));
505 data_size = mus_big_endian_int((unsigned char *)(hdrbuf+8));
506 /* can be bogus -- fixup if possible */
507 true_file_length = lseek(chan,0L,SEEK_END);
508 if (data_size <= 24) data_size = (true_file_length-data_location);
509 original_data_format = mus_big_endian_int((unsigned char *)(hdrbuf+12));
510 switch (original_data_format)
511 { /* defined in /usr/include/sound/soundstruct.h */
512 /* see headers.lisp for a table of all known format names */
513 case 1: data_format = SNDLIB_8_MULAW; break;
514 case 2: data_format = SNDLIB_8_LINEAR; break;
515 case 3: data_format = SNDLIB_16_LINEAR; break;
516 case 4: data_format = SNDLIB_24_LINEAR; break;
517 case 5: data_format = SNDLIB_32_LINEAR; break;
518 case 6: data_format = SNDLIB_32_FLOAT; break;
519 case 7: data_format = SNDLIB_64_DOUBLE; break;
520 case 18: data_format = SNDLIB_16_LINEAR; break;
521 /* "emphasized": Xavier Serra's de-emphasis filter: y(n) = x(n) + .9 y(n-1) */
522 case 27: data_format = SNDLIB_8_ALAW; break;
523 case 30: data_format = SNDLIB_32_LINEAR_LITTLE_ENDIAN; break; /* this is for Snd's internal benefit -- it is not used elsewhere */
524 default: data_format = SNDLIB_UNSUPPORTED; break;
525 }
526 srate = mus_big_endian_int((unsigned char *)(hdrbuf+16));
527 chans = mus_big_endian_int((unsigned char *)(hdrbuf+20));
528 comment_start = 24;
529 comment_end = data_location - 1;
530 if (comment_end < comment_start) comment_end = comment_start;
531 if (match_four_chars((unsigned char *)(hdrbuf+24),I_AFsp)) header_distributed = 1; else header_distributed = 0;
532 maybe_bicsf = mus_big_endian_int((unsigned char *)(hdrbuf+28));
533 if (maybe_bicsf == 107364) read_bicsf_header(chan);
534 data_size = mus_bytes2samples(data_format,data_size);
535 return(0);
536 }
537
538 int mus_write_next_header (int chan, int srate, int chans, int loc, int siz, int format, char *comment, int len)
539 {
540 int i,j;
541 write_four_chars((unsigned char *)hdrbuf,I_DSND); /* ".snd" */
542 i = len/4;
543 j = 24 + (4 * (i+1));
544 if (loc < j) loc = j;
545 mus_set_big_endian_int((unsigned char *)(hdrbuf+4),loc);
546 mus_set_big_endian_int((unsigned char *)(hdrbuf+8),siz);
547 switch (format)
548 {
549 case SNDLIB_8_MULAW: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),1); break;
550 case SNDLIB_8_LINEAR: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),2); break;
551 case SNDLIB_16_LINEAR: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),3); break;
552 case SNDLIB_24_LINEAR: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),4); break;
553 case SNDLIB_32_LINEAR: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),5); break;
554 case SNDLIB_32_FLOAT: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),6); break;
555 case SNDLIB_64_DOUBLE: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),7); break;
556 case SNDLIB_32_LINEAR_LITTLE_ENDIAN: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),30); break; /* see above */
557 case SNDLIB_8_ALAW: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),27); break;
558 default: mus_error(MUS_UNSUPPORTED_DATA_FORMAT,"can't write NeXT/Sun data format: %d",format); return(-1); break;
559 }
560 mus_set_big_endian_int((unsigned char *)(hdrbuf+16),srate);
561 mus_set_big_endian_int((unsigned char *)(hdrbuf+20),chans);
562 write(chan,hdrbuf,24);
563 j = 0;
564 for (i=0;i<len;i++)
565 {
566 hdrbuf[j]=comment[i];
567 j++;
568 if (j == HDRBUFSIZ)
569 {
570 write(chan,hdrbuf,HDRBUFSIZ);
571 j = 0;
572 }
573 }
574 for (i=0;i<(loc-(len+24));i++) /* now fill left over bytes with nulls */
575 {
576 hdrbuf[j]=0;
577 j++;
578 if (j == HDRBUFSIZ)
579 {
580 write(chan,hdrbuf,HDRBUFSIZ);
581 j = 0;
582 }
583 }
584 if (j != 0) write(chan,hdrbuf,j);
585 data_location = loc;
586 return(0);
587 }
588
589 static void update_next_header (int chan, int size)
590 {
591 lseek(chan,8L,SEEK_SET);
592 mus_set_big_endian_int((unsigned char *)(hdrbuf+0),size);
593 write(chan,hdrbuf,4);
594 }
595
596 static void update_next_header_comment (int chan, int loc, char *comment, int len)
597 {
598 int i,j;
599 lseek(chan,(long)(loc-4),SEEK_SET);
600 read(chan,hdrbuf,4);
601 lseek(chan,(long)(loc-4),SEEK_SET);
602 for (j=0;j<4;j++) if (hdrbuf[j]==0) hdrbuf[j] = 32;
603 j = 4;
604 for (i=0;i<len;i++)
605 {
606 hdrbuf[j]=comment[i];
607 j++;
608 if (j == HDRBUFSIZ)
609 {
610 write(chan,hdrbuf,HDRBUFSIZ);
611 j = 0;
612 }
613 }
614 if (j != 0) write(chan,hdrbuf,j);
615 }
616
617
618
619 /* ------------------------------------ AIFF ------------------------------------
620 *
621 * 0: "FORM"
622 * 4: size (bytes)
623 * 8: "AIFF" or "AIFC" -- the latter includes compressed formats (list extended for 8.5 Sound.h)
624 *
625 * Thereafter the file is organized into "chunks", each chunk being
626 * a 4-byte identifer followed by an int (4-bytes) giving the chunk size
627 * not including the 8-byte header. AIFF data is signed. If the chunk
628 * size is odd, an extra (unaccounted-for) null byte is added at the end.
629 *
630 * The chunks we want are "COMM", "SSND", and "APPL".
631 *
632 * COMM: 0: chans
633 * 2: frames
634 * 6: bits per sample
635 * 8: srate as 80-bit IEEE float
636 * then if AIFC (not AIFF), 4 bytes giving compression id ("NONE"=not compressed)
637 * followed by Pascal string giving long name of compression type
638 *
639 * SSND: 0: data location (offset within SSND chunk)
640 *
641 * Other chunks include: ANNO: a comment, INST: loop control, MARK: marker, MIDI: midi,
642 * COMT: comment (max 65536 chars), NAME: sound name, AUTH: author's name
643 * (c), AESD: recording data, APPL: application specific stuff
644 * "MARK" size short-#marks {marks} -- latter are short-ID long-position pstring-name.
645 * "INST" size chars[baseNote detune lowNote highNote lowVelocity HighVelocity] short-gain loops[sustain release]
646 * loop: short-playMode marker-begin marker-end (signed?) shorts)
647 * playMode: 0 no loop, 1 forward loop, 2 forward/backward loop
648 * chars are MIDI data (detune is in cents)
649 * "MIDI" size MIDI-data...
650 * "AESD" size AES Channel Status Data (24 bytes as specified by AES)
651 * see "AES: Guidelines for the use of the AES3 interface"
652 * byte 0: bit 0: 0=consumer, 1=pro
653 * bit 1: 0=audio, 1=non-audio
654 * bits 2:4: emphasis: 0:none, 4:none, 6:CD, 7:CCITT J17
655 * bits 6:7: srate: 00=48KHz, 01=48, 10=44.1, 11=32
656 * byte 1: bits 0:3: chans: 2:mono, else stereo
657 * byte 2 for word size stuff (always ends up 16-bit): bits 3-5=sample length where 4=16-bit
658 * byte 3: multi-channels modes, 4: AES sync ref, 5:unused, 6-9:ASCII source ID, 10-13:ASCII destination ID
659 * byte 14-17:local sample addr, 18-21:time of day addr, then CRC checks
660 * "APPL" size signature data
661 * "COMT" size short-#comments {comments} -- the latter are long-time marker short-text-length char-text
662 * time is in seconds since 1-Jan-1904
663 * "NAME"/"AUTH"/"(c) "/"ANNO" size char-name
664 * "FVER" size(4) AIFC-format-version -- currently always 0xA2805140
665 * "SAXL" -- a desperate kludge to get around Apple's own compression schemes!
666 *
667 * always big-endian
668 * There was also (briefly) an AIFS file, now deprecated.
669 *
670 * originally I thought AIFF (as opposed to AIFC) files were obsolete, but lots of
671 * "legacy" sotfware insists on AIFF still, so mus_header_aiff_p was added to check this case
672 */
673
674 /* ieee-80 conversions -- design by committee! */
675 /* this code taken from CSound sources -- apparently originally written by Malcolm Slaney at Apple */
676
677 #define ULPOW2TO31 ((unsigned int)0x80000000)
678 #define DPOW2TO31 ((double)2147483648.0) /* 2^31 */
679
680 static double myUlongToDouble(unsigned int ul)
681 {
682 double val;
683 if(ul & ULPOW2TO31) val = DPOW2TO31 + (ul & (~ULPOW2TO31));
684 else val = ul;
685 return val;
686 }
687
688 static unsigned int myDoubleToUlong(double val)
689 {
690 unsigned int ul;
691 if(val < DPOW2TO31) ul = (unsigned int)val;
692 else ul = ULPOW2TO31 | (unsigned int)(val-DPOW2TO31);
693 return ul;
694 }
695
696 static double ieee_80_to_double(unsigned char *p)
697 {
698 unsigned char sign;
699 short exp = 0;
700 unsigned int mant1 = 0;
701 unsigned int mant0 = 0;
702 double val;
703 exp = *p++; exp <<= 8; exp |= *p++; sign = (exp & 0x8000) ? 1 : 0; exp &= 0x7FFF;
704 mant1 = *p++; mant1 <<= 8; mant1 |= *p++; mant1 <<= 8; mant1 |= *p++; mant1 <<= 8; mant1 |= *p++;
705 mant0 = *p++; mant0 <<= 8; mant0 |= *p++; mant0 <<= 8; mant0 |= *p++; mant0 <<= 8; mant0 |= *p++;
706 if(mant1 == 0 && mant0 == 0 && exp == 0 && sign == 0)
707 return 0.0;
708 else
709 {
710 val = myUlongToDouble(mant0) * pow(2.0,-63.0);
711 val += myUlongToDouble(mant1) * pow(2.0,-31.0);
712 val *= pow(2.0,((double) exp) - 16383.0);
713 return sign ? -val : val;
714 }
715 }
716
717 static void double_to_ieee_80(double val, unsigned char *p)
718 {
719 unsigned char sign = 0;
720 short exp = 0;
721 unsigned int mant1 = 0;
722 unsigned int mant0 = 0;
723 if(val < 0.0) { sign = 1; val = -val; }
724 if(val != 0.0) /* val identically zero -> all elements zero */
725 {
726 exp = (short)(log(val)/log(2.0) + 16383.0);
727 val *= pow(2.0, 31.0+16383.0-(double)exp);
728 mant1 = myDoubleToUlong(val);
729 val -= myUlongToDouble(mant1);
730 val *= pow(2.0, 32.0);
731 mant0 = myDoubleToUlong(val);
732 }
733 *p++ = ((sign<<7)|(exp>>8)); *p++ = 0xFF & exp;
734 *p++ = 0xFF & (mant1>>24); *p++ = 0xFF & (mant1>>16); *p++ = 0xFF & (mant1>> 8); *p++ = 0xFF & (mant1);
735 *p++ = 0xFF & (mant0>>24); *p++ = 0xFF & (mant0>>16); *p++ = 0xFF & (mant0>> 8); *p++ = 0xFF & (mant0);
736 }
737
738
739 static int update_form_size, update_frames_location, update_ssnd_location;
740
741 static int seek_and_read(int chan, unsigned char *buf, int offset, int nbytes)
742 {
743 if (offset < 0) return(-1);
744 lseek(chan, offset, SEEK_SET);
745 #ifndef MACOS
746 return(read(chan,buf,nbytes));
747 #else
748 return(read(chan,(char *)buf,nbytes));
749 #endif
750 }
751
752 static int read_aiff_marker(int m, unsigned char *buf)
753 {
754 int psize;
755 marker_ids[m] = mus_big_endian_short((unsigned char *)buf);
756 marker_positions[m] = mus_big_endian_int((unsigned char *)(buf+2));
757 psize = (int)buf[6] + 1;
758 if (psize & 1) psize++;
759 return(psize+6);
760 }
761
762 static int read_aiff_header (int chan, int overall_offset)
763 {
764 /* we know we have checked for FORM xxxx AIFF|AIFC when we arrive here */
765 /* as far as I can tell, the COMM block has the header data we seek, and the SSND block has the sound data */
766 /* everything else will be ignored -- apparently we can depend on seeing a "chunk" name, then size */
767 int chunksize,offset,frames,chunkloc,happy,i,j,num_marks,m,moff,msize;
768 type_specifier = mus_uninterpreted_int((unsigned char *)(hdrbuf+8+overall_offset));
769 update_ssnd_location = 0;
770 chunkloc = 12 + overall_offset;
771 offset = 0;
772 for (i=0;i<AUX_COMMENTS;i++) aux_comment_start[i] = 0;
773 data_format = SNDLIB_16_LINEAR;
774 header_distributed = 1;
775 srate = 0;
776 chans = 0;
777 happy = 1;
778 data_size = 0;
779 if (loop_modes)
780 {
781 loop_modes[0] = 0;
782 loop_modes[1] = 0;
783 }
784 true_file_length = lseek(chan,0L,SEEK_END);
785 update_form_size = mus_big_endian_int((unsigned char *)(hdrbuf+4+overall_offset)); /* should be file-size-8 unless there are multiple forms */
786 while (happy)
787 {
788 offset += chunkloc;
789 if (seek_and_read(chan,(unsigned char *)hdrbuf,offset,32) <= 0)
790 {
791 mus_error(MUS_HEADER_READ_FAILED,"AIFF header chunks confused at %d",offset);
792 return(-1);
793 }
794 chunksize = mus_big_endian_int((unsigned char *)(hdrbuf+4));
795 if (match_four_chars((unsigned char *)hdrbuf,I_COMM))
796 {
797 chans = mus_big_endian_short((unsigned char *)(hdrbuf+8));
798 frames = mus_big_endian_int((unsigned char *)(hdrbuf+10));
799 update_frames_location = 10+offset;
800 original_data_format = mus_big_endian_short((unsigned char *)(hdrbuf+14));
801 if ((original_data_format%8) != 0)
802 {
803 /* weird sizes are legal --
804 * these samples are left-justified (and zero padded on the right), so
805 * we can handle any bit size by rounding up to the nearest byte.
806 */
807 original_data_format=8*(1+(original_data_format>>3));
808 }
809 if (original_data_format == 8) data_format = SNDLIB_8_LINEAR;
810 else if (original_data_format == 16) data_format = SNDLIB_16_LINEAR;
811 else if (original_data_format == 24) data_format = SNDLIB_24_LINEAR;
812 else if (original_data_format == 32) data_format = SNDLIB_32_LINEAR;
813 else data_format = SNDLIB_UNSUPPORTED;
814 srate = (int)ieee_80_to_double((unsigned char *)(hdrbuf+16));
815 /* if AIFC, compression type over-rides (possibly bogus) original_data_format */
816 if (type_specifier == mus_uninterpreted_int((unsigned char *)I_AIFC))
817 {
818 /* some aifc files assume the compression field is a new and very weird chunk!! -- surely a bug? */
819 /* AIFF spec says COMM size is always 18, but this is amended in the newer AIFC spec */
820 if (chunksize == 18) chunksize += (5+((int)hdrbuf[30])); /* 5=chunk header length in this case */
821 if ((!(match_four_chars((unsigned char *)(hdrbuf+26),I_NONE))) &&
822 (!(match_four_chars((unsigned char *)(hdrbuf+26),I_twos))))
823 {
824 original_data_format = mus_uninterpreted_int((unsigned char *)(hdrbuf+26));
825 if ((match_four_chars((unsigned char *)(hdrbuf+26),I_ALAW)) ||
826 (match_four_chars((unsigned char *)(hdrbuf+26),I_alaw)))
827 data_format = SNDLIB_8_ALAW;
828 else
829 {
830 if ((match_four_chars((unsigned char *)(hdrbuf+26),I_ULAW)) ||
831 (match_four_chars((unsigned char *)(hdrbuf+26),I_ulaw)))
832 data_format = SNDLIB_8_MULAW;
833 else
834 {
835 /* taken from Sound.h in OS 8.5 -- just guessing... */
836 if (match_four_chars((unsigned char *)(hdrbuf+26),I_sowt))
837 {
838 if (data_format == SNDLIB_16_LINEAR) data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
839 else if (data_format == SNDLIB_24_LINEAR) data_format = SNDLIB_24_LINEAR_LITTLE_ENDIAN;
840 else if (data_format == SNDLIB_32_LINEAR) data_format = SNDLIB_32_LINEAR_LITTLE_ENDIAN;
841 }
842 else
843 {
844 if (match_four_chars((unsigned char *)(hdrbuf+26),I_raw_))
845 {
846 if (data_format == SNDLIB_8_LINEAR) data_format = SNDLIB_8_UNSIGNED;
847 else if (data_format == SNDLIB_16_LINEAR) data_format = SNDLIB_16_UNSIGNED;
848 }
849 else
850 {
851 if (match_four_chars((unsigned char *)(hdrbuf+26),I_fl32))
852 data_format = SNDLIB_32_FLOAT;
853 else
854 {
855 if (match_four_chars((unsigned char *)(hdrbuf+26),I_fl64))
856 data_format = SNDLIB_64_DOUBLE;
857 else
858 {
859 if (match_four_chars((unsigned char *)(hdrbuf+26),I_ima4))
860 {
861 block_align = 34;
862 original_data_format = SNDLIB_AIFF_IMA_ADPCM;
863 }
864 data_format = SNDLIB_UNSUPPORTED;
865 }
866 }
867 }
868 }
869 }
870 }
871 }
872 }
873 data_size = (frames*mus_format2bytes(data_format)*chans);
874 }
875 else
876 {
877 if (match_four_chars((unsigned char *)hdrbuf,I_SSND))
878 {
879 update_ssnd_location = offset+4;
880 data_location = mus_big_endian_int((unsigned char *)(hdrbuf+8)) + offset + 16; /* Baroque! */
881 /* offset is where the hdrbuf is positioned in the file, the sound data offset itself is at loc+8 and the */
882 /* 0-based location of the sound data is at the end of the chunk = 16 (8=header+4=offset+4=blocksize) */
883 /* the next int can be the block size if the data is block-aligned */
884 /* only one SSND per AIFF is allowed */
885 }
886 else
887 {
888 if ((match_four_chars((unsigned char *)hdrbuf,I_ANNO)) || (match_four_chars((unsigned char *)hdrbuf,I_COMT)))
889 {
890 j=0;
891 for (i=0;i<AUX_COMMENTS;i++) if (aux_comment_start[i] == 0) {j=i; break;}
892 if (j >= AUX_COMMENTS) {mus_error(MUS_HEADER_TOO_MANY_AUXILIARY_COMMENTS,"ran out of auxiliary comment space"); j=0;}
893 aux_comment_start[j] = offset+8;
894 if (match_four_chars((unsigned char *)hdrbuf,I_COMT)) aux_comment_start[j] += 8; /* skip time stamp and markerId (not ID, I assume!) */
895 aux_comment_end[j] = offset+7+chunksize;
896 }
897 else
898 {
899 if (match_four_chars((unsigned char *)hdrbuf,I_APPL))
900 {
901 if (match_four_chars((unsigned char *)(hdrbuf+8),I_MUS_))
902 {
903 /* my own chunk has the arbitrary length comment I use (actually the ASCII */
904 /* representation of a lisp program evaluated in the CLM package) to handle mix et al. */
905 /* It is nothing more than the actual string -- remember to pad to even length here. */
906 comment_start = offset + 12;
907 comment_end = comment_start + chunksize - 5;
908 }
909 }
910 else
911 {
912 if (match_four_chars((unsigned char *)hdrbuf,I_INST))
913 {
914 base_note = hdrbuf[8];
915 base_detune = hdrbuf[9];
916 loop_modes[0] = mus_big_endian_short((unsigned char *)(hdrbuf+16));
917 loop_starts[0] = mus_big_endian_short((unsigned char *)(hdrbuf+18));
918 loop_ends[0] = mus_big_endian_short((unsigned char *)(hdrbuf+20));
919 loop_modes[1] = mus_big_endian_short((unsigned char *)(hdrbuf+22));
920 loop_starts[1] = mus_big_endian_short((unsigned char *)(hdrbuf+24));
921 loop_ends[1] = mus_big_endian_short((unsigned char *)(hdrbuf+26));
922 /* these are mark numbers */
923 }
924 else
925 {
926 if (match_four_chars((unsigned char *)hdrbuf,I_MARK))
927 {
928 /* unsigned short #marks, each mark: id pos name (pstring damn it) */
929 num_marks = mus_big_endian_unsigned_short((unsigned char *)(hdrbuf+8));
930 if (num_marks > markers)
931 {
932 if (markers > 0) {if (marker_ids) FREE(marker_ids); if (marker_positions) FREE(marker_positions);}
933 markers = num_marks;
934 marker_ids = (int *)CALLOC(markers,sizeof(int));
935 marker_positions = (int *)CALLOC(markers,sizeof(int));
936 }
937 moff = 10;
938 for (m=0;m<num_marks;m++)
939 {
940 if (seek_and_read(chan,(unsigned char *)hdrbuf,offset+moff,8) > 0)
941 {
942 msize = read_aiff_marker(m,(unsigned char *)hdrbuf);
943 moff += msize;
944 }
945 }
946 }
947 }
948 }
949 }
950 }
951 }
952 chunkloc = (8+chunksize);
953 if (chunksize&1) chunkloc++; /* extra null appended to odd-length chunks */
954 if ((offset+chunkloc) >= update_form_size) happy=0;
955 }
956 if (true_file_length < data_size) data_size = true_file_length - data_location;
957 data_size = mus_bytes2samples(data_format,data_size);
958 return(0);
959 }
960
961 int mus_header_aiff_p(void) {return(type_specifier == mus_uninterpreted_int((unsigned char *)I_AIFF));}
962
963 static int write_aif_header (int chan, int srate, int chans, int siz, int format, char *comment, int len, int aifc_header)
964 {
965 /* we write the simplest possible AIFC header: AIFC | COMM | APPL-MUS_ if needed | SSND eof. */
966 /* the assumption being that we're going to be appending sound data once the header is out */
967 /* INST and MARK chunks added Jul-95 for various programs that expect them (MixView). */
968 int i,j,lenhdr,curend,extra,err=0; /* set aifc to 0 to get old-style AIFF header */
969 char *str;
970 lenhdr=0;
971 extra=0;
972 curend=0;
973 if (len != 0)
974 {
975 lenhdr = 12;
976 if ((len % 4) != 0)
977 extra = (4 - (len % 4));
978 }
979 write_four_chars((unsigned char *)hdrbuf,I_FORM);
980 if (aifc_header)
981 mus_set_big_endian_int((unsigned char *)(hdrbuf+4),len+30+16+38+siz+lenhdr+extra+12+10);
982 else mus_set_big_endian_int((unsigned char *)(hdrbuf+4),len+30+16+38+siz+lenhdr+extra);
983 /*
984 * comment length + 4 for AIFF 18+8 for I_COMM info + 16 for I_SSND info + 38 for INST and MARK +
985 * siz for data + 12 for comment header if any + padding == total size - 8 (i.e. FORM header).
986 * INST+MARK (38) added 3-Jul-95 for Notam software compatibility
987 */
988 if (aifc_header)
989 {
990 write_four_chars((unsigned char *)(hdrbuf+8),I_AIFC);
991 write(chan,hdrbuf,12);
992 curend=12;
993 write_four_chars((unsigned char *)hdrbuf,I_FVER);
994 mus_set_big_endian_int((unsigned char *)(hdrbuf+4),4);
995 mus_set_big_endian_int((unsigned char *)(hdrbuf+8),0xA2805140);
996 }
997 else write_four_chars((unsigned char *)(hdrbuf+8),I_AIFF);
998 write_four_chars((unsigned char *)(hdrbuf+12),I_COMM);
999 if (aifc_header) mus_set_big_endian_int((unsigned char *)(hdrbuf+16),18+10); else mus_set_big_endian_int((unsigned char *)(hdrbuf+16),18);
1000 mus_set_big_endian_short((unsigned char *)(hdrbuf+20),(short)chans);
1001 mus_set_big_endian_int((unsigned char *)(hdrbuf+22),siz / (chans*mus_format2bytes(format)));
1002 switch (format)
1003 {
1004 case SNDLIB_16_LINEAR: case SNDLIB_16_LINEAR_LITTLE_ENDIAN: case SNDLIB_16_UNSIGNED:
1005 mus_set_big_endian_short((unsigned char *)(hdrbuf+26),16);
1006 break;
1007 case SNDLIB_24_LINEAR: case SNDLIB_24_LINEAR_LITTLE_ENDIAN:
1008 mus_set_big_endian_short((unsigned char *)(hdrbuf+26),24);
1009 break;
1010 case SNDLIB_32_LINEAR: case SNDLIB_32_LINEAR_LITTLE_ENDIAN: case SNDLIB_32_FLOAT:
1011 mus_set_big_endian_short((unsigned char *)(hdrbuf+26),32);
1012 break;
1013 case SNDLIB_64_DOUBLE:
1014 mus_set_big_endian_short((unsigned char *)(hdrbuf+26),64);
1015 break;
1016 case SNDLIB_8_LINEAR: case SNDLIB_8_UNSIGNED:
1017 mus_set_big_endian_short((unsigned char *)(hdrbuf+26),8);
1018 break;
1019 case SNDLIB_8_MULAW:
1020 mus_set_big_endian_short((unsigned char *)(hdrbuf+26),8);
1021 break;
1022 case SNDLIB_8_ALAW:
1023 mus_set_big_endian_short((unsigned char *)(hdrbuf+26),8);
1024 break;
1025 default:
1026 mus_error(MUS_UNSUPPORTED_DATA_FORMAT,"can't write AIFF data format: %d",format);
1027 err = -1;
1028 break;
1029 }
1030 double_to_ieee_80((double)srate,(unsigned char *)(hdrbuf+28));
1031 if (aifc_header)
1032 {
1033 switch (format)
1034 {
1035 case SNDLIB_16_LINEAR: case SNDLIB_24_LINEAR: case SNDLIB_32_LINEAR: case SNDLIB_8_LINEAR: str = (char *)I_NONE; break;
1036 case SNDLIB_16_LINEAR_LITTLE_ENDIAN: case SNDLIB_24_LINEAR_LITTLE_ENDIAN: case SNDLIB_32_LINEAR_LITTLE_ENDIAN: str = (char *)I_sowt; break;
1037 case SNDLIB_32_FLOAT: str = (char *)I_fl32; break;
1038 case SNDLIB_64_DOUBLE: str = (char *)I_fl64; break;
1039 case SNDLIB_8_UNSIGNED: case SNDLIB_16_UNSIGNED: str = (char *)I_raw_; break;
1040 case SNDLIB_8_MULAW: str = (char *)I_ulaw; break;
1041 case SNDLIB_8_ALAW: str = (char *)I_alaw; break;
1042 default: str = (char *)I_NONE; break;
1043 }
1044 write_four_chars((unsigned char *)(hdrbuf+38),(const unsigned char *)str);
1045 (*(unsigned char *)(hdrbuf+42)) = 4; /* final pad null not accounted-for */
1046 write_four_chars((unsigned char *)(hdrbuf+43),(const unsigned char *)str);
1047 (*(unsigned char *)(hdrbuf+47)) = 0;
1048 i=48;
1049 }
1050 else i = 38;
1051 if (len != 0)
1052 {
1053 if (aifc_header)
1054 {
1055 write_four_chars((unsigned char *)(hdrbuf+48),I_APPL);
1056 mus_set_big_endian_int((unsigned char *)(hdrbuf+52),len+4+extra);
1057 write_four_chars((unsigned char *)(hdrbuf+56),I_MUS_);
1058 i = 60;
1059 }
1060 else
1061 {
1062 write_four_chars((unsigned char *)(hdrbuf+38),I_APPL);
1063 mus_set_big_endian_int((unsigned char *)(hdrbuf+42),len+4+extra);
1064 write_four_chars((unsigned char *)(hdrbuf+46),I_MUS_);
1065 i = 50;
1066 }
1067 for (j=0;j<len;j++)
1068 {
1069 if (i == HDRBUFSIZ)
1070 {
1071 curend += HDRBUFSIZ;
1072 write(chan,hdrbuf,HDRBUFSIZ);
1073 i=0;
1074 }
1075 hdrbuf[i]=comment[j];
1076 i++;
1077 }
1078 if (extra != 0)
1079 {
1080 if ((i+extra) > HDRBUFSIZ)
1081 {
1082 curend += i;
1083 write(chan,hdrbuf,i);
1084 i=0;
1085 }
1086 for (j=0;j<extra;j++)
1087 {
1088 hdrbuf[i] = 0;
1089 i++;
1090 }
1091 }
1092 }
1093 curend += i;
1094 write(chan,hdrbuf,i);
1095 write_four_chars((unsigned char *)hdrbuf,I_MARK); /* SoundHack includes a blank MARK chunk for some reason */
1096 mus_set_big_endian_int((unsigned char *)(hdrbuf+4),2);
1097 mus_set_big_endian_short((unsigned char *)(hdrbuf+8),0);
1098 write_four_chars((unsigned char *)(hdrbuf+10),I_INST);
1099 mus_set_big_endian_int((unsigned char *)(hdrbuf+14),20);
1100 mus_set_big_endian_int((unsigned char *)(hdrbuf+18),0x3c00007f); /* base-note=middle C, detune=0, lownote=0, highnote=0x7f */
1101 mus_set_big_endian_int((unsigned char *)(hdrbuf+22),0x017f0000); /* lowvelocity=1, highvelocity=0x7f, gain=0 */
1102 mus_set_big_endian_int((unsigned char *)(hdrbuf+26),0); /* no loops */
1103 mus_set_big_endian_int((unsigned char *)(hdrbuf+30),0);
1104 mus_set_big_endian_int((unsigned char *)(hdrbuf+34),0);
1105 write_four_chars((unsigned char *)(hdrbuf+38),I_SSND);
1106 mus_set_big_endian_int((unsigned char *)(hdrbuf+38+4),siz+8);
1107 mus_set_big_endian_int((unsigned char *)(hdrbuf+38+8),0); /* "offset" */
1108 mus_set_big_endian_int((unsigned char *)(hdrbuf+38+12),0); /* "blocksize " */
1109 data_location = 38+16+curend;
1110 write(chan,hdrbuf,38+16);
1111 return(err);
1112 }
1113
1114
1115 static void update_aiff_header (int chan, int siz)
1116 {
1117 /* we apparently have to make sure the form size and the data size are correct
1118 * assumed here that we'll only be updating our own AIFF files
1119 * There are 3 such locations -- the 2nd word of the file which is the overall form size,
1120 * the frames variable in the COMM chunk, and the chunk-size variable in the SSND chunk
1121 * an unexpected hassle for CLM is that we can open/close the output file many times if running mix,
1122 * so we have to update the various size fields taking into account the old size
1123 */
1124 read(chan,hdrbuf,INITIAL_READ_SIZE);
1125 read_aiff_header(chan,0);
1126 lseek(chan,4L,SEEK_SET);
1127 mus_set_big_endian_int((unsigned char *)hdrbuf,siz+update_form_size-mus_samples2bytes(data_format,data_size));
1128 /* cancel old data_size from previous possible write */
1129 write(chan,hdrbuf,4);
1130 lseek(chan,update_frames_location,SEEK_SET);
1131 mus_set_big_endian_int((unsigned char *)hdrbuf,siz/(chans*mus_format2bytes(data_format)));
1132 write(chan,hdrbuf,4);
1133 lseek(chan,update_ssnd_location,SEEK_SET);
1134 mus_set_big_endian_int((unsigned char *)hdrbuf,siz+8);
1135 write(chan,hdrbuf,4);
1136 }
1137
1138 static void update_aiff_header_comment (int chan, char *comment, int len)
1139 {
1140 /* save-stats in CLM appends a comment after the sound data has been written */
1141 int i,j,true_len,old_len;
1142 if (len&1) true_len = len+1; else true_len=len;
1143 lseek(chan,0L,SEEK_END);
1144 write_four_chars((unsigned char *)hdrbuf,I_ANNO);
1145 mus_set_big_endian_int((unsigned char *)(hdrbuf+4),len);
1146 for (i=0,j=8;i<len;i++,j++) hdrbuf[j]=comment[i];
1147 write(chan,hdrbuf,8+true_len);
1148 lseek(chan,4L,SEEK_SET);
1149 read(chan,hdrbuf,4);
1150 old_len = mus_big_endian_int((unsigned char *)hdrbuf);
1151 mus_set_big_endian_int((unsigned char *)hdrbuf,old_len+true_len+8);
1152 lseek(chan,4L,SEEK_SET);
1153 write(chan,hdrbuf,4);
1154 }
1155
1156
1157
1158 /* ------------------------------------ RIFF (wave) ------------------------------------
1159 *
1160 * see ftp.microsoft.com:/SoftLib/MSLFILES/MDRK.EXE (also MMSYSTEM.H and MMREG.H)
1161 * ftp://ftp.isi.edu/in-notes/rfc2361.txt
1162 *
1163 * 0: "RIFF" (little-endian) or "RIFX" (big-endian)
1164 * 4: size
1165 * 8: "WAVE" ("RMID" = midi data, others are AVI, CPPO, ACON etc)
1166 * AVI chunk can include audio data
1167 *
1168 * rest very similar to AIFF (odd-sized chunks are padded)
1169 *
1170 * fmt 0: format code (see below)
1171 * 2: chans
1172 * 4: srate (long)
1173 * 8: average rate "for buffer estimation"
1174 * 12: alignment "block size"
1175 * 14: data size (bits per sample) (PCM only)
1176 * 16: count (bytes) of extra info in the header (i.e. trailing info added to this basic header)
1177 * 20: samples per block (short) in dvi_adpcm
1178 *
1179 * formats are: 0: unknown, 1: PCM, 2: ADPCM, 3: IEEE float, 4: VSELP, 5: IBM_CVSD, 6: alaw, 7: mulaw
1180 * 0x10: OKI_ADPCM, 0x11: DVI_ADPCM, 0x12: MediaSpace_ADPCM,
1181 * 0x13: Sierra_ADPCM, 0x14: G723_ADPCM, 0x15: DIGISTD, 0x16: DIGIFIX, 0x17: Dialogic ADPCM,
1182 * 0x18: Mediavision ADPCM, 0x19: HP cu codec,
1183 * 0x20: Yamaha_ADPCM, 0x21: SONARC, 0x22: DSPGroup_TrueSpeech
1184 * 0x23: EchoSC1, 0x24: AudioFile_AF36, 0x25: APTX, 0x26: AudioFile_AF10
1185 * 0x27: prosody 1612, 0x28: lrc,
1186 * 0x30: Dolby_Ac2, 0x31: GSM610, 0x32: MSN audio codec, 0x33: Antext_ADPCM, 0x34: Control_res_vqlpc,
1187 * 0x35: DIGIREAL, 0x36: DIGIADPCM, 0x37: Control_res_cr10, 0x38: NMS_VBXADPCM, 0x39:Roland rdac,
1188 * 0x3a: echo sc3, 0x3b: Rockwell adpcm, 0x3c: Rockwell digitalk codec, 0x3d: Xebec,
1189 * 0x40: G721_ADPCM, 0x41: G728 CELP, 0x42: MS G723, 0x50: MPEG,
1190 * 0x52: RT24, 0x53: PAC, 0x55: Mpeg layer 3, 0x59: Lucent G723, 0x60: Cirrus,
1191 * 0x61: ESS Tech pcm, 0x62: voxware (obsolete), 0x63: canopus atrac,
1192 * 0x64: G726, 0x65: G722, 0x66: DSAT, 0x67: DSAT display,
1193 * 0x69: voxware (obsolete), 0x70: voxware ac8 (obsolete), 0x71: voxware ac10 (obsolete),
1194 * 0x72: voxware ac16 (obsolete), 0x73: voxware ac20 (obsolete), 0x74: voxware rt24,
1195 * 0x75: voxware rt29, 0x76: voxware rt29hw (obsolete), 0x77: voxware vr12 (obsolete),
1196 * 0x78: voxware vr18 (obsolete), 0x79: voxware tq40 (obsolete),
1197 * 0x80: softsound, 0x81: voxware tq60 (obsolete), 0x82: MS RT24, 0x83: G729A,
1198 * 0x84: MVI_MVI2, 0x85: DF G726, 0x86: DF GSM610, 0x88: isaudio, 0x89: onlive,
1199 * 0x91: sbc24, 0x92: dolby ac3 spdif, 0x97: zyxel adpcm, 0x98: philips lpcbb,
1200 * 0x99: packed, 0x100: rhetorex adpcm,
1201 * 0x101: Irat, 0x102: IBM_alaw?, 0x103: IBM_ADPCM?,
1202 * 0x111: vivo G723, 0x112: vivo siren, 0x123: digital g273
1203 * 0x200: Creative_ADPCM, 0x202: Creative fastspeech 8, 0x203: Creative fastspeech 10,
1204 * 0x220: quarterdeck, 0x300: FM_TOWNS_SND, 0x400: BTV digital, 0x680: VME vmpcm,
1205 * 0x1000: OLIGSM, 0x1001: OLIADPCM, 0x1002: OLICELP, 0x1003: OLISBC, 0x1004: OLIOPR
1206 * 0x1100: LH codec, 0x1400: Norris, 0x1401: isaudio, 0x1500: Soundspace musicompression, 0x2000: DVM
1207 * (see http://www.microsoft.com/asf/resources/draft-ietf-fleischman-codec-subtree-00.txt)
1208 *
1209 * RIFF and LIST chunks have nested chunks. Registered chunk names include:
1210 * LIST with subchunks, one of which can be:
1211 * INFO itself containing:
1212 * IARL: archival location, IART: artist, ICMS: commissioned, ICMT: comment, ICOP: copyright, ICRD: creation date,
1213 * ICRP: uh...cropped, IDIM: dimensions, IDPI: dpi, IENG: engineer, IGNR: genre, IKEY: keywords, ILGT: lightness,
1214 * IMED: medium, INAM: name, IPLT: palette, IPRD: product, ISBJ: subject, ISFT: software, ISHP: sharpness,
1215 * ISRC: source, ISRF: source form, ITCH: technician, ISMP: SMPTE time code, IDIT: digitization time
1216 *
1217 * data chunk has the samples
1218 * other (currently ignored) chunks are wavl = waveform data, fact, cues of some sort, slnt = silence,
1219 * plst = playlist, adtl = associated data list, labl = cue label, note = cue comments,
1220 * ltxt = text associated with data segment (cue), file, DISP = displayable object,
1221 * JUNK = outdated info, PAD = padding, etc
1222 * fact chunk generally has number of samples (used in compressed files)
1223 */
1224
1225 static int wave_to_sndlib_format(int osf, int bps, int little)
1226 {
1227 switch (osf)
1228 {
1229 case 1:
1230 switch (bps)
1231 {
1232 case 8: return(SNDLIB_8_UNSIGNED); break;
1233 case 16: if (little) return(SNDLIB_16_LINEAR_LITTLE_ENDIAN); else return(SNDLIB_16_LINEAR); break;
1234 case 32: if (little) return(SNDLIB_32_LINEAR_LITTLE_ENDIAN); else return(SNDLIB_32_LINEAR); break;
1235 case 24: if (little) return(SNDLIB_24_LINEAR_LITTLE_ENDIAN); else return(SNDLIB_24_LINEAR); break;
1236 default: return(SNDLIB_8_UNSIGNED); break;
1237 }
1238 break;
1239 case 3: if (little) return(SNDLIB_32_FLOAT_LITTLE_ENDIAN); else return(SNDLIB_32_FLOAT); break;
1240 case 6: if (bps == 8) return(SNDLIB_8_ALAW); break;
1241 case 7: if (bps == 8) return(SNDLIB_8_MULAW); break;
1242 /* IBM mulaw follows G711 specs like other versions (this info direct from IBM) */
1243 case 0x101: return(SNDLIB_8_MULAW); break;
1244 case 0x102: return(SNDLIB_8_ALAW); break;
1245 }
1246 return(SNDLIB_UNSUPPORTED);
1247 }
1248
1249 static int read_riff_header (int chan)
1250 {
1251 /* we know we have checked for RIFF xxxx WAVE when we arrive here */
1252 int chunksize,offset,chunkloc,happy,little;
1253 little = 1;
1254 if (match_four_chars((unsigned char *)hdrbuf,I_RIFX)) little=0; /* big-endian data in this case, but I've never seen one */
1255 type_specifier = mus_uninterpreted_int((unsigned char *)(hdrbuf+8));
1256 chunkloc = 12;
1257 offset = 0;
1258 header_distributed = 1;
1259 data_format = SNDLIB_UNSUPPORTED;
1260 srate = 0;
1261 chans = 0;
1262 happy = 1;
1263 data_size = 0;
1264 fact_samples = 0;
1265 bits_per_sample = 0;
1266 true_file_length = lseek(chan,0L,SEEK_END);
1267 update_form_size = big_or_little_endian_int((unsigned char *)(hdrbuf+4),little);
1268 while (happy)
1269 {
1270 offset += chunkloc;
1271 if (seek_and_read(chan,(unsigned char *)hdrbuf,offset,32) <= 0)
1272 {
1273 mus_error(MUS_HEADER_READ_FAILED,"RIFF header chunks confused at %d",offset);
1274 return(-1);
1275 }
1276 chunksize = big_or_little_endian_int((unsigned char *)(hdrbuf+4),little);
1277 if (match_four_chars((unsigned char *)hdrbuf,I_fmt_))
1278 {
1279 /*
1280 * 8: short format code --1=PCM for example
1281 * 10: short chans --1
1282 * 12: long rate --48000 (0xbb80)
1283 * 16: long ave rate --65655 (0x10077)
1284 * 20: short align --2
1285 * 22: short data size (bits) --16
1286 * 24: bytes of extra
1287 * ... some extra data dependent on format
1288 *
1289 * R I F F # # # # W A V E f m t sp
1290 * 5249 4646 f851 0500 5741 5645 666d 7420
1291 * e40f 0000 0100 0100 80bb 0000 0077 0100
1292 * 0200 1000 0000 0000 0000 0000 0000 0000
1293 *
1294 * #x000551f8 = 348664 = size in bytes - 8
1295 * #x00000fe4 = 4068 [fmt_ chunk size?]
1296 */
1297 original_data_format = big_or_little_endian_short((unsigned char *)(hdrbuf+8),little);
1298 chans = big_or_little_endian_short((unsigned char *)(hdrbuf+10),little);
1299 srate = big_or_little_endian_int((unsigned char *)(hdrbuf+12),little);
1300 block_align = big_or_little_endian_short((unsigned char *)(hdrbuf+20),little);
1301 bits_per_sample = big_or_little_endian_short((unsigned char *)(hdrbuf+22),little);
1302 data_format = wave_to_sndlib_format(original_data_format,bits_per_sample,little);
1303 }
1304 else
1305 {
1306 if (match_four_chars((unsigned char *)hdrbuf,I_data))
1307 {
1308 update_ssnd_location = offset+4;
1309 data_location = offset + 8;
1310 data_size = big_or_little_endian_int((unsigned char *)(hdrbuf+4),little);
1311 happy = 0;
1312 }
1313 else
1314 {
1315 if (match_four_chars((unsigned char *)hdrbuf,I_fact))
1316 {
1317 fact_samples = big_or_little_endian_int((unsigned char *)(hdrbuf+8),little);
1318 }
1319 else
1320 {
1321 if (match_four_chars((unsigned char *)hdrbuf,I_inst))
1322 {
1323 base_note = hdrbuf[8];
1324 base_detune = hdrbuf[9];
1325 /* rest is gain low-note high-note low-velocity high-velocity */
1326 }
1327 else
1328 {
1329 if (match_four_chars((unsigned char *)hdrbuf,I_clm_))
1330 {
1331 comment_start = offset + 8;
1332 comment_end = comment_start + chunksize - 1; /* end of comment not start of next chunk */
1333 }
1334 }
1335 }
1336 }
1337 }
1338 chunkloc = (8+chunksize);
1339 if (chunksize&1) chunkloc++; /* extra null appended to odd-length chunks */
1340 }
1341 if (true_file_length < data_size) data_size = true_file_length - data_location;
1342 data_size = mus_bytes2samples(data_format,data_size);
1343 return(0);
1344 }
1345
1346 static int write_riff_header (int chan, int srate, int chans, int siz, int format, char *comment, int len)
1347 {
1348 int offset,i,j,lenhdr,extra,curend,err=0;
1349 lenhdr=0;
1350 extra=0;
1351 if (len != 0)
1352 {
1353 lenhdr = 12;
1354 if ((len % 4) != 0)
1355 extra = (4 - (len % 4));
1356 }
1357 write_four_chars((unsigned char *)hdrbuf,I_RIFF);
1358 mus_set_little_endian_int((unsigned char *)(hdrbuf+4),len+36+siz+lenhdr+extra);
1359 write_four_chars((unsigned char *)(hdrbuf+8),I_WAVE);
1360 write_four_chars((unsigned char *)(hdrbuf+12),I_fmt_);
1361 mus_set_little_endian_int((unsigned char *)(hdrbuf+16),24-8);
1362 switch (format)
1363 {
1364 case SNDLIB_8_MULAW:
1365 mus_set_little_endian_short((unsigned char *)(hdrbuf+20),7);
1366 mus_set_little_endian_short((unsigned char *)(hdrbuf+34),8);
1367 break;
1368 case SNDLIB_8_ALAW:
1369 mus_set_little_endian_short((unsigned char *)(hdrbuf+20),6);
1370 mus_set_little_endian_short((unsigned char *)(hdrbuf+34),8);
1371 break;
1372 case SNDLIB_8_UNSIGNED:
1373 mus_set_little_endian_short((unsigned char *)(hdrbuf+20),1);
1374 mus_set_little_endian_short((unsigned char *)(hdrbuf+34),8);
1375 break;
1376 case SNDLIB_16_LINEAR_LITTLE_ENDIAN:
1377 mus_set_little_endian_short((unsigned char *)(hdrbuf+20),1);
1378 mus_set_little_endian_short((unsigned char *)(hdrbuf+34),16);
1379 break;
1380 case SNDLIB_24_LINEAR_LITTLE_ENDIAN:
1381 mus_set_little_endian_short((unsigned char *)(hdrbuf+20),1);
1382 mus_set_little_endian_short((unsigned char *)(hdrbuf+34),24);
1383 break;
1384 case SNDLIB_32_LINEAR_LITTLE_ENDIAN:
1385 mus_set_little_endian_short((unsigned char *)(hdrbuf+20),1);
1386 mus_set_little_endian_short((unsigned char *)(hdrbuf+34),32);
1387 break;
1388 case SNDLIB_32_FLOAT_LITTLE_ENDIAN:
1389 mus_set_little_endian_short((unsigned char *)(hdrbuf+20),3);
1390 mus_set_little_endian_short((unsigned char *)(hdrbuf+34),32);
1391 break;
1392 default:
1393 mus_error(MUS_UNSUPPORTED_DATA_FORMAT,"can't write RIFF data format: %d",format);
1394 err = -1;
1395 break;
1396 }
1397 mus_set_little_endian_short((unsigned char *)(hdrbuf+22),(short)chans);
1398 mus_set_little_endian_int((unsigned char *)(hdrbuf+24),srate);
1399 mus_set_little_endian_int((unsigned char *)(hdrbuf+28),srate * chans * mus_format2bytes(format)); /* added chans 10-Mar-99 */
1400 mus_set_little_endian_short((unsigned char *)(hdrbuf+32),(short)(chans * mus_format2bytes(format)));
1401
1402 offset = 36;
1403 i = 36;
1404 curend = 0;
1405 if (len != 0)
1406 {
1407 offset += len+12;
1408 write_four_chars((unsigned char *)(hdrbuf+36),I_clm_);
1409 mus_set_little_endian_int((unsigned char *)(hdrbuf+40),len+extra);
1410 i = 44;
1411 for (j=0;j<len;j++)
1412 {
1413 if (i == HDRBUFSIZ)
1414 {
1415 curend += HDRBUFSIZ;
1416 write(chan,hdrbuf,HDRBUFSIZ);
1417 i=0;
1418 }
1419 hdrbuf[i]=comment[j];
1420 i++;
1421 }
1422 if (extra != 0)
1423 {
1424 if ((i+extra) > HDRBUFSIZ)
1425 {
1426 curend += i;
1427 write(chan,hdrbuf,i);
1428 i=0;
1429 }
1430 for (j=0;j<extra;j++)
1431 {
1432 hdrbuf[i] = 0;
1433 i++;
1434 }
1435 }
1436 }
1437 curend += i;
1438 write(chan,hdrbuf,i);
1439 write_four_chars((unsigned char *)hdrbuf,I_data);
1440 mus_set_little_endian_int((unsigned char *)(hdrbuf+4),siz);
1441 data_location = 8+curend;
1442 write(chan,hdrbuf,8);
1443 return(err);
1444 }
1445
1446
1447 static void update_riff_header (int chan, int siz)
1448 {
1449 read(chan,hdrbuf,INITIAL_READ_SIZE);
1450 read_riff_header(chan);
1451 lseek(chan,4L,SEEK_SET);
1452 mus_set_little_endian_int((unsigned char *)hdrbuf,(siz+update_form_size-mus_samples2bytes(data_format,data_size)));
1453 /* see update_aiff_header for explanation */
1454 write(chan,hdrbuf,4);
1455 lseek(chan,update_ssnd_location,SEEK_SET);
1456 mus_set_little_endian_int((unsigned char *)hdrbuf,siz);
1457 write(chan,hdrbuf,4);
1458 }
1459
1460
1461 static void update_riff_header_comment (int chan, char *comment, int len)
1462 {
1463 /* save-stats in CLM appends a comment after the sound data has been written */
1464 int i,j,true_len,old_len;
1465 if (len&1) true_len = len+1; else true_len=len;
1466 lseek(chan,0L,SEEK_END);
1467 write_four_chars((unsigned char *)hdrbuf,I_INFO);
1468 mus_set_little_endian_int((unsigned char *)(hdrbuf+4),len);
1469 for (i=0,j=8;i<len;i++,j++) hdrbuf[j]=comment[i];
1470 write(chan,hdrbuf,8+true_len);
1471 lseek(chan,4L,SEEK_SET);
1472 read(chan,hdrbuf,4);
1473 old_len = mus_little_endian_int((unsigned char *)hdrbuf);
1474 mus_set_little_endian_int((unsigned char *)hdrbuf,old_len+true_len+8);
1475 lseek(chan,4L,SEEK_SET);
1476 write(chan,hdrbuf,4);
1477 }
1478
1479
1480 /* ------------------------------------ AVI ------------------------------------
1481 * actually a video format, but it sometimes contains embedded 'wave' data
1482 *
1483 * RIFF xxx AVI
1484 * <various LISTs>
1485 * LIST xxxx hdr1 LIST strl(?) strh | strf | strn etc
1486 * strf is the WAVE header starting with the sound format
1487 * LIST xxxx movi ##db|##wb -- wb subblocks have the audio data (these need to be collected as a single stream)
1488 * there are many complications that we make no effort to handle here
1489 *
1490 * described in http://www.rahul.net/jfm/avi.html
1491 */
1492
1493 static int read_avi_header (int chan)
1494 {
1495 /* we know we have checked for RIFF xxxx AVI when we arrive here */
1496 int chunksize,offset,chunkloc,happy,cksize,rdsize,ckoff,cktotal;
1497 int cksizer,ckoffr,cktotalr,bits;
1498 type_specifier = mus_uninterpreted_int((unsigned char *)(hdrbuf+8));
1499 chunkloc = 12;
1500 offset = 0;
1501 header_distributed = 1;
1502 data_format = SNDLIB_UNSUPPORTED;
1503 srate = 0;
1504 chans = 1;
1505 happy = 1;
1506 data_size = 0;
1507 data_location = 0;
1508 true_file_length = lseek(chan,0L,SEEK_END);
1509 while (happy)
1510 {
1511 offset += chunkloc;
1512 if (seek_and_read(chan,(unsigned char *)hdrbuf,offset,32) <= 0)
1513 {
1514 mus_error(MUS_HEADER_READ_FAILED,"AVI header chunks confused at %d",offset);
1515 return(-1);
1516 }
1517 chunksize = mus_little_endian_int((unsigned char *)(hdrbuf+4));
1518 if (match_four_chars((unsigned char *)hdrbuf,I_LIST))
1519 {
1520 ckoff = offset+12;
1521 cktotal = 12;
1522 if (match_four_chars((unsigned char *)(hdrbuf+8),I_movi))
1523 {
1524 while (cktotal < chunksize)
1525 {
1526 lseek(chan,ckoff,SEEK_SET);
1527 read(chan,hdrbuf,8);
1528 cksize = mus_little_endian_int((unsigned char *)(hdrbuf+4));
1529 if ((hdrbuf[2] == 'w') && (hdrbuf[3] == 'b'))
1530 {
1531 data_location = ckoff;
1532 if (srate != 0) happy=0;
1533 break;
1534 }
1535 ckoff += (8+cksize);
1536 cktotal += (8+cksize);
1537 }
1538 }
1539 else
1540 {
1541 while (cktotal < chunksize)
1542 {
1543 lseek(chan,ckoff,SEEK_SET);
1544 read(chan,hdrbuf,8);
1545 cksize = mus_little_endian_int((unsigned char *)(hdrbuf+4));
1546 ckoff += (8+cksize);
1547 cktotal += (8+cksize);
1548 if (match_four_chars((unsigned char *)hdrbuf,I_LIST))
1549 {
1550 ckoffr = ckoff+12;
1551 cktotalr = 12;
1552 while (cktotalr < cksize)
1553 {
1554 lseek(chan,ckoffr,SEEK_SET);
1555 read(chan,hdrbuf,8);
1556 cksizer = mus_little_endian_int((unsigned char *)(hdrbuf+4));
1557 ckoffr += (8+cksizer);
1558 cktotalr += (8+cksizer);
1559 if (match_four_chars((unsigned char *)hdrbuf,I_strf))
1560 {
1561 if (cksizer < HDRBUFSIZ) rdsize = cksizer; else rdsize = HDRBUFSIZ;
1562 read(chan,hdrbuf,rdsize);
1563 original_data_format = mus_little_endian_short((unsigned char *)hdrbuf);
1564 chans = mus_little_endian_short((unsigned char *)(hdrbuf+2));
1565 srate = mus_little_endian_int((unsigned char *)(hdrbuf+4));
1566 /* block_align = mus_little_endian_short((unsigned char *)(hdrbuf+12)); */
1567 bits = mus_little_endian_short((unsigned char *)(hdrbuf+14));
1568 /* only 16 bit linear little endian for now */
1569 if ((bits == 16) && (original_data_format == 1))
1570 original_data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
1571 if (data_location != 0) happy = 0;
1572 break;
1573 }
1574 }
1575 }
1576 }
1577 }
1578 }
1579 chunkloc = (8+chunksize);
1580 if (chunksize&1) chunkloc++; /* extra null appended to odd-length chunks */
1581 }
1582 return(0);
1583 }
1584
1585
1586
1587 /* ------------------------------------ SoundFont 2.0 ------------------------------------
1588 *
1589 * Emu's SoundFont(tm) format uses RIFF -- at ftp.creaf.com:/pub/emu/sf2_00a.ps)
1590 *
1591 * RIFF xxxx sfbk followed by
1592 * LIST xxxx INFO chunk (nothing of interest -- icmt subchunk might have comments)
1593 * LIST xxxx sdta chunk = data
1594 * smpl chunk (16 bit linear little-endian)
1595 * LIST xxxx pdta list chunk
1596 * shdr subchunk has srate at 40 (int), samples at 28
1597 */
1598
1599 static int read_soundfont_header (int chan)
1600 {
1601 /* we know we have checked for RIFF xxxx sfbk when we arrive here */
1602 int chunksize,offset,chunkloc,happy,type,cksize,rdsize,ckoff;
1603 type_specifier = mus_uninterpreted_int((unsigned char *)(hdrbuf+8));
1604 chunkloc = 12;
1605 offset = 0;
1606 header_distributed = 1;
1607 data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
1608 srate = 0;
1609 chans = 1; /* to hell with soundfont stereo */
1610 happy = 1;
1611 data_size = 0;
1612 data_location = 0;
1613 true_file_length = lseek(chan,0L,SEEK_END);
1614 while (happy)
1615 {
1616 offset += chunkloc;
1617 if (seek_and_read(chan,(unsigned char *)hdrbuf,offset,32) <= 0)
1618 {
1619 mus_error(MUS_HEADER_READ_FAILED,"SoundFont header chunks confused at %d",offset);
1620 return(-1);
1621 }
1622 chunksize = mus_little_endian_int((unsigned char *)(hdrbuf+4));
1623 if (match_four_chars((unsigned char *)hdrbuf,I_LIST))
1624 {
1625 /* everything is squirreled away in LIST chunks in this format */
1626 if (match_four_chars((unsigned char *)(hdrbuf+8),I_pdta))
1627 {
1628 /* go searching for I_shdr -- headers this complicated should be illegal. */
1629 ckoff = offset+12;
1630 lseek(chan,ckoff,SEEK_SET);
1631 while (!srate)
1632 {
1633 read(chan,hdrbuf,8);
1634 cksize = mus_little_endian_int((unsigned char *)(hdrbuf+4));
1635 ckoff += (8+cksize);
1636 /* here we need to jump over subchunks! -- 4-Aug-97 */
1637 if (match_four_chars((unsigned char *)hdrbuf,I_shdr))
1638 {
1639 if (cksize < HDRBUFSIZ) rdsize = cksize; else rdsize = HDRBUFSIZ;
1640 read(chan,hdrbuf,rdsize);
1641 data_size = 2 * mus_little_endian_int((unsigned char *)(hdrbuf+24));
1642 srate = mus_little_endian_int((unsigned char *)(hdrbuf+36));
1643 type = mus_little_endian_short((unsigned char *)(hdrbuf+44));
1644 if (type != 1)
1645 {
1646 mus_error(MUS_UNSUPPORTED_DATA_FORMAT,"can't handle this SoundFont data type: %x",type);
1647 return(-1);
1648 }
1649 happy = (!data_location);
1650 }
1651 else lseek(chan,ckoff,SEEK_SET);
1652 }
1653 }
1654 else
1655 {
1656 if (match_four_chars((unsigned char *)(hdrbuf+8),I_sdta))
1657 {
1658 /* assume smpl follows + subchunk size */
1659 /* Convert 1.4 appears to create a separate smpl chunk */
1660 data_location = offset+20; /* LIST xxxx sdta smpl xxxx ... */
1661 happy = (!srate);
1662 }
1663 }
1664 }
1665 chunkloc = (8+chunksize);
1666 if (chunksize&1) chunkloc++; /* extra null appended to odd-length chunks */
1667 }
1668 if (true_file_length < data_size) data_size = true_file_length - data_location;
1669 data_size = mus_bytes2samples(data_format,data_size);
1670 return(0);
1671 }
1672
1673
1674
1675
1676 /* ------------------------------------ NIST ------------------------------------
1677 *
1678 * code available in ogitools-v1.0.tar.gz at svr-ftp.eng.cam.ac.uk:comp.speech/sources
1679 *
1680 * 0: "NIST_1A"
1681 * 8: data_location as ASCII representation of integer (apparently always " 1024")
1682 * 16: start of complicated header -- see below for details
1683 *
1684 * The most recent version of the SPHERE package is available
1685 * via anonymous ftp from jaguar.ncsl.nist.gov [129.6.48.157] in the pub directory
1686 * in compressed tar form as "sphere-v.tar.Z" (where "v" is the version
1687 * code 2.6a last I looked). shortpack is also at this site.
1688 *
1689 * here's an example:
1690 *
1691 * NIST_1A
1692 * 1024
1693 * database_id -s5 TIMIT
1694 * database_version -s3 1.0
1695 * utterance_id -s8 aks0_sa1
1696 * channel_count -i 1
1697 * sample_count -i 63488
1698 * sample_rate -i 16000
1699 * sample_min -i -6967
1700 * sample_max -i 7710
1701 * sample_n_bytes -i 2
1702 * sample_byte_format -s2 01
1703 * sample_sig_bits -i 16
1704 * end_head
1705 *
1706 * the sample_byte_format can be "10"=big-endian or "01"=little-endian, or "shortpack-v0"=compressed via shortpack
1707 * other formats are wavpack and shorten.
1708 *
1709 * another field is 'sample_coding' which can be pcm (i.e. linear), 'pcm,embedded-shorten-v1.09', mu-law, ulaw, pculaw etc --
1710 * so unpredictable as to be totally useless. This means we sometimes try to decode shorten-encoded files because
1711 * we ignore this field. And worse, there's a 'channels_interleaved' field that (apparently) can be FALSE. Tough.
1712 */
1713
1714 #define MAX_FIELD_LENGTH 80
1715
1716 static int decode_nist_value (char *str,int base,int end)
1717 {
1718 /* can be -i -r or -snnn where nnn=ascii rep of integer = len of string (!) */
1719 /* we'll deal only with integer fields (and well-behaved string fields) */
1720 int i,j;
1721 char value[MAX_FIELD_LENGTH];
1722 i=base;
1723 while ((i<end) && (i<MAX_FIELD_LENGTH) && (str[i] != '-')) i++; /* look for -i or whatever */
1724 while ((i<end) && (i<MAX_FIELD_LENGTH) && (str[i] != ' ')) i++; /* look for space after it */
1725 i++;
1726 if (i>=MAX_FIELD_LENGTH) return(0);
1727 for (j=0;i<end;j++,i++)
1728 value[j]=str[i];
1729 value[j]=0;
1730 if (value[0]=='s') return(SNDLIB_NIST_shortpack);
1731 sscanf(value,"%d",&i);
1732 return(i);
1733 }
1734
1735 static int read_nist_header (int chan)
1736 {
1737 char str[MAX_FIELD_LENGTH],name[MAX_FIELD_LENGTH];
1738 int happy = 1;
1739 int k,hend,curbase,j,n,nm,samples,bytes,byte_format;
1740 type_specifier = mus_uninterpreted_int((unsigned char *)hdrbuf); /* the actual id is "NIST_1A" */
1741 for (k=8;k<16;k++) str[k-8]=hdrbuf[k];
1742 sscanf(str,"%d",&data_location); /* always "1024" */
1743 n = 16;
1744 hend = INITIAL_READ_SIZE;
1745 k=0;
1746 curbase = 0;
1747 samples = 0;
1748 bytes = 0;
1749 srate = 0;
1750 chans = 0;
1751 comment_start = 16;
1752 comment_end = 16;
1753 byte_format = 10;
1754 for (j=0;j<MAX_FIELD_LENGTH;j++) str[j]=' ';
1755 while (happy)
1756 {
1757 /* much as in xIFF files, march through the file looking for the data we're after */
1758 /* in this case we munch a character at a time... */
1759 str[k] = hdrbuf[n];
1760 if ((((str[k] == '\0') || (str[k] == '\n')) || ((curbase+n+1) >= data_location)) || (k == 79))
1761 {
1762 /* got a complete record (assuming no embedded newlines, of course) */
1763 /* now look for a record we care about and decode it */
1764 nm = 0;
1765 while ((str[nm] != ' ') && (nm < MAX_FIELD_LENGTH))
1766 {
1767 name[nm] = str[nm];
1768 nm++;
1769 }
1770 if (nm >= MAX_FIELD_LENGTH)
1771 {
1772 header_type = raw_sound_file;
1773 data_format = SNDLIB_UNSUPPORTED;
1774 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"invalid NIST header?");
1775 return(-1);
1776 }
1777 name[nm]=0;
1778 if (strcmp(name,"sample_rate") == 0) srate = decode_nist_value(str,nm,k); else
1779 if (strcmp(name,"channel_count") == 0) chans = decode_nist_value(str,nm,k); else
1780 if (strcmp(name,"end_head") == 0) {happy = 0; comment_end=curbase+n-1;} else
1781 if (strcmp(name,"sample_count") == 0) samples = decode_nist_value(str,nm,k); else
1782 if ((bytes == 0) && (strcmp(name,"sample_n_bytes") == 0)) bytes = decode_nist_value(str,nm,k); else
1783 if ((bytes == 0) && (strcmp(name,"sample_sig_bits") == 0)) {bytes = decode_nist_value(str,nm,k); bytes = (bytes>>3);} else
1784 if (strcmp(name,"sample_byte_format") == 0) byte_format = decode_nist_value(str,nm,k); else
1785 if (strcmp(name,"end_head") == 0) happy = 0;
1786 for (j=0;j<=k;j++) str[j]=' ';
1787 k=0;
1788 if ((curbase+n+1) > 1024) happy=0;
1789 }
1790 else
1791 k++;
1792 n++;
1793 if (n >= hend)
1794 {
1795 curbase += hend;
1796 n = 0;
1797 read(chan,hdrbuf,HDRBUFSIZ);
1798 hend = HDRBUFSIZ;
1799 }
1800 }
1801 data_size = samples*bytes;
1802 if (byte_format == SNDLIB_NIST_shortpack)
1803 {
1804 data_format = SNDLIB_UNSUPPORTED;
1805 original_data_format = SNDLIB_NIST_shortpack;
1806 }
1807 else
1808 {
1809 if (bytes == 2)
1810 {
1811 if (byte_format == 10)
1812 data_format = SNDLIB_16_LINEAR;
1813 else data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
1814 }
1815 else data_format = SNDLIB_8_MULAW;
1816 }
1817 data_size = mus_bytes2samples(data_format,data_size);
1818 header_distributed = 1;
1819 return(0);
1820 }
1821
1822 static int write_nist_header (int chan, int srate, int chans, int siz, int format)
1823 {
1824 char *header;
1825 int datum;
1826 datum = mus_format2bytes(format);
1827 header = (char *)CALLOC(1024,sizeof(char));
1828 sprintf(header,"NIST_1A\n 1024\nchannel_count -i %d\nsample_rate -i %d\nsample_n_bytes -i %d\nsample_byte_format -s2 %s\nsample_sig_bits -i %d\nsample_count -i %d\nend_head\n",
1829 chans,srate,datum,
1830 ((format == SNDLIB_16_LINEAR) || (format == SNDLIB_24_LINEAR) || (format == SNDLIB_32_LINEAR)) ? "10" : "01",
1831 datum* 8,siz/datum);
1832 #ifndef MACOS
1833 write(chan,(unsigned char *)header,1024);
1834 #else
1835 write(chan,header,1024);
1836 #endif
1837 data_location = 1024;
1838 FREE(header);
1839 return(0);
1840 }
1841
1842 static void update_nist_header (int chan, int siz)
1843 {
1844 lseek(chan,0L,SEEK_SET);
1845 read(chan,hdrbuf,INITIAL_READ_SIZE);
1846 read_nist_header(chan);
1847 lseek(chan,0L,SEEK_SET);
1848 write_nist_header(chan,mus_header_srate(),mus_header_chans(),siz,mus_header_format());
1849 }
1850
1851
1852 /* ------------------------------------ BICSF ------------------------------------
1853 * (actually, this is EBICSF and the old BICSF is called IRCAM below)
1854 *
1855 * 0-28: NeXT-compatible header, read by read_next_header above.
1856 * 28: bicsf magic number (107364 or trouble)
1857 * 32: srate as a 32-bit float
1858 * 36: chans
1859 * 40: data format indicator (2=16-bit linear, 4=32-bit float)
1860 * 44: begin chunks, if any
1861 *
1862 * followed by AIFF-style chunked header info with chunks like:
1863 *
1864 * COMM size comment
1865 * MAXA size {max amps (up to 4)} (frame offsets) time-tag unix msec counter
1866 * CUE, PRNT, ENV etc
1867 */
1868
1869 static int read_bicsf_header (int chan)
1870 {
1871 int chunksize,chunkname,offset,chunkloc,happy;
1872 type_specifier = mus_uninterpreted_int((unsigned char *)(hdrbuf+28));
1873 header_type = BICSF_sound_file;
1874 data_location = 1024;
1875 if (data_size == 0) data_size = (true_file_length-data_location);
1876 lseek(chan,40,SEEK_SET);
1877 read(chan,hdrbuf,HDRBUFSIZ);
1878 original_data_format = mus_big_endian_int((unsigned char *)hdrbuf);
1879 switch (original_data_format)
1880 {
1881 case 2: data_format = SNDLIB_16_LINEAR; break;
1882 case 4: data_format = SNDLIB_32_FLOAT; break;
1883 default: break;
1884 }
1885
1886 /* now check for a COMM chunk, setting the comment pointers */
1887 chunkloc = 4; /* next header + magic number, srate, chans, packing, then chunks, I think */
1888 offset = 40;
1889 header_distributed = 1;
1890 happy = 1;
1891 while (happy)
1892 {
1893 if ((offset+chunkloc) >= data_location)
1894 happy = 0;
1895 else
1896 {
1897 offset += chunkloc;
1898 if (seek_and_read(chan,(unsigned char *)hdrbuf,offset,32) <= 0)
1899 {
1900 mus_error(MUS_HEADER_READ_FAILED,"Bicsf header chunks confused at %d",offset);
1901 return(-1);
1902 }
1903 chunkname = mus_uninterpreted_int((unsigned char *)hdrbuf);
1904 chunksize = mus_big_endian_int((unsigned char *)(hdrbuf+4));
1905 if (match_four_chars((unsigned char *)hdrbuf,I_COMM))
1906 {
1907 comment_start = 8+offset;
1908 comment_end = comment_start + chunksize -1;
1909 happy = 0;
1910 }
1911 else
1912 {
1913 if ((chunkname == 0) || (chunksize == 0))
1914 happy = 0;
1915 }
1916 chunkloc = (8+chunksize);
1917 }
1918 }
1919 return(0);
1920 /* from here we fall back into read_next_header */
1921 }
1922
1923
1924
1925 /* ------------------------------------ IRCAM ------------------------------------
1926 * read/write CLM (old-style BICSF) -- added write option for Sun port 12-Dec-94
1927 *
1928 * 0: 0x1a364 or variations thereof -- byte order gives big/little_endian decision,
1929 * ^ digit gives machine info, according to AFsp sources -- see IRCAM ints above
1930 * 4: srate as a 32-bit float
1931 * 8: chans
1932 * 12: data format indicator (2=16-bit linear, 4=32-bit float)
1933 * according to new Sox (version 11), these packing modes are now bytes/sample in low short, code in high
1934 * so 1 = char, 0x10001 = alaw, 0x20001 = mulaw, 2 = short, 0x40004 = long, 4 = float
1935 * 16: comment start -- how to tell if it's a real comment?
1936 * apparently these are separated as short code, short blocksize, then data
1937 * codes: 0=end, 1=maxamp, 2=comment, 3=pvdata, 4=audioencode and codemax??
1938 * 1024: data start
1939 *
1940 * apparently the byte order depends on the machine.
1941 * and yet... convert 1.4 makes a .sf file with little endian header, the VAX id, and big endian data?
1942 */
1943
1944 static int read_ircam_header (int chan)
1945 {
1946 short bcode,bloc,bsize;
1947 int happy,offset,little;
1948 type_specifier = mus_uninterpreted_int((unsigned char *)hdrbuf);
1949 if ((mus_little_endian_int((unsigned char *)hdrbuf) == I_IRCAM_VAX) ||
1950 (mus_little_endian_int((unsigned char *)hdrbuf) == I_IRCAM_MIPS))
1951 little=1;
1952 else little=0;
1953 data_location = 1024;
1954 true_file_length=lseek(chan,0L,SEEK_END);
1955 data_size = (true_file_length-1024);
1956 original_data_format = big_or_little_endian_int((unsigned char *)(hdrbuf+12),little);
1957 data_format = SNDLIB_UNSUPPORTED;
1958 if (original_data_format == 2)
1959 {
1960 if (little) data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN; else data_format = SNDLIB_16_LINEAR;
1961 }
1962 else if (original_data_format == 4)
1963 {
1964 if (little)
1965 {
1966 if (mus_little_endian_int((unsigned char *)hdrbuf) == I_IRCAM_VAX)
1967 data_format = SNDLIB_32_VAX_FLOAT;
1968 else data_format = SNDLIB_32_FLOAT_LITTLE_ENDIAN;
1969 }
1970 else data_format = SNDLIB_32_FLOAT;
1971 }
1972 else if (original_data_format == 0x40004)
1973 {
1974 if (little) data_format = SNDLIB_32_LINEAR_LITTLE_ENDIAN;
1975 else data_format = SNDLIB_32_LINEAR;
1976 }
1977 else if (original_data_format == 0x10001) data_format = SNDLIB_8_ALAW;
1978 else if (original_data_format == 0x20001) data_format = SNDLIB_8_MULAW;
1979 else if (original_data_format == 1) data_format = SNDLIB_8_LINEAR;
1980 srate = (int)big_or_little_endian_float((unsigned char *)(hdrbuf+4),little);
1981 chans = big_or_little_endian_int((unsigned char *)(hdrbuf+8),little);
1982 bloc=16;
1983 happy=1;
1984 offset=0;
1985 while (happy)
1986 {
1987 offset += bloc;
1988 if (seek_and_read(chan,(unsigned char *)hdrbuf,offset,32) <= 0)
1989 {
1990 mus_error(MUS_HEADER_READ_FAILED,"IRCAM header chunks confused at %d",offset);
1991 return(-1);
1992 }
1993 bcode = big_or_little_endian_short((unsigned char *)hdrbuf,little);
1994 bsize = big_or_little_endian_short((unsigned char *)(hdrbuf+2),little);
1995 if (bcode == 2)
1996 {
1997 happy = 0;
1998 comment_start = 4+offset;
1999 comment_end = comment_start+bsize-1; /* was -5? */
2000 }
2001 bloc = bsize;
2002 if ((bsize <= 0) || (bcode <= 0) || ((offset+bloc) > 1023)) happy = 0;
2003 }
2004 header_distributed = 0;
2005 data_size = mus_bytes2samples(data_format,data_size);
2006 return(0);
2007 }
2008
2009 static int write_ircam_header (int chan, int srate, int chans, int format, char *comment, int len)
2010 {
2011 int i,j,err=0;
2012 #ifdef NEXT
2013 mus_set_big_endian_int((unsigned char *)hdrbuf,0x4a364);
2014 #else
2015 mus_set_big_endian_int((unsigned char *)hdrbuf,0x2a364); /* SUN id */
2016 #endif
2017 mus_set_big_endian_float((unsigned char *)(hdrbuf+4),(float)srate);
2018 mus_set_big_endian_int((unsigned char *)(hdrbuf+8),chans);
2019 switch (format)
2020 {
2021 case SNDLIB_8_MULAW: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),0x20001); break;
2022 case SNDLIB_8_ALAW: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),0x10001); break;
2023 case SNDLIB_16_LINEAR: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),2); break;
2024 case SNDLIB_32_LINEAR: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),0x40004); break;
2025 case SNDLIB_32_FLOAT: mus_set_big_endian_int((unsigned char *)(hdrbuf+12),4); break;
2026 default:
2027 mus_error(MUS_UNSUPPORTED_DATA_FORMAT,"IRCAM unsupported sound data format type: %d",format);
2028 err = -1;
2029 break;
2030 }
2031 if (len > 0)
2032 {
2033 mus_set_big_endian_short((unsigned char *)(hdrbuf+16),2);
2034 mus_set_big_endian_short((unsigned char *)(hdrbuf+18),(short)len);
2035 }
2036 else
2037 {
2038 mus_set_big_endian_int((unsigned char *)(hdrbuf+16),0);
2039 }
2040 write(chan,hdrbuf,20);
2041 data_location = 1024;
2042 j = 0;
2043 for (i=0;i<len;i++)
2044 {
2045 hdrbuf[j]=comment[i];
2046 j++;
2047 if (j == HDRBUFSIZ)
2048 {
2049 write(chan,hdrbuf,HDRBUFSIZ);
2050 j = 0;
2051 }
2052 }
2053 for (i=0;i<(1024-(len+20));i++) /* now fill left over bytes with nulls */
2054 {
2055 hdrbuf[j]=0;
2056 j++;
2057 if (j == HDRBUFSIZ)
2058 {
2059 write(chan,hdrbuf,HDRBUFSIZ);
2060 j = 0;
2061 }
2062 }
2063 if (j != 0) write(chan,hdrbuf,j);
2064 return(err);
2065 }
2066
2067 static void update_ircam_header (void)
2068 {
2069 /* size is implicit in file size - header */
2070 }
2071
2072
2073 /* ------------------------------------ 8SVX -------------------------------------
2074 * (also known as IFF)
2075 *
2076 * very similar to AIFF:
2077 * "BODY" => [4] samples [n] data
2078 * "VHDR" => srate (short)
2079 * "CHAN" => chans
2080 * "ANNO" and "NAME"
2081 *
2082 * big_endian throughout
2083 */
2084
2085 static int read_8svx_header (int chan)
2086 {
2087 int chunksize,offset,chunkloc,happy;
2088 type_specifier = mus_uninterpreted_int((unsigned char *)hdrbuf);
2089 chunkloc = 12;
2090 offset = 0;
2091 data_format = SNDLIB_8_LINEAR;
2092 header_distributed = 1;
2093 srate = 0;
2094 chans = 1;
2095 happy = 1;
2096 update_form_size = mus_big_endian_int((unsigned char *)(hdrbuf+4));
2097 while (happy)
2098 {
2099 offset += chunkloc;
2100 if (seek_and_read(chan,(unsigned char *)hdrbuf,offset,32) <= 0)
2101 {
2102 mus_error(MUS_HEADER_READ_FAILED,"IFF header chunks confused at %d",offset);
2103 return(-1);
2104 }
2105 chunksize = mus_big_endian_int((unsigned char *)(hdrbuf+4));
2106 if (match_four_chars((unsigned char *)hdrbuf,I_CHAN))
2107 {
2108 chans = mus_big_endian_int((unsigned char *)(hdrbuf+8));
2109 chans = (chans & 0x01) + ((chans & 0x02) >> 1) + ((chans & 0x04) >> 2) + ((chans & 0x08) >> 3);
2110 /* what in heaven's name is this? Each bit corresponds to a channel? */
2111 }
2112 else
2113 {
2114 if (match_four_chars((unsigned char *)hdrbuf,I_VHDR))
2115 {
2116 /* num_samples (int) at hdrbuf+8 */
2117 srate = mus_big_endian_unsigned_short((unsigned char *)(hdrbuf+20));
2118 original_data_format = hdrbuf[23];
2119 if (original_data_format != 0) data_format = SNDLIB_UNSUPPORTED;
2120 }
2121 else
2122 {
2123 if ((match_four_chars((unsigned char *)hdrbuf,I_ANNO)) || (match_four_chars((unsigned char *)hdrbuf,I_NAME)))
2124 {
2125 comment_start = offset+8;
2126 comment_end = comment_start+chunksize-1;
2127 }
2128 else
2129 {
2130 if (match_four_chars((unsigned char *)hdrbuf,I_BODY))
2131 {
2132 data_size = chunksize;
2133 data_location = offset+12;
2134 happy = 0;
2135 }
2136 }
2137 }
2138 }
2139 chunkloc = (8+chunksize);
2140 if (chunksize&1) chunkloc++; /* extra null appended to odd-length chunks */
2141 }
2142 data_size = mus_bytes2samples(data_format,data_size);
2143 return(0);
2144 }
2145
2146
2147 /* ------------------------------------ VOC --------------------------------------
2148 *
2149 * 0: "Creative Voice File" followed by a couple ctrl-Z ('32) (swapped data)
2150 * 20: header end (short) {8svx, 26=data_offset, 0x10a=version, ((~version + 0x1234) & 0xffff) = 0x1129}
2151 * [20]: first block:
2152 * block code, 1=data, 0=end, 9=data_16 (2=continue, 3=silence, 4=marker, 5=text, 6=loop, 7=loop-end, 8=extended)
2153 * block len as 24 bit int(?)
2154 * if data, then rate code (byte), then data (assuming 8-bit unsigned, mono)
2155 * if data_16, long srate, byte: data size (8 or 16), byte chans
2156 * if text, ascii text (a comment)
2157 * if extended (8) precedes 1 (data): 8 4 then time constant (short), byte: packing code (0), byte chans (0=mono)
2158 *
2159 * apparently always little_endian
2160 * updated extensively 29-Aug-95 from sox10 voc.c
2161 */
2162
2163 static int read_voc_header(int chan)
2164 {
2165 int type,happy,len,curbase,voc_extended,bits,code;
2166 data_format = SNDLIB_8_UNSIGNED;
2167 chans = 1;
2168 happy = 1;
2169 voc_extended = 0;
2170 true_file_length=lseek(chan,0L,SEEK_END);
2171 curbase = mus_little_endian_short((unsigned char *)(hdrbuf+20));
2172 header_distributed = 1;
2173 lseek(chan,curbase,SEEK_SET);
2174 read(chan,hdrbuf,HDRBUFSIZ);
2175 type = (int)(hdrbuf[0]);
2176 len=(((int)hdrbuf[3])<<16)+(((int)hdrbuf[2])<<8)+(((int)hdrbuf[1]));
2177 while (happy)
2178 {
2179 if (type == 1) /* voc_data */
2180 {
2181 data_size = len-1; /* was -3 */
2182 data_location = curbase+6;
2183 if (voc_extended == 0)
2184 {
2185 srate = (int)(1000000.0/(256 - ((int)(hdrbuf[4]&0xff))));
2186 original_data_format = hdrbuf[5];
2187 if (hdrbuf[5] == 0) data_format = SNDLIB_8_UNSIGNED; else data_format = SNDLIB_UNSUPPORTED;
2188 }
2189 happy = 0;
2190 }
2191 else
2192 {
2193 if (type == 9) /* voc_data_16 */
2194 {
2195 data_size = len-1; /* was -3 */
2196 data_location = curbase+6;
2197 srate = mus_little_endian_int((unsigned char *)(hdrbuf+4));
2198 bits = ((int)hdrbuf[8]);
2199 if (bits == 8)
2200 {
2201 code = mus_little_endian_short((unsigned char *)(hdrbuf+10));
2202 if (code == 6)
2203 data_format = SNDLIB_8_ALAW;
2204 else
2205 if (code == 7)
2206 data_format = SNDLIB_8_MULAW;
2207 else data_format = SNDLIB_8_UNSIGNED;
2208 }
2209 else
2210 if (bits == 16)
2211 data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
2212 else data_format = SNDLIB_UNSUPPORTED;
2213 chans = (int)hdrbuf[9];
2214 if (chans == 0) chans = 1;
2215 happy = 0;
2216 }
2217 else
2218 {
2219 if (((len+curbase)<true_file_length) && (type != 0))
2220 {
2221 if (type == 5) /* voc_text */
2222 {
2223 comment_start = curbase+4;
2224 comment_end = comment_start + len - 1;
2225 }
2226 else
2227 {
2228 if (type == 8) /* voc_extended */
2229 {
2230 srate = (256000000 / (65536 - mus_little_endian_short((unsigned char *)(hdrbuf+4))));
2231 if ((int)(hdrbuf[7]) == 0) chans=1; else chans=2;
2232 if ((int)(hdrbuf[6]) != 0) data_format = SNDLIB_UNSUPPORTED;
2233 }
2234 }
2235 if (seek_and_read(chan,(unsigned char *)hdrbuf,curbase+len+4,HDRBUFSIZ) <= 0)
2236 {
2237 mus_error(MUS_HEADER_READ_FAILED,"VOC header looks wrong");
2238 return(-1);
2239 }
2240 curbase += len;
2241 }
2242 else happy = 0;
2243 }
2244 }
2245 }
2246 data_size = mus_bytes2samples(data_format,data_size);
2247 return(0);
2248 }
2249
2250
2251
2252 /* ------------------------------------ ADC ------------------------------------
2253 * also known as OGI format
2254 * TIMIT format is identical except it omits the data format field (header size claims to be bytes)
2255 *
2256 * from ad.h and other files, ogitools-v1.0.tar.gz
2257 * we'll look for the big/little endian sequence (short) 8 1 1-or-2 given big/little decision
2258 *
2259 * 0: header size in shorts (8 = 16 bytes) (OGI says this is in bytes)
2260 * 2: version (1)
2261 * 4: chans
2262 * 6: rate (srate = 4000000/rate)
2263 * 8: samples (int) -- seems to be off by 2 -- are they counting ints here?
2264 * 12: data format (0=big-endian)
2265 * 16: data start
2266 */
2267
2268 static int read_adc_header(int chan)
2269 {
2270 int little;
2271 little = mus_uninterpreted_int((unsigned char *)(hdrbuf+12)); /* 0=big endian */
2272 data_location = 16;
2273 if (little) data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN; else data_format = SNDLIB_16_LINEAR;
2274 chans = big_or_little_endian_short((unsigned char *)(hdrbuf+4),little);
2275 srate = 4000000 / big_or_little_endian_short((unsigned char *)(hdrbuf+6),little);
2276 data_size = 2*big_or_little_endian_int((unsigned char *)(hdrbuf+8),little);
2277 comment_start=0;
2278 comment_end=0;
2279 header_distributed = 0;
2280 true_file_length=lseek(chan,0L,SEEK_END);
2281 data_size = mus_bytes2samples(data_format,data_size);
2282 return(0);
2283 }
2284
2285
2286
2287 /* ------------------------------------ AVR --------------------------------------
2288 *
2289 * 0: "2BIT"
2290 * 4: sample name (null padded ASCII)
2291 * 12: chans (short) (0=mono, -1=stereo)
2292 * 14: sample size (8 or 16 bit) (short) (value is 8, 12, or 16)
2293 * 16: sample format (signed or unsigned) (short) (0=unsigned, -1=signed)
2294 * 18: loop (on/off), 20: midi (-1 = no MIDI)
2295 * 22: srate
2296 * avr.txt has:
2297 * 22: Replay speed 0=5.485 Khz, 1=8.084 Khz, 2=10.971 Khz, 3=16.168 Khz, 4=21.942 Khz, 5=32.336 Khz, 6=43.885 Khz, 7=47.261 Khz
2298 * 23: sample rate in Hertz (as a 3 byte quantity??)
2299 * 26: length in samples
2300 * 30: loop beg, 34: loop end, 38: midi (keyboard split), 40: compression, 42: nada ("reserved"), 44: name
2301 * 64: comment (limited to 64 bytes)
2302 * 128: data start
2303 *
2304 * the Atari .avr files appear to be 8000 Hz, mono, 8-bit linear unsigned data with an unknown header of 128 words
2305 * apparently there was a change in format sometime in the 90's.
2306 *
2307 * The actual avr files I've found on the net are either garbled, or
2308 * something is wrong with this definition (taken from CMJ and www.wotsit.org's avr.txt).
2309 * SGI dmconvert assumes big-endian here -- this is an Atari format, so it's probably safe to assume big-endian.
2310 */
2311
2312 static int read_avr_header(int chan)
2313 {
2314 int dsize,dsigned,i;
2315 chans = mus_big_endian_short((unsigned char *)(hdrbuf+12));
2316 if (chans == 0) chans=1; else chans=2;
2317 data_location = 128;
2318 data_size = mus_big_endian_int((unsigned char *)(hdrbuf+26));
2319 header_distributed = 0;
2320 srate = mus_big_endian_unsigned_short((unsigned char *)(hdrbuf+24));
2321 dsize = mus_big_endian_short((unsigned char *)(hdrbuf+14));
2322 dsigned = mus_big_endian_short((unsigned char *)(hdrbuf+16));
2323 if (dsize == 16)
2324 {
2325 if (dsigned == 0)
2326 data_format = SNDLIB_16_UNSIGNED;
2327 else data_format = SNDLIB_16_LINEAR;
2328 }
2329 else
2330 {
2331 if (dsigned == 0)
2332 data_format = SNDLIB_8_UNSIGNED;
2333 else data_format = SNDLIB_8_LINEAR;
2334 }
2335 if (seek_and_read(chan,(unsigned char *)hdrbuf,64,64) <= 0)
2336 {
2337 mus_error(MUS_HEADER_READ_FAILED,"AVR header looks wrong");
2338 return(-1);
2339 }
2340 comment_start = 64;
2341 i = 0;
2342 while ((i < 64) && (hdrbuf[i] != 0)) i++;
2343 comment_end = 64+(i-1);
2344 true_file_length=lseek(chan,0L,SEEK_END);
2345 data_size = mus_bytes2samples(data_format,data_size);
2346 return(0);
2347 }
2348
2349
2350
2351
2352 /* ------------------------------------ SNDT -------------------------------------
2353 *
2354 * this taken from sndrtool.c (sox-10): (modified 6-Feb-98)
2355 * 0: "SOUND" (or off by two throughout if not "0x1a"?)
2356 * 5: 0x1a
2357 * 6-7: 0
2358 * 8-11: nsamps (at 12)
2359 * 12-15: 0
2360 * 16-19: nsamps
2361 * 20-21: srate (little endian short) (at 22)
2362 * 22-23: 0
2363 * 24-25: 10
2364 * 26-27: 4
2365 * 28-> : <filename> "- File created by Sound Exchange"
2366 * .->95: 0 ?
2367 */
2368
2369 /* similar is Sounder format:
2370 * 0: 0
2371 * 2: short srate (little endian)
2372 * 4: 10
2373 * 6: 4
2374 * then data
2375 * but this format can't be distinguished from a raw sound file
2376 */
2377
2378 static int read_sndt_header(int chan)
2379 {
2380 data_format = SNDLIB_8_UNSIGNED;
2381 chans = 1;
2382 srate = mus_little_endian_unsigned_short((unsigned char *)(hdrbuf+20));
2383 data_location = 126;
2384 data_size = mus_little_endian_int((unsigned char *)(hdrbuf+8));
2385 if (data_size < 0) data_size = mus_little_endian_int((unsigned char *)(hdrbuf+10));
2386 if (srate <= 1) srate = mus_little_endian_unsigned_short((unsigned char *)(hdrbuf+22));
2387 header_distributed = 0;
2388 true_file_length=lseek(chan,0L,SEEK_END);
2389 return(0);
2390 }
2391
2392
2393 /* ------------------------------------ Covox v8 -------------------------------------
2394 *
2395 * 0: 377 125 377 252 377 125 377 252 x x 0's to 16
2396 * then 8-bit unsigned data
2397 */
2398
2399 static int read_covox_header(int chan)
2400 {
2401 data_format = SNDLIB_8_UNSIGNED;
2402 chans = 1;
2403 header_distributed = 0;
2404 data_location = 16;
2405 srate = 8000;
2406 true_file_length=lseek(chan,0L,SEEK_END);
2407 data_size = true_file_length - data_location;
2408 return(0);
2409 }
2410
2411
2412 /* ------------------------------------ Digitracker SPL -------------------------------------
2413 * (Atari-related, I think, and now obsolete)
2414 * 0: DSPL
2415 * 4: version
2416 * 5: sample name
2417 * 37: filename
2418 * 45: c-4 freq (srate?)
2419 * 47: length
2420 * 51: loop data
2421 * 59: vol
2422 * 60: bit 0: 0=8 bit, 1=16
2423 * 61: data (in sample data chunks or as straight data??)
2424 */
2425
2426 static int read_spl_header(int chan)
2427 {
2428 chans = 1;
2429 header_distributed = 0;
2430 data_location = 61;
2431 srate = 8000; /* I need an example to decode this */
2432 true_file_length=lseek(chan,0L,SEEK_END);
2433 if (hdrbuf[60]&1) data_format = SNDLIB_16_LINEAR; else data_format = SNDLIB_8_LINEAR; /* unsigned? */
2434 data_size = mus_bytes2samples(data_format,true_file_length - data_location);
2435 return(0);
2436 }
2437
2438
2439 /* ------------------------------------ SMP -------------------------------------
2440 *
2441 * 0: "SOUND SAMPLE DATA "
2442 * 18: "2.1 "
2443 * 22-81: comment
2444 * 82-111: sample name
2445 * header 112 bytes
2446 * long samples (bytes=samples*2)
2447 * then data start
2448 * data
2449 * always little endian
2450 */
2451
2452 static int read_smp_header(int chan)
2453 {
2454 data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
2455 chans = 1;
2456 comment_start=22;
2457 comment_end=81;
2458 header_distributed = 1;
2459 data_location = 116;
2460 lseek(chan,112,SEEK_SET);
2461 read(chan,hdrbuf,4);
2462 data_size = 2*(mus_little_endian_int((unsigned char *)hdrbuf));
2463 srate = 8000; /* docs mention an srate floating around at the end of the file, but I can't find it in any example */
2464 true_file_length=lseek(chan,0L,SEEK_END);
2465 data_size = mus_bytes2samples(data_format,data_size);
2466 return(0);
2467 }
2468
2469
2470 /* ------------------------------------ SPPACK -------------------------------------
2471 *
2472 * from AF docs:
2473 * Bytes Type Contents
2474 * 0 160 char Text strings (2 * 80)
2475 * 160 80 char Command line
2476 * 240 2 int Domain
2477 * 242 2 int Frame size
2478 * 244 4 float Sampling frequency
2479 * 252 2 int File identifier (i.e. #o100 #o303)
2480 * 254 2 int Data type (0xfc0e = sampled data file)
2481 * 256 2 int Resolution (in bits)
2482 * 258 2 int Companding flag (1=linear, 2=alaw, 3=mulaw)
2483 * 272 240 char Text strings (3 * 80)
2484 * 512 ... -- Audio data
2485 *
2486 */
2487
2488 static int read_sppack_header(int chan)
2489 {
2490 int typ,bits;
2491 float sr;
2492 data_location = 512;
2493 chans = 1;
2494 lseek(chan,240,SEEK_SET);
2495 read(chan,hdrbuf,22);
2496 typ = mus_big_endian_short((unsigned char *)hdrbuf);
2497 data_format = SNDLIB_UNSUPPORTED;
2498 header_distributed = 0;
2499 if (typ == 1)
2500 {
2501 if (((hdrbuf[254])==252) && ((hdrbuf[255])==14)) /* #xfc and #x0e */
2502 {
2503 typ = mus_big_endian_short((unsigned char *)(hdrbuf+18));
2504 bits = mus_big_endian_short((unsigned char *)(hdrbuf+16));
2505 sr = mus_big_endian_float((unsigned char *)(hdrbuf+4));
2506 srate = (int)sr;
2507 switch (typ)
2508 {
2509 case 1: if (bits == 16) data_format = SNDLIB_16_LINEAR; else data_format = SNDLIB_8_LINEAR; break;
2510 case 2: data_format = SNDLIB_8_ALAW; break;
2511 case 3: data_format = SNDLIB_8_MULAW; break;
2512 default: data_format = SNDLIB_UNSUPPORTED; break;
2513 }
2514 data_size=lseek(chan,0L,SEEK_END);
2515 data_size=mus_bytes2samples(data_format,data_size-512);
2516 comment_start=0;
2517 comment_end=0;
2518 }
2519 }
2520 true_file_length=lseek(chan,0L,SEEK_END);
2521 return(0);
2522 }
2523
2524
2525 /* ------------------------------------ ESPS (Entropic Signal Processing System) -------------------------------------
2526 *
2527 * specs at ftp.entropic.com
2528 * from AFgetInfoES.c:
2529 *
2530 * Bytes Type Contents
2531 * 8 -> 11 -- Header size (bytes)
2532 * 12 -> 15 int Sampled data record size
2533 * 16 -> 19 int File identifier: 0x00006a1a or 0x1a6a0000
2534 * 40 -> 65 char File creation date
2535 * 124 -> 127 int Number of samples
2536 * 132 -> 135 int Number of doubles in a data record
2537 * 136 -> 139 int Number of floats in a data record
2538 * 140 -> 143 int Number of longs in a data record
2539 * 144 -> 147 int Number of shorts in a data record
2540 * 148 -> 151 int Number of chars in a data record
2541 * 160 -> 167 char User name
2542 * 333 -> H-1 -- "Generic" header items, including "record_freq" {followed by a "double8"=64-bit ?}
2543 * H -> ... -- Audio data
2544 */
2545
2546 static int read_esps_header (int chan)
2547 {
2548 char str[80];
2549 int happy = 1;
2550 int k,hend,curbase,j,n,chars,floats,shorts,doubles,little;
2551 data_location = mus_big_endian_int((unsigned char *)(hdrbuf+8));
2552 little = (hdrbuf[18] == 0);
2553 true_file_length = lseek(chan,0L,SEEK_END);
2554 data_size = true_file_length - data_location;
2555 header_distributed = 0;
2556 srate = 8000;
2557 chans = 1;
2558 lseek(chan,132,SEEK_SET);
2559 read(chan,hdrbuf,HDRBUFSIZ);
2560 if (little)
2561 {
2562 doubles = mus_little_endian_int((unsigned char *)hdrbuf);
2563 floats = mus_little_endian_int((unsigned char *)(hdrbuf+4));
2564 shorts = mus_little_endian_int((unsigned char *)(hdrbuf+12));
2565 chars = mus_little_endian_int((unsigned char *)(hdrbuf+16));
2566 }
2567 else
2568 {
2569 doubles = mus_big_endian_int((unsigned char *)hdrbuf);
2570 floats = mus_big_endian_int((unsigned char *)(hdrbuf+4));
2571 shorts = mus_big_endian_int((unsigned char *)(hdrbuf+12));
2572 chars = mus_big_endian_int((unsigned char *)(hdrbuf+16));
2573 }
2574 if (shorts != 0)
2575 {
2576 data_format = ((little) ? SNDLIB_16_LINEAR_LITTLE_ENDIAN : SNDLIB_16_LINEAR);
2577 chans = shorts;
2578 }
2579 else
2580 {
2581 if (doubles != 0)
2582 {
2583 data_format = ((little) ? SNDLIB_64_DOUBLE_LITTLE_ENDIAN : SNDLIB_64_DOUBLE);
2584 chans = doubles;
2585 }
2586 else
2587 {
2588 if (floats != 0)
2589 {
2590 data_format = ((little) ? SNDLIB_32_FLOAT_LITTLE_ENDIAN : SNDLIB_32_FLOAT);
2591 chans = floats;
2592 }
2593 else
2594 {
2595 if (chars != 0)
2596 {
2597 data_format = SNDLIB_8_LINEAR; /* ?? */
2598 chans = chars;
2599 }
2600 }
2601 }
2602 }
2603 /* search for "record_freq" to get srate */
2604 lseek(chan,333,SEEK_SET);
2605 read(chan,hdrbuf,HDRBUFSIZ);
2606 curbase=333;
2607 hend=curbase+HDRBUFSIZ;
2608 k=0;
2609 n=0;
2610 for (j=0;j<80;j++) str[j]=' ';
2611 while (happy)
2612 {
2613 str[k] = hdrbuf[n];
2614 if ((str[k] == 'q') || (str[k] == 3) || ((curbase+n+1) >= data_location) || (k == 78))
2615 { /* 3 = C-C marks end of record */
2616 str[k+1]=0;
2617 if (strcmp(str,"record_freq") == 0)
2618 {
2619 if (seek_and_read(chan,(unsigned char *)hdrbuf,curbase+n,32) <= 0)
2620 {
2621 mus_error(MUS_HEADER_READ_FAILED,"ESPS header looks wrong");
2622 return(-1);
2623 }
2624 n=0;
2625 if (little)
2626 srate = (int)mus_little_endian_double((unsigned char *)(hdrbuf+8));
2627 else srate = (int)mus_big_endian_double((unsigned char *)(hdrbuf+8));
2628 happy = 0;
2629 }
2630 if ((curbase+n+1) >= data_location) happy = 0;
2631 k=0;
2632 }
2633 else
2634 k++;
2635 n++;
2636 if (n >= hend)
2637 {
2638 curbase += hend;
2639 n = 0;
2640 read(chan,hdrbuf,HDRBUFSIZ);
2641 hend = HDRBUFSIZ;
2642 }
2643 }
2644 if (srate == 0) srate = 8000;
2645 data_size = mus_bytes2samples(data_format,data_size);
2646 return(0);
2647 }
2648
2649
2650
2651 /* ------------------------------------ INRS -------------------------------------
2652 *
2653 * from AFgetInfoIN.c:
2654 *
2655 * INRS-Telecommunications audio file:
2656 * Bytes Type Contents
2657 * 0 -> 3 float Sampling Frequency (VAX float format)
2658 * 6 -> 25 char Creation time (e.g. Jun 12 16:52:50 1990)
2659 * 26 -> 29 int Number of speech samples in the file (? -- old INRS files omit this)
2660 * The data in an INRS-Telecommunications audio file is in 16-bit integer (little-endian)
2661 * format. Header is always 512 bytes. Always mono.
2662 *
2663 */
2664
2665 static int inrs_srates[NINRS] = {6500, 6667, 8000, 10000, 12000, 16000, 20000};
2666
2667 static int read_inrs_header (int chan, int loc)
2668 {
2669
2670 true_file_length = lseek(chan,0L,SEEK_END);
2671 comment_start = 6;
2672 comment_end = 25;
2673 header_distributed = 0;
2674 data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
2675 srate = loc;
2676 chans = 1;
2677 data_location = 512;
2678 data_size = mus_bytes2samples(data_format,true_file_length-512);
2679 return(0);
2680 }
2681
2682
2683 /* ------------------------------------ MAUD -------------------------------------
2684 *
2685 * very similar to AIFF:
2686 * "MHDR" => 4: chunksize (32)
2687 * 8: samples
2688 * 12: bits
2689 * 14: ditto
2690 * 16: clock freq
2691 * 20: clock div (srate = freq/div)
2692 * 22: chan info (0=mono, 1=stereo)
2693 * 24: ditto(?!)
2694 * 26: format (0=unsigned 8 or signed 16 (see bits), 2=alaw, 3=mulaw)
2695 * 28-40: unused
2696 * "MDAT" => data
2697 * "ANNO" => comment
2698 */
2699
2700 static int read_maud_header (int chan)
2701 {
2702 int chunksize,offset,chunkloc,happy,num,den;
2703 type_specifier = mus_uninterpreted_int((unsigned char *)hdrbuf);
2704 chunkloc = 12;
2705 offset = 0;
2706 data_format = SNDLIB_8_LINEAR;
2707 header_distributed = 1;
2708 srate = 0;
2709 chans = 1;
2710 happy = 1;
2711 update_form_size = mus_big_endian_int((unsigned char *)(hdrbuf+4));
2712 while (happy)
2713 {
2714 offset += chunkloc;
2715 if (seek_and_read(chan,(unsigned char *)hdrbuf,offset,32) <= 0)
2716 {
2717 mus_error(MUS_HEADER_READ_FAILED,"MAUD header chunk bogus at %d",offset);
2718 return(-1);
2719 }
2720 chunksize = mus_big_endian_int((unsigned char *)(hdrbuf+4));
2721 if (match_four_chars((unsigned char *)hdrbuf,I_MHDR))
2722 {
2723 data_size = mus_big_endian_int((unsigned char *)(hdrbuf+8));
2724 num = mus_big_endian_int((unsigned char *)(hdrbuf+16));
2725 den = mus_big_endian_short((unsigned char *)(hdrbuf+20));
2726 srate = (int)(num/den);
2727 num = mus_big_endian_short((unsigned char *)(hdrbuf+12));
2728 den = mus_big_endian_short((unsigned char *)(hdrbuf+26));
2729 if (num == 8)
2730 {
2731 switch (den)
2732 {
2733 case 0: data_format = SNDLIB_8_UNSIGNED; break;
2734 case 2: data_format = SNDLIB_8_ALAW; break;
2735 case 3: data_format = SNDLIB_8_MULAW; break;
2736 default: data_format = SNDLIB_UNSUPPORTED; break;
2737 }
2738 }
2739 else data_format = SNDLIB_16_LINEAR;
2740 num = mus_big_endian_short((unsigned char *)(hdrbuf+22));
2741 if (num == 0) chans = 1; else chans = 2;
2742 }
2743 else
2744 {
2745 if (match_four_chars((unsigned char *)hdrbuf,I_ANNO))
2746 {
2747 comment_start = offset+8;
2748 comment_end = comment_start+chunksize-1;
2749 }
2750 else
2751 {
2752 if (match_four_chars((unsigned char *)hdrbuf,I_MDAT))
2753 {
2754 data_location = offset+12;
2755 happy = 0;
2756 }
2757 }
2758 }
2759 chunkloc = (8+chunksize);
2760 if (chunksize&1) chunkloc++; /* extra null appended to odd-length chunks */
2761 }
2762 data_size = mus_bytes2samples(data_format,data_size);
2763 return(0);
2764 }
2765
2766
2767
2768 /* ------------------------------------ Sound Designer I -------------------------------------
2769 *
2770 * complicated and defined in terms of Pascal records, so the following is a stab in the dark:
2771 *
2772 * 0: 1336 (i.e. header size)
2773 * 764: comment (str255)
2774 * 1020: sample rate (long)
2775 * 1028: data size (short)
2776 * 1030: a code string describing the data type (i.e. "linear") (str32)
2777 * 1064: user comment (str255)
2778 *
2779 * file type: 'SFIL'
2780 *
2781 * always big_endian
2782 */
2783
2784 static int read_sd1_header (int chan)
2785 {
2786 int n;
2787 chans = 1;
2788 header_distributed = 0;
2789 data_location = 1336;
2790 lseek(chan,1020,SEEK_SET);
2791 read(chan,hdrbuf,64);
2792 srate = mus_big_endian_int((unsigned char *)hdrbuf);
2793 n = mus_big_endian_short((unsigned char *)(hdrbuf+8));
2794 if (n == 16)
2795 data_format = SNDLIB_16_LINEAR;
2796 else data_format = SNDLIB_8_LINEAR;
2797 true_file_length = lseek(chan,0L,SEEK_END);
2798 data_size = mus_bytes2samples(data_format,true_file_length-1336);
2799 n = ((unsigned char)hdrbuf[44]);
2800 if (n != 0)
2801 {
2802 comment_start = 1064;
2803 comment_end = comment_start+n-1;
2804 }
2805 return(0);
2806 }
2807
2808
2809
2810 /* ------------------------------------ PSION alaw -------------------------------------
2811 *
2812 * 0: "ALawSoundFile**"
2813 * 16: version
2814 * 18: length (bytes)
2815 * 22: padding
2816 * 24: repeats
2817 * 26-32: nada
2818 * 32: data
2819 *
2820 * always mono 8-bit alaw 8000 Hz. All the examples on the psion net site appear to be little endian.
2821 */
2822
2823 static int read_psion_header (int chan)
2824 {
2825 chans = 1;
2826 header_distributed = 0;
2827 data_location = 32;
2828 srate = 8000;
2829 data_format = SNDLIB_8_ALAW;
2830 data_size = mus_little_endian_int((unsigned char *)(hdrbuf+18)); /* always little-endian? */
2831 true_file_length=lseek(chan,0,SEEK_END);
2832 if ((true_file_length+32) != data_size) data_size = (true_file_length-32);
2833 data_size = mus_bytes2samples(data_format,data_size);
2834 return(0);
2835 }
2836
2837
2838
2839 /* ------------------------------------ Tandy DeskMate -------------------------------------
2840 *
2841 * 0: short 1A (c-Z = .snd ID byte)
2842 * 1: data type (0=no compression, 1=music compression, 2=speech compression)
2843 * 2: number of notes (= 1 if sound)
2844 * 3: instrument number (= 0 if sound, otherwise this is an "instrument" file)
2845 * 4: sound/instrument name (ASCIZ -- 10 bytes)
2846 * 14: sampling rate (apparently one of 5500, 11000, 22000 -- is this unsigned?)
2847 * 16: begin variable 28-byte records, after which is sound data as unsigned 8-bit linear ("PCM")
2848 * in sound files:
2849 * 16: 0xFF 0 0xFF 0xFF
2850 * 20: data location if compressed
2851 * 24: 8 bytes of non-sound related things
2852 * 32: sound size
2853 * 36: 8 more useless bytes
2854 *
2855 * always 8-bit unsigned linear mono
2856 * This info from oak.oakland.edu:/SimTel/msdos/sound/tspak17.zip (now at ftp.coast.net:/pub/SimTel/msdos/sound)
2857 */
2858 static int read_deskmate_header (int chan)
2859 {
2860 /* if we reach here, we're at 0 with HDRBUFSIZ read in */
2861 chans = 1;
2862 header_distributed = 0;
2863 data_location = 44;
2864 srate = mus_little_endian_short((unsigned char *)(hdrbuf+14)); /* unsigned? */
2865 data_format = SNDLIB_8_UNSIGNED;
2866 data_size = mus_little_endian_int((unsigned char *)(hdrbuf+32));
2867 true_file_length=lseek(chan,0,SEEK_END);
2868 data_size = mus_bytes2samples(data_format,data_size);
2869 return(0);
2870 }
2871
2872
2873 /* ------------------------------------ Tandy DeskMate 2500 -------------------------------------
2874 * the "new .snd file format"
2875 *
2876 * 0: name of sound, 10 byte ASCIZ
2877 * 10: nada (probably to be backwards compatible...)
2878 * 44: snd ID -- 0x1A80
2879 * 46: number of samples
2880 * 48: sound number
2881 * 50: nada
2882 * 66: compression code (see above)
2883 * 68: nada
2884 * 88: sampling rate
2885 * 90: nada
2886 * 114: sample descriptors:
2887 * 0: link to next (0 if last)
2888 * 4: nada
2889 * 10: data location
2890 * 12: number of bytes in sample
2891 * 46: end of descriptor (presumably start of data)
2892 */
2893 static int read_deskmate_2500_header (int chan)
2894 {
2895 /* if we reach here, we're at 0 with HDRBUFSIZ read in */
2896 chans = 1;
2897 header_distributed = 0;
2898 data_location = 114+46;
2899 srate = mus_little_endian_short((unsigned char *)(hdrbuf+88));
2900 data_format = SNDLIB_8_UNSIGNED;
2901 data_size = mus_little_endian_int((unsigned char *)(hdrbuf+46));
2902 true_file_length=lseek(chan,0,SEEK_END);
2903 data_size = mus_bytes2samples(data_format,data_size);
2904 return(0);
2905 }
2906
2907
2908 /* ------------------------------------ Gravis Ultrasound Patch -------------------------------------
2909 *
2910 * http://www.gravis.com/Public/sdk/PATCHKIT.ZIP
2911 *
2912 * header [128], instruments [62], layers [49], waveheaders (nested)
2913 * always little endian, actual files don't match exactly with any documentation
2914 *
2915 * Header block:
2916 * 0: "GF1PATCH100" or "GF1PATCH110"
2917 * 12: "ID#000002"
2918 * 22: comment (copyright notice) (60 bytes ASCIZ)
2919 * 82: number of instruments
2920 * 83: number of voices
2921 * 84: wave channels
2922 * 85: number of waves
2923 * 87: vol
2924 * 89: size?
2925 * 93: reserved (36? bytes)
2926 *
2927 * Instrument block:
2928 * 0: id
2929 * 2: name (16 bytes)
2930 * 18: size
2931 * 22: number of layers
2932 * 23: reserved (40? bytes)
2933 *
2934 * Layer block:
2935 * 0: "previous"
2936 * 1: id
2937 * 2: size
2938 * 6: number of wave samples
2939 * 10: reserved (40? bytes)
2940 *
2941 * Wave block:
2942 * 0: name (7 bytes ASCIZ)
2943 * 7: "fractions"
2944 * 8: data size of wave sample
2945 * 12: loop start
2946 * 16: loop end
2947 * 20: sample rate
2948 * 22: low freq
2949 * 26: high freq
2950 * 30: root freq
2951 * 34: tune
2952 * 36: balance
2953 * 37: envelope data (6+6 bytes I think)
2954 * 49: tremolo and vibrato data (6 bytes)
2955 * 55: mode bit 0: 8/16, 1: signed/unsigned
2956 * 56: scale freq
2957 * 58: scale factor
2958 * 60: reserved (36 bytes)
2959 * followed by data presumably
2960 */
2961
2962 static int read_gravis_header(int chan)
2963 {
2964 int mode;
2965 lseek(chan,0,SEEK_SET);
2966 read(chan,hdrbuf,128);
2967 chans = hdrbuf[84];
2968 if (chans == 0) chans=1;
2969 comment_start = 22;
2970 comment_end = 81;
2971 lseek(chan,239,SEEK_SET); /* try to jump to wave sample block (128+62+49) */
2972 read(chan,hdrbuf,128);
2973 srate = mus_little_endian_unsigned_short((unsigned char *)(hdrbuf+20));
2974 data_size = mus_little_endian_unsigned_short((unsigned char *)(hdrbuf+8));
2975 mode = hdrbuf[55];
2976 if (mode&1)
2977 {
2978 if (mode&2)
2979 data_format = SNDLIB_16_UNSIGNED_LITTLE_ENDIAN;
2980 else data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
2981 }
2982 else
2983 {
2984 if (mode&2)
2985 data_format = SNDLIB_8_UNSIGNED;
2986 else data_format = SNDLIB_8_LINEAR;
2987 }
2988
2989 data_location = 337;
2990 header_distributed = 0;
2991 true_file_length = lseek(chan,0L,SEEK_END);
2992 data_size = mus_bytes2samples(data_format,data_size);
2993 return(0);
2994 }
2995
2996
2997
2998 /* ------------------------------------ Goldwave -------------------------------------
2999 *
3000 * http://web.cs.mun.ca/~chris3/goldwave/goldwave.html
3001 */
3002
3003 static int read_goldwave_header(int chan)
3004 {
3005 chans = 1;
3006 header_distributed = 0;
3007 data_location = 28;
3008 data_size = mus_little_endian_int((unsigned char *)(hdrbuf+22));
3009 true_file_length = lseek(chan,0L,SEEK_END);
3010 if (data_size <= 24) data_size = (true_file_length-data_location);
3011 srate = mus_little_endian_int((unsigned char *)(hdrbuf+18));
3012 data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
3013 return(0);
3014 }
3015
3016
3017 /* ------------------------------------ Sonic Resource Foundry -------------------------------------
3018 *
3019 * more reverse engineering...
3020 * http://www.sfoundry.com/
3021 */
3022
3023 static int read_srfs_header(int chan)
3024 {
3025 chans = 1; /* might be short at header[4] */
3026 header_distributed = 0;
3027 data_location = 32;
3028 true_file_length = lseek(chan,0L,SEEK_END);
3029 data_size = (true_file_length-data_location);
3030 srate = mus_little_endian_int((unsigned char *)(hdrbuf+6));
3031 data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
3032 return(0);
3033 }
3034
3035
3036 /* ------------------------------------ Quicktime -------------------------------------
3037 *
3038 * infinitely complicated -- see Quicktime File Format doc from Apple.
3039 * there's no relation between this document and actual files -- a bizarre joke?
3040 */
3041
3042 static int read_qt_header(int chan)
3043 {
3044 chans = 1;
3045 header_distributed = 0;
3046 data_location = 12;
3047 true_file_length = lseek(chan,0L,SEEK_END);
3048 data_size = (true_file_length-data_location);
3049 srate = 11025; /* ?? */
3050 data_format = SNDLIB_8_UNSIGNED;
3051 return(0);
3052 }
3053
3054
3055 /* ------------------------------------ SBStudioII -------------------------------------
3056 *
3057 * from a file created by Convert 1.4
3058 * 0: SND <space>
3059 * 8: file size - 8
3060 * SNNA SNIN SNDT blocks:
3061 *
3062 * built in blocks, other names are SNIN, SNDT
3063 * need to scan for SNDT, block length, data
3064 * SNNA len name
3065 * supposedly ends with END (but my examples don't)
3066 * SNIN:
3067 * num (2), reserved (2), tuning (1), vol (2), type (2) bit 0: 1=PCM, bit 1: 1=16,0=8 (then loop data)
3068 * info from Pac.txt (pac.zip) at http://www.wotsit.org/music.htm
3069 */
3070
3071 static int read_sbstudio_header(int chan)
3072 {
3073 int i,happy,tmp;
3074 unsigned char *bp;
3075 lseek(chan,0,SEEK_SET);
3076 read(chan,hdrbuf,HDRBUFSIZ);
3077 chans = 1;
3078 header_distributed = 0;
3079 srate = 8000; /* no sampling rate field in this header */
3080 data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN; /* might change later */
3081 true_file_length = lseek(chan,0L,SEEK_END);
3082 data_size = true_file_length - 56; /* first guess */
3083 happy = 1;
3084 i=8;
3085 bp = (unsigned char *)(hdrbuf+8);
3086 while (happy)
3087 {
3088 if (match_four_chars(bp,I_SNDT))
3089 {
3090 data_size = mus_little_endian_int((unsigned char *)(bp+4));
3091 data_location = i+8;
3092 happy = 0;
3093 }
3094 else
3095 {
3096 if (match_four_chars(bp,I_SNIN))
3097 {
3098 tmp = mus_little_endian_short((unsigned char *)(bp+15));
3099 if ((tmp&1)==0)
3100 data_format = SNDLIB_UNSUPPORTED;
3101 else
3102 {
3103 if ((tmp&2)==0) data_format = SNDLIB_8_LINEAR;
3104 }
3105 i+=26;
3106 bp+=26;
3107 }
3108 else
3109 {
3110 i++;
3111 bp++;
3112 }
3113 }
3114 if (i >= HDRBUFSIZ)
3115 {
3116 data_format = SNDLIB_UNSUPPORTED;
3117 happy = 0;
3118 }
3119 }
3120 data_size = mus_bytes2samples(data_format,data_size);
3121 return(0);
3122 }
3123
3124
3125 /* ------------------------------------ Delusion Sound -------------------------------------
3126 *
3127 * more reverse engineering...
3128 * from a file created by Convert 1.4
3129 * 0: DDSF
3130 * 5: name (text)
3131 * 55: data
3132 * probaby similar to DMF format describe in Dmf-form.txt but I don't see any other block names in the data
3133 */
3134
3135 static int read_delusion_header(int chan)
3136 {
3137 chans = 1;
3138 header_distributed = 0;
3139 data_location = 55;
3140 true_file_length = lseek(chan,0L,SEEK_END);
3141 data_size = (true_file_length-data_location);
3142 srate = 8000;
3143 data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
3144 data_size = mus_bytes2samples(data_format,data_size);
3145 return(0);
3146 }
3147
3148
3149
3150 /* ------------------------------------ Farandole Composer WaveSample -------------------------------------
3151 *
3152 * 0: FSM 254
3153 * 4: name (text) (32 bytes)
3154 * 36: 10,13,26 or something like that
3155 * 39: len?
3156 * 40: volume
3157 * 41: looping data
3158 * 49: type (0=8-bit, else 16)
3159 * 50: loop mode
3160 * 51: data
3161 * described in Fsm.txt and Far-form.txt http://www.wotsit.org/music.htm
3162 */
3163
3164 static int read_farandole_header(int chan)
3165 {
3166 chans = 1;
3167 header_distributed = 0;
3168 data_location = 51;
3169 true_file_length = lseek(chan,0L,SEEK_END);
3170 data_size = (true_file_length-data_location);
3171 srate = 8000;
3172 if (hdrbuf[49] == 0)
3173 data_format = SNDLIB_8_LINEAR;
3174 else data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
3175 data_size = mus_bytes2samples(data_format,data_size);
3176 return(0);
3177 }
3178
3179
3180
3181 /* ------------------------------------ Yamaha TX-16 -------------------------------------
3182 *
3183 * ftp://ftp.t0.or.at/pub/sound/tx16w/samples.yamaha
3184 * http://www.t0.or.at/~mpakesch/tx16w/
3185 *
3186 * from tx16w.c sox 12.15: (7-Oct-98) (Mark Lakata and Leigh Smith)
3187 * char filetype[6] "LM8953"
3188 * nulls[10],
3189 * dummy_aeg[6]
3190 * format 0x49 = looped, 0xC9 = non-looped
3191 * sample_rate 1 = 33 kHz, 2 = 50 kHz, 3 = 16 kHz
3192 * atc_length[3] if sample rate 0, [2]&0xfe = 6: 33kHz, 0x10:50, 0xf6: 16, depending on [5] but to heck with it
3193 * rpt_length[3] (these are for looped samples, attack and loop lengths)
3194 * unused[2]
3195 */
3196
3197 static int read_tx16_header(int chan)
3198 {
3199 chans = 1;
3200 header_distributed = 0;
3201 data_location = 32;
3202 true_file_length = lseek(chan,0L,SEEK_END);
3203 data_size = (true_file_length-data_location);
3204 srate = 16000;
3205 if (hdrbuf[23] == 1) srate = 33000;
3206 else if (hdrbuf[23] == 2) srate = 50000;
3207 else if (hdrbuf[23] == 3) srate = 16000;
3208 else if (hdrbuf[23] == 0)
3209 {
3210 if ((hdrbuf[26]&0xFE) == 6) srate = 33000;
3211 else if ((hdrbuf[26]&0xFE) == 0x10) srate = 50000;
3212 else if ((hdrbuf[26]&0xFE) == 0xf6) srate = 16000;
3213 }
3214 original_data_format = SNDLIB_12_LINEAR_LITTLE_ENDIAN; /* can't read this format yet */
3215 data_format = SNDLIB_UNSUPPORTED;
3216 data_size = (int)((float)data_size / 1.5);
3217 return(0);
3218 }
3219
3220
3221 /* ------------------------------------ Yamaha SY-85 and SY-99 -------------------------------------
3222 *
3223 * more reverse engineering...
3224 * 0: SY85 (SY80 is SY-99) SY85ALL SY80 SYALL
3225 * 5: name ("WAVE1")
3226 * (26 int len)
3227 * (33: comment or prompt?)
3228 * data in 16-bit little endian (?)
3229 */
3230
3231 static int read_sy85_header(int chan)
3232 {
3233 chans = 1;
3234 header_distributed = 0;
3235 data_location = 1024;
3236 true_file_length = lseek(chan,0L,SEEK_END);
3237 data_size = (true_file_length-data_location);
3238 srate = 8000; /* unknown */
3239 data_format = SNDLIB_16_LINEAR; /* not right */
3240 data_size = mus_bytes2samples(data_format,data_size);
3241 return(0);
3242 }
3243
3244
3245 /* ------------------------------------ Kurzweil 2000 -------------------------------------
3246 *
3247 * "PRAM" then header len as big endian int??
3248 * from krz2tx.c (Mark Lakata)
3249 */
3250 static int read_kurzweil_2000_header(int chan)
3251 {
3252 chans = 1;
3253 header_distributed = 0;
3254 data_location = mus_big_endian_int((unsigned char *)(hdrbuf+4));
3255 true_file_length = lseek(chan,0L,SEEK_END);
3256 data_size = (true_file_length-data_location);
3257 srate = 44100; /* unknown */
3258 data_format = SNDLIB_16_LINEAR;
3259 data_size = mus_bytes2samples(data_format,data_size);
3260 return(0);
3261 }
3262
3263
3264
3265 /* ------------------------------------ Ultratracker WaveSample -------------------------------------
3266 *
3267 * 0..31: name (32=ctrl-Z?)
3268 * 33: PMUWFD (but docs say this is "dos name" -- perhaps we can't recognize this header type reliably)
3269 * 44: 4 ints giving loop and size data
3270 * 60: vol
3271 * 61: "bidi" 0|8|24->8 bit else 16 -- but actual example has 0 with 16-bit
3272 * 62: finetune
3273 * 64: data (or 68?)
3274 * described in Ult-form.txt http://www.wotsit.org/music.htm
3275 */
3276
3277 static int read_ultratracker_header(int chan)
3278 {
3279 chans = 1;
3280 header_distributed = 0;
3281 data_location = 64;
3282 true_file_length = lseek(chan,0L,SEEK_END);
3283 data_size = (true_file_length-data_location);
3284 srate = 8000;
3285 data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
3286 data_size = mus_bytes2samples(data_format,data_size);
3287 return(0);
3288 }
3289
3290
3291
3292 /* ------------------------------------ Sample dump exchange -------------------------------------
3293 *
3294 * 0: SDX:
3295 * sdx2tx.c (Mark Lakata) reads from 4 for 26 (^z), then
3296 * version (1)
3297 * comment as pascal-style string (byte len, bytes chars)
3298 * then 23 bytes:
3299 * 0: packing (0=pcm)
3300 * 1: midi channel
3301 * 2 + 256*[3]: sample number
3302 * 4: sample format (15: 16 bit unsigned(?), 8: 8bit unsigned(?)
3303 * 5: sample rate (big int?)
3304 * 9: sample length
3305 * 13: loop start
3306 * 17: loop end
3307 * 21: loop type
3308 * 22: reserved
3309 */
3310
3311 static int read_sample_dump_header(int chan)
3312 {
3313 int i,len;
3314 for (i=4;i<HDRBUFSIZ;i++) if (hdrbuf[i] == 26) break;
3315 len = hdrbuf[i+2];
3316 if (len>0)
3317 {
3318 comment_start = i+3;
3319 comment_end = i+3+len;
3320 }
3321 seek_and_read(chan, (unsigned char *)hdrbuf, i+3+len, HDRBUFSIZ);
3322 srate = mus_little_endian_int((unsigned char *)(hdrbuf+5));
3323 /* data_size = mus_little_endian_int((unsigned char *)(hdrbuf+9)); */
3324 if ((srate<100) || (srate>100000)) srate = 8000;
3325 chans = 1;
3326 header_distributed = 0;
3327 data_location = i+3+len+23;;
3328 true_file_length = lseek(chan,0L,SEEK_END);
3329 data_size = (true_file_length-data_location);
3330 data_format = SNDLIB_16_UNSIGNED_LITTLE_ENDIAN;
3331 data_size = mus_bytes2samples(data_format,data_size);
3332 return(0);
3333 }
3334
3335
3336 /* ------------------------------------ Digiplayer ST3 -------------------------------------
3337 *
3338 * 0: 1 (use 'SCRS' at 76)
3339 * 1: name
3340 * 13: nada
3341 * 14: "paragraph" offset of sample data
3342 * 16: length in bytes (looks like #samples in the actual files...)
3343 * 20: loop start
3344 * 24: loop end
3345 * 28: vol
3346 * 29: ?
3347 * 30: 0=unpacked, 1=DP30ADPCM
3348 * 31: bits: 0=loop, 1=stereo (chans not interleaved!), 2=16-bit samples (little endian)
3349 * 32: freq
3350 * 36: nada
3351 * 40: nada
3352 * 42: 512
3353 * 44: date?
3354 * 48: sample name (28 char ASCIZ)
3355 * 76: 'SCRS'
3356 * 80: data starts
3357 *
3358 * info from http://www.wotsit.org/music.htm (I forgot to write down the file name)
3359 */
3360
3361 static int read_digiplayer_header(int chan)
3362 {
3363 chans = 1;
3364 header_distributed = 0;
3365 data_location = 80;
3366 true_file_length = lseek(chan,0L,SEEK_END);
3367 data_size = (true_file_length-data_location);
3368 srate = 8000;
3369 data_format = SNDLIB_16_UNSIGNED_LITTLE_ENDIAN;
3370 if (hdrbuf[30]&2) chans=2;
3371 if (hdrbuf[30]&1)
3372 data_format = SNDLIB_UNSUPPORTED;
3373 else
3374 {
3375 if (hdrbuf[30]&4) data_format = SNDLIB_8_UNSIGNED; /* may be backwards -- using Convert 1.4 output here */
3376 }
3377 data_size = mus_bytes2samples(data_format,data_size);
3378 return(0);
3379 }
3380
3381
3382
3383 /* ------------------------------------ CSRE adf -------------------------------------
3384 *
3385 * Info from Stuart Rosen
3386 *
3387 * 0-7: CSRE40
3388 * 8: samples in file (long)
3389 * 12: center line(?) (long)
3390 * 16: start channel(?) (unsigned)
3391 * 18: bits -- 12 or 16 (unsigned) -- is 12 bit sample file packed?
3392 * 20: number system (0=signed, 1=unsigned)
3393 * 22: srate in kHz (float)
3394 * 26: peak sample in file (long) (can be 0)
3395 * 30-511: comment possibly
3396 *
3397 * probably always little-endian (S.R. reads each sample using sizeof(int) -> 16 bits I think)
3398 * if 12-bit unsigned we need to handle the offset somewhere
3399 */
3400
3401 static int read_adf_header(int chan)
3402 {
3403 int bits,numsys;
3404 lseek(chan,0,SEEK_SET);
3405 read(chan,hdrbuf,30);
3406 chans = 1;
3407 numsys = mus_little_endian_unsigned_short((unsigned char *)(hdrbuf+20));
3408 bits = mus_little_endian_unsigned_short((unsigned char *)(hdrbuf+18));
3409 if ((bits == 16) || (bits == 12))
3410 {
3411 if (numsys == 0)
3412 data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
3413 else data_format = SNDLIB_16_UNSIGNED_LITTLE_ENDIAN;
3414 }
3415 else data_format = SNDLIB_UNSUPPORTED;
3416 srate = (int)mus_little_endian_float((unsigned char *)(hdrbuf+22));
3417 data_size = mus_little_endian_int((unsigned char *)(hdrbuf+8));
3418 data_location = 512;
3419 true_file_length = lseek(chan,0L,SEEK_END);
3420 return(0);
3421 }
3422
3423
3424
3425 /* ------------------------------------ Diamondware -------------------------------------
3426 *
3427 * info from Keith Weiner at DiamondWare (www.dw.com):
3428 *
3429 * 0-22: DWD Header Byte "DiamondWare Digitized\n\0"
3430 * 23: 1A (EOF to abort printing of file)
3431 * 24: Major version number
3432 * 25: Minor version number
3433 * 26-29: Unique sound ID (checksum XOR timestamp)
3434 * 30: Reserved
3435 * 31: Compression type (0=none)
3436 * 32-33: Sampling rate (in Hz)
3437 * 34: Number of channels (1=mono, 2=stereo) (interleaved)
3438 * 35: Number of bits per sample (8, 16) (all data signed)
3439 * 36-37: Absolute value of largest sample in file
3440 * 38-41: length of data section (in bytes)
3441 * 42-45: # samples (16-bit stereo is 4 bytes/sample)
3442 * 46-49: Offset of data from start of file (in bytes)
3443 * 50-53: Reserved for future expansion (markers)
3444 * 54-55: Padding
3445 * 56:offset -- additional text: field=value
3446 * suggested fields: TITLE, ORGARTIST, GENRE, KEYWORDS, ORGMEDIUM, EDITOR, DIGITIZER, COMMENT, SUBJECT, COPYRIGHT, SOFTWARE, CREATEDATE
3447 *
3448 * since this is all Windows/DOS oriented, I'll assume little-endian byte order.
3449 */
3450
3451 static int read_diamondware_header(int chan)
3452 {
3453 lseek(chan,0,SEEK_SET);
3454 read(chan,hdrbuf,64);
3455 chans = hdrbuf[34];
3456 if (hdrbuf[31] == 0)
3457 {
3458 if (hdrbuf[35] == 8) data_format = SNDLIB_8_LINEAR;
3459 else data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN;
3460 }
3461 else data_format = SNDLIB_UNSUPPORTED;
3462 srate = mus_little_endian_unsigned_short((unsigned char *)(hdrbuf+32));
3463 data_size = mus_little_endian_int((unsigned char *)(hdrbuf+38));
3464 if (data_format != SNDLIB_UNSUPPORTED)
3465 data_size = mus_bytes2samples(data_format,data_size);
3466 data_location = mus_little_endian_int((unsigned char *)(hdrbuf+46));
3467 true_file_length = lseek(chan,0L,SEEK_END);
3468 return(0);
3469 }
3470
3471
3472 /* ------------------------------------ Comdisco SPW -------------------------------------
3473 * info from AFsp libtsp/AF/nucleus/AFgetSWpar.c
3474 *
3475 * header is text as in NIST:
3476 *
3477 * $SIGNAL_FILE 9\n (12 chars)
3478 * $USER_COMMENT
3479 * <comment line(s)>
3480 * $COMMON_INFO
3481 * SPW Version = 3.10
3482 * System Type = <machine> (e.g. "sun4","hp700")
3483 * Sampling Frequency = <Sfreq> (e.g. "8000")
3484 * Starting Time = 0
3485 * $DATA_INFO
3486 * Number of points = <Nsamp> (e.g. "2000")
3487 * Signal Type = <type> ("Double", "Float", "Fixed-point", "Integer", "Logical")
3488 * Fixed Point Format = <16,0,t> <16,16,t> <8,8,t> <8,0,t> (optional)
3489 * Complex Format = Real_Imag (optional)
3490 * $DATA <data_type> ("ASCII", "BINARY")
3491 *
3492 * the fixed point <n,m,b> is decoded as n=number of bits total per sample, m=integer bits, b=t: signed, u: unsigned
3493 * if $DATA ASCII, data is ascii text as in IEEE text files.
3494 * There are other complications as well. We'll just hack up a stop-gap until someone complains.
3495 */
3496
3497 static int read_comdisco_header (int chan)
3498 {
3499 /* need to grab a line at a time, call strcmp over and over. This is very tedious. */
3500 char *line = NULL;
3501 char portion[32];
3502 char value[32];
3503 int i,j,k,m,n,curend,commenting,offset,len,little,type;
3504 int happy = 1;
3505 k = 15;
3506 line = (char *)CALLOC(256,sizeof(char));
3507 little = 0;
3508 offset = 0;
3509 type = 0;
3510 curend = INITIAL_READ_SIZE;
3511 commenting = 0;
3512 while (happy)
3513 {
3514 for (i=0;i<256;i++)
3515 {
3516 if (k == curend)
3517 {
3518 offset += curend;
3519 read(chan,hdrbuf,HDRBUFSIZ);
3520 k = 0;
3521 curend = HDRBUFSIZ;
3522 }
3523 if (hdrbuf[k] == '\n') {k++; break;}
3524 line[i] = hdrbuf[k++];
3525 }
3526 line[i] = '\0';
3527 if ((strcmp(line,"$DATA BINARY") == 0) || (strcmp(line,"$DATA ASCII") == 0)) {happy = 0; data_location = offset+k;}
3528 if (strcmp(line,"$USER_COMMENT") == 0)
3529 {
3530 comment_start = offset+k;
3531 commenting = 1;
3532 }
3533 else
3534 {
3535 if (commenting)
3536 {
3537 if (line[0] == '$')
3538 {
3539 comment_end = offset+k-2-strlen(line);
3540 commenting = 0;
3541 }
3542 }
3543 }
3544 if (line[0] != '$')
3545 {
3546 len = strlen(line);
3547 for (j=0;j<8;j++) portion[j]=line[j];
3548 portion[8]='\0';
3549 for (j=8;j<len;j++) if (line[j] == '=') break;
3550 for (n=0,m=j+2;m<len;m++,n++) value[n]=line[m];
3551 value[n]='\0';
3552 if (strcmp(portion,"Sampling") == 0) sscanf(value,"%d",&srate); else
3553 if (strcmp(portion,"Number o") == 0) sscanf(value,"%d",&data_size); else
3554 if (strcmp(portion,"Signal T") == 0) {if (value[1] == 'o') type=2; else if (value[1] == 'l') type=1;} else
3555 if (strcmp(portion,"Fixed Po") == 0) {if (value[1] == '8') type=3;}
3556 }
3557 }
3558 /* now clean up this mess */
3559 chans = 1;
3560 header_distributed = 0;
3561 switch (type)
3562 {
3563 case 0: if (little) data_format = SNDLIB_16_LINEAR_LITTLE_ENDIAN; else data_format = SNDLIB_16_LINEAR; break;
3564 case 1: if (little) data_format = SNDLIB_32_FLOAT_LITTLE_ENDIAN; else data_format = SNDLIB_32_FLOAT; break;
3565 case 2: if (little) data_format = SNDLIB_64_DOUBLE_LITTLE_ENDIAN; else data_format = SNDLIB_64_DOUBLE; break;
3566 case 3: data_format = SNDLIB_8_LINEAR; break;
3567 }
3568 true_file_length = lseek(chan,0L,SEEK_END);
3569 FREE(line);
3570 return(0);
3571 }
3572
3573
3574 /* ------------------------------------ MS ASF -------------------------------------
3575 *
3576 * asf format is described at http://www.microsoft.com/asf/specs.htm
3577 * http://www.microsoft.com/asf/spec3/ASF0198ps.exe
3578 *
3579 * this header is completely insane
3580 */
3581
3582 static int read_asf_header (int chan)
3583 {
3584 /* a chunked data format, so not really acceptable here or elsewhere -- needs to be unchunked */
3585 int len,ilen = 0,i,j,asf_huge,present,bits = 0;
3586 /* apparently "huge" has some meaning in Windoze C */
3587 len = mus_little_endian_int((unsigned char *)(hdrbuf+16)); /* actually 64 bits */
3588 i = (128+64) / 8;
3589 asf_huge = 0;
3590 srate = 0;
3591 chans = 0;
3592 while (i<len)
3593 {
3594 seek_and_read(chan,(unsigned char *)hdrbuf,i,HDRBUFSIZ);
3595 if ((unsigned int)(hdrbuf[1]) == 0x29)
3596 switch (hdrbuf[0])
3597 {
3598 case 0xd0:
3599 asf_huge = (hdrbuf[((128+64+128+64+64+64+64+32)/8)] & 2);
3600 break;
3601 case 0xd4:
3602 present = ((hdrbuf[16+8+16+8+8+ 4+4+4+4+ 4+4] >> 3) & 0x3);
3603 if (present)
3604 j = 16+8+16+8+8+ 4+4+4+4+ 4+4+ 4+ (4+4+4) + 2;
3605 else j = 16+8+16+8+8+ 4+4+4+4+ 4+4+ 4+ 2;
3606 srate = mus_little_endian_int((unsigned char *)(hdrbuf+j+11+36));
3607 bits = mus_little_endian_int((unsigned char *)(hdrbuf+j+11+32));
3608 chans = mus_little_endian_unsigned_short((unsigned char *)(hdrbuf+j+65));
3609 original_data_format = mus_little_endian_int((unsigned char *)(hdrbuf+j+11));
3610 break;
3611 default: break;
3612 }
3613 ilen = mus_little_endian_int((unsigned char *)(hdrbuf+16));
3614 if (ilen <= 0) break;
3615 if ((chans>0) && (srate>0)) break;
3616 i+=ilen;
3617 }
3618 i=len;
3619 seek_and_read(chan,(unsigned char *)hdrbuf,i,HDRBUFSIZ);
3620 data_format = SNDLIB_UNSUPPORTED;
3621 if (((unsigned int)(hdrbuf[1]) == 0x29) && ((unsigned int)(hdrbuf[0]) == 0xd2))
3622 {
3623 ilen = mus_little_endian_int((unsigned char *)(hdrbuf+16));
3624 if (asf_huge) asf_huge=4; else asf_huge=2;
3625 data_location = i+20+asf_huge+2+4+3+1;
3626 if (bits == 0) bits=8;
3627 data_format = wave_to_sndlib_format(original_data_format,bits,1);
3628 }
3629 if (data_format != SNDLIB_UNSUPPORTED)
3630 data_size = mus_bytes2samples(data_format,(ilen - data_location));
3631 return(0);
3632 }
3633
3634
3635
3636 /* ------------------------------------ no header, Sound Designer II, SoundEdit, SoundEdit 16 -------------------------------------
3637 *
3638 * Sound Designer II data fork is a raw data file -- interleaved channels, bytes in sequence.
3639 * The associated resource fork under "STR " has "sample-size" "sample-rate" and "channels".
3640 * Similarly the resources "sdDD" id 1000, "sdML" id 1000, and "sdLL" id 1000 return pascal records of
3641 * respectively Document Data, Markers and text, Loop data. I don't see any useful info in any of these
3642 * except perhaps the file comment in the "sdDD" record of type str255 10 bytes in (I think).
3643 * See headers.lisp for a reader for some of this stuff.
3644 * file type: 'Sd2f'
3645 *
3646 * SoundEdit data fork contains 8-bit unsigned linear samples. The resource fork has:
3647 * REPT: 0: mouse pos
3648 * 4: length of sound in samples
3649 * 8: sample number of beginning of selection (if any)
3650 * 12: ditto end of selection
3651 * 16: ditto loopback beginning (if any)
3652 * 20: ditto loopback end
3653 * INFO: 0: nada
3654 * 8: "record frequency"
3655 * 12: ditto for playback
3656 * 16: compression mode: 0=none
3657 * 20: chans (0=mono, 1=stereo)
3658 * 24: window position
3659 * 28: sample rate: 1=22KHz, 2=11, 3=7, 4=5
3660 * 32: length of left channel in samples
3661 * 36: if stereo, ditto right channel
3662 * file type: 'FSDD', creator: 'SFX!'
3663 *
3664 * SoundEdit 16 data fork has either 8 or 16-bit linear unsigned samples. The resource fork has:
3665 * TRKS: 0: -7 (version number)
3666 * 4: track length in bytes
3667 * 8: track offset in samples
3668 * 12: left/right stereo
3669 * 16: track selected flag
3670 * 20: sample rate
3671 * 22: pstring -- track title (31 chars, fixed size)
3672 * 54: (?) gain
3673 * one TRKS resource for each track in the file
3674 * INFO: essentially the same as above, but with added version number at
3675 * 40: 0=SoundEdit, -2=SoundEdit 16
3676 * 44: reserved
3677 * 52: sample rate
3678 * and then other stuff that doesn't look interesting
3679 * LABS: 16: pstring (31 chars) track label
3680 * CUES: 0: sample location
3681 * 4: pstring (31 chars) cue point text
3682 * PReS: spectral stuff
3683 * PRnt: printer stuff
3684 * CLRS: colors stuff
3685 * REPT: same as above
3686 * file type: 'jB1 ', creator: 'jBox'.
3687 */
3688
3689 static int header_raw_srate = 44100;
3690 static int header_raw_chans = 2;
3691 static int header_raw_format = SNDLIB_16_LINEAR;
3692
3693 static int read_no_header (int chan)
3694 {
3695 srate = header_raw_srate;
3696 chans = header_raw_chans;
3697 data_format = header_raw_format;
3698 header_distributed = 0;
3699 data_location = 0;
3700 data_size = lseek(chan,0L,SEEK_END);
3701 true_file_length = data_size;
3702 data_size = mus_bytes2samples(data_format,data_size);
3703 return(0);
3704 }
3705
3706 void mus_set_raw_header_defaults(int sr, int chn, int frm)
3707 {
3708 header_raw_srate = sr;
3709 header_raw_chans = chn;
3710 header_raw_format = frm;
3711 }
3712
3713
3714 #ifdef MACOS
3715
3716 /* try to read SDII resources */
3717 /* apparently c2pstr or the reverse operate in place!! so we copy the strings first */
3718 #include <Resources.h>
3719 #include <Sound.h>
3720
3721 static int mus_resource(char *resname)
3722 {
3723 Handle sndH;
3724 OSErr err;
3725 char *val,*tmp;
3726 int rtn = -1;
3727 tmp = (char *)CALLOC(strlen(resname)+2,sizeof(char));
3728 strcpy(tmp,resname);
3729 sndH = GetNamedResource('STR ',(const unsigned char *)c2pstr(tmp));
3730 FREE(tmp);
3731 err = ResError();
3732 if ((err == noErr) && (sndH))
3733 {
3734 LoadResource(sndH);
3735 val = p2cstr((unsigned char *)(*sndH));
3736 sscanf(val,"%d",&rtn);
3737 ReleaseResource(sndH);
3738 }
3739 return(rtn);
3740 }
3741
3742 #endif
3743
3744
3745 /* ------------------------------------ all together now ------------------------------------ */
3746
3747 int mus_read_header_with_fd (int chan)
3748 {
3749 /* returns 0 on success (at least to the extent that we can report the header type), -1 for error */
3750 int i,happy,loc = 0;
3751 read(chan,hdrbuf,INITIAL_READ_SIZE);
3752 header_type = unsupported_sound_file;
3753 data_format = SNDLIB_UNSUPPORTED;
3754 comment_start = 0;
3755 comment_end = 0;
3756 if ((match_four_chars((unsigned char *)hdrbuf,I_DSND)) || (match_four_chars((unsigned char *)hdrbuf,I_DECN)))
3757 {
3758 header_type = NeXT_sound_file;
3759 return(read_next_header(chan));
3760 }
3761 if (match_four_chars((unsigned char *)hdrbuf,I_FORM))
3762 {
3763 /* next 4 bytes are apparently the file size or something equally useless */
3764 if (match_four_chars((unsigned char *)(hdrbuf+8),I_AIFF))
3765 {
3766 header_type = AIFF_sound_file;
3767 return(read_aiff_header(chan,0));
3768 }
3769 if (match_four_chars((unsigned char *)(hdrbuf+8),I_AIFC))
3770 {
3771 header_type = AIFC_sound_file;
3772 return(read_aiff_header(chan,0));
3773 }
3774 if (match_four_chars((unsigned char *)(hdrbuf+8),I_8SVX))
3775 {
3776 header_type = SVX_sound_file;
3777 return(read_8svx_header(chan));
3778 }
3779 if (match_four_chars((unsigned char *)(hdrbuf+8),I_MAUD))
3780 {
3781 header_type = MAUD_sound_file;
3782 return(read_maud_header(chan));
3783 }
3784 /* apparently SAMP here -> sampled audio data (?) */
3785 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"unrecognized header");
3786 return(-1); /* i.e. unknown FORM header */
3787 }
3788 if ((match_four_chars((unsigned char *)hdrbuf,I_RIFF)) || match_four_chars((unsigned char *)hdrbuf,I_RIFX))
3789 {
3790 if (match_four_chars((unsigned char *)(hdrbuf+8),I_WAVE))
3791 {
3792 header_type = RIFF_sound_file;
3793 return(read_riff_header(chan));
3794 }
3795 if (match_four_chars((unsigned char *)(hdrbuf+8),I_sfbk))
3796 {
3797 header_type = soundfont_sound_file;
3798 return(read_soundfont_header(chan));
3799 }
3800 if (match_four_chars((unsigned char *)(hdrbuf+8),I_AVI_))
3801 {
3802 header_type = AVI_sound_file;
3803 return(read_avi_header(chan));
3804 }
3805 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"unrecognized header");
3806 return(-1); /* unknown RIFF header */
3807 }
3808 if ((equal_big_or_little_endian((unsigned char *)hdrbuf,I_IRCAM_VAX)) ||
3809 (equal_big_or_little_endian((unsigned char *)hdrbuf,I_IRCAM_SUN)) ||
3810 (equal_big_or_little_endian((unsigned char *)hdrbuf,I_IRCAM_MIPS)) ||
3811 (equal_big_or_little_endian((unsigned char *)hdrbuf,I_IRCAM_NEXT)))
3812 {
3813 header_type = IRCAM_sound_file;
3814 return(read_ircam_header(chan));
3815 }
3816 if (match_four_chars((unsigned char *)hdrbuf,I_NIST))
3817 {
3818 header_type = NIST_sound_file;
3819 return(read_nist_header(chan));
3820 }
3821 if (match_four_chars((unsigned char *)hdrbuf,I_SOUN))
3822 {
3823 if ((match_four_chars((unsigned char *)(hdrbuf+4),I_SMP1)) && (match_four_chars((unsigned char *)(hdrbuf+8),I_SMP2)))
3824 {
3825 header_type = SMP_sound_file;
3826 return(read_smp_header(chan));
3827 }
3828 else
3829 {
3830 header_type = SNDT_sound_file;
3831 return(read_sndt_header(chan));
3832 }
3833 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"unrecognized header");
3834 return(-1);
3835 }
3836 if ((match_four_chars((unsigned char *)hdrbuf,I_VOC0)) && (match_four_chars((unsigned char *)(hdrbuf+4),I_VOC1)))
3837 {
3838 header_type = VOC_sound_file;
3839 return(read_voc_header(chan));
3840 }
3841 if (match_four_chars((unsigned char *)hdrbuf,I_AVR_))
3842 {
3843 header_type = AVR_sound_file;
3844 return(read_avr_header(chan));
3845 }
3846 if (mus_big_endian_short((unsigned char *)hdrbuf) == 1336)
3847 {
3848 header_type = SD1_sound_file;
3849 return(read_sd1_header(chan));
3850 }
3851 if ((match_four_chars((unsigned char *)hdrbuf,I_ALaw)) && (match_four_chars((unsigned char *)(hdrbuf+4),I_Soun)))
3852 {
3853 header_type = PSION_sound_file;
3854 return(read_psion_header(chan));
3855 }
3856 if ((match_four_chars((unsigned char *)hdrbuf,I_GF1P)) && (match_four_chars((unsigned char *)(hdrbuf+4),I_ATCH)))
3857 {
3858 header_type = gravis_sound_file;
3859 return(read_gravis_header(chan));
3860 }
3861 if ((match_four_chars((unsigned char *)hdrbuf,I_DSIG)) && (match_four_chars((unsigned char *)(hdrbuf+4),I_NAL_)))
3862 {
3863 header_type = comdisco_sound_file;
3864 return(read_comdisco_header(chan));
3865 }
3866 if ((match_four_chars((unsigned char *)hdrbuf,I_GOLD)) && (match_four_chars((unsigned char *)(hdrbuf+4),I__WAV)))
3867 {
3868 header_type = goldwave_sound_file;
3869 return(read_goldwave_header(chan));
3870 }
3871 if ((match_four_chars((unsigned char *)hdrbuf,I_Diam)) && (match_four_chars((unsigned char *)(hdrbuf+4),I_ondW)))
3872 {
3873 header_type = DiamondWare_sound_file;
3874 return(read_diamondware_header(chan));
3875 }
3876 if (match_four_chars((unsigned char *)hdrbuf,I_SRFS))
3877 {
3878 header_type = srfs_sound_file;
3879 return(read_srfs_header(chan));
3880 }
3881 if (match_four_chars((unsigned char *)hdrbuf,I_CSRE))
3882 {
3883 header_type = ADF_sound_file;
3884 return(read_adf_header(chan));
3885 }
3886 if ((hdrbuf[0] == 0xf0) && (hdrbuf[1] == 0x7e) && (hdrbuf[3] == 0x01))
3887 {
3888 header_type = MIDI_sample_dump;
3889 chans = 1;
3890 srate = srate = (int)(1.0e9 / (float)((hdrbuf[7] + (hdrbuf[8]<<7) + (hdrbuf[9]<<14))));
3891 data_size = (hdrbuf[10] + (hdrbuf[11]<<7) + (hdrbuf[12]<<14));
3892 /* since this file type has embedded blocks, we have to translate it elsewhere */
3893 return(0);
3894 }
3895 /* no recognized magic number at start -- poke around in possible header for other types */
3896 /* ESPS is either 0x00006a1a or 0x1a6a0000 at byte 16 */
3897 if (equal_big_or_little_endian((unsigned char *)(hdrbuf+16),0x00006a1a))
3898 {
3899 header_type = ESPS_sound_file;
3900 return(read_esps_header(chan));
3901 }
3902 lseek(chan,0,SEEK_SET);
3903 read(chan,hdrbuf,256);
3904 if ((hdrbuf[252]==64) && (hdrbuf[253]==195)) /* #o100 and #o303 */
3905 {
3906 header_type = SPPACK_sound_file;
3907 return(read_sppack_header(chan));
3908 }
3909 if ((match_four_chars((unsigned char *)(hdrbuf+65),I_FSSD)) && (match_four_chars((unsigned char *)(hdrbuf+128),I_HCOM)))
3910 {
3911 header_type = HCOM_sound_file;
3912 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"can't read HCOM header");
3913 return(-1);
3914 }
3915 happy = 0;
3916 for (i=0;i<NINRS;i++)
3917 {
3918 if (equal_big_or_little_endian((unsigned char *)hdrbuf,I_INRS[i]))
3919 {
3920 happy = 1;
3921 loc = inrs_srates[i];
3922 }
3923 }
3924 if (happy)
3925 {
3926 header_type = INRS_sound_file;
3927 return(read_inrs_header(chan,loc));
3928 }
3929 if (mus_big_endian_unsigned_int((unsigned char *)hdrbuf) == 0xAAAAAAAA)
3930 {
3931 header_type = MUS10_sound_file;
3932 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"can't read Mus10 header");
3933 return(-1);
3934 }
3935 if ((match_four_chars((unsigned char *)hdrbuf,I_SPIB)) || (match_four_chars((unsigned char *)hdrbuf,I_S___)))
3936 {
3937 header_type = IEEE_sound_file;
3938 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"can't read IEEE header");
3939 return(-1);
3940 }
3941 if (match_four_chars((unsigned char *)hdrbuf,I_DVSM))
3942 {
3943 header_type=DVSM_sound_file;
3944 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"can't read DVSM header");
3945 return(-1);
3946 }
3947 if (match_four_chars((unsigned char *)hdrbuf,I_Drat))
3948 {
3949 header_type=RealAudio_sound_file;
3950 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"can't read real audio header");
3951 return(-1);
3952 }
3953 if (match_four_chars((unsigned char *)hdrbuf,I_MThd))
3954 {
3955 header_type=MIDI_file;
3956 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"can't read Midi header");
3957 return(-1);
3958 }
3959 if ((match_four_chars((unsigned char *)hdrbuf,I_Esig)) && (match_four_chars((unsigned char *)(hdrbuf+4),I_nalc)))
3960 {
3961 header_type=Esignal_file;
3962 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"can't read Esignal header");
3963 return(-1);
3964 }
3965 if (match_four_chars((unsigned char *)hdrbuf,I_SND_))
3966 {
3967 header_type = SBStudioII_sound_file;
3968 return(read_sbstudio_header(chan));
3969 }
3970 if (match_four_chars((unsigned char *)hdrbuf,I_FSMt))
3971 {
3972 header_type = Farandole_sound_file;
3973 return(read_farandole_header(chan));
3974 }
3975 if (match_four_chars((unsigned char *)hdrbuf,I_SDXc))
3976 {
3977 header_type = Sample_dump_sound_file;
3978 return(read_sample_dump_header(chan));
3979 }
3980 if (match_four_chars((unsigned char *)hdrbuf,I_DDSF))
3981 {
3982 header_type = Delusion_sound_file;
3983 return(read_delusion_header(chan));
3984 }
3985 if (match_four_chars((unsigned char *)hdrbuf,I_LM89))
3986 {
3987 header_type = Yamaha_TX16_sound_file;
3988 return(read_tx16_header(chan));
3989 }
3990 if (match_four_chars((unsigned char *)hdrbuf,I_SY85))
3991 {
3992 header_type = Yamaha_SY85_sound_file;
3993 return(read_sy85_header(chan));
3994 }
3995 if (match_four_chars((unsigned char *)hdrbuf,I_SY80))
3996 {
3997 header_type = Yamaha_SY99_sound_file;
3998 return(read_sy85_header(chan));
3999 }
4000 if (match_four_chars((unsigned char *)hdrbuf,I_PRAM))
4001 {
4002 header_type = Kurzweil_2000_sound_file;
4003 return(read_kurzweil_2000_header(chan));
4004 }
4005 if (match_four_chars((unsigned char *)(hdrbuf+35),I_UWFD))
4006 {
4007 header_type = Ultratracker_sound_file;
4008 return(read_ultratracker_header(chan));
4009 }
4010 if (match_four_chars((unsigned char *)(hdrbuf+76),I_SCRS))
4011 {
4012 header_type = digiplayer_sound_file;
4013 return(read_digiplayer_header(chan));
4014 }
4015 if (match_four_chars((unsigned char *)hdrbuf,I_covox))
4016 {
4017 header_type = Covox_sound_file;
4018 return(read_covox_header(chan));
4019 }
4020 if (match_four_chars((unsigned char *)hdrbuf,I_DSPL))
4021 {
4022 header_type = SPL_sound_file;
4023 return(read_spl_header(chan));
4024 }
4025 if (mus_big_endian_short((unsigned char *)hdrbuf) == 0x1A00)
4026 {
4027 header_type = DeskMate_sound_file;
4028 return(read_deskmate_header(chan));
4029 }
4030 if (mus_big_endian_short((unsigned char *)(hdrbuf+44)) == 0x1A80)
4031 {
4032 header_type = DeskMate_2500_sound_file;
4033 return(read_deskmate_2500_header(chan));
4034 }
4035 #ifdef SNDLIB_LITTLE_ENDIAN
4036 if (mus_uninterpreted_int((unsigned char *)hdrbuf) == 0x01000800)
4037 #else
4038 if (mus_uninterpreted_int((unsigned char *)hdrbuf) == 0x00080001)
4039 #endif
4040 {
4041 header_type = ADC_sound_file;
4042 return(read_adc_header(chan));
4043 }
4044
4045 if ((match_four_chars((unsigned char *)hdrbuf,I_ones)) &&
4046 (match_four_chars((unsigned char *)(hdrbuf+12),I_FORM)))
4047 {
4048 /* possibly an OMF file with an embedded AIFF data file -- this is just a guess... */
4049 header_type = OMF_sound_file;
4050 return(read_aiff_header(chan,12));
4051 /* another (apparently) along these lines is TOC */
4052 }
4053
4054 if ((match_four_chars((unsigned char *)hdrbuf,I_zeros)) &&
4055 (match_four_chars((unsigned char *)(hdrbuf+4),I_mdat)))
4056 {
4057 /* possibly quicktime?? */
4058 header_type = Quicktime_sound_file;
4059 return(read_qt_header(chan));
4060 }
4061
4062 if ((match_four_chars((unsigned char *)hdrbuf,I_asf0)) &&
4063 (match_four_chars((unsigned char *)(hdrbuf+4),I_asf1)) &&
4064 (match_four_chars((unsigned char *)(hdrbuf+8),I_asf2)) &&
4065 (match_four_chars((unsigned char *)(hdrbuf+12),I_asf3)))
4066 {
4067 header_type = asf_sound_file;
4068 return(read_asf_header(chan));
4069 }
4070
4071 header_type = raw_sound_file;
4072 return(read_no_header(chan));
4073 }
4074
4075 int mus_read_header (char *name)
4076 {
4077 int chan,err = 0;
4078 #ifdef MACOS
4079 int loc,happy;
4080 char *dupname;
4081 #endif
4082 chan = mus_open_read(name);
4083 if (chan == -1) return(-1);
4084 err = mus_read_header_with_fd(chan);
4085
4086 #ifdef MACOS
4087 /* on the Mac, we should look for the resource fork. */
4088 /* we'll at least check SDII possibilities */
4089 /* if I had an example of SoundEdit output, I'd add support for that too */
4090
4091 if (header_type == raw_sound_file)
4092 {
4093 dupname = (char *)CALLOC(strlen(name)+2,sizeof(char));
4094 strcpy(dupname,name);
4095 loc = OpenResFile((const unsigned char *)c2pstr(dupname));
4096 FREE(dupname);
4097 if (loc != -1)
4098 {
4099 happy = mus_resource("channels");
4100 if (happy != -1)
4101 {
4102 /* found an SDII file?!? */
4103 chans = happy;
4104 srate = mus_resource("sample-rate");
4105 happy = mus_resource("sample-size");
4106 if (happy == 1)
4107 data_format = SNDLIB_8_UNSIGNED;
4108 else data_format = SNDLIB_16_LINEAR;
4109 data_size = mus_bytes2samples(data_format,true_file_length);
4110 header_type = SD2_sound_file;
4111 }
4112 CloseResFile(loc);
4113 }
4114 }
4115 /* we could also check the file type:
4116 * FInfo fi;
4117 * err = GetFInfo((const unsigned char *)c2pstr(name),fd,&fi);
4118 * if (err == noErr) <check fi.fdType against possibiliites given above>
4119 */
4120
4121 #endif
4122
4123 close(chan);
4124 return(err);
4125 }
4126
4127 int mus_write_header_with_fd (int chan, int type, int in_srate, int in_chans, int loc, int size, int format, char *comment, int len)
4128 {
4129 int siz;
4130 siz = mus_samples2bytes(format,size);
4131 switch (type)
4132 {
4133 case NeXT_sound_file: return(mus_write_next_header(chan,in_srate,in_chans,loc,siz,format,comment,len)); break;
4134 case AIFC_sound_file: return(write_aif_header(chan,in_srate,in_chans,siz,format,comment,len,1)); break;
4135 case AIFF_sound_file: return(write_aif_header(chan,in_srate,in_chans,siz,format,comment,len,0)); break;
4136 case RIFF_sound_file: return(write_riff_header(chan,in_srate,in_chans,siz,format,comment,len)); break;
4137 case IRCAM_sound_file: return(write_ircam_header(chan,in_srate,in_chans,format,comment,len)); break;
4138 case NIST_sound_file: return(write_nist_header(chan,in_srate,in_chans,siz,format)); break;
4139 case raw_sound_file:
4140 data_location = 0;
4141 data_size = mus_bytes2samples(format,siz);
4142 srate = in_srate;
4143 chans = in_chans;
4144 header_type = raw_sound_file;
4145 data_format = format;
4146 break;
4147 default:
4148 {
4149 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"can't write %s header",mus_header_type2string(type));
4150 return(-1);
4151 break;
4152 }
4153 }
4154 return(0);
4155 }
4156
4157 int mus_write_header (char *name, int type, int in_srate, int in_chans, int loc, int size, int format, char *comment, int len)
4158 {
4159 int chan,err;
4160 chan = mus_create(name);
4161 if (chan == -1) return(-1);
4162 err = mus_write_header_with_fd(chan,type,in_srate,in_chans,loc,size,format,comment,len);
4163 close(chan);
4164 return(err);
4165 }
4166
4167 int mus_update_header_with_fd(int chan, int type, int size)
4168 {
4169 /* do not export unless you remember that size here is in bytes! */
4170 lseek(chan,0L,SEEK_SET);
4171 switch (type)
4172 {
4173 case NeXT_sound_file: update_next_header(chan,size); break;
4174 case AIFC_sound_file: case AIFF_sound_file: update_aiff_header(chan,size); break;
4175 case RIFF_sound_file: update_riff_header(chan,size); break;
4176 case IRCAM_sound_file: update_ircam_header(); break;
4177 case NIST_sound_file: update_nist_header(chan,size); break;
4178 case raw_sound_file: break;
4179 default:
4180 {
4181 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"can't udpate %s header",mus_header_type2string(type));
4182 return(-1);
4183 break;
4184 }
4185 }
4186 return(0);
4187 }
4188
4189 int mus_update_header (char *name, int type, int size, int srate, int format, int chans, int loc)
4190 {
4191 int chan,siz,err;
4192 chan = mus_reopen_write(name);
4193 if (chan == -1) return(-1);
4194 siz = mus_samples2bytes(format,size);
4195 err = mus_update_header_with_fd(chan,type,siz);
4196 if (type == NeXT_sound_file)
4197 {
4198 if (srate != 0)
4199 {
4200 lseek(chan,16L,SEEK_SET);
4201 mus_set_big_endian_int((unsigned char *)hdrbuf,srate);
4202 write(chan,hdrbuf,4);
4203 }
4204 if (chans != 0)
4205 {
4206 lseek(chan,20L,SEEK_SET);
4207 mus_set_big_endian_int((unsigned char *)hdrbuf,chans);
4208 write(chan,hdrbuf,4);
4209 }
4210 if (loc != 0)
4211 {
4212 lseek(chan,4L,SEEK_SET);
4213 mus_set_big_endian_int((unsigned char *)hdrbuf,loc);
4214 write(chan,hdrbuf,4);
4215 }
4216 }
4217 close(chan);
4218 return(err);
4219 }
4220
4221 int mus_update_header_comment (char *name, int loc, char *comment, int len, int typ)
4222 {
4223 int chan;
4224 chan = mus_reopen_write(name);
4225 if (chan == -1) return(-1);
4226 switch (typ)
4227 {
4228 case NeXT_sound_file: update_next_header_comment(chan,loc,comment,len); break;
4229 case AIFC_sound_file: case AIFF_sound_file: update_aiff_header_comment(chan,comment,len); break;
4230 case RIFF_sound_file: update_riff_header_comment(chan,comment,len); break;
4231 case raw_sound_file: break;
4232 default:
4233 {
4234 mus_error(MUS_UNSUPPORTED_HEADER_TYPE,"can't udpate %s header comment",mus_header_type2string(typ));
4235 return(-1);
4236 break;
4237 }
4238 }
4239 return(0);
4240 }
4241
4242 int mus_header_writable(int type, int format) /* -2 to ignore format for this call */
4243 {
4244 switch (type)
4245 {
4246 case NeXT_sound_file:
4247 if (format == -2) return(1);
4248 switch (format)
4249 {
4250 case SNDLIB_8_MULAW: case SNDLIB_8_LINEAR: case SNDLIB_16_LINEAR: case SNDLIB_24_LINEAR:
4251 case SNDLIB_32_LINEAR: case SNDLIB_32_FLOAT: case SNDLIB_64_DOUBLE: case SNDLIB_8_ALAW:
4252 case SNDLIB_32_LINEAR_LITTLE_ENDIAN:
4253 return(1); break;
4254 default:
4255 return(0); break;
4256 }
4257 break;
4258 case NIST_sound_file:
4259 if (format == -2) return(1);
4260 switch (format)
4261 {
4262 case SNDLIB_8_LINEAR: case SNDLIB_16_LINEAR: case SNDLIB_24_LINEAR: case SNDLIB_32_LINEAR:
4263 case SNDLIB_16_LINEAR_LITTLE_ENDIAN: case SNDLIB_24_LINEAR_LITTLE_ENDIAN: case SNDLIB_32_LINEAR_LITTLE_ENDIAN:
4264 return(1); break;
4265 default:
4266 return(0); break;
4267 }
4268 break;
4269 case AIFC_sound_file:
4270 if (format == -2) return(1);
4271 switch (format)
4272 {
4273 case SNDLIB_16_LINEAR: case SNDLIB_24_LINEAR: case SNDLIB_32_LINEAR:
4274 case SNDLIB_8_LINEAR: case SNDLIB_8_MULAW: case SNDLIB_8_ALAW:
4275 case SNDLIB_32_FLOAT: case SNDLIB_64_DOUBLE: case SNDLIB_8_UNSIGNED: case SNDLIB_16_UNSIGNED:
4276 case SNDLIB_16_LINEAR_LITTLE_ENDIAN: case SNDLIB_24_LINEAR_LITTLE_ENDIAN: case SNDLIB_32_LINEAR_LITTLE_ENDIAN:
4277 return(1);
4278 break;
4279 default:
4280 return(0);
4281 break;
4282 }
4283 break;
4284 case AIFF_sound_file:
4285 if (format == -2) return(1);
4286 switch (format)
4287 {
4288 case SNDLIB_16_LINEAR: case SNDLIB_24_LINEAR: case SNDLIB_32_LINEAR: case SNDLIB_8_LINEAR:
4289 return(1);
4290 break;
4291 default:
4292 return(0);
4293 break;
4294 }
4295 break;
4296 case RIFF_sound_file:
4297 if (format == -2) return(1);
4298 switch (format)
4299 {
4300 case SNDLIB_8_MULAW: case SNDLIB_8_ALAW: case SNDLIB_8_UNSIGNED: case SNDLIB_32_FLOAT_LITTLE_ENDIAN:
4301 case SNDLIB_16_LINEAR_LITTLE_ENDIAN: case SNDLIB_24_LINEAR_LITTLE_ENDIAN: case SNDLIB_32_LINEAR_LITTLE_ENDIAN:
4302 return(1);
4303 break;
4304 default:
4305 return(0);
4306 break;
4307 }
4308 break;
4309 case IRCAM_sound_file:
4310 if (format == -2) return(1);
4311 switch (format)
4312 {
4313 case SNDLIB_8_MULAW: case SNDLIB_8_ALAW: case SNDLIB_16_LINEAR: case SNDLIB_32_LINEAR: case SNDLIB_32_FLOAT:
4314 return(1);
4315 break;
4316 default:
4317 return(0);
4318 break;
4319 }
4320 break;
4321 case raw_sound_file:
4322 return(format != SNDLIB_32_VAX_FLOAT); /* the only type we don't write */
4323 break;
4324 default: return(0); break;
4325 }
4326 return(0);
4327 }
4328
4329
4330
4331 /* ------------------------------------------------------------------------
4332 * old Mus10, SAM formats, just for completeness
4333 *
4334 * These were used for sound data on the PDP-10s at SAIL and CCRMA in the 70's and 80's.
4335 * The word length was 36-bits. (SAM here refers to the Samson box, the Systems Concepts
4336 * Digital Synthesizer, built by Peter Samson), not the SAM format associated (apparently)
4337 * with ModEdit.
4338 *
4339 * "New" format as used by nearly all CCRMA software pre-1990:
4340 *
4341 * WD 0 - '525252525252 (chosen because "it is unlikely to occur at random"!)
4342 * WD 1 - Clock rate in Hz (PDP-10 36-bit floating point)
4343 * PDP-10 floating point format was sign in bit 0, excess 128 exponent in 1-8, fraction in 9-35
4344 * WD 2 - #samples per word,,pack-code, (has # samples per word in LH, pack-code in RH)
4345 * 0 for 12-bit fixed point (this was the main one)
4346 * 1 for 18-bit fixed point
4347 * 2 for 9-bit floating point incremental (never used)
4348 * 3 for 36-bit floating point (never used)
4349 * 4 for 16-bit sambox fixed point, right justified
4350 * 5 for 20-bit sambox fixed point
4351 * 6 for 20-bit right-adjusted fixed point (sambox SAT format=SAM output)
4352 * 7 for 16-bit fixed point, left justified (never used)
4353 * N>9 for N bit bytes in ILDB format (never used)
4354 * WD 3 - # channels
4355 * WD 4 - Maximum amplitude (if known) (PDP-10 float)
4356 * WD 5 - number of Sambox ticks per pass (inverse of Sambox clock rate, sort of)
4357 * WD 6 - Total #samples in file. If 0 then #wds_in_file*#samps_per_wd assumed.
4358 * WD 7 - Block size (if any). 0 means sound is not blocked.
4359 * WDs '10-'77 Reserved for EDSND usage, but I used it anyway.
4360 * WDs '100-'177 Text description of file (in ASCIZ format) (ASCIZ=ASCII+null if I remember right = C string(?))
4361 *
4362 * "Old" format (pre-1977)
4363 *
4364 * WD 0 - '525252525252
4365 * WD 1 - Clock rate => rate as integer,,code
4366 * code=0 for 6.4Kc (or anything else)
4367 * =1 for 12.8Kc, =2 for 25.6Kc, =3 for 51.2Kc
4368 * =5 for 102.4Kc, =6 for 204.8Kc
4369 * WD 2 - #sample per word,,pack
4370 * 0 for 12 bit
4371 * 1 for 16 bit (18 bit)
4372 * 2 for 9 bit floating point incremental
4373 * 3 for 36-bit floating point
4374 * N>9 for N bit bytes in ILDB format
4375 * WD 3 - # channels
4376 * WD 4 - Maximum amplitude (if known, otherwise 0)
4377 * WDs 5-77 Reserved for future expansion
4378 * WDs 100-177 Text description of file (in ASCIZ format)
4379 *
4380 * ------------------------------------
4381 * and even more esoteric... from the MIT PDP-6 (1971-76):
4382 * JRST 1
4383 * 0
4384 * blkcnt,,2000
4385 * duration,, --- ; negative halfword number to be counted down for duration
4386 * v0 v1 v2 v3 v4 v5 ; 6 six-bit byes, each encoding pitch no. from 2.-63, 63 not used
4387 * duration,, --
4388 * v0 v1 v2 v3 v4 v5
4389 * ...
4390 * checksum
4391 * ...
4392 * blkcnt,,blkaddr ; neg half word in block, not counting itself or checksum,,addr of block start
4393 * ...
4394 * 0,,--
4395 * 0
4396 * checksum ;=ROT 1 and ADD including blkcnt,,blkaddr
4397 * -1,,41
4398 * JRST 101
4399 * checksum
4400 * -1,,41
4401 * JRST 101
4402 * checksum
4403 * JUMPA 101
4404 * JUMPA 101
4405 *
4406 * ah, the good old days...
4407 */
4408
4409 #if 0
4410 One supported sample type is the DVSM-Format of the programs WinRec, WinCut
4411 and Fortune. Those are programs for the ATARI FALCON.
4412
4413 A DVSM sample file has the following structure:
4414
4415 char magic[6]; /* "DVSM" */
4416 int headlen; /* Headlen in Bytes*/
4417 int freq; /* Sample freqency 0=8kHz 7=50kHz*/
4418 char pack; /* 0 unpacked, 2=DVS packmethod*/
4419 char mode; /* 0=Stereo 8Bit,1=Stereo 16Bit,2=Mono 8Bit,3=Mono 16*/
4420 long blocklen; /* if pack>0: Length of a packed block*/
4421
4422 followed by cookies and the sound data.
4423
4424 The sample frequencies 0 to 7 correspond to the following frequencies:
4425 sam_freq[8]={8195,9834,12292,16390,19668,24585,32778,49170};
4426 For further information refer to the WinRec documentation or take a look at
4427 the article series 'Sound Sample Formate' in the german magazin ST Computer
4428 (3/94 - 6/94).
4429
4430 Confusingly enough there also appears to be a DVMS header (see sox11 cvsd.c)
4431 struct dvms_header {
4432 char Filename[14];
4433 unsigned Id;
4434 unsigned State;
4435 time_t Unixtime;
4436 unsigned Usender;
4437 unsigned Ureceiver;
4438 ULONG Length;
4439 unsigned Srate;
4440 unsigned Days;
4441 unsigned Custom1;
4442 unsigned Custom2;
4443 char Info[16];
4444 char extend[64];
4445 unsigned Crc;
4446 };
4447 #define DVMS_HEADER_LEN 120
4448
4449 #endif
4450
4451 #if 0
4452 /*
4453 SCRIBE is headerless, 16-bit little endian data
4454
4455 (Hidden Markov Model ToolKit output -- obscure!)
4456 HTK format files consist of a contiguous sequence of samples preceded by a header. Each sample is a vector of either 2-byte
4457 integers or 4-byte floats. 2-byte integers are used for compressed forms as described below and for vector quantised data as
4458 described later in section 5.11. HTK format data files can also be used to store speech waveforms as described in section 5.8.
4459
4460 The HTK file format header is 12 bytes long and contains the following data
4461 nSamples -- number of samples in file (4-byte integer)
4462 sampPeriod -- sample period in 100ns units (4-byte integer)
4463 sampSize -- number of bytes per sample (2-byte integer)
4464 parmKind -- a code indicating the sample kind (2-byte integer)
4465
4466 The parameter kind consists of a 6 bit code representing the basic parameter kind plus additional bits for each of the possible
4467 qualifiers . The basic parameter kind codes are
4468
4469 0 WAVEFORM sampled waveform
4470 1 LPC linear prediction filter coefficients
4471 2 LPREFC linear prediction reflection coefficients
4472 3 LPCEPSTRA LPC cepstral coefficients
4473 4 LPDELCEP LPC cepstra plus delta coefficients
4474 5 IREFC LPC reflection coef in 16 bit integer format
4475 6 MFCC mel-frequency cepstral coefficients
4476 7 FBANK log mel-filter bank channel outputs
4477 8 MELSPEC linear mel-filter bank channel outputs
4478 9 USER user defined sample kind
4479 10 DISCRETE vector quantised data
4480
4481 and the bit-encoding for the qualifiers (in octal) is
4482 _E 000100 has energy
4483 _N 000200 absolute energy suppressed
4484 _D 000400 has delta coefficients
4485 _A 001000 has acceleration coefficients
4486 _C 002000 is compressed
4487 _Z 004000 has zero mean static coef.
4488 _K 010000 has CRC checksum
4489 _O 020000 has 0'th cepstral coef.
4490 */
4491 #endif
4492
4493 #if 0
4494 /*
4495 Esignal starts with 48 byte ASCII preamble:
4496
4497 "Esignal"\n
4498 7 byte version id\n
4499 7 byte left padded data format choice (i.e. " EDR1", EDR2, ASCII, or machine name) EDR1=4byte ints, EDR2=8 byte longs\n
4500 7 byte preamble size (i.e. " 48")\n
4501 7 byte left padded header size (bytes, includes preamble)\n
4502 7 byte left padded record size\n
4503
4504 for example:
4505 Esignal
4506 0.0B
4507 ASCII
4508 48
4509 502
4510 -1
4511
4512 default formats are big endian ints and shorts, IEEE floats
4513
4514 array desc:
4515 short data type code
4516 short rank (i.e. nchans in this context I guess)
4517 long dimensions (i.e. sample number? -- rank of these)
4518 <data>
4519
4520 type codes:
4521 1 NO_TYPE 10 UCHAR
4522 2 ARRAY 11 BOOL
4523 3 DOUBLE 12 DOUBLE_COMPLEX
4524 4 FLOAT 13 FLOAT_COMPLEX
4525 5 LONG 14 LONG_COMPLEX
4526 6 ULONG 15 SHORT_COMPLEX
4527 7 SHORT 16 SCHAR_COMPLEX
4528 8 USHORT 17 CHAR
4529 9 SCHAR 18 WCHAR
4530
4531 here's a simple example:
4532
4533 PREAMBLE
4534 0 45 73 69 67 6e 61 6c 0a "Esignal\n" "magic number"
4535 8 20 20 20 30 2e 30 42 0a " 0.0B\n" version
4536 16 20 20 20 45 44 52 31 0a " EDR1\n" architecture
4537 24 20 20 20 20 20 34 38 0a " 48\n" preamble size
4538 32 20 20 20 20 32 38 35 0a " 285\n" header size
4539 40 20 20 20 20 20 20 32 0a " 2\n" record size
4540 START OF FIELD LIST
4541 48 00 00 00 04 4 number of fields
4542 FIRST FIELD: commandLine
4543 52 00 00 00 0b 11 length of name
4544 56 63 6f 6d 6d 61 6e 64 4c "commandL" field name
4545 64 69 6e 65 "ine" ...
4546 67 00 11 17 (CHAR) data type
4547 69 00 01 1 number of dimensions
4548 71 00 00 00 11 17 dimension
4549 75 00 00 00 00 0 length of units
4550 79 3f f0 00 00 00 00 00 00 1.0 scale
4551 87 00 00 00 00 00 00 00 00 0.0 offset
4552 95 00 00 00 00 0 number of axis names
4553 99 00 01 1 (GLOBAL) occurrence class
4554 101 45 72 65 63 6f 72 64 20 "Erecord " data
4555 109 73 70 65 65 63 68 2e 73 "speech.s" ...
4556 117 64 "d" ...
4557 118 00 00 00 00 0 number of subfields
4558 SECOND FIELD: startTime
4559 122 00 00 00 09 9 length of name
4560 126 73 74 61 72 74 54 69 6d "startTim" field name
4561 134 65 "e" ...
4562 135 00 03 3 (DOUBLE) data type
4563 137 00 00 0 number of dimensions
4564 139 00 00 00 01 1 length of units
4565 143 73 "s" units
4566 144 3f f0 00 00 00 00 00 00 1.0 scale
4567 152 00 00 00 00 00 00 00 00 0.0 offset
4568 160 00 00 00 00 0 number of axis names
4569 164 00 01 1 (GLOBAL) occurrence class
4570 166 00 00 00 00 00 00 00 00 0.0 data
4571 174 00 00 00 00 0 number of subfields
4572 THIRD FIELD: recordFreq
4573 178 00 00 00 0a 10 length of name
4574 182 72 65 63 6f 72 64 46 72 "recordFr" field name
4575 190 65 71 "eq"
4576 192 00 03 3 (DOUBLE) data type
4577 194 00 00 0 number of dimensions
4578 196 00 00 00 02 2 length of units
4579 200 48 7a "Hz" units
4580 202 3f f0 00 00 00 00 00 00 1.0 scale
4581 210 00 00 00 00 00 00 00 00 0.0 offset
4582 218 00 00 00 00 0 number of axis names
4583 222 00 01 1 (GLOBAL) occurrence class
4584 224 40 bf 40 00 00 00 00 00 8000.0 data
4585 232 00 00 00 00 0 number of subfields
4586 FOURTH FIELD: samples
4587 236 00 00 00 07 7 length of name
4588 240 73 61 6d 70 6c 65 73 "samples" field name
4589 247 00 07 7 (SHORT) data type
4590 249 00 01 1 number of dimensions
4591 251 00 00 00 01 1 dimension
4592 255 00 00 00 00 0 length of units
4593
4594 so we might 'read' these guys by getting the header length from the preamble,
4595 and the data type by searching blindly for "samples" followed by the type
4596 indication, then just guess at a sampling rate.
4597 */
4598 #endif
4599
4600 #if 0
4601 /* MIME uses base64 encoding which is something like: */
4602 int decode_char (unsigned char c)
4603 {
4604 if (isupper (c)) return(c - 'A');
4605 else if (islower (c)) return(c - 'a' + 26);
4606 else if (isdigit (c)) return(c - '0' + 52);
4607 else if (c == '+') return(62);
4608 else if (c == '/') return(63);
4609 return(0);
4610 }
4611
4612 from_base64(char* cs, int *buf)
4613 {
4614 /* assume we grab 4 chars and set 3 ints on each call */
4615 int dc1,dc2,dc3,dc4;
4616 dc1=decode_char(cs[0]); dc2=decode_char(cs[1]); dc3=decode_char(cs[2]); dc4=decode_char(cs[3]);
4617 buf[0]=((dc1<<2) | (dc2>>4)); buf[1]=(((dc2&0xf)<<4) | (dc3>>2)); buf[2]=(((dc3&0x3)<<6) | dc4);
4618 }
4619 #endif
4620
4621 /* ILS headers (info from P Kabal): Interactive Laboratory System.
4622 * in 1988 info from ils@hub.ucsb.edu
4623 * v4 is in longs, v3 in shorts
4624 * data is 16-bit linear (probably big-endian) (locs below are in version format)
4625 * 0: #pts in analysis window, 1: #autoregressive coeffs, 2: preemphasis, 3: shift per frame, 4: hamming if 'y'
4626 * 5: #data blocks, 6: #resonances, 7: start frame, 8: #frames, 9: start sector, 10: #autoregressive coeffs
4627 * 11: #pts past whole block, 12-15: 'field chars', 16: #frames, 17: autoreg flag, 18: #disk num of file
4628 * 19: another disk number, 20: analysis mnemonic, 22-26: id chars, 35-36: scaling mult, 37-38: scaling adder
4629 * 57: starting chan, 58: #chans, 59: mulaw if 50, 60: power of ten mult for sampling freq, 61: int srate,
4630 * 62: -29000 if not sampled, -32000 if sampled, 63: 32149 if initialized.
4631 * 128: data starts (or 256 in v3, I think) -- byte 512 in any case.
4632 */
4633
4634 /* for MIDI and Synth-related formats by the dozen see http://www.wotsit.org/music.htm */
4635
4636 /*
4637 * real audio: http://www1.real.com/devzone/sdks/rmsdk/guide/index.html
4638 */
4639 /*
4640 {
4641 int i;
4642 lseek(chan,0,SEEK_SET);
4643 read(chan,hdrbuf,HDRBUFSIZ);
4644 for (i=0;i<HDRBUFSIZ;i++)
4645 {
4646 fprintf(stderr,"%d: %d %c %d %d %d %d\n",
4647 i,
4648 hdrbuf[i],hdrbuf[i],
4649 mus_little_endian_short((unsigned char *)(hdrbuf+i)),
4650 mus_big_endian_short((unsigned char *)(hdrbuf+i)),
4651 mus_little_endian_int((unsigned char *)(hdrbuf+i)),
4652 mus_big_endian_int(unsigned char *)(hdrbuf+i));
4653 }
4654 }
4655 */
4656 /* from /usr/share/magic:
4657 # Real Audio (Magic .ra\0375)
4658 0 belong 0x2e7261fd realaudio sound file
4659 0 string .RMF\0\0\0 realmedia file
4660 */