1 /* readers/writers for various sound file headers
2  *
3  * Currently supported read/write (in standard sample types):
4  *      NeXT/Sun/DEC/AFsp
5  *      AIFF/AIFC
6  *      RIFF (microsoft wave)
7  *      RF64 (EBU)
8  *      IRCAM (old style)
9  *      NIST-sphere
10  *      CAFF
11  *      no header
12  *
13  * Currently supported read-only (in selected sample types):
14  *      8SVX (IFF), EBICSF, INRS, ESPS, SPPACK, ADC (OGI), AVR, VOC, CSL, snack "SMP", PVF,
15  *      Sound Tools, Turtle Beach SMP, SoundFont 2.0, Sound Designer I, PSION alaw, MAUD,
16  *      Gravis Ultrasound, Comdisco SPW, Goldwave sample, OMF, quicktime, sox,
17  *      Sonic Foundry (w64), SBStudio II, Delusion digital, Digiplayer ST3, Farandole Composer WaveSample,
18  *      Ultratracker WaveSample, Sample Dump exchange, Yamaha SY85 and SY99 (buggy), Yamaha TX16W,
19  *      Covox v8, AVI, Kurzweil 2000, Paris Ensoniq, Impulse tracker, Korg, Akai type 4, Maui,
20  *
21  * for a few of these I'm still trying to get documentation -- best sources of info are:
22  *     ftp.cwi.nl:pub/audio (info files)
23  *     the AFsp sources http://www.TSP.ECE.McGill.CA/MMSP/Documents/AudioFormats/index.html
24  *     the SOX sources
25  *     svr-ftp.eng.cam.ac.uk:/comp.speech/tools
26  *     http://www.wotsit.org
27  *     CAFF: http://developer.apple.com/documentation/MusicAudio/Reference/CAFSpec/
28  *           and afconvert can be found in /Developer/Examples/CoreAudio/Services/AudioFileTools/
29  *     RIFF: Microsoft Multimedia Programmer's Reference Manual at ftp.microsoft.com:/SoftLib/MSLFILES/MDRK.EXE
30  *     AVI: http://www.rahul.net/jfm/avi.html
31  *     EBU RF64: http://www.ebu.ch/CMSimages/en/tec_doc_t3306_tcm6-42570.pdf
32  *     Sound Designer: "Developer Documentation" from Digidesign
33  *
34  * test cases (sample files): ccrma-ftp.stanford.edu:/pub/Lisp/sf.tar.gz
35  */
36 
37 #include "mus-config.h"
38 
39 #if USE_SND
40   #include "snd.h"
41 #endif
42 
43 #include <math.h>
44 #include <stdio.h>
45 #include <errno.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #ifndef _MSC_VER
49   #include <unistd.h>
50 #else
51   #include <io.h>
52   #pragma warning(disable: 4244)
53 #endif
54 #include <stdint.h>
55 #include <inttypes.h>
56 
57 #include "_sndlib.h"
58 #include "sndlib-strings.h"
59 
60 
61 /* can't use LONG_MAX here because we want a 4-byte max even on 64-bit machines */
62 #define BIGGEST_4_BYTE_SIGNED_INT  2147483647L
63 #define BIGGEST_4_BYTE_UNSIGNED_INT 4294967295UL
64 
65 
66 static const uint8_t I_DSND[4] = {'.','s','n','d'};  /* NeXT/Sun/Dec/SGI/AFsp first word */
67 static const uint8_t I_FORM[4] = {'F','O','R','M'};  /* AIFF first word */
68 static const uint8_t I_AIFF[4] = {'A','I','F','F'};  /* AIFF second word */
69 static const uint8_t I_AIFC[4] = {'A','I','F','C'};  /* ditto but might be compressed data */
70 static const uint8_t I_COMM[4] = {'C','O','M','M'};
71 static const uint8_t I_COMT[4] = {'C','O','M','T'};
72 static const uint8_t I_INFO[4] = {'I','N','F','O'};
73 static const uint8_t I_INST[4] = {'I','N','S','T'};
74 static const uint8_t I_MARK[4] = {'M','A','R','K'};
75 static const uint8_t I_SSND[4] = {'S','S','N','D'};
76 static const uint8_t I_NONE[4] = {'N','O','N','E'};
77 static const uint8_t I_ULAW[4] = {'U','L','A','W'};  /* AIFC compression types that we can handle */
78 static const uint8_t I_ulaw[4] = {'u','l','a','w'};  /* or maybe it's lowercase (Apple) ... */
79 static const uint8_t I_raw_[4] = {'r','a','w',' '};  /* AIFC offset binary OS 8.5 (others are 'MAC3' 'MAC6' 'cdx4' 'cdx2' 'str4') */
80 static const uint8_t I_sowt[4] = {'s','o','w','t'};  /* AIFC 16-bit little endian -- used by Mac when extracting CD tracks */
81 static const uint8_t I_fl32[4] = {'f','l','3','2'};  /* AIFC 32-bit float */
82 static const uint8_t I_fl64[4] = {'f','l','6','4'};  /* AIFC 64-bit float */
83 static const uint8_t I_alaw[4] = {'a','l','a','w'};  /* apple */
84 static const uint8_t I_APPL[4] = {'A','P','P','L'};
85 static const uint8_t I_MUS_[4] = {'C','L','M',' '};  /* I hereby claim this AIFF chunk name */
86 static const uint8_t I_RIFF[4] = {'R','I','F','F'};  /* RIFF first word */
87 static const uint8_t I_RIFX[4] = {'R','I','F','X'};  /* RIFX first word (big-endian RIFF file) */
88 static const uint8_t I_WAVE[4] = {'W','A','V','E'};
89 static const uint8_t I_fmt_[4] = {'f','m','t',' '};
90 static const uint8_t I_data[4] = {'d','a','t','a'};
91 static const uint8_t I_fact[4] = {'f','a','c','t'};  /* used by compressed RIFF files */
92 static const uint8_t I_clm_[4] = {'c','l','m',' '};
93 static const uint8_t I_NIST[4] = {'N','I','S','T'};  /* first word of NIST SPHERE files */
94 static const uint8_t I_VOC0[4] = {'C','r','e','a'};  /* Actual text is "Creative Voice File" */
95 static const uint8_t I_SOUN[4] = {'S','O','U','N'};  /* Sound Tools first word="SOUND" -- not unique as SMP files start with "SOUND SAMPLE" */
96 static const uint8_t I_ANNO[4] = {'A','N','N','O'};
97 static const uint8_t I_NAME[4] = {'N','A','M','E'};
98 static const uint8_t I_AVR_[4] = {'2','B','I','T'};  /* first word of AVR files */
99 static const uint8_t I_SPIB[4] = {'%','/','/','\n'}; /* first word of IEEE spib text sound files */
100 static const uint8_t I_S___[4] = {'%','-','-','-'};  /* first word of other IEEE spib text sound files */
101 static const uint8_t I_ALaw[4] = {'A','L','a','w'};  /* first word of PSION alaw files */
102 static const uint8_t I_MThd[4] = {'M','T','h','d'};  /* sigh -- the M word */
103 static const uint8_t I_DECN[4] = {'.','s','d','\0'}; /* first word of DEC files (?) */
104 static const uint8_t I_LIST[4] = {'L','I','S','T'};
105 static const uint8_t I_GF1P[4] = {'G','F','1','P'};  /* first word of Gravis Ultrsound patch files */
106 static const uint8_t I_DSIG[4] = {'$','S','I','G'};  /* first word of Comdisco SPW file */
107 static const uint8_t I_GOLD[4] = {'G','O','L','D'};  /* first word Goldwave(?) sample file */
108 static const uint8_t I_SRFS[4] = {'S','R','F','S'};  /* first word Sonic Resource Foundry file(?) */
109 static const uint8_t I_Diam[4] = {'D','i','a','m'};  /* first word DiamondWare file */
110 static const uint8_t I_CSRE[4] = {'C','S','R','E'};  /* adf first word -- second starts with "40" */
111 static const uint8_t I_SND_[4] = {'S','N','D',' '};  /* SBStudio II */
112 static const uint8_t I_DDSF[4] = {'D','D','S','F'};  /* Delusion Digital Sound File */
113 static const uint8_t I_FSMt[4] = {'F','S','M',(uint8_t)'\376'};  /* Farandole Composer WaveSample */
114 static const uint8_t I_UWFD[4] = {'U','W','F','D'};  /* Ultratracker Wavesample */
115 static const uint8_t I_LM89[4] = {'L','M','8','9'};  /* Yamaha TX-16 */
116 static const uint8_t I_SY80[4] = {'S','Y','8','0'};  /* Yamaha SY-99 */
117 static const uint8_t I_SY85[4] = {'S','Y','8','5'};  /* Yamaha SY-85 */
118 static const uint8_t I_SCRS[4] = {'S','C','R','S'};  /* Digiplayer ST3 */
119 static const uint8_t I_covox[4] = {(uint8_t)'\377','\125',(uint8_t)'\377',(uint8_t)'\252'};
120 static const uint8_t I_PRAM[4] = {'P','R','A','M'};  /* Kurzweil 2000 */
121 static const uint8_t I__PAF[4] = {' ','p','a','f'};  /* Paris Ensoniq */
122 static const uint8_t I_FAP_[4] = {'f','a','p',' '};  /* Paris Ensoniq */
123 static const uint8_t I_file[4] = {'f','i','l','e'};  /* snack "SMP" */
124 static const uint8_t I_PVF1[4] = {'P','V','F','1'};  /* portable voice format (mgetty) */
125 static const uint8_t I_PVF2[4] = {'P','V','F','2'};
126 static const uint8_t I_riff[4] = {'r','i','f','f'};  /* SoundForge */
127 static const uint8_t I_TWIN[4] = {'T','W','I','N'};  /* TwinVQ */
128 static const uint8_t I_IMPS[4] = {'I','M','P','S'};  /* Impulse Tracker */
129 static const uint8_t I_SMP1[4] = {'S','M','P','1'};  /* Korg */
130 static const uint8_t I_Maui[4] = {'M','a','u','i'};  /* Turtle Beach */
131 static const uint8_t I_SDIF[4] = {'S','D','I','F'};  /* IRCAM sdif */
132 #if G7XX
133 static const uint8_t I_NVF_[4] = {'N','V','F',' '};  /* Nomad II Creative NVF */
134 #endif
135 static const uint8_t I_ajkg[4] = {'a','j','k','g'};  /* shorten */
136 static const uint8_t I_RF64[4] = {'R','F','6','4'};  /* EBU RF64 */
137 static const uint8_t I_ds64[4] = {'d','s','6','4'};  /* EBU RF64 */
138 static const uint8_t I_caff[4] = {'c','a','f','f'};  /* Apple CAFF */
139 static const uint8_t I_desc[4] = {'d','e','s','c'};  /* Apple CAFF */
140 static const uint8_t I_lpcm[4] = {'l','p','c','m'};  /* Apple CAFF */
141 static const uint8_t I_dSoX[4] = {'.','S','o','X'};  /* Sox intermediate (little-endian?) */
142 static const uint8_t I_XoSd[4] = {'X','o','S','.'};  /* Sox intermediate */
143 
144 #define HDRBUFSIZ 256
145 static uint8_t *hdrbuf;
146 #define INITIAL_READ_SIZE 256
147 
148 /* AIFF files can have any number of ANNO chunks, so we'll grab at least 4 of them */
149 #define AUX_COMMENTS 4
150 static mus_long_t *aux_comment_start = NULL, *aux_comment_end = NULL;
151 
152 #define LOOPS 2
153 static int *loop_modes = NULL, *loop_starts = NULL, *loop_ends = NULL;
154 static int markers = 0;
155 static int *marker_ids = NULL, *marker_positions = NULL;
156 
157 static bool hdrbuf_is_inited = false;
158 
159 
160 /* for CLM */
mus_reset_headers_c(void)161 void mus_reset_headers_c(void)
162 {
163   hdrbuf_is_inited = false;
164   markers = 0;
165 }
166 
167 
mus_header_initialize(void)168 int mus_header_initialize(void)
169 {
170   if (!hdrbuf_is_inited)
171     {
172       hdrbuf_is_inited = true;
173       hdrbuf = (uint8_t *)calloc(HDRBUFSIZ, sizeof(uint8_t));
174       aux_comment_start = (mus_long_t *)calloc(AUX_COMMENTS, sizeof(mus_long_t));
175       aux_comment_end = (mus_long_t *)calloc(AUX_COMMENTS, sizeof(mus_long_t));
176       loop_modes = (int *)calloc(LOOPS, sizeof(int));
177       loop_starts = (int *)calloc(LOOPS, sizeof(int));
178       loop_ends = (int *)calloc(LOOPS, sizeof(int));
179       if ((!hdrbuf) || (!aux_comment_start) || (!aux_comment_end) ||
180 	  (!loop_modes) || (!loop_starts) || (!loop_ends))
181 	return(mus_error(MUS_MEMORY_ALLOCATION_FAILED, "mus_header_initialize: buffer allocation failed"));
182     }
183   return(MUS_NO_ERROR);
184 }
185 
186 
187 #define I_IRCAM_VAX  0x0001a364
188 #define I_IRCAM_SUN  0x0002a364
189 #define I_IRCAM_MIPS 0x0003a364
190 #define I_IRCAM_NEXT  0x0004a364
191 
192 static mus_long_t data_location = 0;
193 static int srate = 0, chans = 0, original_sample_type = 0;
194 static mus_sample_t sample_type = MUS_UNKNOWN_SAMPLE;
195 static mus_header_t header_type = MUS_UNKNOWN_HEADER;
196 static int type_specifier = 0, bits_per_sample = 0, block_align = 0, fact_samples = 0;
197 static mus_long_t comment_start = 0, comment_end = 0;
198 static mus_long_t true_file_length = 0, data_size = 0;
199 static int base_detune = 0, base_note = 0;
200 static bool little_endian = false;
201 
mus_header_samples(void)202 mus_long_t mus_header_samples(void)            {return(data_size);}
mus_header_data_location(void)203 mus_long_t mus_header_data_location(void)      {return(data_location);}
mus_header_chans(void)204 int mus_header_chans(void)                     {return(chans);}
mus_header_srate(void)205 int mus_header_srate(void)                     {return(srate);}
mus_header_type(void)206 mus_header_t mus_header_type(void)             {return(header_type);}
mus_header_sample_type(void)207 mus_sample_t mus_header_sample_type(void)      {return(sample_type);}
mus_header_comment_start(void)208 mus_long_t mus_header_comment_start(void)      {return(comment_start);}
mus_header_comment_end(void)209 mus_long_t mus_header_comment_end(void)        {return(comment_end);}
mus_header_aux_comment_start(int n)210 mus_long_t mus_header_aux_comment_start(int n) {if (aux_comment_start) return(aux_comment_start[n]); else return(-1);}
mus_header_aux_comment_end(int n)211 mus_long_t mus_header_aux_comment_end(int n)   {if (aux_comment_end) return(aux_comment_end[n]); else return(-1);}
mus_header_type_specifier(void)212 int mus_header_type_specifier(void)            {return(type_specifier);}
mus_header_bits_per_sample(void)213 int mus_header_bits_per_sample(void)           {return(bits_per_sample);}
mus_header_fact_samples(void)214 int mus_header_fact_samples(void)              {return(fact_samples);}
mus_header_block_align(void)215 int mus_header_block_align(void)               {return(block_align);}
mus_header_true_length(void)216 mus_long_t mus_header_true_length(void)        {return(true_file_length);}
mus_header_original_sample_type(void)217 int mus_header_original_sample_type(void)      {return(original_sample_type);}
mus_header_loop_mode(int which)218 int mus_header_loop_mode(int which)            {if (loop_modes) return(loop_modes[which]); else return(-1);}
mus_header_loop_start(int which)219 int mus_header_loop_start(int which)           {if (loop_starts) return(loop_starts[which]); else return(-1);}
mus_header_loop_end(int which)220 int mus_header_loop_end(int which)             {if (loop_ends) return(loop_ends[which]); else return(-1);}
mus_header_mark_position(int id)221 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);}
mus_header_base_detune(void)222 int mus_header_base_detune(void)               {return(base_detune);}
mus_header_base_note(void)223 int mus_header_base_note(void)                 {return(base_note);}
224 
mus_header_mark_info(int ** m_ids,int ** m_positions)225 int mus_header_mark_info(int **m_ids, int **m_positions)
226 {
227   (*m_ids) = marker_ids;
228   (*m_positions) = marker_positions;
229   return(markers);
230 }
231 
232 
mus_bytes_per_sample(mus_sample_t samp_type)233 int mus_bytes_per_sample(mus_sample_t samp_type)
234 {
235   switch (samp_type)
236     {
237     case MUS_BYTE:             return(1);
238     case MUS_BSHORT:           return(2);
239     case MUS_UBYTE:            return(1);
240     case MUS_MULAW:            return(1);
241     case MUS_ALAW:             return(1);
242     case MUS_BINT:             return(4);
243     case MUS_BFLOAT:           return(4);
244     case MUS_BFLOAT_UNSCALED:  return(4);
245     case MUS_B24INT:           return(3);
246     case MUS_BDOUBLE:          return(8);
247     case MUS_BDOUBLE_UNSCALED: return(8);
248     case MUS_LSHORT:           return(2);
249     case MUS_LINT:             return(4);
250     case MUS_LFLOAT:           return(4);
251     case MUS_LDOUBLE:          return(8);
252     case MUS_LFLOAT_UNSCALED:  return(4);
253     case MUS_LDOUBLE_UNSCALED: return(8);
254     case MUS_L24INT:           return(3);
255     case MUS_UBSHORT:          return(2);
256     case MUS_ULSHORT:          return(2);
257     case MUS_BINTN:            return(4);
258     case MUS_LINTN:            return(4);
259     default:                   return(1); /* we divide by this number, so 0 is not safe */
260     }
261 }
262 
263 
mus_samples_to_bytes(mus_sample_t samp_type,mus_long_t size)264 mus_long_t mus_samples_to_bytes (mus_sample_t samp_type, mus_long_t size)
265 {
266   return(size * (mus_bytes_per_sample(samp_type)));
267 }
268 
269 
mus_bytes_to_samples(mus_sample_t samp_type,mus_long_t size)270 mus_long_t mus_bytes_to_samples (mus_sample_t samp_type, mus_long_t size)
271 {
272   return((mus_long_t)(size / (mus_bytes_per_sample(samp_type))));
273 }
274 
275 
equal_big_or_little_endian(const uint8_t * n1,const uint32_t n2)276 static bool equal_big_or_little_endian(const uint8_t *n1, const uint32_t n2)
277 {
278   return((mus_char_to_ubint(n1) == n2) || (mus_char_to_ulint(n1) == n2));
279 }
280 
281 
big_or_little_endian_short(const uint8_t * n,bool little)282 static short big_or_little_endian_short(const uint8_t *n, bool little)
283 {
284   if (little) return(mus_char_to_lshort(n));
285   return(mus_char_to_bshort(n));
286 }
287 
288 
big_or_little_endian_int(const uint8_t * n,bool little)289 static int big_or_little_endian_int(const uint8_t *n, bool little)
290 {
291   if (little) return(mus_char_to_lint(n));
292   return(mus_char_to_bint(n));
293 }
294 
295 
big_or_little_endian_uint(const uint8_t * n,bool little)296 static uint32_t big_or_little_endian_uint(const uint8_t *n, bool little)
297 {
298   if (little) return(mus_char_to_ulint(n));
299   return(mus_char_to_ubint(n));
300 }
301 
302 
big_or_little_endian_float(const uint8_t * n,bool little)303 static float big_or_little_endian_float(const uint8_t *n, bool little)
304 {
305   if (little) return(mus_char_to_lfloat(n));
306   return(mus_char_to_bfloat(n));
307 }
308 
309 
match_four_chars(const uint8_t * head,const uint8_t * match)310 static bool match_four_chars(const uint8_t *head, const uint8_t *match)
311 {
312   return((head[0] == match[0]) &&
313 	 (head[1] == match[1]) &&
314 	 (head[2] == match[2]) &&
315 	 (head[3] == match[3]));
316 }
317 
318 
write_four_chars(uint8_t * head,const uint8_t * match)319 static void write_four_chars(uint8_t *head, const uint8_t *match)
320 {
321   head[0] = match[0];
322   head[1] = match[1];
323   head[2] = match[2];
324   head[3] = match[3];
325 }
326 
327 
mus_header_type_name(mus_header_t type)328 const char *mus_header_type_name(mus_header_t type)
329 {
330   switch (type)
331     {
332     case MUS_NEXT:             return("Sun/Next");
333     case MUS_AIFC:             return("AIFC");
334     case MUS_RIFF:             return("RIFF");
335     case MUS_BICSF:            return("BICSF");
336     case MUS_NIST:             return("NIST");
337     case MUS_INRS:             return("INRS");
338     case MUS_ESPS:             return("ESPS");
339     case MUS_SVX:              return("SVX8");
340     case MUS_VOC:              return("VOC");
341     case MUS_SNDT:             return("SNDT");
342     case MUS_SOX:              return("Sox");
343     case MUS_RAW:              return("raw (no header)");
344     case MUS_SMP:              return("SMP");
345     case MUS_AVR:              return("AVR");
346     case MUS_IRCAM:            return("IRCAM");
347     case MUS_SD1:              return("Sound Designer 1");
348     case MUS_SPPACK:           return("SPPACK");
349     case MUS_MUS10:            return("Mus10");
350     case MUS_HCOM:             return("HCOM");
351     case MUS_PSION:            return("PSION");
352     case MUS_MAUD:             return("MAUD");
353     case MUS_IEEE:             return("IEEE text");
354     case MUS_MATLAB:           return("Matlab");
355     case MUS_ADC:              return("ADC/OGI");
356     case MUS_MIDI:             return("MIDI");
357     case MUS_SOUNDFONT:        return("SoundFont");
358     case MUS_GRAVIS:           return("Gravis Ultrasound patch");
359     case MUS_COMDISCO:         return("Comdisco SPW signal");
360     case MUS_GOLDWAVE:         return("Goldwave sample");
361     case MUS_SRFS:             return("SRFS");
362     case MUS_MIDI_SAMPLE_DUMP: return("MIDI sample dump");
363     case MUS_DIAMONDWARE:      return("DiamondWare");
364     case MUS_ADF:              return("CSRE adf");
365     case MUS_SBSTUDIOII:       return("SBStudioII");
366     case MUS_DELUSION:         return("Delusion");
367     case MUS_FARANDOLE:        return("Farandole");
368     case MUS_SAMPLE_DUMP:      return("Sample dump");
369     case MUS_ULTRATRACKER:     return("Ultratracker");
370     case MUS_YAMAHA_TX16W:     return("TX-16W");
371     case MUS_YAMAHA_SY85:      return("Sy-85");
372     case MUS_YAMAHA_SY99:      return("Sy-99");
373     case MUS_KURZWEIL_2000:    return("Kurzweil 2000");
374     case MUS_KORG:             return("Korg");
375     case MUS_MAUI:             return("Turtle Beach");
376     case MUS_IMPULSETRACKER:   return("Impulse Tracker");
377     case MUS_AKAI4:            return("AKAI 4");
378     case MUS_DIGIPLAYER:       return("Digiplayer ST3");
379     case MUS_COVOX:            return("Covox V8");
380     case MUS_AVI:              return("AVI");
381     case MUS_OMF:              return("OMF");
382     case MUS_QUICKTIME:        return("Quicktime");
383     case MUS_ASF:              return("asf");
384     case MUS_AIFF:             return("AIFF");
385     case MUS_PAF:              return("Ensoniq Paris");
386     case MUS_CSL:              return("CSL");
387     case MUS_FILE_SAMP:        return("snack SMP");
388     case MUS_PVF:              return("Portable Voice Format");
389     case MUS_SOUNDFORGE:       return("SoundForge");
390     case MUS_TWINVQ:           return("TwinVQ");
391     case MUS_SDIF:             return("IRCAM sdif");
392 #if G7XX
393     case MUS_NVF:              return("Creative NVF");
394 #endif
395     case MUS_OGG:              return("Ogg Vorbis");
396     case MUS_FLAC:             return("Flac");
397     case MUS_SPEEX:            return("Speex");
398     case MUS_MPEG:             return("mpeg");
399     case MUS_SHORTEN:          return("shorten");
400     case MUS_TTA:              return("tta");
401     case MUS_WAVPACK:          return("wavpack");
402     case MUS_RF64:             return("rf64");
403     case MUS_CAFF:             return("caff");
404     default:                   return("unknown");
405     }
406 }
407 
408 
mus_sample_type_name(mus_sample_t samp_type)409 const char *mus_sample_type_name(mus_sample_t samp_type)
410 {
411   switch (samp_type)
412     {
413     case MUS_BSHORT:           return("big endian short (16 bits)");
414     case MUS_MULAW:            return("mulaw (8 bits)");
415     case MUS_BYTE:             return("signed byte (8 bits)");
416     case MUS_BFLOAT:           return("big endian float (32 bits)");
417     case MUS_BFLOAT_UNSCALED:  return("big endian float (32 bits, unscaled)");
418     case MUS_BINT:             return("big endian int (32 bits)");
419     case MUS_ALAW:             return("alaw (8 bits)");
420     case MUS_UBYTE:            return("unsigned byte (8 bits)");
421     case MUS_B24INT:           return("big endian int (24 bits)");
422     case MUS_BDOUBLE:          return("big endian double (64 bits)");
423     case MUS_BDOUBLE_UNSCALED: return("big endian double (64 bits, unscaled)");
424     case MUS_LSHORT:           return("little endian short (16 bits)");
425     case MUS_LINT:             return("little endian int (32 bits)");
426     case MUS_LFLOAT:           return("little endian float (32 bits)");
427     case MUS_LDOUBLE:          return("little endian double (64 bits)");
428     case MUS_LFLOAT_UNSCALED:  return("little endian float (32 bits, unscaled)");
429     case MUS_LDOUBLE_UNSCALED: return("little endian double (64 bits, unscaled)");
430     case MUS_UBSHORT:          return("unsigned big endian short (16 bits)");
431     case MUS_ULSHORT:          return("unsigned little endian short (16 bits)");
432     case MUS_L24INT:           return("little endian int (24 bits)");
433     case MUS_BINTN:            return("normalized big endian int (32 bits)");
434     case MUS_LINTN:            return("normalized little endian int (32 bits)");
435     default:                   return("unknown");
436     }
437 }
438 
439 
mus_sample_type_short_name(mus_sample_t samp_type)440 const char *mus_sample_type_short_name(mus_sample_t samp_type)
441 {
442   switch (samp_type)
443     {
444     case MUS_BSHORT:           return("short int");
445     case MUS_MULAW:            return("mulaw");
446     case MUS_BYTE:             return("signed byte");
447     case MUS_BFLOAT:           return("float");
448     case MUS_BFLOAT_UNSCALED:  return("float unscaled)");
449     case MUS_BINT:             return("int");
450     case MUS_ALAW:             return("alaw");
451     case MUS_UBYTE:            return("unsigned byte");
452     case MUS_B24INT:           return("24-bit int");
453     case MUS_BDOUBLE:          return("double");
454     case MUS_BDOUBLE_UNSCALED: return("double unscaled");
455     case MUS_LSHORT:           return("short int");
456     case MUS_LINT:             return("int");
457     case MUS_LFLOAT:           return("float");
458     case MUS_LDOUBLE:          return("double");
459     case MUS_LFLOAT_UNSCALED:  return("float unscaled");
460     case MUS_LDOUBLE_UNSCALED: return("double unscaled");
461     case MUS_UBSHORT:          return("unsigned short");
462     case MUS_ULSHORT:          return("unsigned short");
463     case MUS_L24INT:           return("24-bit int");
464     case MUS_BINTN:            return("normalized int");
465     case MUS_LINTN:            return("normalized int");
466     default:                   return("unknown");
467     }
468 }
469 
470 
471 #if (HAVE_EXTENSION_LANGUAGE) && (HAVE_RUBY) /* HAVE_EXTENSION_LANGUAGE is not redundant -- make sndinfo for example */
472   #define TO_LANG(Str) (const char *)xen_scheme_constant_to_ruby(Str)
473 #else
474   #define TO_LANG(Str) Str
475 #endif
476 
477 
mus_header_type_to_string(mus_header_t type)478 const char *mus_header_type_to_string(mus_header_t type)
479 {
480   switch (type)
481     {
482     case MUS_NEXT:      return(TO_LANG(S_mus_next));
483     case MUS_AIFF:      return(TO_LANG(S_mus_aiff));
484     case MUS_AIFC:      return(TO_LANG(S_mus_aifc));
485     case MUS_RIFF:      return(TO_LANG(S_mus_riff));
486     case MUS_NIST:      return(TO_LANG(S_mus_nist));
487     case MUS_IRCAM:     return(TO_LANG(S_mus_ircam));
488     case MUS_RAW:       return(TO_LANG(S_mus_raw));
489     case MUS_BICSF:     return(TO_LANG(S_mus_bicsf));
490     case MUS_VOC:       return(TO_LANG(S_mus_voc));
491     case MUS_SVX:       return(TO_LANG(S_mus_svx));
492     case MUS_SOUNDFONT: return(TO_LANG(S_mus_soundfont));
493     case MUS_RF64:      return(TO_LANG(S_mus_rf64));
494     case MUS_CAFF:      return(TO_LANG(S_mus_caff));
495     default: break;
496     }
497   return(NULL);
498 }
499 
500 
mus_sample_type_to_string(mus_sample_t samp_type)501 const char *mus_sample_type_to_string(mus_sample_t samp_type)
502 {
503   switch (samp_type)
504     {
505     case MUS_BSHORT:           return(TO_LANG(S_mus_bshort));
506     case MUS_LSHORT:           return(TO_LANG(S_mus_lshort));
507     case MUS_MULAW:            return(TO_LANG(S_mus_mulaw));
508     case MUS_ALAW:             return(TO_LANG(S_mus_alaw));
509     case MUS_BYTE:             return(TO_LANG(S_mus_byte));
510     case MUS_UBYTE:            return(TO_LANG(S_mus_ubyte));
511     case MUS_BFLOAT:           return(TO_LANG(S_mus_bfloat));
512     case MUS_LFLOAT:           return(TO_LANG(S_mus_lfloat));
513     case MUS_BINT:             return(TO_LANG(S_mus_bint));
514     case MUS_LINT:             return(TO_LANG(S_mus_lint));
515     case MUS_BINTN:            return(TO_LANG(S_mus_bintn));
516     case MUS_LINTN:            return(TO_LANG(S_mus_lintn));
517     case MUS_B24INT:           return(TO_LANG(S_mus_b24int));
518     case MUS_L24INT:           return(TO_LANG(S_mus_l24int));
519     case MUS_BDOUBLE:          return(TO_LANG(S_mus_bdouble));
520     case MUS_LDOUBLE:          return(TO_LANG(S_mus_ldouble));
521     case MUS_UBSHORT:          return(TO_LANG(S_mus_ubshort));
522     case MUS_ULSHORT:          return(TO_LANG(S_mus_ulshort));
523     case MUS_BDOUBLE_UNSCALED: return(TO_LANG(S_mus_bdouble_unscaled));
524     case MUS_LDOUBLE_UNSCALED: return(TO_LANG(S_mus_ldouble_unscaled));
525     case MUS_BFLOAT_UNSCALED:  return(TO_LANG(S_mus_bfloat_unscaled));
526     case MUS_LFLOAT_UNSCALED:  return(TO_LANG(S_mus_lfloat_unscaled));
527     default: break;
528     }
529   return(NULL);
530 }
531 
532 
any_sample_type_name(mus_sample_t sndlib_samp_type)533 static const char *any_sample_type_name(mus_sample_t sndlib_samp_type)
534 {
535   if (mus_is_sample_type(sndlib_samp_type))
536     return(mus_sample_type_name(sndlib_samp_type));
537   else return(mus_header_original_sample_type_name(mus_header_original_sample_type(), mus_header_type()));
538 }
539 
540 
541 #define SEEK_FILE_LENGTH(File) lseek(File, 0L, SEEK_END)
542 static int read_bicsf_header(const char *filename, int fd);
543 
544 
545 
546 /* ------------------------------------ NeXT (or Sun) --------------------------------
547  *
548  *   0:  ".snd"
549  *   4:  data_location (bytes) (not necessarily word aligned on Sun)
550  *   8:  data_size (bytes) -- sometimes incorrect ("advisory")
551  *   12: sample type indicator -- see below
552  *   16: srate (int)
553  *   20: chans
554  *   24: comment start
555  *
556  * in an AFsp file, the first 4 bytes of the comment are "AFsp",
557  * for bicsf, the integer at 28 is 107364 or 107415
558  *
559  * on NeXTStep, always big-endian.  ".snd"==0x2e736e64 on big-endian machines.
560  *
561  * formats are:
562  * 0 unspecified, 1 mulaw_8, 2 linear_8, 3 linear_16, 4 linear_24, 5 linear_32, 6 float,
563  * 7 double, 8 indirect, 9 nested, 10 dsp_core, 11 dsp_data_8, 12 dsp_data_16, 13 dsp_data_24,
564  * 14 dsp_data_32, 16 display, 17 mulaw_squelch, 18 emphasized, 19 compressed, 20 compressed_emphasized
565  * 21 dsp_commands, 22 dsp_commands_samples, 23 adpcm_g721, 24 adpcm_g722, 25 adpcm_g723,
566  * 26 adpcm_g723_5, 27 alaw_8, 28 aes, 29 delat_mulaw_8
567  *   internal Snd(lib)-only formats:
568  *     30: mus_lint, 31: mus_lfloat,
569  *     32: mus_bintn, 33: mus_lintn,
570  *     34: mus_ldouble and others... (added by me for Snd internal use)
571  */
572 
573 /* according to the file /usr/share/magic, the DECN versions were little endian */
574 
575 
read_next_header(const char * filename,int fd)576 static int read_next_header(const char *filename, int fd)
577 {
578   int maybe_bicsf, err = MUS_NO_ERROR, i;
579 
580   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)hdrbuf);
581   data_location = mus_char_to_ubint((uint8_t *)(hdrbuf + 4));
582   if (data_location < 24) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data location: %" print_mus_long "?", filename, data_location));
583 
584   data_size = mus_char_to_ubint((uint8_t *)(hdrbuf + 8)); /* changed to unsigned 11-Nov-06 */
585   /* can be bogus -- fixup if possible */
586   true_file_length = SEEK_FILE_LENGTH(fd);
587   if ((data_size <= 24) || (data_size > true_file_length))
588     data_size = (true_file_length - data_location);
589   else
590     {
591       if (true_file_length > (mus_long_t)0x80000000) /* (1 << 31)) */
592 	data_size = true_file_length - data_location; /* assume size field overflowed 32 bits */
593     }
594 
595   original_sample_type = mus_char_to_bint((uint8_t *)(hdrbuf + 12));
596   switch (original_sample_type)
597     {
598     case 1:  sample_type = MUS_MULAW;            break;
599     case 2:  sample_type = MUS_BYTE;             break; /* some sound files assume MUS_UBYTE here! (NAS from 1994 X11R6 contrib) */
600     case 3:  sample_type = MUS_BSHORT;           break;
601     case 4:  sample_type = MUS_B24INT;           break;
602     case 5:  sample_type = MUS_BINT;             break;
603     case 6:  sample_type = MUS_BFLOAT;           break;
604     case 7:  sample_type = MUS_BDOUBLE;          break;
605     case 18: sample_type = MUS_BSHORT;           break; /* "emphasized": Xavier Serra's de-emphasis filter: y(n) = x(n) + .9 y(n-1) */
606     case 27: sample_type = MUS_ALAW;             break;
607     case 30: sample_type = MUS_LINT;             break; /* from here on, for Snd's internal benefit -- these are probably not used elsewhere */
608     case 31: sample_type = MUS_LFLOAT;           break;
609     case 32: sample_type = MUS_BINTN;            break;
610     case 33: sample_type = MUS_LINTN;            break;
611     case 34: sample_type = MUS_LDOUBLE;          break;
612     case 35: sample_type = MUS_ULSHORT;          break;
613     case 36: sample_type = MUS_UBSHORT;          break;
614     case 37: sample_type = MUS_LFLOAT_UNSCALED;  break;
615     case 38: sample_type = MUS_BFLOAT_UNSCALED;  break;
616     case 39: sample_type = MUS_LDOUBLE_UNSCALED; break;
617     case 40: sample_type = MUS_BDOUBLE_UNSCALED; break;
618     case 41: sample_type = MUS_LSHORT;           break;
619     case 42: sample_type = MUS_L24INT;           break;
620     case 43: sample_type = MUS_UBYTE;            break;
621     default: sample_type = MUS_UNKNOWN_SAMPLE;   break;
622     }
623 
624   srate = mus_char_to_bint((uint8_t *)(hdrbuf + 16));
625   chans = mus_char_to_bint((uint8_t *)(hdrbuf + 20));
626 
627   comment_start = 0;
628   comment_end = 0;
629   for (i = 24; i < data_location - 1; i++)
630     if (hdrbuf[i] == '\0')
631       break;
632     else
633       {
634 	if (hdrbuf[i] != ' ')
635 	  {
636 	    comment_start = i;
637 	    comment_end = data_location - 1;
638 	    break;
639 	  }
640       }
641   if (comment_end < comment_start) comment_end = comment_start;
642 
643   maybe_bicsf = mus_char_to_bint((uint8_t *)(hdrbuf + 28));
644   if (maybe_bicsf == 107364) err = read_bicsf_header(filename, fd);
645 
646   data_size = mus_bytes_to_samples(sample_type, data_size);
647   return(err);
648 }
649 
650 
sndlib_format_to_next(mus_sample_t samp_type)651 static int sndlib_format_to_next(mus_sample_t samp_type)
652 {
653   switch (samp_type)
654     {
655     case MUS_MULAW:            return(1);
656     case MUS_BYTE:             return(2);
657     case MUS_BSHORT:           return(3);
658     case MUS_B24INT:           return(4);
659     case MUS_BINT:             return(5);
660     case MUS_BFLOAT:           return(6);
661     case MUS_BDOUBLE:          return(7);
662     case MUS_ALAW:             return(27);
663     case MUS_LINT:             return(30);
664     case MUS_LFLOAT:           return(31);
665     case MUS_BINTN:            return(32);
666     case MUS_LINTN:            return(33);
667     case MUS_LDOUBLE:          return(34);
668     case MUS_ULSHORT:          return(35);
669     case MUS_UBSHORT:          return(36);
670     case MUS_LFLOAT_UNSCALED:  return(37);
671     case MUS_BFLOAT_UNSCALED:  return(38);
672     case MUS_LDOUBLE_UNSCALED: return(39);
673     case MUS_BDOUBLE_UNSCALED: return(40);
674     case MUS_LSHORT:           return(41);
675     case MUS_L24INT:           return(42);
676     case MUS_UBYTE:            return(43);
677     default:
678       return(mus_error(MUS_UNSUPPORTED_SAMPLE_TYPE, "Next header: can't write sample type: %d (%s)",
679 		       samp_type,
680 		       any_sample_type_name(samp_type)));
681     }
682 }
683 
684 
header_write(int fd,uint8_t * buf,int chars)685 static int header_write(int fd, uint8_t *buf, int chars)
686 {
687   if (chars > 0)
688     {
689       int64_t bytes;
690       bytes = (int64_t)write(fd, buf, chars);
691       if (bytes != chars)
692 	{
693 	  char *errstr;
694 	  errstr = STRERROR(errno);
695 	  return(mus_error(MUS_WRITE_ERROR, "header_write: wrote %" print_mus_long " of %d bytes, %s",
696 			   bytes, chars, (errstr) ? errstr : "unknown error?"));
697 	}
698     }
699   return(MUS_NO_ERROR);
700 }
701 
702 
header_read(int fd,uint8_t * buf,int chars)703 static int header_read(int fd, uint8_t *buf, int chars)
704 {
705   if (chars > 0)
706     {
707       int64_t bytes;
708       bytes = (int64_t)read(fd, buf, chars);
709       if (bytes != chars)
710 	{
711 	  char *errstr;
712 	  errstr = STRERROR(errno);
713 	  return(mus_error(MUS_READ_ERROR, "header_read: read %" print_mus_long " of %d bytes, %s",
714 			   bytes, chars, (errstr) ? errstr : "unknown error?"));
715 	}
716     }
717   return(MUS_NO_ERROR);
718 }
719 
720 
write_next_comment(int fd,const char * comment,int len,int loc)721 static void write_next_comment(int fd, const char *comment, int len, int loc)
722 {
723   if (len > 0)
724     header_write(fd, (uint8_t *)comment, len);
725   len = loc - (len + 24);
726   if (len > 0)
727     {
728       uint8_t *combuf;
729       combuf = (uint8_t *)calloc(len, sizeof(uint8_t));
730       header_write(fd, combuf, len);
731       free(combuf);
732     }
733 }
734 
mus_header_write_next_header(int fd,int wsrate,int wchans,int loc,int siz,mus_sample_t samp_type,const char * comment,int len)735 static int mus_header_write_next_header(int fd, int wsrate, int wchans, int loc, int siz, mus_sample_t samp_type, const char *comment, int len)
736 {
737   int i, j;
738   write_four_chars((uint8_t *)hdrbuf, I_DSND); /* ".snd" */
739   i = len / 4;
740   j = 24 + (4 * (i + 1));
741   if (loc < j) loc = j;
742   mus_bint_to_char((uint8_t *)(hdrbuf + 4), loc);
743   mus_bint_to_char((uint8_t *)(hdrbuf + 8), siz);
744   mus_bint_to_char((uint8_t *)(hdrbuf + 12), sndlib_format_to_next(samp_type));
745   mus_bint_to_char((uint8_t *)(hdrbuf + 16), wsrate);
746   mus_bint_to_char((uint8_t *)(hdrbuf + 20), wchans);
747   header_write(fd, hdrbuf, 24);
748   write_next_comment(fd, comment, len, loc);
749   data_location = loc;
750   return(MUS_NO_ERROR);
751 }
752 
753 
754 
755 /* ------------------------------------ AIFF ------------------------------------
756  *
757  *  0: "FORM"
758  *  4: size (bytes)
759  *  8: "AIFF" or "AIFC" -- the latter includes compressed formats (list extended for 8.5 Sound.h)
760  *
761  *  Thereafter the file is organized into "chunks", each chunk being
762  *  a 4-byte identifier followed by an int (4-bytes) giving the chunk size
763  *  not including the 8-byte header.  AIFF data is signed.  If the chunk
764  *  size is odd, an extra (unaccounted-for) null byte is added at the end.
765  *
766  *  The chunks we want are "COMM", "SSND", and "APPL".
767  *
768  * COMM: 0: chans
769  *       2: framples
770  *       6: bits per sample
771  *       8: srate as 80-bit IEEE float
772  *  then if AIFC (not AIFF), 4 bytes giving compression id ("NONE"=not compressed)
773  *    followed by Pascal string giving long name of compression type
774  *
775  * SSND: 0: data location (offset within SSND chunk)
776  *
777  * Other chunks include:  ANNO: a comment, INST: loop control, MARK: marker, MIDI: midi,
778  *                        COMT: comment (max 65536 chars), NAME: sound name, AUTH: author's name
779  *                        (c), AESD: recording data, APPL: application specific stuff
780  *    "MARK" size short-#marks {marks} -- latter are short-ID long-position pstring-name.
781  *    "INST" size chars[baseNote detune lowNote highNote lowVelocity HighVelocity] short-gain loops[sustain release]
782  *      loop: short-playMode marker-begin marker-end (signed?) shorts)
783  *         playMode: 0 no loop, 1 forward loop, 2 forward/backward loop
784  *      chars are MIDI data (detune is in cents)
785  *    "MIDI" size MIDI-data...
786  *    "AESD" size AES Channel Status Data (24 bytes as specified by AES)
787  *      see "AES: Guidelines for the use of the AES3 interface"
788  *      byte 0: bit 0: 0 = consumer, 1 = pro
789  *              bit 1: 0 = audio, 1 = non-audio
790  *              bits 2:4: emphasis: 0:none, 4:none, 6:CD, 7:CCITT J17
791  *              bits 6:7: srate: 00 = 48KHz, 01 = 48, 10 = 44.1, 11 = 32
792  *      byte 1: bits 0:3: chans: 2:mono, else stereo
793  *      byte 2 for word size stuff (always ends up 16-bit): bits 3-5 = sample length where 4 = 16-bit
794  *      byte 3: multi-channels modes, 4: AES sync ref, 5:unused, 6-9:ASCII source ID, 10-13:ASCII destination ID
795  *      byte 14-17:local sample addr, 18-21:time of day addr, then CRC checks
796  *    "APPL" size signature data
797  *    "COMT" size short-#comments {comments} -- the latter are long-time marker short-text-length char-text
798  *       time is in seconds since 1-Jan-1904
799  *    "NAME"/"AUTH"/"(c) "/"ANNO" size char-name
800  *    "FVER" size(4) AIFC-format-version -- currently always 0xA2805140
801  *    "SAXL" -- a desperate kludge to get around Apple's own compression schemes!
802  *
803  * always big-endian
804  * There was also (briefly) an AIFS file, now deprecated.
805  */
806 
807 
808 /* ieee-80 conversions -- design by committee! */
809 /* this code taken from CSound sources -- apparently originally written by Malcolm Slaney at Apple */
810 
811 #define ULPOW2TO31	((uint32_t)0x80000000)
812 #define DPOW2TO31	((double)2147483648.0)	/* 2^31 */
813 
myUlongToDouble(uint32_t ul)814 static double myUlongToDouble(uint32_t ul)
815 {
816   double val;
817   if (ul & ULPOW2TO31) val = DPOW2TO31 + (ul & (~ULPOW2TO31));
818   else val = ul;
819   return val;
820 }
821 
822 
myDoubleToUlong(double val)823 static uint32_t myDoubleToUlong(double val)
824 {
825   uint32_t ul;
826   if (val < DPOW2TO31) ul = (uint32_t)val;
827   else ul = ULPOW2TO31 | (uint32_t)(val-DPOW2TO31);
828   return ul;
829 }
830 
831 
ieee_80_to_double(uint8_t * p)832 static double ieee_80_to_double(uint8_t *p)
833 {
834   uint8_t sign;
835   short lexp = 0;
836   uint32_t mant1 = 0;
837   uint32_t mant0 = 0;
838   lexp = *p++;  lexp <<= 8;  lexp |= *p++;  sign = (lexp & 0x8000) ? 1 : 0;  lexp &= 0x7FFF;
839   mant1 = *p++;  mant1 <<= 8;  mant1 |= *p++;  mant1 <<= 8;  mant1 |= *p++;  mant1 <<= 8;  mant1 |= *p++;
840   mant0 = *p++;  mant0 <<= 8;  mant0 |= *p++;  mant0 <<= 8;  mant0 |= *p++;  mant0 <<= 8;  mant0 |= *p++;
841   if (mant1 == 0 && mant0 == 0 && lexp == 0 && sign == 0)
842     return 0.0;
843   else
844     {
845       double val;
846       val = myUlongToDouble(mant0) * pow(2.0, -63.0);
847       val += myUlongToDouble(mant1) * pow(2.0, -31.0);
848       val *= pow(2.0, ((double) lexp) - 16383.0);
849       return sign ? -val : val;
850     }
851 }
852 
853 
double_to_ieee_80(double val,uint8_t * p)854 static void double_to_ieee_80(double val, uint8_t *p)
855 {
856   short lexp = 0;
857   uint8_t sign = 0;
858   uint32_t mant1 = 0;
859   uint32_t mant0 = 0;
860   if (val < 0.0)
861     {
862       sign = 1;
863       val = -val;
864     }
865   if (val != 0.0)	/* val identically zero -> all elements zero */
866     {
867       lexp = (short)(log(val) / log(2.0) + 16383.0);
868       val *= pow(2.0, 31.0 + 16383.0 - (double)lexp);
869       mant1 = myDoubleToUlong(val);
870       val -= myUlongToDouble(mant1);
871       val *= pow(2.0, 32.0);
872       mant0 = myDoubleToUlong(val);
873     }
874   *p++ = ((sign << 7) | (lexp >> 8));  *p++ = 0xFF & lexp;
875   *p++ = 0xFF & (mant1 >> 24);  *p++ = 0xFF & (mant1 >> 16);  *p++ = 0xFF & (mant1 >> 8);  *p++ = 0xFF & (mant1);
876   *p++ = 0xFF & (mant0 >> 24);  *p++ = 0xFF & (mant0 >> 16);  *p++ = 0xFF & (mant0 >> 8);  *p++ = 0xFF & (mant0);
877 }
878 
879 
880 static mus_long_t update_form_size, update_framples_location, update_ssnd_location, update_rf64_location;
881 
seek_and_read(int fd,uint8_t * buf,mus_long_t offset,int nbytes)882 static int64_t seek_and_read(int fd, uint8_t *buf, mus_long_t offset, int nbytes)
883 {
884   if (offset < 0) return(-1);
885   lseek(fd, offset, SEEK_SET);
886   return(read(fd, buf, nbytes));
887 }
888 
889 
read_aiff_marker(int m,uint8_t * buf)890 static int read_aiff_marker(int m, uint8_t *buf)
891 {
892   int psize;
893   marker_ids[m] = mus_char_to_bshort((uint8_t *)buf);
894   marker_positions[m] = mus_char_to_bint((uint8_t *)(buf + 2));
895   psize = (int)buf[6] + 1;
896   if (psize & 1) psize++;
897   return(psize+6);
898 }
899 
900 
read_aif_mark_chunk(int fd,uint8_t * buf,mus_long_t offset)901 static void read_aif_mark_chunk(int fd, uint8_t *buf, mus_long_t offset)
902 {
903   int num_marks, m, moff, msize;
904   /* unsigned short #marks, each mark: id pos name (pstring damn it) */
905   num_marks = mus_char_to_ubshort((uint8_t *)(buf + 8));
906   if (num_marks > markers)
907     {
908       if (markers > 0)
909 	{
910 	  if (marker_ids) free(marker_ids);
911 	  if (marker_positions) free(marker_positions);
912 	}
913       markers = num_marks;
914       marker_ids = (int *)calloc(markers, sizeof(int));
915       marker_positions = (int *)calloc(markers, sizeof(int));
916     }
917   moff = 10;
918   for (m = 0; m < num_marks; m++)
919     {
920       if (seek_and_read(fd, (uint8_t *)buf, offset + moff, 8) > 0)
921 	{
922 	  msize = read_aiff_marker(m, (uint8_t *)buf);
923 	  moff += msize;
924 	}
925     }
926 }
927 
928 
read_aif_inst_chunk(uint8_t * buf)929 static void read_aif_inst_chunk(uint8_t *buf)
930 {
931   base_note = buf[8];
932   base_detune = buf[9];
933   loop_modes[0] = mus_char_to_bshort((uint8_t *)(buf + 16));
934   loop_starts[0] = mus_char_to_bshort((uint8_t *)(buf + 18));
935   loop_ends[0] = mus_char_to_bshort((uint8_t *)(buf + 20));
936   loop_modes[1] = mus_char_to_bshort((uint8_t *)(buf + 22));
937   loop_starts[1] = mus_char_to_bshort((uint8_t *)(buf + 24));
938   loop_ends[1] = mus_char_to_bshort((uint8_t *)(buf + 26));
939   /* these are mark numbers */
940 }
941 
942 
read_aif_aux_comment(uint8_t * buf,mus_long_t offset,int chunksize)943 static void read_aif_aux_comment(uint8_t *buf, mus_long_t offset, int chunksize)
944 {
945   int i, j = 0;
946   for (i = 0; i < AUX_COMMENTS; i++)
947     if (aux_comment_start[i] == 0)
948       {
949 	j = i;
950 	break;
951       }
952   if (j >= AUX_COMMENTS)
953     {
954       mus_print("read_aiff_header: ran out of auxiliary comment space");
955       j = 0;
956     }
957   aux_comment_start[j] = offset + 8;
958   if (match_four_chars((uint8_t *)buf, I_COMT))
959     aux_comment_start[j] += 8; /* skip time stamp and markerId (not ID, I assume!) */
960   aux_comment_end[j] = offset + 7 + chunksize;
961 }
962 
963 
read_aif_appl_chunk(uint8_t * buf,mus_long_t offset,int chunksize)964 static void read_aif_appl_chunk(uint8_t *buf, mus_long_t offset, int chunksize)
965 {
966   static const uint8_t I_SU7M[4] = {'S','U','7','M'};
967   static const uint8_t I_SU7R[4] = {'S','U','7','R'};
968 
969   if (match_four_chars((uint8_t *)(buf + 8), I_MUS_))
970     {
971       /* my chunk has an arbitrary length comment (a lisp program evaluated in the CLM package)
972        *   to handle mix et al.  Can't use the built-in chunk for this because the comment length might
973        *   be greater than 65536 chars.  Need to remember to pad to even length here.
974        */
975       comment_start = offset + 12;
976       comment_end = comment_start + chunksize - 5;
977     }
978   else
979     {
980       if ((match_four_chars((uint8_t *)(buf + 8), I_SU7M)) ||
981 	  (match_four_chars((uint8_t *)(buf + 8), I_SU7R)))
982 	{
983 	  mus_print("this is an SU700 ssp file?");
984 	  data_location = 512;
985 	  chans = 1;
986 	  /* actually SU7M and SU7R point to 2 chan data as separate chunks */
987 	}
988     }
989 }
990 
991 
mus_ubint_to_char(uint8_t * j,uint32_t x)992 static void mus_ubint_to_char(uint8_t *j, uint32_t x)
993 {
994   uint8_t *ox = (uint8_t *)&x;
995 #if MUS_LITTLE_ENDIAN
996   j[0] = ox[3]; j[1] = ox[2]; j[2] = ox[1]; j[3] = ox[0];
997 #else
998   memcpy((void *)j, (void *)ox, 4);
999 #endif
1000 }
1001 
1002 
read_aiff_header(const char * filename,int fd,int overall_offset)1003 static int read_aiff_header(const char *filename, int fd, int overall_offset)
1004 {
1005   /* we know we have checked for FORM xxxx AIFF|AIFC when we arrive here */
1006   /* as far as I can tell, the COMM block has the header data we seek, and the SSND block has the sound data */
1007   uint32_t chunkloc, ssnd_bytes = 0;
1008   int i;
1009   bool happy = true, got_comm = false;
1010   mus_long_t offset = 0;
1011 
1012   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)(hdrbuf + 8 + overall_offset));
1013   update_ssnd_location = 0;
1014   chunkloc = 12 + overall_offset;
1015   for (i = 0; i < AUX_COMMENTS; i++) aux_comment_start[i] = 0;
1016   sample_type = MUS_BSHORT;
1017   srate = 0;
1018   chans = 0;
1019   markers = 0;
1020   if (marker_ids) free(marker_ids);
1021   if (marker_positions) free(marker_positions);
1022   marker_ids = NULL;
1023   marker_positions = NULL;
1024 
1025   true_file_length = SEEK_FILE_LENGTH(fd);
1026   update_form_size = mus_char_to_ubint((uint8_t *)(hdrbuf + 4 + overall_offset)); /* should be file-size - 8 unless there are multiple forms */
1027 
1028   while (happy)
1029     {
1030       uint32_t chunksize;
1031       offset += chunkloc;
1032       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 32) <= 0)
1033 	{
1034 	  if ((got_comm) && (data_location > 0))
1035 	    {
1036 	      mus_print("%s, aiff header: chunks confused at %" print_mus_long "; will try to continue", filename, offset);
1037 	      break;
1038 	    }
1039 	  return(mus_error(MUS_HEADER_READ_FAILED, "%s, aiff header: chunks confused at %" print_mus_long , filename, offset));
1040 	}
1041 
1042       chunksize = mus_char_to_ubint((uint8_t *)(hdrbuf + 4));
1043       if ((chunksize == 0) && /* can be empty data chunk */
1044 	  (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0))
1045 	break;
1046 
1047       /* fprintf(stderr, "chunk: %c%c%c%c for %d\n", hdrbuf[0], hdrbuf[1], hdrbuf[2], hdrbuf[3], chunksize); */
1048 
1049       if (match_four_chars((uint8_t *)hdrbuf, I_COMM))
1050 	{
1051 	  uint32_t framples;
1052 	  got_comm = true;
1053 
1054 	  chans = mus_char_to_bshort((uint8_t *)(hdrbuf + 8));
1055 	  framples = mus_char_to_ubint((uint8_t *)(hdrbuf + 10)); /* was bint 27-Jul-01 */
1056 	  update_framples_location = 10 + offset;
1057 
1058 	  original_sample_type = mus_char_to_bshort((uint8_t *)(hdrbuf + 14));
1059 	  if ((original_sample_type % 8) != 0)
1060 	    {
1061 	      /* weird sizes are legal --
1062 	       * these samples are left-justified (and zero padded on the right), so
1063 	       * we can handle any bit size by rounding up to the nearest byte.
1064 	       */
1065 	      original_sample_type = 8 * (1 + (original_sample_type >> 3));
1066 	    }
1067 	  if (original_sample_type == 8) sample_type = MUS_BYTE;
1068 	  else if (original_sample_type == 16) sample_type = MUS_BSHORT;
1069 	  else if (original_sample_type == 24) sample_type = MUS_B24INT;
1070 	  else if (original_sample_type == 32) sample_type = MUS_BINT;
1071 	  else if (original_sample_type == 64) sample_type = MUS_BDOUBLE;
1072 	  else return(mus_error(MUS_HEADER_READ_FAILED, "%s: bits per sample: %d?", filename, mus_char_to_bshort((uint8_t *)(hdrbuf + 14))));
1073 
1074 	  srate = (int)ieee_80_to_double((uint8_t *)(hdrbuf + 16));
1075 
1076 	  /* if AIFC, compression type over-rides (possibly bogus) original_sample_type */
1077 	  if (type_specifier == mus_char_to_uninterpreted_int((unsigned const char *)I_AIFC))
1078 	    {
1079 	      static const uint8_t I_twos[4] = {'t','w','o','s'};  /* AIFC big endian? */
1080 	      /* some aifc files assume the compression field is a new and very weird chunk!! -- surely a bug? */
1081 	      /* AIFF spec says COMM size is always 18, but this is amended in the newer AIFC spec */
1082 	      if (chunksize == 18) chunksize += (5 + ((int)hdrbuf[30]));             /* 5 = chunk header length in this case */
1083 	      if ((!(match_four_chars((uint8_t *)(hdrbuf + 26), I_NONE))) &&
1084 		  (!(match_four_chars((uint8_t *)(hdrbuf + 26), I_twos))))
1085 		{
1086 		  static const uint8_t I_ALAW[4] = {'A','L','A','W'};
1087 		  original_sample_type = mus_char_to_uninterpreted_int((uint8_t *)(hdrbuf + 26));
1088 		  if ((match_four_chars((uint8_t *)(hdrbuf + 26), I_ALAW)) ||
1089 		      (match_four_chars((uint8_t *)(hdrbuf + 26), I_alaw)))
1090 		    sample_type = MUS_ALAW;
1091 		  else
1092 		    {
1093 		      if ((match_four_chars((uint8_t *)(hdrbuf + 26), I_ULAW)) ||
1094 			  (match_four_chars((uint8_t *)(hdrbuf + 26), I_ulaw)))
1095 			sample_type = MUS_MULAW;
1096 		      else
1097 			{
1098 			  static const uint8_t I_ni23[4] = {'n','i','2','3'};
1099 			  if ((match_four_chars((uint8_t *)(hdrbuf + 26), I_sowt)) ||
1100 			      (match_four_chars((uint8_t *)(hdrbuf + 26), I_ni23)))
1101 			    {
1102 			      /* Sound.h sez sowt is just 16-bit format */
1103 			      if (sample_type == MUS_BSHORT) sample_type = MUS_LSHORT;
1104 			      else if (sample_type == MUS_B24INT) sample_type = MUS_L24INT;
1105 			      else if (sample_type == MUS_BINT) sample_type = MUS_LINT;
1106 			    }
1107 			  else
1108 			    {
1109 			      if (match_four_chars((uint8_t *)(hdrbuf + 26), I_raw_))
1110 				{
1111 				  if (sample_type == MUS_BYTE) sample_type = MUS_UBYTE;
1112 				  else if (sample_type == MUS_BSHORT) sample_type = MUS_UBSHORT;
1113 				}
1114 			      else
1115 				{
1116 				  uint8_t I_FL32[4] = {'F','L','3','2'};  /* 32-bit float (apparently used by CSound and SoundHack) */
1117 				  if ((match_four_chars((uint8_t *)(hdrbuf + 26), I_fl32)) ||
1118 				      (match_four_chars((uint8_t *)(hdrbuf + 26), I_FL32)))
1119 				    sample_type = MUS_BFLOAT;
1120 				  else
1121 				    {
1122 				      if (match_four_chars((uint8_t *)(hdrbuf + 26), I_fl64))
1123 					sample_type = MUS_BDOUBLE;
1124 				      else
1125 					{
1126 					  static const uint8_t I_ima4[4] = {'i','m','a','4'};  /* AIFC IMA adpcm apparently */
1127 					  if (match_four_chars((uint8_t *)(hdrbuf + 26), I_ima4))
1128 					    {
1129 					      block_align = 34;
1130 					      original_sample_type = MUS_AIFF_IMA_ADPCM;
1131 					    }
1132 					  else
1133 					    {
1134 					      static const uint8_t I_in32[4] = {'i','n','3','2'};
1135 					      if (match_four_chars((uint8_t *)(hdrbuf + 26), I_in32))
1136 						sample_type = MUS_BINT;
1137 					      else
1138 						{
1139 						  static const uint8_t I_in24[4] = {'i','n','2','4'};
1140 						  if (match_four_chars((uint8_t *)(hdrbuf + 26), I_in24))
1141 						    sample_type = MUS_B24INT;
1142 						  else
1143 						    {
1144 						      /* others from Sound.h:
1145 							 0x6D730002, -- Microsoft ADPCM - ACM code 2
1146 							 0x6D730011, -- DVI/Intel IMA ADPCM - ACM code 17
1147 							 'MAC3' -- MACE 3:1
1148 							 'MAC6' -- MACE 6:1
1149 							 'cdx4' -- CD/XA 4:1
1150 							 'cdx2' -- CD/XA 2:1
1151 							 'dvca' -- DV Audio
1152 							 'QDMC' -- QDesign music
1153 							 'QDM2' -- QDesign2 music
1154 							 'Qclp' -- QUALCOMM PureVoice
1155 							 0x6D730055 -- MPEG Layer 3, CBR only (pre QT4.1)
1156 							 '.mp3' -- MPEG Layer 3, CBR & VBR (QT4.1 and later)
1157 
1158 							 openquicktime and ffmpeg have decoders for some of these; all too complex for my taste
1159 							 on a Mac, we could apparently pick up decoders from coreaudio
1160 						      */
1161 						      sample_type = MUS_UNKNOWN_SAMPLE;
1162 						    }
1163 						}
1164 					    }
1165 					}
1166 				    }
1167 				}
1168 			    }
1169 			}
1170 		    }
1171 		}
1172 	    }
1173 	  data_size = (framples * mus_bytes_per_sample(sample_type) * chans);
1174 	}
1175       else
1176 	{
1177 	  if (match_four_chars((uint8_t *)hdrbuf, I_SSND))
1178 	    {
1179 	      if (data_location != 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: two SSND chunks found", filename));
1180 	      update_ssnd_location = offset + 4;
1181 	      data_location = mus_char_to_bint((uint8_t *)(hdrbuf + 8)) + offset + 16; /* Baroque! */
1182 
1183 	      /* offset is where the hdrbuf is positioned in the file, the sound data offset itself is at loc+8 and the */
1184 	      /* 0-based location of the sound data is at the end of the chunk = 16 (8 = header+4 = offset+4 = blocksize) */
1185 	      /* the next int can be the block size if the data is block-aligned */
1186 	      /* only one SSND per AIFF is allowed */
1187 
1188 	      if (chunksize == 0) break; /* this may happen while pre-reading an in-progress output file for updating */
1189 	      ssnd_bytes = offset + chunksize - data_location + 8;
1190 	    }
1191 	  else
1192 	    {
1193 	      static const uint8_t I_AUTH[4] = {'A','U','T','H'};
1194 	      if ((match_four_chars((uint8_t *)hdrbuf, I_ANNO)) ||
1195 		  (match_four_chars((uint8_t *)hdrbuf, I_COMT)) ||
1196 		  (match_four_chars((uint8_t *)hdrbuf, I_NAME)) ||
1197 		  (match_four_chars((uint8_t *)hdrbuf, I_AUTH)))
1198 		read_aif_aux_comment(hdrbuf, offset, chunksize);
1199 	      else
1200 		{
1201 		  if (match_four_chars((uint8_t *)hdrbuf, I_APPL))
1202 		    read_aif_appl_chunk(hdrbuf, offset, chunksize);
1203 		  else
1204 		    {
1205 		      if (match_four_chars((uint8_t *)hdrbuf, I_INST))
1206 			read_aif_inst_chunk(hdrbuf);
1207 		      else
1208 			{
1209 			  if (match_four_chars((uint8_t *)hdrbuf, I_MARK))
1210 			    read_aif_mark_chunk(fd, hdrbuf, offset);
1211 			}
1212 		    }
1213 		}
1214 	    }
1215 	}
1216       chunkloc = (8 + chunksize);
1217       if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */
1218       if ((offset + chunkloc) >= update_form_size) happy = false;
1219     }
1220 
1221   if (!got_comm)
1222     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no COMM chunk", filename));
1223   if (data_location == 0)
1224     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no SSND (data) chunk", filename));
1225 
1226   if (data_size > true_file_length)
1227     {
1228       data_size = true_file_length - data_location;
1229       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
1230     }
1231 
1232   if ((data_size > ssnd_bytes) && (sample_type != MUS_UNKNOWN_SAMPLE))
1233     data_size = ssnd_bytes;
1234   data_size = mus_bytes_to_samples(sample_type, data_size);
1235 
1236   return(MUS_NO_ERROR);
1237 }
1238 
1239 
sndlib_format_to_aiff_bits(mus_sample_t samp_type)1240 static int sndlib_format_to_aiff_bits(mus_sample_t samp_type)
1241 {
1242   switch (samp_type)
1243     {
1244     case MUS_BSHORT: case MUS_LSHORT: case MUS_UBSHORT: case MUS_ULSHORT:  return(16);
1245     case MUS_B24INT: case MUS_L24INT:                                      return(24);
1246     case MUS_BINT: case MUS_LINT: case MUS_BFLOAT: case MUS_LFLOAT:        return(32);
1247     case MUS_BDOUBLE: case MUS_LDOUBLE:                                    return(64);
1248     case MUS_BYTE: case MUS_UBYTE: case MUS_MULAW: case MUS_ALAW:          return(8);
1249     default:
1250       return(mus_error(MUS_UNSUPPORTED_SAMPLE_TYPE, "aiff header: can't write sample type: %d (%s)",
1251 		       samp_type,
1252 		       any_sample_type_name(samp_type)));
1253       break;
1254     }
1255 }
1256 
1257 
sndlib_format_to_aifc_name(mus_sample_t samp_type)1258 static const char *sndlib_format_to_aifc_name(mus_sample_t samp_type)
1259 {
1260   switch (samp_type)
1261     {
1262     case MUS_BSHORT: case MUS_B24INT: case MUS_BINT: case MUS_BYTE: return((const char *)I_NONE); /* use in24 and in32? */
1263     case MUS_LSHORT: case MUS_L24INT: case MUS_LINT:                return((const char *)I_sowt); /* should this use ni23? */
1264     case MUS_BFLOAT:                                                return((const char *)I_fl32);
1265     case MUS_BDOUBLE:                                               return((const char *)I_fl64);
1266     case MUS_UBYTE: case MUS_UBSHORT:                               return((const char *)I_raw_);
1267     case MUS_MULAW:                                                 return((const char *)I_ulaw);
1268     case MUS_ALAW:                                                  return((const char *)I_alaw);
1269     default:                                                        return((const char *)I_NONE);
1270     }
1271 }
1272 
1273 
write_aif_header(int fd,int wsrate,int wchans,mus_long_t siz,mus_sample_t samp_type,const char * comment,int len,bool aifc_header)1274 static int write_aif_header(int fd, int wsrate, int wchans, mus_long_t siz, mus_sample_t samp_type, const char *comment, int len, bool aifc_header)
1275 {
1276   /* we write the simplest possible AIFC header: AIFC | COMM | APPL-MUS_ if needed | SSND eof. */
1277   /* the assumption being that we're going to be appending sound data once the header is out   */
1278   /* INST and MARK chunks added Jul-95 for various programs that expect them (MixView).        */
1279   /* set aifc_header to false to get old-style AIFF header */
1280   int i, j, lenhdr = 0, lenloop, curend = 0, extra = 0;
1281 
1282   lenloop = 38;
1283   if ((loop_modes[0] != 0) || (loop_modes[1] != 0)) lenloop = 42 + 28;
1284   if (len != 0)
1285     {
1286       lenhdr = 12;
1287       if ((len % 4) != 0)
1288 	extra = (4 - (len % 4));
1289     }
1290 
1291   write_four_chars((uint8_t *)hdrbuf, I_FORM);
1292   if (aifc_header)
1293     mus_ubint_to_char((uint8_t *)(hdrbuf + 4), len + 30 + 16 + lenloop + siz + lenhdr + extra + 12 + 10);
1294   else mus_ubint_to_char((uint8_t *)(hdrbuf + 4), len + 30 + 16 + lenloop + siz + lenhdr + extra);
1295 
1296   /*
1297    * comment length + 4 for AIFF 18+8 for I_COMM info + 16 for I_SSND info + 38 for INST and MARK +
1298    * siz for data + 12 for comment header if any + padding == total size - 8 (i.e. FORM header).
1299    * INST+MARK (38) added 3-Jul-95 for Notam software compatibility
1300    */
1301   if (aifc_header)
1302     {
1303       static const uint8_t I_FVER[4] = {'F','V','E','R'};
1304       write_four_chars((uint8_t *)(hdrbuf + 8), I_AIFC);
1305       header_write(fd, hdrbuf, 12);
1306       curend = 12;
1307       write_four_chars((uint8_t *)hdrbuf, I_FVER);
1308       mus_bint_to_char((uint8_t *)(hdrbuf + 4), 4);
1309       mus_bint_to_char((uint8_t *)(hdrbuf + 8), 0xA2805140);
1310     }
1311   else write_four_chars((uint8_t *)(hdrbuf + 8), I_AIFF);
1312 
1313   write_four_chars((uint8_t *)(hdrbuf + 12), I_COMM);
1314   if (aifc_header)
1315     mus_bint_to_char((uint8_t *)(hdrbuf + 16), 18 + 10);
1316   else mus_bint_to_char((uint8_t *)(hdrbuf + 16), 18);
1317 
1318   mus_bshort_to_char((uint8_t *)(hdrbuf + 20), (short)wchans);
1319   if (wchans > 0)
1320     mus_ubint_to_char((uint8_t *)(hdrbuf + 22), siz / (wchans * mus_bytes_per_sample(samp_type)));
1321 
1322   mus_bshort_to_char((uint8_t *)(hdrbuf + 26), sndlib_format_to_aiff_bits(samp_type));
1323   double_to_ieee_80((double)wsrate, (uint8_t *)(hdrbuf + 28));
1324 
1325   if (aifc_header)
1326     {
1327       char *str;
1328       str = (char *)sndlib_format_to_aifc_name(samp_type);
1329       write_four_chars((uint8_t *)(hdrbuf + 38), (const uint8_t *)str);
1330       (*(uint8_t *)(hdrbuf + 42)) = 4; /* final pad null not accounted-for */
1331       write_four_chars((uint8_t *)(hdrbuf + 43), (const uint8_t *)str);
1332       (*(uint8_t *)(hdrbuf + 47)) = 0;
1333       i = 48;
1334     }
1335   else i = 38;
1336 
1337   if (len != 0)
1338     {
1339       if (aifc_header)
1340 	{
1341 	  write_four_chars((uint8_t *)(hdrbuf + 48), I_APPL);
1342 	  mus_bint_to_char((uint8_t *)(hdrbuf + 52), len + 4 + extra);
1343 	  write_four_chars((uint8_t *)(hdrbuf + 56), I_MUS_);
1344 	  i = 60;
1345 	}
1346       else
1347 	{
1348 	  write_four_chars((uint8_t *)(hdrbuf + 38), I_APPL);
1349 	  mus_bint_to_char((uint8_t *)(hdrbuf + 42), len + 4 + extra);
1350 	  write_four_chars((uint8_t *)(hdrbuf + 46), I_MUS_);
1351 	  i = 50;
1352 	}
1353       for (j = 0; j < len; j++)
1354 	{
1355 	  if (i == HDRBUFSIZ)
1356 	    {
1357 	      curend += HDRBUFSIZ;
1358 	      header_write(fd, hdrbuf, HDRBUFSIZ);
1359 	      i = 0;
1360 	    }
1361 	  hdrbuf[i] = comment[j];
1362 	  i++;
1363 	}
1364       if (extra != 0)
1365 	{
1366 	  if ((i + extra) > HDRBUFSIZ)
1367 	    {
1368 	      curend += i;
1369 	      header_write(fd, hdrbuf, i);
1370 	      i = 0;
1371 	    }
1372 	  for (j = 0; j < extra; j++)
1373 	    {
1374 	      hdrbuf[i] = 0;
1375 	      i++;
1376 	    }
1377 	}
1378     }
1379   curend += i;
1380   header_write(fd, hdrbuf, i);
1381 
1382   if ((loop_modes[0] == 0) && (loop_modes[1] == 0))
1383     {
1384       write_four_chars((uint8_t *)hdrbuf, I_MARK);   /* SoundHack includes a blank MARK chunk for some reason */
1385       mus_bint_to_char((uint8_t *)(hdrbuf + 4), 2);
1386       mus_bshort_to_char((uint8_t *)(hdrbuf + 8), 0);
1387       write_four_chars((uint8_t *)(hdrbuf + 10), I_INST);
1388       mus_bint_to_char((uint8_t *)(hdrbuf + 14), 20);
1389       mus_bint_to_char((uint8_t *)(hdrbuf + 18), 0x3c00007f); /* base-note = middle C, detune = 0, lownote = 0, highnote = 0x7f */
1390       mus_bint_to_char((uint8_t *)(hdrbuf + 22), 0x017f0000); /* lowvelocity = 1, highvelocity = 0x7f, gain = 0 */
1391       mus_bint_to_char((uint8_t *)(hdrbuf + 26), 0);          /* no loops */
1392       mus_bint_to_char((uint8_t *)(hdrbuf + 30), 0);
1393       mus_bint_to_char((uint8_t *)(hdrbuf + 34), 0);
1394       header_write(fd, hdrbuf, 38);
1395       curend += 38;
1396     }
1397   else
1398     {
1399       write_four_chars((uint8_t *)hdrbuf, I_MARK);
1400       mus_bint_to_char((uint8_t *)(hdrbuf + 4), 8 * 4 + 2); /* 2 for mark#, then 2:id + 4:pos + 2:pstr */
1401       /* loop_info: 0..3 are markers positions (ids 1..4) */
1402       mus_bshort_to_char((uint8_t *)(hdrbuf + 8), 4);
1403       for (j = 0; j < 4; j++)
1404 	{
1405 	  mus_bshort_to_char((uint8_t *)(hdrbuf + 10 + 8 * j), j + 1);
1406 	  switch (j)
1407 	    {
1408 	    case 0: mus_bint_to_char((uint8_t *)(hdrbuf + 10 + 8 * j + 2), loop_starts[0]); break;
1409 	    case 1: mus_bint_to_char((uint8_t *)(hdrbuf + 10 + 8 * j + 2), loop_ends[0]);   break;
1410 	    case 2: mus_bint_to_char((uint8_t *)(hdrbuf + 10 + 8 * j + 2), loop_starts[1]); break;
1411 	    case 3: mus_bint_to_char((uint8_t *)(hdrbuf + 10 + 8 * j + 2), loop_ends[1]);   break;
1412 	    }
1413 	  mus_bshort_to_char((uint8_t *)(hdrbuf + 10 + 8 * j + 6), 0);
1414 	}
1415       header_write(fd, hdrbuf, 42);
1416       curend += 42;
1417       write_four_chars((uint8_t *)hdrbuf, I_INST);
1418       mus_bint_to_char((uint8_t *)(hdrbuf + 4), 20);
1419       mus_bint_to_char((uint8_t *)(hdrbuf + 8), 0x3c00007f);
1420       mus_bint_to_char((uint8_t *)(hdrbuf + 12), 0x017f0000);
1421       hdrbuf[8] = (uint8_t)(base_note);
1422       hdrbuf[9] = (uint8_t)(base_detune);
1423       mus_bshort_to_char((uint8_t *)(hdrbuf + 16), loop_modes[0]);
1424       mus_bshort_to_char((uint8_t *)(hdrbuf + 18), 1);
1425       mus_bshort_to_char((uint8_t *)(hdrbuf + 20), 2);
1426       mus_bshort_to_char((uint8_t *)(hdrbuf + 22), loop_modes[1]);
1427       mus_bshort_to_char((uint8_t *)(hdrbuf + 24), 3);
1428       mus_bshort_to_char((uint8_t *)(hdrbuf + 26), 4);
1429       header_write(fd, hdrbuf, 28);
1430       curend += 28;
1431     }
1432   write_four_chars((uint8_t *)(hdrbuf), I_SSND);
1433   mus_bint_to_char((uint8_t *)(hdrbuf + 4), siz + 8);
1434   mus_bint_to_char((uint8_t *)(hdrbuf + 8), 0);                        /* "offset" */
1435   mus_bint_to_char((uint8_t *)(hdrbuf + 12), 0);                       /* "blocksize " */
1436   header_write(fd, hdrbuf, 16);
1437   data_location = 16 + curend;
1438   return(MUS_NO_ERROR);
1439 }
1440 
1441 
mus_header_aiff_aux_comment(const char * name,mus_long_t * starts,mus_long_t * ends)1442 char *mus_header_aiff_aux_comment(const char *name, mus_long_t *starts, mus_long_t *ends)
1443 {
1444   /* AIFC: look for aux comments (ANNO chunks) */
1445   char *sc = NULL;
1446   if ((starts) && (starts[0] != 0))
1447     {
1448       mus_long_t full_len;
1449       int fd, i;
1450       fd = mus_file_open_read(name);
1451       if (fd == -1) return(NULL);
1452       full_len = 0;
1453       for (i = 0; i < AUX_COMMENTS; i++)
1454 	if ((starts[i] > 0) &&
1455 	    (starts[i] < ends[i]))
1456 	  full_len += (ends[i] - starts[i] + 3);
1457       if (full_len > 0)
1458 	{
1459 	  mus_long_t sc_len;
1460 	  sc = (char *)calloc(full_len, sizeof(char));
1461 	  sc_len = 0;
1462 	  for (i = 0; i < AUX_COMMENTS; i++)
1463 	    {
1464 	      mus_long_t start, end;
1465 	      start = starts[i];
1466 	      end = ends[i];
1467 	      if ((start > 0) && (start < end))
1468 		{
1469 		  int j;
1470 		  mus_long_t len;
1471 		  len = end - start + 1;
1472 		  lseek(fd, start, SEEK_SET);
1473 		  header_read(fd, (uint8_t *)(sc + sc_len), len);
1474 		  for (j = 0; j < len; j++)
1475 		    if (sc[j + sc_len] == 0)
1476 		      sc[j + sc_len] = ' ';
1477 		  sc_len += len;
1478 		  sc[sc_len++] = '\n';
1479 		}
1480 	    }
1481 	}
1482       CLOSE(fd, name);
1483     }
1484   return(sc);
1485 }
1486 
1487 
1488 
1489 /* ------------------------------------ CAFF ------------------------------------
1490  *
1491  * this is a new format from Apple ("Core Audio File Format") described at
1492  *    http://developer.apple.com/documentation/MusicAudio/Reference/CAFSpec
1493  *
1494  * all chunks as in AIFC but size is signed 64-bit int
1495  *
1496  * 0: 'caff'
1497  * 4: 1 ("version")
1498  * 6: 0 ("flags")
1499  * 8: 'desc' (required to be in this position)
1500  * 12: sizeof apple's CAFAudioFormat struct -- (32)
1501  *   20: srate (float64)
1502  *   28: format (int32)
1503  *   32: format flags
1504  *   36: bytes per "packet"
1505  *   40: framples per packet
1506  *   44: channels per frample
1507  *   48: bits per channel
1508  * audio data is in 'data' chunk
1509  */
1510 
1511 
read_caff_header(int fd)1512 static int read_caff_header(int fd)
1513 {
1514   mus_long_t chunksize = 8, offset = 0;
1515   bool happy = false;
1516   int err = MUS_NO_ERROR;
1517 
1518   #define data_is_float (1L << 0)
1519   #define data_is_big_endian (1L << 1)
1520   /* misleading name -- flag is 1 if data is little endian */
1521 
1522   sample_type = MUS_UNKNOWN_SAMPLE;
1523   srate = 0;
1524   chans = 0;
1525   data_size = 0;
1526   true_file_length = SEEK_FILE_LENGTH(fd);
1527 
1528   while (!happy)
1529     {
1530       offset += chunksize;
1531       if (offset >= true_file_length) break;
1532       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 64) <= 0) break;
1533       chunksize = mus_char_to_blong((uint8_t *)(hdrbuf + 4));
1534       if (chunksize < 0)
1535 	break;
1536 
1537       /* 'desc' is always the first chunk, but easier to handle in the loop */
1538       if (match_four_chars((uint8_t *)hdrbuf, I_desc))
1539 	{
1540 	  int format_flags, channels_per_frample, bits_per_channel;
1541 	  srate = (int)mus_char_to_bdouble((uint8_t *)(hdrbuf + 12));
1542 	  format_flags = mus_char_to_ubint((uint8_t *)(hdrbuf + 24));
1543 	  /* bytes_per_packet = mus_char_to_ubint((uint8_t *)(hdrbuf + 28)); */
1544 	  /* framples_per_packet = mus_char_to_ubint((uint8_t *)(hdrbuf + 32)); */
1545 	  channels_per_frample = mus_char_to_ubint((uint8_t *)(hdrbuf + 36));
1546 	  bits_per_channel = mus_char_to_ubint((uint8_t *)(hdrbuf + 40));
1547 	  chans = channels_per_frample;
1548 
1549 	  /* format id can be 'lpcm' 'alaw' 'ulaw' and a bunch of others we ignore */
1550 	  original_sample_type = mus_char_to_bint((uint8_t *)(hdrbuf + 20));
1551 	  if (match_four_chars((uint8_t *)(hdrbuf + 20), I_lpcm))
1552 	    {
1553 	      if (format_flags & data_is_float)
1554 		{
1555 		  if (!(format_flags & data_is_big_endian))
1556 		    {
1557 		      if (bits_per_channel == 32)
1558 			sample_type = MUS_BFLOAT;
1559 		      else
1560 			{
1561 			  if (bits_per_channel == 64)
1562 			    sample_type = MUS_BDOUBLE;
1563 			  else err = MUS_UNSUPPORTED_SAMPLE_TYPE;
1564 			}
1565 		    }
1566 		  else
1567 		    {
1568 		      if (bits_per_channel == 32)
1569 			sample_type = MUS_LFLOAT;
1570 		      else
1571 			{
1572 			  if (bits_per_channel == 64)
1573 			    sample_type = MUS_LDOUBLE;
1574 			  else err = MUS_UNSUPPORTED_SAMPLE_TYPE;
1575 			}
1576 		    }
1577 		}
1578 	      else
1579 		{
1580 		  if (!(format_flags & data_is_big_endian))
1581 		    {
1582 		      if (bits_per_channel == 32)
1583 			sample_type = MUS_BINTN;
1584 		      else
1585 			{
1586 			  if (bits_per_channel == 24)
1587 			    sample_type = MUS_B24INT;
1588 			  else
1589 			    {
1590 			      if (bits_per_channel == 16)
1591 				sample_type = MUS_BSHORT;
1592 			      else
1593 				{
1594 				  if (bits_per_channel == 8)
1595 				    sample_type = MUS_BYTE;
1596 				  else err = MUS_UNSUPPORTED_SAMPLE_TYPE;
1597 				}
1598 			    }
1599 			}
1600 		    }
1601 		  else
1602 		    {
1603 		      if (bits_per_channel == 32)
1604 			sample_type = MUS_LINTN;
1605 		      else
1606 			{
1607 			  if (bits_per_channel == 24)
1608 			    sample_type = MUS_L24INT;
1609 			  else
1610 			    {
1611 			      if (bits_per_channel == 16)
1612 				sample_type = MUS_LSHORT;
1613 			      else
1614 				{
1615 				  if (bits_per_channel == 8)
1616 				    sample_type = MUS_BYTE;
1617 				  else err = MUS_UNSUPPORTED_SAMPLE_TYPE;
1618 				}
1619 			    }
1620 			}
1621 		    }
1622 		}
1623 	    }
1624 	  else
1625 	    {
1626 	      if (match_four_chars((uint8_t *)(hdrbuf + 20), I_alaw))
1627 		{
1628 		  sample_type = MUS_ALAW;
1629 		}
1630 	      else
1631 		{
1632 		  if (match_four_chars((uint8_t *)(hdrbuf + 20), I_ulaw))
1633 		    {
1634 		      sample_type = MUS_MULAW;
1635 		    }
1636 		  else err = MUS_UNSUPPORTED_SAMPLE_TYPE;
1637 		}
1638 	    }
1639 	}
1640       else
1641 	{
1642 	  if (match_four_chars((uint8_t *)hdrbuf, I_data))
1643 	    {
1644 	      happy = true;
1645 	      data_location = offset + 16; /* skip the 4 bytes for "edit count" */
1646 	      update_framples_location = offset + 4;
1647 
1648 	      /* here chunksize can be -1! */
1649 	      if (chunksize > 0)
1650 		data_size = chunksize;
1651 	      else data_size = true_file_length - data_location;
1652 	    }
1653 	  /* else edct or something for comment? */
1654 
1655 	}
1656       chunksize += 12;
1657     }
1658 
1659   if (err == MUS_NO_ERROR)
1660     data_size = mus_bytes_to_samples(sample_type, data_size);
1661 
1662   return(err);
1663 }
1664 
1665 
write_caff_header(int fd,int wsrate,int wchans,mus_long_t wsize,mus_sample_t samp_type)1666 static int write_caff_header(int fd, int wsrate, int wchans, mus_long_t wsize, mus_sample_t samp_type)
1667 {
1668   int format_flags = 0, bytes_per_packet = 0, framples_per_packet = 1, bits_per_channel = 0;
1669 
1670   switch (samp_type)
1671     {
1672     case MUS_ALAW:
1673       bytes_per_packet = 1;
1674       bits_per_channel = 8;
1675       break;
1676 
1677     case MUS_MULAW:
1678       bytes_per_packet = 1;
1679       bits_per_channel = 8;
1680       break;
1681 
1682     default:
1683       if ((samp_type == MUS_LFLOAT) || (samp_type == MUS_LDOUBLE) || (samp_type == MUS_BFLOAT) || (samp_type == MUS_BDOUBLE))
1684 	format_flags = 1;
1685       if ((samp_type == MUS_LFLOAT) || (samp_type == MUS_LDOUBLE) || (samp_type == MUS_LINTN) || (samp_type == MUS_L24INT) || (samp_type == MUS_LSHORT))
1686 	format_flags |= 2;
1687       switch (samp_type)
1688 	{
1689 	case MUS_BYTE:
1690 	  bytes_per_packet = 1;
1691 	  bits_per_channel = 8;
1692 	  break;
1693 
1694 	case MUS_LSHORT: case MUS_BSHORT:
1695 	  bytes_per_packet = 2;
1696 	  bits_per_channel = 16;
1697 	  break;
1698 
1699 	case MUS_L24INT: case MUS_B24INT:
1700 	  bytes_per_packet = 3;
1701 	  bits_per_channel = 24;
1702 	  break;
1703 
1704 	case MUS_LFLOAT: case MUS_BFLOAT: case MUS_BINTN: case MUS_LINTN:
1705 	  bytes_per_packet = 4;
1706 	  bits_per_channel = 32;
1707 	  break;
1708 
1709 	case MUS_LDOUBLE: case MUS_BDOUBLE:
1710 	  bytes_per_packet = 8;
1711 	  bits_per_channel = 64;
1712 	  break;
1713 
1714 	default: break;
1715 	}
1716       break;
1717     }
1718   bytes_per_packet *= wchans;
1719 
1720   write_four_chars((uint8_t *)hdrbuf, I_caff);
1721   mus_bshort_to_char((uint8_t *)(hdrbuf + 4), 1);
1722   mus_bshort_to_char((uint8_t *)(hdrbuf + 6), 0);
1723   write_four_chars((uint8_t *)(hdrbuf + 8), I_desc);
1724   mus_blong_to_char((uint8_t *)(hdrbuf + 12), 32);
1725   mus_bdouble_to_char((uint8_t *)(hdrbuf + 20), (double)wsrate);
1726   switch (samp_type)
1727     {
1728     case MUS_ALAW:
1729       write_four_chars((uint8_t *)(hdrbuf + 28), I_alaw);
1730       break;
1731 
1732     case MUS_MULAW:
1733       write_four_chars((uint8_t *)(hdrbuf + 28), I_ulaw);
1734       break;
1735 
1736     default:
1737       write_four_chars((uint8_t *)(hdrbuf + 28), I_lpcm);
1738       break;
1739     }
1740   mus_bint_to_char((uint8_t *)(hdrbuf + 32), format_flags);
1741   mus_bint_to_char((uint8_t *)(hdrbuf + 36), bytes_per_packet);
1742   mus_bint_to_char((uint8_t *)(hdrbuf + 40), framples_per_packet);
1743   mus_bint_to_char((uint8_t *)(hdrbuf + 44), wchans);
1744   mus_bint_to_char((uint8_t *)(hdrbuf + 48), bits_per_channel);
1745   write_four_chars((uint8_t *)(hdrbuf + 52), I_data);
1746   mus_blong_to_char((uint8_t *)(hdrbuf + 56), wsize);
1747   update_framples_location = 56;
1748   mus_bint_to_char((uint8_t *)(hdrbuf + 64), 0);
1749   data_location = 68;
1750   header_write(fd, hdrbuf, 68);
1751   return(MUS_NO_ERROR);
1752 }
1753 
1754 
1755 
1756 /* ------------------------------------ RIFF (wave) ------------------------------------
1757  *
1758  * see ftp.microsoft.com:/SoftLib/MSLFILES/MDRK.EXE (also MMSYSTEM.H and MMREG.H)
1759  *     ftp://ftp.isi.edu/in-notes/rfc2361.txt
1760  *
1761  *   0: "RIFF" (little-endian) or "RIFX" (big-endian)
1762  *   4: size
1763  *   8: "WAVE"  ("RMID" = midi data, others are AVI, CPPO, ACON, DLS? etc)
1764  *       AVI chunk can include audio data
1765  *
1766  *   rest very similar to AIFF (odd-sized chunks are padded)
1767  *
1768  * fmt  0: format code (see below)
1769  *      2: chans
1770  *      4: srate (long)
1771  *      8: average rate "for buffer estimation"
1772  *     12: alignment "block size"
1773  *     14: data size (bits per sample) (PCM only)
1774  *     16: count (bytes) of extra info in the header (i.e. trailing info added to this basic header)
1775  *     20: samples per block (short) in dvi_adpcm
1776  *
1777  * formats are: 0: unknown, 1: PCM, 2: ADPCM, 3: IEEE float, 4: VSELP, 5: IBM_CVSD, 6: alaw, 7: mulaw
1778  *              0x10: OKI_ADPCM, 0x11: DVI_ADPCM, 0x12: MediaSpace_ADPCM,
1779  *              0x13: Sierra_ADPCM, 0x14: G723_ADPCM, 0x15: DIGISTD, 0x16: DIGIFIX, 0x17: Dialogic ADPCM,
1780  *              0x18: Mediavision ADPCM, 0x19: HP cu codec,
1781  *              0x20: Yamaha_ADPCM, 0x21: SONARC, 0x22: DSPGroup_TrueSpeech
1782  *              0x23: EchoSC1, 0x24: AudioFile_AF36, 0x25: APTX, 0x26: AudioFile_AF10
1783  *              0x27: prosody 1612, 0x28: lrc,
1784  *              0x30: Dolby_Ac2, 0x31: GSM610, 0x32: MSN audio codec, 0x33: Antext_ADPCM, 0x34: Control_res_vqlpc,
1785  *              0x35: DIGIREAL, 0x36: DIGIADPCM, 0x37: Control_res_cr10, 0x38: NMS_VBXADPCM, 0x39:Roland rdac,
1786  *              0x3a: echo sc3, 0x3b: Rockwell adpcm, 0x3c: Rockwell digitalk codec, 0x3d: Xebec,
1787  *              0x40: G721_ADPCM, 0x41: G728 CELP, 0x42: MS G723, 0x50: MPEG,
1788  *              0x52: RT24, 0x53: PAC, 0x55: Mpeg layer 3, 0x59: Lucent G723, 0x60: Cirrus,
1789  *              0x61: ESS Tech pcm, 0x62: voxware (obsolete), 0x63: canopus atrac,
1790  *              0x64: G726, 0x65: G722, 0x66: DSAT, 0x67: DSAT display,
1791  *              0x69: voxware (obsolete), 0x70: voxware ac8 (obsolete), 0x71: voxware ac10 (obsolete),
1792  *              0x72: voxware ac16 (obsolete), 0x73: voxware ac20 (obsolete), 0x74: voxware rt24,
1793  *              0x75: voxware rt29, 0x76: voxware rt29hw (obsolete), 0x77: voxware vr12 (obsolete),
1794  *              0x78: voxware vr18 (obsolete), 0x79: voxware tq40 (obsolete),
1795  *              0x80: softsound, 0x81: voxware tq60 (obsolete), 0x82: MS RT24, 0x83: G729A,
1796  *              0x84: MVI_MVI2, 0x85: DF G726, 0x86: DF GSM610, 0x88: isaudio, 0x89: onlive,
1797  *              0x91: sbc24, 0x92: dolby ac3 spdif, 0x97: zyxel adpcm, 0x98: philips lpcbb,
1798  *              0x99: packed, 0x100: rhetorex adpcm,
1799  *              0x101: Irat, 0x102: IBM_alaw?, 0x103: IBM_ADPCM?,
1800  *              0x111: vivo G723, 0x112: vivo siren, 0x123: digital g273
1801  *              0x200: Creative_ADPCM, 0x202: Creative fastspeech 8, 0x203: Creative fastspeech 10,
1802  *              0x220: quarterdeck, 0x300: FM_TOWNS_SND, 0x400: BTV digital, 0x680: VME vmpcm,
1803  *              0x1000: OLIGSM, 0x1001: OLIADPCM, 0x1002: OLICELP, 0x1003: OLISBC, 0x1004: OLIOPR
1804  *              0x1100: LH codec, 0x1400: Norris, 0x1401: isaudio, 0x1500: Soundspace musicompression, 0x2000: DVM
1805  * (see http://www.microsoft.com/asf/resources/draft-ietf-fleischman-codec-subtree-00.txt)
1806  *   and new:   0xFFFE: wave_format_extensible: bits/sample, mapping, 16 byte guid, 1st 2 bytes are code as above
1807  *
1808  * RIFF and LIST chunks have nested chunks.  Registered chunk names include:
1809  *   LIST with subchunks, one of which can be:
1810  *     INFO itself containing:
1811  *       IARL: archival location, IART: artist, ICMS: commissioned, ICMT: comment, ICOP: copyright, ICRD: creation date,
1812  *       ICRP: uh...cropped, IDIM: dimensions, IDPI: dpi, IENG: engineer, IGNR: genre, IKEY: keywords, ILGT: lightness,
1813  *       IMED: medium, INAM: name, IPLT: palette, IPRD: product, ISBJ: subject, ISFT: software, ISHP: sharpness,
1814  *       ISRC: source, ISRF: source form, ITCH: technician, ISMP: SMPTE time code, IDIT: digitization time
1815  *
1816  * data chunk has the samples
1817  * other (currently ignored) chunks are wavl = waveform data, fact, cues of some sort, slnt = silence,
1818  *     plst = playlist, adtl = associated data list, labl = cue label, note = cue comments,
1819  *     ltxt = text associated with data segment (cue), file, DISP = displayable object,
1820  *     JUNK = EBU placeholder -- see below, PAD = padding, etc
1821  * fact chunk generally has number of samples (used in compressed files)
1822  * bext chunk has comments -- perhaps add these to the info/list list?  I need an example! -- is the chunk id "bext"?
1823  */
1824 
wave_to_sndlib_format(int osf,int bps,bool little)1825 static mus_sample_t wave_to_sndlib_format(int osf, int bps, bool little)
1826 {
1827   switch (osf)
1828     {
1829     case 1:
1830       switch (bps)
1831 	{
1832 	case 8: return(MUS_UBYTE); break;
1833 	case 16: if (little) return(MUS_LSHORT); else return(MUS_BSHORT); break;
1834 	case 32: if (little) return(MUS_LINT); else return(MUS_BINT); break;
1835 	case 24: if (little) return(MUS_L24INT); else return(MUS_B24INT); break;
1836 	default: return(MUS_UBYTE); break;
1837 	}
1838       break;
1839     case 3:
1840       if (little)
1841 	{
1842 	  if (bps == 64)
1843 	    return(MUS_LDOUBLE);
1844 	  else return(MUS_LFLOAT);
1845 	  }
1846       else
1847 	{
1848 	  if (bps == 64)
1849 	    return(MUS_BDOUBLE);
1850 	  else return(MUS_BFLOAT);
1851 	  }
1852       break;
1853     case 6: if (bps == 8) return(MUS_ALAW); break;
1854     case 7: if (bps == 8) return(MUS_MULAW); break;
1855       /* IBM mulaw follows G711 specs like other versions (this info direct from IBM) */
1856     case 0x101: return(MUS_MULAW); break;
1857     case 0x102: return(MUS_ALAW); break;
1858     }
1859   return(MUS_UNKNOWN_SAMPLE);
1860 }
1861 
1862 
read_riff_fmt_chunk(uint8_t * hbuf,bool little)1863 static void read_riff_fmt_chunk(uint8_t *hbuf, bool little)
1864 {
1865   /* fmt chunk (also used in RF64 below)
1866    *
1867    * 8:  short format code        --1 = PCM for example
1868    * 10: short chans              --1
1869    * 12: long rate                --48000 (0xbb80)
1870    * 16: long ave rate            --65655 (0x10077)
1871    * 20: short align              --2
1872    * 22: short data size (bits)   --16
1873    * 24: bytes of extra
1874    * ... some extra data dependent on format
1875    *
1876    *  R I  F F  # #  # #  W A  V E  f m  t sp
1877    *  5249 4646 f851 0500 5741 5645 666d 7420
1878    *  e40f 0000 0100 0100 80bb 0000 0077 0100
1879    *  0200 1000 0000 0000 0000 0000 0000 0000
1880    *
1881    *  #x000551f8 = 348664 = size in bytes - 8
1882    *  #x00000fe4 = 4068 [fmt_ chunk size?]
1883    */
1884   original_sample_type = big_or_little_endian_short((uint8_t *)(hbuf + 8), little);
1885   chans = big_or_little_endian_short((uint8_t *)(hbuf + 10), little);
1886   srate = big_or_little_endian_int((uint8_t *)(hbuf + 12), little);
1887   block_align = big_or_little_endian_short((uint8_t *)(hbuf + 20), little);
1888   bits_per_sample = big_or_little_endian_short((uint8_t *)(hbuf + 22), little);
1889   if (original_sample_type == -2)        /* 0xFFFE = "extensible" : short size=22, short bits, long chanmap, short format */
1890     original_sample_type = big_or_little_endian_short((uint8_t *)(hbuf + 24 + 8), little);
1891   sample_type = wave_to_sndlib_format(original_sample_type, bits_per_sample, little);
1892 }
1893 
1894 
write_riff_fmt_chunk(int fd,uint8_t * hbuf,mus_sample_t samp_type,int wsrate,int wchans)1895 static int write_riff_fmt_chunk(int fd, uint8_t *hbuf, mus_sample_t samp_type, int wsrate, int wchans)
1896 {
1897   int err = MUS_NO_ERROR;
1898   write_four_chars((uint8_t *)hbuf, I_fmt_);
1899   mus_lint_to_char((uint8_t *)(hbuf + 4), 16);
1900   switch (samp_type)
1901     {
1902     case MUS_MULAW:
1903       mus_lshort_to_char((uint8_t *)(hbuf + 8), 7);
1904       mus_lshort_to_char((uint8_t *)(hbuf + 22), 8);
1905       break;
1906 
1907     case MUS_ALAW:
1908       mus_lshort_to_char((uint8_t *)(hbuf + 8), 6);
1909       mus_lshort_to_char((uint8_t *)(hbuf + 22), 8);
1910       break;
1911 
1912     case MUS_UBYTE:
1913       mus_lshort_to_char((uint8_t *)(hbuf + 8), 1);
1914       mus_lshort_to_char((uint8_t *)(hbuf + 22), 8);
1915       break;
1916 
1917     case MUS_LSHORT:
1918       mus_lshort_to_char((uint8_t *)(hbuf + 8), 1);
1919       mus_lshort_to_char((uint8_t *)(hbuf + 22), 16);
1920       break;
1921 
1922     case MUS_L24INT:
1923       mus_lshort_to_char((uint8_t *)(hbuf + 8), 1);
1924       mus_lshort_to_char((uint8_t *)(hbuf + 22), 24);
1925       break;
1926 
1927     case MUS_LINT:
1928       mus_lshort_to_char((uint8_t *)(hbuf + 8), 1);
1929       mus_lshort_to_char((uint8_t *)(hbuf + 22), 32);
1930       break;
1931 
1932     case MUS_LFLOAT:
1933       mus_lshort_to_char((uint8_t *)(hbuf + 8), 3);
1934       mus_lshort_to_char((uint8_t *)(hbuf + 22), 32);
1935       break;
1936 
1937     case MUS_LDOUBLE:
1938       mus_lshort_to_char((uint8_t *)(hbuf + 8), 3);
1939       mus_lshort_to_char((uint8_t *)(hbuf + 22), 64);
1940       break;
1941 
1942     default:
1943       /* don't call mus_error directly -- we need to close the file first in mus_header_write */
1944       err = MUS_UNSUPPORTED_SAMPLE_TYPE;
1945       break;
1946     }
1947   mus_lshort_to_char((uint8_t *)(hbuf + 10), (short)wchans);
1948   mus_lint_to_char((uint8_t *)(hbuf + 12), wsrate);
1949   mus_lint_to_char((uint8_t *)(hbuf + 16), wsrate * wchans * mus_bytes_per_sample(samp_type)); /* added chans 10-Mar-99 */
1950   mus_lshort_to_char((uint8_t *)(hbuf + 20), (short)(wchans * mus_bytes_per_sample(samp_type)));
1951   /* 22 short written above = bits/sample */
1952   header_write(fd, hbuf, 24);
1953   return(err);
1954 }
1955 
1956 
1957 static const uint8_t I_JUNK[4] = {'J','U','N','K'};
1958 
read_riff_header(const char * filename,int fd)1959 static int read_riff_header(const char *filename, int fd)
1960 {
1961   /* we know we have checked for RIFF xxxx WAVE when we arrive here */
1962   int chunkloc = 12, i;
1963   bool little = true, got_fmt = false;
1964   mus_long_t offset = 0;
1965 
1966   if (match_four_chars((uint8_t *)hdrbuf, I_RIFX)) little = false; /* big-endian data in this case, but I've never seen one */
1967   little_endian = little;
1968   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)(hdrbuf + 8));
1969   sample_type = MUS_UNKNOWN_SAMPLE;
1970   srate = 0;
1971   chans = 0;
1972   fact_samples = 0;
1973   bits_per_sample = 0;
1974   for (i = 0; i < AUX_COMMENTS; i++) aux_comment_start[i] = 0;
1975   true_file_length = SEEK_FILE_LENGTH(fd);
1976   update_form_size = big_or_little_endian_int((uint8_t *)(hdrbuf + 4), little);
1977 
1978   while (true)
1979     {
1980       uint32_t chunksize;
1981       offset += chunkloc;
1982       if (offset >= true_file_length) break;
1983       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 64) <= 0) break;
1984       chunksize = big_or_little_endian_uint((uint8_t *)(hdrbuf + 4), little);
1985       if ((chunksize == 0) && /* can be empty data chunk */
1986 	  (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0))
1987 	break;
1988       if (match_four_chars((uint8_t *)hdrbuf, I_fmt_))
1989 	{
1990 	  got_fmt = true;
1991 	  update_framples_location = 12 + offset;
1992 	  read_riff_fmt_chunk(hdrbuf, little);
1993 	}
1994       else
1995 	{
1996 	  if ((match_four_chars((uint8_t *)hdrbuf, I_data)) && (data_location == 0))
1997 	    {
1998 	      update_ssnd_location = offset + 4;
1999 	      data_location = offset + 8;
2000 	      data_size = big_or_little_endian_uint((uint8_t *)(hdrbuf + 4), little); /* was int 27-Jul-01 */
2001 	      if (chunksize == 0) break; /* see aiff comment */
2002 	    }
2003 	  else
2004 	    {
2005 	      if (match_four_chars((uint8_t *)hdrbuf, I_fact))
2006 		{
2007 		  fact_samples = big_or_little_endian_int((uint8_t *)(hdrbuf + 8), little);
2008 		}
2009 	      else
2010 		{
2011 		  static const uint8_t I_inst[4] = {'i','n','s','t'};  /* RIFF wants lower case, just to be different */
2012 		  if (match_four_chars((uint8_t *)hdrbuf, I_inst))
2013 		    {
2014 		      base_note = hdrbuf[8];
2015 		      base_detune = hdrbuf[9];
2016 		      /* rest is gain low-note high-note low-velocity high-velocity */
2017 		    }
2018 		  else
2019 		    {
2020 		      if (match_four_chars((uint8_t *)hdrbuf, I_clm_))
2021 			{
2022 			  comment_start = offset + 8;
2023 			  comment_end = comment_start + chunksize - 1; /* end of comment not start of next chunk */
2024 			}
2025 		      else
2026 			{
2027 			  if ((match_four_chars((uint8_t *)hdrbuf, I_LIST)) &&
2028 			      (match_four_chars((uint8_t *)(hdrbuf + 8), I_INFO)))
2029 			    {
2030 			      aux_comment_start[0] = offset + 8;
2031 			      aux_comment_end[0] = offset + 8 + chunksize - 1;
2032 			    }
2033 			  else
2034 			    {
2035 			      if (match_four_chars((uint8_t *)hdrbuf, I_JUNK))
2036 				update_rf64_location = offset;
2037 			    }
2038 			}
2039 		    }
2040 		}
2041 	    }
2042 	}
2043       chunkloc = (8 + chunksize);
2044       if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */
2045     }
2046   if (!got_fmt)
2047     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no fmt chunk?", filename));
2048   if (data_location == 0)
2049     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no data chunk?", filename));
2050   if (data_size > true_file_length)
2051     {
2052       data_size = true_file_length - data_location;
2053       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
2054     }
2055   data_size = mus_bytes_to_samples(sample_type, data_size);
2056   return(MUS_NO_ERROR);
2057 }
2058 
2059 
write_riff_clm_comment(int fd,const char * comment,int len,int extra)2060 static void write_riff_clm_comment(int fd, const char *comment, int len, int extra)
2061 {
2062   int i = 0, j;
2063   write_four_chars((uint8_t *)hdrbuf, I_clm_);
2064   mus_lint_to_char((uint8_t *)(hdrbuf + 4), len + extra);
2065   i = 8;
2066   for (j = 0; j < len; j++)
2067     {
2068       if (i == HDRBUFSIZ)
2069 	{
2070 	  header_write(fd, hdrbuf, HDRBUFSIZ);
2071 	  i = 0;
2072 	}
2073       hdrbuf[i++] = comment[j];
2074     }
2075   if (extra != 0)
2076     {
2077       if ((i + extra) > HDRBUFSIZ)
2078 	{
2079 	  header_write(fd, hdrbuf, i);
2080 	  i = 0;
2081 	}
2082       for (j = 0; j < extra; j++)
2083 	hdrbuf[i++] = 0;
2084     }
2085   if (i > 0)
2086     {
2087       header_write(fd, hdrbuf, i);
2088     }
2089 }
2090 
2091 
mus_ulint_to_char(uint8_t * j,uint32_t x)2092 static void mus_ulint_to_char(uint8_t *j, uint32_t x)
2093 {
2094   uint8_t *ox = (uint8_t *)&x;
2095 #if (!MUS_LITTLE_ENDIAN)
2096   j[0] = ox[3]; j[1] = ox[2]; j[2] = ox[1]; j[3] = ox[0];
2097 #else
2098   memcpy((void *)j, (void *)ox, 4);
2099 #endif
2100 }
2101 
2102 
write_riff_header(int fd,int wsrate,int wchans,mus_long_t siz,mus_sample_t samp_type,const char * comment,int len)2103 static int write_riff_header(int fd, int wsrate, int wchans, mus_long_t siz, mus_sample_t samp_type, const char *comment, int len)
2104 {
2105   int j, extra = 0, err = MUS_NO_ERROR;
2106 
2107   data_location = 36 + 36 + 8;
2108   if (len != 0)
2109     {
2110       if ((len % 4) != 0)
2111 	extra = (4 - (len % 4));
2112       data_location += (8 + len + extra);
2113     }
2114   /* 36 = "RIFF" + size(4) + "WAVE" + "fmt " + size(4) + 16 for data */
2115   /*   second 36 is for "JUNK" chunk, 8 is data chunk header */
2116 
2117   write_four_chars((uint8_t *)hdrbuf, I_RIFF);
2118   mus_ulint_to_char((uint8_t *)(hdrbuf + 4), (uint32_t)(data_location + siz - 8)); /* added -8 25-June-07 */
2119   write_four_chars((uint8_t *)(hdrbuf + 8), I_WAVE);
2120   header_write(fd, hdrbuf, 12);
2121 
2122   /* add JUNK chunk for possible change to RF64 during write */
2123   write_four_chars((uint8_t *)hdrbuf, I_JUNK);
2124   mus_lint_to_char((uint8_t *)(hdrbuf + 4), 28);
2125   for (j = 8; j < 36; j++) hdrbuf[j] = 0;
2126   header_write(fd, hdrbuf, 36);
2127 
2128   /* fmt chunk */
2129   err = write_riff_fmt_chunk(fd, hdrbuf, samp_type, wsrate, wchans);
2130 
2131   /* include possible clm (comment) chunk */
2132   if (len > 0)
2133     write_riff_clm_comment(fd, comment, len, extra);
2134 
2135   /* start the data chunk */
2136   write_four_chars((uint8_t *)hdrbuf, I_data);
2137   mus_ulint_to_char((uint8_t *)(hdrbuf + 4), (uint32_t)siz);
2138   header_write(fd, hdrbuf, 8);
2139   return(err);
2140 }
2141 
2142 
mus_header_riff_aux_comment(const char * name,mus_long_t * starts,mus_long_t * ends)2143 char *mus_header_riff_aux_comment(const char *name, mus_long_t *starts, mus_long_t *ends)
2144 {
2145   char *sc = NULL, *auxcom;
2146   if ((starts) && (starts[0] != 0))
2147     {
2148       int j, fd, k, m;
2149       mus_long_t i, end;
2150       /* found a LIST+INFO chunk (and no other comment) */
2151       fd = mus_file_open_read(name);
2152       if (fd == -1) return(NULL);
2153       i = starts[0];
2154       end = ends[0];
2155       sc = (char *)calloc(end - i + 2, sizeof(char));
2156       j = 0;
2157       k = 4;
2158       lseek(fd, i, SEEK_SET);
2159       auxcom = (char *)calloc(end - i + 2, sizeof(char));
2160       header_read(fd, (uint8_t *)auxcom, end - i + 1);
2161       CLOSE(fd, name);
2162       i += 4;
2163       while (i < end)
2164 	{
2165 	  int len;
2166 	  for (m = 0; m < 4; m++) sc[j++] = auxcom[k++];
2167 	  len = mus_char_to_lint((uint8_t *)(auxcom + k));
2168 	  if ((len <= 0) || (len > end)) break;
2169 	  sc[j++] = ':';
2170 	  sc[j++] = ' ';
2171 	  k += 4;
2172 	  for (m = 0; m < len; m++)
2173 	    if (auxcom[k] != 0)
2174 	      sc[j++] = auxcom[k++];
2175 	    else k++;
2176 	  sc[j++] ='\n';
2177 	  if (len & 1)
2178 	    {
2179 	      len++;
2180 	      k++;
2181 	    }
2182 	  i += (len + 8);
2183 	}
2184       free(auxcom);
2185     }
2186   return(sc);
2187 }
2188 
2189 
2190 
2191 /* ------------------------------------ W64 ------------------------------------
2192  *
2193  * soundforge -- just a quick hack until I get better documentation
2194  */
2195 
read_soundforge_header(const char * filename,int fd)2196 static int read_soundforge_header(const char *filename, int fd)
2197 {
2198   /* like RIFF but lowercase and 64-bit vals */
2199   int i, off;
2200   mus_long_t offset, chunkloc;
2201   chunkloc = 12 * 2 + 16;
2202   offset = 0;
2203   sample_type = MUS_UNKNOWN_SAMPLE;
2204   srate = 0;
2205   chans = 0;
2206   fact_samples = 0;
2207   bits_per_sample = 0;
2208   for (i = 0; i < AUX_COMMENTS; i++) aux_comment_start[i] = 0;
2209   true_file_length = SEEK_FILE_LENGTH(fd);
2210   update_form_size = mus_char_to_llong((uint8_t *)(hdrbuf + 4 * 2));
2211   while (true)
2212     {
2213       int chunksize;
2214       offset += chunkloc;
2215       if (offset >= true_file_length) break;
2216       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 64) <= 0) break;
2217       chunksize = mus_char_to_llong((uint8_t *)(hdrbuf + 16));
2218       if ((chunksize == 0) && /* can be empty data chunk? */
2219 	  (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0))
2220 	break;
2221       if (chunksize < 0)
2222 	break;
2223 
2224       if (match_four_chars((uint8_t *)hdrbuf, I_fmt_))
2225 	{
2226 	  off = 16;
2227 	  original_sample_type = mus_char_to_lshort((uint8_t *)(hdrbuf + 8 + off));
2228 	  chans = mus_char_to_lshort((uint8_t *)(hdrbuf + 10 + off));
2229 	  srate = mus_char_to_lint((uint8_t *)(hdrbuf + 12 + off));
2230 	  block_align = mus_char_to_lshort((uint8_t *)(hdrbuf + 20 + off));
2231 	  bits_per_sample = mus_char_to_lshort((uint8_t *)(hdrbuf + 22 + off));
2232 	  sample_type = wave_to_sndlib_format(original_sample_type, bits_per_sample, true);
2233 	}
2234       else
2235 	{
2236 	  if ((match_four_chars((uint8_t *)hdrbuf, I_data)) && (data_location == 0))
2237 	    {
2238 	      data_location = offset + 16 + 8;
2239 	      data_size = mus_char_to_llong((uint8_t *)(hdrbuf + 16));
2240 	      if (chunksize == 0) break; /* see aiff comment */
2241 	    }
2242 	  else
2243 	    {
2244 	      if (match_four_chars((uint8_t *)hdrbuf, I_fact))
2245 		{
2246 		  fact_samples = mus_char_to_llong((uint8_t *)(hdrbuf + 8));
2247 		}
2248 	    }
2249 	}
2250       chunkloc = chunksize % 8;
2251       if (chunkloc == 0)
2252 	chunkloc = chunksize;
2253       else chunkloc = chunksize + 8 - chunkloc;
2254       /* I think they are rounding up to a multiple of 8 here (sigh) */
2255     }
2256 
2257   if (data_location == 0)
2258     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no data chunk?", filename));
2259 
2260   if (data_size > true_file_length)
2261     {
2262       data_size = true_file_length - data_location;
2263       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
2264     }
2265   data_size = mus_bytes_to_samples(sample_type, data_size);
2266 
2267   return(MUS_NO_ERROR);
2268 }
2269 
2270 
2271 
2272 /* ------------------------------------ RF64 ------------------------------------
2273  *
2274  * see http://www.ebu.ch/CMSimages/en/tec_doc_t3306_tcm6-42570.pdf.
2275  *
2276  * RF64 0xFFFFFFFF WAVE
2277  *   ds64 size(32) RIFF-size(64) data-size(64) fact-samples(64) table-len table
2278  *   fmt_ size format-data
2279  *   data 0xFFFFFFFF data...
2280  *
2281  * if RIFF WAVE is being written with possibility of overflow size, use
2282  * RIFF size WAVE JUNK then the ds64 chunk as above
2283  *   if size overflows, reset RIFF->RF64, JUNK->ds64, size->-1 twice etc
2284  *
2285  * JUNK size = 28
2286  * all ints are little endian
2287  *
2288  */
2289 
read_rf64_header(const char * filename,int fd)2290 static int read_rf64_header(const char *filename, int fd)
2291 {
2292   /* we've checked RF64 xxxx WAVE before getting here */
2293   /* this is very similar (identical) to RIFF for the most part, but I decided it was cleanest to copy the code */
2294 
2295   mus_long_t chunkloc;
2296   bool got_fmt = false, got_ds64 = false;
2297   mus_long_t offset;
2298   little_endian = true;
2299   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)(hdrbuf + 8));
2300   chunkloc = 12;
2301   offset = 0;
2302   sample_type = MUS_UNKNOWN_SAMPLE;
2303   srate = 0;
2304   chans = 0;
2305   fact_samples = 0;
2306   bits_per_sample = 0;
2307   {
2308     int i;
2309     for (i = 0; i < AUX_COMMENTS; i++) aux_comment_start[i] = 0;
2310   }
2311   true_file_length = SEEK_FILE_LENGTH(fd);
2312   update_form_size = -1;                                                          /* at hdrbuf+4 -> 0xFFFFFFFF */
2313 
2314   while (true)
2315     {
2316       mus_long_t chunksize;
2317       offset += chunkloc;
2318       if (offset >= true_file_length) break;
2319       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 64) <= 0) break;
2320       chunksize = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
2321       if ((chunksize == 0) &&                                                      /* can be empty data chunk */
2322 	  (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0))
2323 	break;
2324       if (chunksize < -1)
2325 	break;
2326 
2327       if (match_four_chars((uint8_t *)hdrbuf, I_ds64))
2328 	{
2329 	  /* RIFF form size | data size | fact samples */
2330 	  update_form_size = mus_char_to_llong((uint8_t *)(hdrbuf + 8));
2331 	  data_size = mus_char_to_llong((uint8_t *)(hdrbuf + 16));
2332 	  fact_samples = (int)mus_char_to_llong((uint8_t *)(hdrbuf + 24));
2333 	  update_rf64_location = offset + 8;
2334 	  got_ds64 = true;
2335 	  /* ignore "table" for now */
2336 	}
2337       else
2338 	{
2339 	  if (match_four_chars((uint8_t *)hdrbuf, I_fmt_))
2340 	    {
2341 	      got_fmt = true;
2342 	      update_framples_location = 12 + offset;
2343 	      read_riff_fmt_chunk(hdrbuf, true);
2344 	    }
2345 	  else
2346 	    {
2347 	      if ((match_four_chars((uint8_t *)hdrbuf, I_data)) && (data_location == 0))
2348 		{
2349 		  update_ssnd_location = offset + 4;
2350 		  data_location = offset + 8;
2351 		  /* chunksize (at hdrbuf + 4) here is -1 */
2352 		  chunksize = data_size;
2353 		  if (chunksize <= 0) break; /* argh -- we need the ds64 chunk before this chunk */
2354 		}
2355 	      else
2356 		{
2357 		  /* ignore possible fact, inst chunks */
2358 		  if (match_four_chars((uint8_t *)hdrbuf, I_clm_))
2359 		    {
2360 		      comment_start = offset + 8;
2361 		      comment_end = comment_start + chunksize - 1; /* end of comment not start of next chunk */
2362 		    }
2363 		  else
2364 		    {
2365 		      if ((match_four_chars((uint8_t *)hdrbuf, I_LIST)) &&
2366 			  (match_four_chars((uint8_t *)(hdrbuf + 8), I_INFO)))
2367 			{
2368 			  aux_comment_start[0] = offset + 8;
2369 			  aux_comment_end[0] = offset + 8 + chunksize - 1;
2370 			}
2371 		    }
2372 		}
2373 	    }
2374 	}
2375       chunkloc = (8 + chunksize);
2376       if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */
2377     }
2378 
2379   if (!got_fmt)
2380     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no fmt chunk?", filename));
2381   if (!got_ds64)
2382     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no ds64 chunk?", filename));
2383 
2384   if (data_location == 0)
2385     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no data chunk?", filename));
2386 
2387   if (data_size > true_file_length)
2388     {
2389       data_size = true_file_length - data_location;
2390       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
2391     }
2392   data_size = mus_bytes_to_samples(sample_type, data_size);
2393 
2394   return(MUS_NO_ERROR);
2395 }
2396 
2397 
write_rf64_header(int fd,int wsrate,int wchans,mus_long_t size,mus_sample_t samp_type,const char * comment,int len)2398 static int write_rf64_header(int fd, int wsrate, int wchans, mus_long_t size, mus_sample_t samp_type, const char *comment, int len)
2399 {
2400   int extra = 0, err = MUS_NO_ERROR;
2401   data_location = 36 + 36 + 8;
2402   if (len != 0)
2403     {
2404       if ((len % 4) != 0)
2405 	extra = (4 - (len % 4));
2406       data_location += (8 + len + extra);
2407     }
2408 
2409   write_four_chars((uint8_t *)hdrbuf, I_RF64);
2410   mus_lint_to_char((uint8_t *)(hdrbuf + 4), -1);
2411   write_four_chars((uint8_t *)(hdrbuf + 8), I_WAVE);
2412   header_write(fd, hdrbuf, 12);
2413 
2414   /* ds64 chunk */
2415   write_four_chars((uint8_t *)hdrbuf, I_ds64);
2416   mus_lint_to_char((uint8_t *)(hdrbuf + 4), 28);
2417   mus_llong_to_char((uint8_t *)(hdrbuf + 8), data_location + size - 8); /* -8 added 25-June-07 */
2418   mus_llong_to_char((uint8_t *)(hdrbuf + 16), size);
2419   mus_llong_to_char((uint8_t *)(hdrbuf + 24), size);
2420   mus_lint_to_char((uint8_t *)(hdrbuf + 32), 0); /* "table size" */
2421   header_write(fd, hdrbuf, 36);
2422 
2423   err = write_riff_fmt_chunk(fd, hdrbuf, samp_type, wsrate, wchans);
2424 
2425   if (len > 0)
2426     write_riff_clm_comment(fd, comment, len, extra);
2427 
2428   write_four_chars((uint8_t *)hdrbuf, I_data);
2429   mus_lint_to_char((uint8_t *)(hdrbuf + 4), -1);
2430   header_write(fd, hdrbuf, 8);
2431   return(err);
2432 }
2433 
2434 
mus_header_convert_riff_to_rf64(const char * filename,mus_long_t size)2435 static int mus_header_convert_riff_to_rf64(const char *filename, mus_long_t size)
2436 {
2437   int err, fd;
2438 
2439   update_rf64_location = -1;
2440   update_ssnd_location = 0;
2441   /* mus_header_change_type copies the entire file, which is probably a bad idea in this case */
2442 
2443   err = mus_header_read(filename);
2444   if (err != MUS_NO_ERROR) return(err);
2445 
2446   if ((update_ssnd_location == 0) ||
2447       (update_rf64_location <= 0))  /* "JUNK" chunk has to be there already for this to work */
2448     return(MUS_CANT_CONVERT);
2449 
2450   fd = mus_file_reopen_write(filename);
2451   if (fd == -1) return(false);
2452 
2453   /* change overall type to rf64 and set size to RIFF -1 */
2454   write_four_chars((uint8_t *)hdrbuf, I_RF64);
2455   mus_lint_to_char((uint8_t *)(hdrbuf + 4), -1);
2456   header_write(fd, hdrbuf, 8);
2457 
2458   /* set data chunk's size to -1 */
2459   lseek(fd, update_ssnd_location, SEEK_SET);
2460   mus_lint_to_char((uint8_t *)(hdrbuf + 4), -1);
2461   header_write(fd, hdrbuf, 4);
2462 
2463   /* convert the "JUNK" chunk to be a "ds64" chunk */
2464   lseek(fd, update_rf64_location, SEEK_SET);
2465   write_four_chars((uint8_t *)hdrbuf, I_ds64);
2466   mus_lint_to_char((uint8_t *)(hdrbuf + 4), 28);
2467   mus_llong_to_char((uint8_t *)(hdrbuf + 8), data_location + size - 8);
2468   mus_llong_to_char((uint8_t *)(hdrbuf + 16), size);
2469   mus_llong_to_char((uint8_t *)(hdrbuf + 24), size);
2470   header_write(fd, hdrbuf, 36);
2471 
2472   CLOSE(fd, filename);
2473   return(true);
2474 }
2475 
2476 
2477 /* ------------------------------------ AVI ------------------------------------
2478  * actually a video format, but it sometimes contains embedded 'wave' data
2479  *
2480  * RIFF xxx AVI
2481  *   <various LISTs>
2482  *   LIST xxxx hdr1 LIST strl(?) strh | strf | strn etc
2483  *     strf is the WAVE header starting with the sound format
2484  *   LIST xxxx movi ##db|##wb -- wb subblocks have the audio data (these need to be collected as a single stream)
2485  * there are many complications that we make no effort to handle here
2486  *
2487  * described in http://www.rahul.net/jfm/avi.html
2488  */
2489 
read_avi_header(const char * filename,int fd)2490 static int read_avi_header(const char *filename, int fd)
2491 {
2492   static const uint8_t I_strf[4] = {'s','t','r','f'};
2493   static const uint8_t I_movi[4] = {'m','o','v','i'};
2494 
2495   /* we know we have checked for RIFF xxxx AVI  when we arrive here */
2496   int chunkloc, cksize, bits;
2497   bool happy = true;
2498   mus_long_t ckoff, cktotal, offset;
2499   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)(hdrbuf + 8));
2500   chunkloc = 12;
2501   offset = 0;
2502   sample_type = MUS_UNKNOWN_SAMPLE;
2503   srate = 0;
2504   chans = 1;
2505   true_file_length = SEEK_FILE_LENGTH(fd);
2506   while (happy)
2507     {
2508       int chunksize;
2509       offset += chunkloc;
2510       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 32) <= 0)
2511 	return(mus_error(MUS_HEADER_READ_FAILED, "%s avi header: chunks confused at %" print_mus_long, filename, offset));
2512       chunksize = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
2513       if ((chunksize == 0) && /* can be empty data chunk? */
2514 	  (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0))
2515 	break;
2516       if (chunksize < 0)
2517 	break;
2518       if (match_four_chars((uint8_t *)hdrbuf, I_LIST))
2519 	{
2520 	  ckoff = offset + 12;
2521 	  cktotal = 12;
2522 	  if (match_four_chars((uint8_t *)(hdrbuf + 8), I_movi))
2523 	    {
2524 	      while (cktotal < chunksize)
2525 		{
2526 		  lseek(fd, ckoff, SEEK_SET);
2527 		  header_read(fd, hdrbuf, 8);
2528 		  cksize = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
2529 		  if ((hdrbuf[2] == 'w') && (hdrbuf[3] == 'b'))
2530 		    {
2531 		      data_location = ckoff;
2532 		      if (srate != 0) happy = false;
2533 		      break;
2534 		    }
2535 		  ckoff += (8 + cksize);
2536 		  cktotal += (8 + cksize);
2537 		}
2538 	    }
2539 	  else
2540 	    {
2541 	      while (cktotal < chunksize)
2542 		{
2543 		  lseek(fd, ckoff, SEEK_SET);
2544 		  header_read(fd, hdrbuf, 8);
2545 		  cksize = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
2546 		  ckoff += (8 + cksize);
2547 		  cktotal += (8 + cksize);
2548 		  if (match_four_chars((uint8_t *)hdrbuf, I_LIST))
2549 		    {
2550 		      mus_long_t ckoffr, cktotalr, rdsize;
2551 		      ckoffr = ckoff + 12;
2552 		      cktotalr = 12;
2553 		      while (cktotalr < cksize)
2554 			{
2555 			  mus_long_t cksizer;
2556 			  lseek(fd, ckoffr, SEEK_SET);
2557 			  header_read(fd, hdrbuf, 8);
2558 			  cksizer = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
2559 			  ckoffr += (8 + cksizer);
2560 			  cktotalr += (8 + cksizer);
2561 			  if (match_four_chars((uint8_t *)hdrbuf, I_strf))
2562 			    {
2563 			      if (cksizer < HDRBUFSIZ)
2564 				rdsize = cksizer;
2565 			      else rdsize = HDRBUFSIZ;
2566 			      header_read(fd, hdrbuf, rdsize);
2567 			      original_sample_type = mus_char_to_lshort((uint8_t *)hdrbuf);
2568 			      chans = mus_char_to_lshort((uint8_t *)(hdrbuf + 2));
2569 			      srate = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
2570 			      /* block_align = mus_char_to_lshort((uint8_t *)(hdrbuf + 12)); */
2571 			      bits = mus_char_to_lshort((uint8_t *)(hdrbuf + 14));
2572 			      /* only 16 bit linear little endian for now */
2573 			      if ((bits == 16) && (original_sample_type == 1))
2574 				sample_type = MUS_LSHORT;
2575 			      if (data_location != 0) happy = false;
2576 			      break;
2577 			    }
2578 			}
2579 		    }
2580 		}
2581 	    }
2582 	}
2583       chunkloc = (8 + chunksize);
2584       if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */
2585     }
2586   if (data_location == 0)
2587     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no movi chunk?", filename));
2588   if (data_location > true_file_length)
2589     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
2590   data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location);
2591   return(MUS_NO_ERROR);
2592 }
2593 
2594 
2595 
2596 /* ------------------------------------ SoundFont 2.0 ------------------------------------
2597  *
2598  * Emu's SoundFont(tm) format uses RIFF -- at ftp.creaf.com:/pub/emu/sf2_00a.ps)
2599  *
2600  * RIFF xxxx sfbk followed by
2601  *   LIST xxxx INFO chunk (nothing of interest -- icmt subchunk might have comments)
2602  *   LIST xxxx sdta chunk = data
2603  *     smpl chunk (16 bit linear little-endian)
2604  *   LIST xxxx pdta list chunk
2605  *     shdr subchunk has srate at 40 (int), samples at 28
2606  *
2607  * http://smurf.sourceforge.net/sfont_intro.php
2608  * http://www.hammersound.net/
2609  */
2610 
2611 static int soundfont_entries = 0;
2612 static int *soundfont_starts = NULL, *soundfont_ends = NULL, *soundfont_loop_starts = NULL, *soundfont_loop_ends = NULL;
2613 static int soundfont_size = 0;
2614 static char **soundfont_names = NULL;
2615 
soundfont_entry(const char * name,int start,int end,int loop_start,int loop_end)2616 static void soundfont_entry(const char *name, int start, int end, int loop_start, int loop_end)
2617 {
2618   if (soundfont_entries == soundfont_size)
2619     {
2620       int i;
2621       if (soundfont_size == 0)
2622 	{
2623 	  soundfont_size = 8;
2624 	  soundfont_starts = (int *)calloc(soundfont_size, sizeof(int));
2625 	  soundfont_ends = (int *)calloc(soundfont_size, sizeof(int));
2626 	  soundfont_loop_starts = (int *)calloc(soundfont_size, sizeof(int));
2627 	  soundfont_loop_ends = (int *)calloc(soundfont_size, sizeof(int));
2628 	  soundfont_names = (char **)calloc(soundfont_size, sizeof(char *));
2629 	}
2630       else
2631 	{
2632 	  if (soundfont_size < 123123123)
2633 	    soundfont_size += 8;
2634 	  /* believe it or not, without the 123123123 shuffle, gcc complains at mus_header_read_1 [line 5519!]
2635 	   * that we are making a naughty assumption about overflows.
2636 	   */
2637 	  soundfont_starts = (int *)realloc(soundfont_starts, soundfont_size * sizeof(int));
2638 	  soundfont_ends = (int *)realloc(soundfont_ends, soundfont_size * sizeof(int));
2639 	  soundfont_loop_starts = (int *)realloc(soundfont_loop_starts, soundfont_size * sizeof(int));
2640 	  soundfont_loop_ends = (int *)realloc(soundfont_loop_ends, soundfont_size * sizeof(int));
2641 	  soundfont_names = (char **)realloc(soundfont_names, soundfont_size * sizeof(char *));
2642 	}
2643       for (i = soundfont_entries; i < soundfont_size; i++) soundfont_names[i] = NULL;
2644     }
2645   if (!soundfont_names[soundfont_entries]) soundfont_names[soundfont_entries] = (char *)calloc(20, sizeof(char));
2646   strcpy(soundfont_names[soundfont_entries], name);
2647   soundfont_starts[soundfont_entries] = start;
2648   soundfont_ends[soundfont_entries] = end;
2649   soundfont_loop_starts[soundfont_entries] = loop_start;
2650   soundfont_loop_ends[soundfont_entries] = loop_end;
2651   soundfont_entries++;
2652 }
2653 
2654 
mus_header_sf2_entries(void)2655 int mus_header_sf2_entries(void) {return(soundfont_entries);}
mus_header_sf2_name(int n)2656 char *mus_header_sf2_name(int n) {return(soundfont_names[n]);}
mus_header_sf2_start(int n)2657 int mus_header_sf2_start(int n) {return(soundfont_starts[n]);}
mus_header_sf2_end(int n)2658 int mus_header_sf2_end(int n) {return(soundfont_ends[n]);}
mus_header_sf2_loop_start(int n)2659 int mus_header_sf2_loop_start(int n) {return(soundfont_loop_starts[n]);}
mus_header_sf2_loop_end(int n)2660 int mus_header_sf2_loop_end(int n) {return(soundfont_loop_ends[n]);}
2661 
2662 
read_soundfont_header(const char * filename,int fd)2663 static int read_soundfont_header(const char *filename, int fd)
2664 {
2665   static const uint8_t I_sdta[4] = {'s','d','t','a'};
2666   static const uint8_t I_shdr[4] = {'s','h','d','r'};
2667   static const uint8_t I_pdta[4] = {'p','d','t','a'};
2668 
2669   /* we know we have checked for RIFF xxxx sfbk when we arrive here */
2670   int chunkloc, type, cksize, i, this_end, last_end;
2671   mus_long_t ckoff, offset;
2672   bool happy = true;
2673 
2674   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)(hdrbuf + 8));
2675   chunkloc = 12;
2676   offset = 0;
2677   soundfont_entries = 0;
2678   sample_type = MUS_LSHORT;
2679   srate = 0;
2680   chans = 1;
2681   last_end = 0;
2682   true_file_length = SEEK_FILE_LENGTH(fd);
2683 
2684   while (happy)
2685     {
2686       int chunksize;
2687       offset += chunkloc;
2688       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 32) <= 0)
2689 	return(mus_error(MUS_HEADER_READ_FAILED, "%s soundfont header: chunks confused at %" print_mus_long, filename, offset));
2690       chunksize = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
2691       if ((chunksize == 0) && /* can be empty data chunk? */
2692 	  (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0))
2693 	break;
2694       if (chunksize < 0)
2695 	break;
2696       if (match_four_chars((uint8_t *)hdrbuf, I_LIST))
2697 	{
2698 	  /* everything is squirreled away in LIST chunks in this format */
2699 	  if (match_four_chars((uint8_t *)(hdrbuf + 8), I_pdta))
2700 	    {
2701 	      /* go searching for I_shdr -- headers this complicated should be illegal. */
2702 	      ckoff = offset + 12;
2703 	      lseek(fd, ckoff, SEEK_SET);
2704 	      while (srate == 0)
2705 		{
2706 		  int64_t bytes;
2707 		  bytes = (int64_t)read(fd, hdrbuf, 8);
2708 		  if (bytes == 0)
2709 		    {
2710 		      happy = false;
2711 		      break;
2712 		    }
2713 		  i = 0;
2714 		  cksize = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
2715 		  ckoff += (8 + cksize);
2716 		  /* here we need to jump over subchunks! -- 4-Aug-97 */
2717 		  if (match_four_chars((uint8_t *)hdrbuf, I_shdr))
2718 		    {
2719 		      /* each sound:
2720 		       *  0: name
2721 		       * 20: start (in samples from start of bank)
2722 		       * 24: end
2723 		       * 28: loop start (also relative to start of bank)
2724 		       * 32: loop end
2725 		       * 36: sample rate
2726 		       * 40: pitch (60 = middle C)
2727 		       * 41: detune (cents)
2728 		       * 42: link (to other channel if any?)
2729 		       * 44: type (1 = mono, 2 = mono right, 4 = mono left, others (0x8000) apparently for ROM presets?)
2730 		       */
2731 		      while (i < cksize)
2732 			{
2733 			  header_read(fd, hdrbuf, 46);
2734 			  i += 46;
2735 			  type = mus_char_to_lshort((uint8_t *)(hdrbuf + 44));
2736 			  if ((type == 1) &&
2737 			      (mus_char_to_lint((uint8_t *)(hdrbuf + 24)) > 0))
2738 			    {
2739 			      if (srate == 0)
2740 				srate = mus_char_to_lint((uint8_t *)(hdrbuf + 36));
2741 			      soundfont_entry((char *)(hdrbuf),
2742 					      mus_char_to_lint((uint8_t *)(hdrbuf + 20)),
2743 					      this_end = mus_char_to_lint((uint8_t *)(hdrbuf + 24)),
2744 					      mus_char_to_lint((uint8_t *)(hdrbuf + 28)),
2745 					      mus_char_to_lint((uint8_t *)(hdrbuf + 32)));
2746 			      if (this_end > last_end) last_end = this_end;
2747 			    }
2748 			}
2749 		      happy = (data_location == 0);
2750 		    }
2751 		  else
2752 		    {
2753 		      if (ckoff >= offset + 8 + chunksize)
2754 			break;
2755 		      lseek(fd, ckoff, SEEK_SET);
2756 		    }
2757 		}
2758 	    }
2759 	  else
2760 	    {
2761 	      if (match_four_chars((uint8_t *)(hdrbuf + 8), I_sdta))
2762 		{
2763 		  /* assume smpl follows + subchunk size */
2764 		  /* Convert 1.4 appears to create a separate smpl chunk */
2765 		  data_location = offset + 20; /* LIST xxxx sdta smpl xxxx ... */
2766 		  happy = (srate == 0);
2767 		}
2768 	    }
2769 	}
2770       chunkloc = (8 + chunksize);
2771       if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */
2772     }
2773   if (srate == 0)
2774     return(mus_error(MUS_HEADER_READ_FAILED, "%s: srate == 0", filename));
2775   if (data_location == 0)
2776     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no sdta chunk?", filename));
2777   if (last_end > 0)
2778     data_size = last_end; /* samples already */
2779   else data_size = (true_file_length - data_location) / 2;
2780   return(MUS_NO_ERROR);
2781 }
2782 
2783 
2784 
2785 
2786 /* ------------------------------------ NIST ------------------------------------
2787  *
2788  * code available in ogitools-v1.0.tar.gz at svr-ftp.eng.cam.ac.uk:comp.speech/sources
2789  *
2790  *   0: "NIST_1A"
2791  *   8: data_location as ASCII representation of integer (apparently always "   1024")
2792  *  16: start of complicated header -- see below for details
2793  *
2794  *  The most recent version of the SPHERE package is available
2795  *  via anonymous ftp from jaguar.ncsl.nist.gov [129.6.48.157] in the pub directory
2796  *  in compressed tar form as "sphere-v.tar.Z" (where "v" is the version
2797  *  code 2.6a last I looked).  shortpack is also at this site.
2798  *
2799  *  here's an example:
2800  *
2801  *  NIST_1A
2802  *     1024
2803  *  database_id -s5 TIMIT
2804  *  database_version -s3 1.0
2805  *  utterance_id -s8 aks0_sa1
2806  *  channel_count -i 1
2807  *  sample_count -i 63488
2808  *  sample_rate -i 16000
2809  *  sample_min -i -6967
2810  *  sample_max -i 7710
2811  *  sample_n_bytes -i 2
2812  *  sample_byte_format -s2 01
2813  *  sample_sig_bits -i 16
2814  *  end_head
2815  *
2816  * the sample_byte_format can be "10"=big-endian or "01"=little-endian, or "shortpack-v0"=compressed via shortpack
2817  * other formats are wavpack and shorten.
2818  *
2819  * another field is 'sample_coding' which can be pcm (i.e. linear), 'pcm, embedded-shorten-v1.09', mu-law, alaw, ulaw, pculaw etc --
2820  *   so unpredictable as to be totally useless. This means we sometimes try to decode shorten-encoded files because
2821  *   we ignore this field.  And worse, there's a 'channels_interleaved' field that (apparently) can be false.  Tough.
2822  */
2823 
2824 #define MAX_FIELD_LENGTH 80
2825 
decode_nist_value(char * str,int base,int end)2826 static int decode_nist_value(char *str, int base, int end)
2827 {
2828   /* can be -i -r or -snnn where nnn = ascii rep of integer = len of string (!) */
2829   /* we'll deal only with integer fields (and well-behaved string fields) */
2830   int i, j;
2831   char value[MAX_FIELD_LENGTH];
2832   memset((void *)value, 0, MAX_FIELD_LENGTH);
2833   i = base;
2834   while ((i < end) && (i < MAX_FIELD_LENGTH) && (str[i] != '-')) i++; /* look for -i or whatever */
2835   while ((i < end) && (i < MAX_FIELD_LENGTH) && (str[i] != ' ')) i++; /* look for space after it */
2836   i++;
2837   if (i >= MAX_FIELD_LENGTH) return(0);
2838   for (j = 0; i < end; j++, i++)
2839     value[j] = str[i];
2840   value[j] = 0;
2841   if (value[0] =='s') return(MUS_NIST_SHORTPACK);
2842   sscanf(value, "%12d", &i);
2843   /* what is the correct way to use mus_long_ts here for the sample count? */
2844   return(i);
2845 }
2846 
2847 
read_nist_header(const char * filename,int fd)2848 static int read_nist_header(const char *filename, int fd)
2849 {
2850   char str[MAX_FIELD_LENGTH], name[MAX_FIELD_LENGTH];
2851   bool happy = true;
2852   mus_long_t curbase;
2853   int k, hend, j, n, nm, samples, bytes, byte_format, idata_location = 0;
2854 
2855   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)hdrbuf); /* the actual id is "NIST_1A" */
2856   memset((void *)str, 0, MAX_FIELD_LENGTH);
2857   memset((void *)name, 0, MAX_FIELD_LENGTH);
2858 
2859   for (k = 8; k < 16; k++)
2860     str[k - 8] = hdrbuf[k];
2861 
2862   sscanf(str, "%12d", &idata_location);       /* always "1024" */
2863   if (idata_location != 1024)
2864     return(mus_error(MUS_HEADER_READ_FAILED, "%s NIST data location: %d?", filename, idata_location));
2865 
2866   data_location = 1024;
2867   n = 16;
2868   hend = INITIAL_READ_SIZE;
2869   k = 0;
2870   curbase = 0;
2871   samples = 0;
2872   bytes = 0;
2873   srate = 0;
2874   chans = 0;
2875   comment_start = 16;
2876   comment_end = 16;
2877   byte_format = 10;
2878   for (j = 0; j < MAX_FIELD_LENGTH; j++)
2879     str[j] =' ';
2880 
2881   while (happy)
2882     {
2883       /* much as in xIFF files, march through the file looking for the data we're after */
2884       /* in this case we munch a character at a time... */
2885       str[k] = hdrbuf[n];
2886       if ((((str[k] == '\0') || (str[k] == '\n')) || ((curbase + n + 1) >= data_location)) || (k == 79))
2887 	{
2888 	  /* got a complete record (assuming no embedded newlines, of course) */
2889 	  /* now look for a record we care about and decode it */
2890 	  nm = 0;
2891 	  while ((nm < MAX_FIELD_LENGTH) && (str[nm] != ' ') && (str[nm] != '\0') && (str[nm] != '\n'))
2892 	    {
2893 	      name[nm] = str[nm];
2894 	      nm++;
2895 	    }
2896 	  if (nm >= MAX_FIELD_LENGTH)
2897 	    {
2898 	      header_type = MUS_RAW;
2899 	      sample_type = MUS_UNKNOWN_SAMPLE;
2900 	      return(mus_error(MUS_UNSUPPORTED_HEADER_TYPE, "%s nist header: unreadable field (length = %d)?", filename, nm));
2901 	    }
2902 	  name[nm] = 0;
2903 	  if (strcmp(name, "sample_rate") == 0) srate = decode_nist_value(str, nm, k); else
2904 	    if (strcmp(name, "channel_count") == 0) chans = decode_nist_value(str, nm, k); else
2905 	      if (strcmp(name, "end_head") == 0) {happy = false; comment_end = curbase + n - 9;} else
2906 		if (strcmp(name, "sample_count") == 0) samples = decode_nist_value(str, nm, k); else
2907 		  if ((bytes == 0) && (strcmp(name, "sample_n_bytes") == 0)) bytes = decode_nist_value(str, nm, k); else
2908 		    if ((bytes == 0) && (strcmp(name, "sample_sig_bits") == 0)) {bytes = decode_nist_value(str, nm, k); bytes = (bytes >> 3);} else
2909 		      if (strcmp(name, "sample_byte_format") == 0) byte_format = decode_nist_value(str, nm, k);
2910 	  for (j = 0; j <= k; j++) str[j] =' ';
2911 	  k = 0;
2912 	  if ((curbase + n + 1) > 1024) happy = false;
2913 	}
2914       else
2915 	k++;
2916       n++;
2917       if (n >= hend)
2918 	{
2919 	  int64_t read_bytes;
2920 	  curbase += hend;
2921 	  n = 0;
2922 	  read_bytes = (int64_t)read(fd, hdrbuf, HDRBUFSIZ);
2923 	  if (read_bytes < HDRBUFSIZ)
2924 	    return(mus_error(MUS_HEADER_READ_FAILED, "%s NIST header truncated?", filename));
2925 	  hend = HDRBUFSIZ;
2926 	}
2927     }
2928 
2929   data_size = samples * bytes;
2930   if (byte_format == MUS_NIST_SHORTPACK)
2931     {
2932       sample_type = MUS_UNKNOWN_SAMPLE;
2933       original_sample_type = MUS_NIST_SHORTPACK;
2934     }
2935   else
2936     {
2937       switch (bytes)
2938 	{
2939 	case 1:
2940 	  sample_type = MUS_MULAW;
2941 	  break;
2942 
2943 	case 2:
2944 	  if (byte_format == 10)
2945 	    sample_type = MUS_BSHORT;
2946 	  else sample_type = MUS_LSHORT;
2947 	  break;
2948 
2949 	case 3:
2950 	  if (byte_format == 10)
2951 	    sample_type = MUS_B24INT;
2952 	  else sample_type = MUS_L24INT;
2953 	  break;
2954 
2955 	case 4:
2956 	  if (byte_format == 10)
2957 	    sample_type = MUS_BINT;
2958 	  else sample_type = MUS_LINT;
2959 	  break;
2960 
2961 	default:
2962 	  sample_type = MUS_BYTE;
2963 	  break;
2964 	}
2965     }
2966 
2967   true_file_length = SEEK_FILE_LENGTH(fd);
2968   if ((data_size > true_file_length) && (original_sample_type != MUS_NIST_SHORTPACK))
2969     {
2970       data_size = true_file_length - data_location;
2971       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
2972     }
2973   data_size = mus_bytes_to_samples(sample_type, data_size);
2974 
2975   return(MUS_NO_ERROR);
2976 }
2977 
2978 
write_nist_header(int fd,int wsrate,int wchans,mus_long_t size,mus_sample_t samp_type)2979 static int write_nist_header(int fd, int wsrate, int wchans, mus_long_t size, mus_sample_t samp_type)
2980 {
2981   char *header;
2982   int datum;
2983   datum = mus_bytes_per_sample(samp_type);
2984   header = (char *)calloc(1024, sizeof(char));
2985   snprintf(header, 1024, "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 %" print_mus_long "\nend_head\n",
2986 	  wchans, wsrate, datum,
2987 	  ((samp_type == MUS_BSHORT) || (samp_type == MUS_B24INT) || (samp_type == MUS_BINT)) ? "10" : "01",
2988 	  datum * 8,
2989 	  size / datum);
2990   header_write(fd, (uint8_t *)header, 1024);
2991   data_location = 1024;
2992   free(header);
2993   return(MUS_NO_ERROR);
2994 }
2995 
2996 
2997 
2998 /* ------------------------------------ BICSF ------------------------------------
2999  * (actually, this is EBICSF and the old BICSF is called IRCAM below)
3000  *
3001  * 0-28: NeXT-compatible header, read by read_next_header above.
3002  *   28: bicsf magic number (107364 or trouble)
3003  *   32: srate as a 32-bit float
3004  *   36: chans
3005  *   40: sample type indicator (2 = 16-bit linear, 4 = 32-bit float)
3006  *   44: begin chunks, if any
3007  *
3008  * followed by AIFF-style chunked header info with chunks like:
3009  *
3010  *   COMM size comment
3011  *   MAXA size {max amps (up to 4)} (frample offsets) time-tag unix msec counter
3012  *   CUE, PRNT, ENV etc
3013  *
3014  * except in Paul Lansky's "hybrid" headers, according to MixViews.
3015  */
3016 
read_bicsf_header(const char * filename,int fd)3017 static int read_bicsf_header(const char *filename, int fd)
3018 {
3019   int chunksize, chunkname, offset, chunkloc;
3020   bool happy = true;
3021 
3022   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)(hdrbuf + 28));
3023   header_type = MUS_BICSF;
3024   data_location = 1024;
3025   if (data_size == 0) data_size = (true_file_length - data_location);
3026 
3027   lseek(fd, 40, SEEK_SET);
3028   header_read(fd, hdrbuf, HDRBUFSIZ);
3029   original_sample_type = mus_char_to_bint((uint8_t *)hdrbuf);
3030   switch (original_sample_type)
3031     {
3032     case 2: sample_type = MUS_BSHORT; break;
3033     case 4: sample_type = MUS_BFLOAT; break;
3034     case 8: sample_type = MUS_BDOUBLE; break;
3035     default: break;
3036     }
3037 
3038   /* now check for a COMM chunk, setting the comment pointers */
3039   chunkloc = 4; /* next header + magic number, srate, chans, packing, then chunks, I think */
3040   offset = 40;
3041 
3042   while (happy)
3043     {
3044       if (((offset + chunkloc) >= data_location) ||
3045 	  ((offset + chunkloc) < 40))
3046 	happy = false;
3047       else
3048 	{
3049 	  offset += chunkloc;
3050 	  if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 32) <= 0)
3051 	    return(mus_error(MUS_HEADER_READ_FAILED, "%s bicsf header: chunks confused at %d", filename, offset));
3052 
3053 	  chunkname = mus_char_to_uninterpreted_int((uint8_t *)hdrbuf);
3054 	  chunksize = mus_char_to_bint((uint8_t *)(hdrbuf + 4));
3055 
3056 	  if (chunksize < 0)
3057 	    break;
3058 	  if (match_four_chars((uint8_t *)hdrbuf, I_COMM))
3059 	    {
3060 	      comment_start = 8 + offset;
3061 	      comment_end = comment_start + chunksize -1;
3062 	      happy = false;
3063 	    }
3064 	  else
3065 	    {
3066 	      if ((chunkname == 0) || (chunksize <= 0))
3067 		happy = false;
3068 	    }
3069 	  chunkloc = (8 + chunksize);
3070 	}
3071     }
3072 
3073   return(MUS_NO_ERROR);
3074   /* from here we fall back into read_next_header */
3075 }
3076 
3077 
3078 
3079 /* ------------------------------------ IRCAM ------------------------------------
3080  * old-style BICSF -- added write option for Sun port 12-Dec-94
3081  *
3082  *    0: 0x1a364 or variations thereof -- byte order gives big/little_endian decision,
3083  *         ^ digit gives machine info, according to AFsp sources -- see IRCAM ints above
3084  *    4: srate as a 32-bit float
3085  *    8: chans
3086  *   12: sample type indicator (2 = 16-bit linear, 4 = 32-bit float)
3087  *       according to new Sox (version 11), these packing modes are now bytes/sample in low short, code in high
3088  *       so 1 = char, 0x10001 = alaw, 0x20001 = mulaw, 2 = short, 3 = 24bit?, 0x40004 = long, 4 = float (AFsp sez 4 can also be double)
3089  *   16: comment start -- how to tell if it's a real comment?
3090  *       apparently these are separated as short code, short blocksize, then data
3091  *       codes: 0 = end, 1 = maxamp, 2 = comment, 3 = pvdata, 4 = audioencode and codemax??
3092  * 1024: data start
3093  *
3094  * apparently the byte order depends on the machine.
3095  * and yet... convert 1.4 makes a .sf file with little endian header, the VAX id, and big endian data?
3096  *            Csound also uses the VAX magic number with little-endian unscaled floats!  Argh.
3097  *            even worse, Paul Lansky plops some version of this at the end of a NeXT header!  Complete chaos...
3098  */
3099 
read_ircam_header(const char * filename,int fd)3100 static int read_ircam_header(const char *filename, int fd)
3101 {
3102   short bloc;
3103   int offset;
3104   bool little, happy = true;
3105 
3106   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)hdrbuf);
3107   if ((mus_char_to_lint((uint8_t *)hdrbuf) == I_IRCAM_VAX) ||
3108       (mus_char_to_lint((uint8_t *)hdrbuf) == I_IRCAM_MIPS))
3109     little = true;
3110   else little = false;
3111   little_endian = little;
3112   data_location = 1024;
3113   true_file_length = SEEK_FILE_LENGTH(fd);
3114   data_size = (true_file_length - 1024);
3115   original_sample_type = big_or_little_endian_int((uint8_t *)(hdrbuf + 12), little);
3116   sample_type = MUS_UNKNOWN_SAMPLE;
3117 
3118   if (original_sample_type == 2)
3119     {
3120       if (little)
3121 	sample_type = MUS_LSHORT;
3122       else sample_type = MUS_BSHORT;
3123     }
3124   else if (original_sample_type == 4)
3125     {
3126       if (little)
3127 	{
3128 	  if (mus_char_to_lint((uint8_t *)hdrbuf) == I_IRCAM_VAX)
3129 	    sample_type = MUS_LFLOAT_UNSCALED; /* Csound and MixViews */
3130 	  else sample_type = MUS_LFLOAT;
3131 	}
3132       else sample_type = MUS_BFLOAT;
3133     }
3134   else if (original_sample_type == 0x40004)
3135     {
3136       if (little) sample_type = MUS_LINT;
3137       else sample_type = MUS_BINT;
3138     }
3139   else if (original_sample_type == 0x10001) sample_type = MUS_ALAW;
3140   else if (original_sample_type == 0x20001) sample_type = MUS_MULAW;
3141   else if (original_sample_type == 1) sample_type = MUS_BYTE;
3142   else if (original_sample_type == 3)
3143     {
3144       if (little) sample_type = MUS_L24INT;
3145       else sample_type = MUS_B24INT;
3146     }
3147   else if (original_sample_type == 8)
3148     {
3149       if (little) sample_type = MUS_LDOUBLE;
3150       else sample_type = MUS_BDOUBLE;
3151     }
3152 
3153   srate = (int)big_or_little_endian_float((uint8_t *)(hdrbuf + 4), little);
3154   chans = big_or_little_endian_int((uint8_t *)(hdrbuf + 8), little);
3155   bloc = 16;
3156   offset = 0;
3157 
3158   while (happy)
3159     {
3160       short bcode, bsize;
3161       offset += bloc;
3162       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 32) <= 0)
3163 	return(mus_error(MUS_HEADER_READ_FAILED, "%s ircam header: chunks confused at %d", filename, offset));
3164 
3165       bcode = big_or_little_endian_short((uint8_t *)hdrbuf, little);
3166       bsize = big_or_little_endian_short((uint8_t *)(hdrbuf + 2), little);
3167 
3168       if (bcode == 2)
3169 	{
3170 	  happy = false;
3171 	  comment_start = 4 + offset;
3172 	  comment_end = comment_start + bsize - 1; /* was -5? */
3173 	}
3174       bloc = bsize;
3175       if ((bsize <= 0) || (bcode <= 0) || ((offset + bloc) > 1023)) happy = false;
3176     }
3177 
3178   data_size = mus_bytes_to_samples(sample_type, data_size);
3179   return(MUS_NO_ERROR);
3180 }
3181 
3182 
sndlib_format_to_ircam(mus_sample_t samp_type)3183 static int sndlib_format_to_ircam(mus_sample_t samp_type)
3184 {
3185   switch (samp_type)
3186     {
3187     case MUS_MULAW:  return(0x20001); break;
3188     case MUS_ALAW:   return(0x10001); break;
3189     case MUS_BSHORT: return(2);       break;
3190     case MUS_BINT:   return(0x40004); break;
3191     case MUS_BFLOAT: return(4);       break;
3192     default:
3193       return(mus_error(MUS_UNSUPPORTED_SAMPLE_TYPE, "IRCAM header unsupported sample type: %d (%s)", samp_type, any_sample_type_name(samp_type)));
3194       break;
3195     }
3196 }
3197 
3198 
write_ircam_comment(int fd,const char * comment,int len)3199 static void write_ircam_comment(int fd, const char *comment, int len)
3200 {
3201   if (len > 0)
3202     {
3203       mus_bshort_to_char((uint8_t *)hdrbuf, 2);
3204       mus_bshort_to_char((uint8_t *)(hdrbuf + 2), (short)len);
3205       header_write(fd, hdrbuf, 4);
3206       header_write(fd, (uint8_t *)comment, len);
3207     }
3208   else
3209     {
3210       mus_bint_to_char((uint8_t *)hdrbuf, 0);
3211       header_write(fd, hdrbuf, 4);
3212     }
3213   len = 1024 - (len + 20);
3214   if (len > 0)
3215     {
3216       uint8_t *combuf;
3217       combuf = (uint8_t *)calloc(len, sizeof(uint8_t));
3218       header_write(fd, combuf, len);
3219       free(combuf);
3220     }
3221 }
3222 
3223 
write_ircam_header(int fd,int wsrate,int wchans,mus_sample_t samp_type,const char * comment,int len)3224 static int write_ircam_header(int fd, int wsrate, int wchans, mus_sample_t samp_type, const char *comment, int len)
3225 {
3226   mus_bint_to_char((uint8_t *)hdrbuf, 0x2a364); /* SUN id */
3227   mus_bfloat_to_char((uint8_t *)(hdrbuf + 4), (float)wsrate);
3228   mus_bint_to_char((uint8_t *)(hdrbuf + 8), wchans);
3229   mus_bint_to_char((uint8_t *)(hdrbuf + 12), sndlib_format_to_ircam(samp_type));
3230   header_write(fd, hdrbuf, 16);
3231   data_location = 1024;
3232   write_ircam_comment(fd, comment, len);
3233   return(MUS_NO_ERROR);
3234 }
3235 
3236 
3237 
3238 /* ------------------------------------ 8SVX -------------------------------------
3239  * (also known as IFF)
3240  *
3241  * very similar to AIFF:
3242  *  "BODY" => [4] samples [n] data
3243  *  "VHDR" => srate (short)
3244  *  "CHAN" => chans
3245  *  "ANNO" and "NAME"
3246  *
3247  * big_endian throughout
3248  */
3249 
read_8svx_header(const char * filename,int fd,bool bytewise)3250 static int read_8svx_header(const char *filename, int fd, bool bytewise)
3251 {
3252   static const uint8_t I_BODY[4] = {'B','O','D','Y'};
3253   static const uint8_t I_CHAN[4] = {'C','H','A','N'};
3254   static const uint8_t I_VHDR[4] = {'V','H','D','R'};
3255   int offset, chunkloc;
3256   bool happy = true;
3257 
3258   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)hdrbuf);
3259   chunkloc = 12;
3260   offset = 0;
3261   if (bytewise) sample_type = MUS_BYTE; else sample_type = MUS_BSHORT;
3262   srate = 0;
3263   chans = 1;
3264   true_file_length = SEEK_FILE_LENGTH(fd);
3265   update_form_size = mus_char_to_bint((uint8_t *)(hdrbuf + 4));
3266 
3267   while (happy)
3268     {
3269       int chunksize;
3270       offset += chunkloc;
3271       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 32) <= 0)
3272 	return(mus_error(MUS_HEADER_READ_FAILED, "%s 8svx header: chunks confused at %d", filename, offset));
3273 
3274       chunksize = mus_char_to_bint((uint8_t *)(hdrbuf + 4));
3275       if ((chunksize == 0) && /* can be empty data chunk? */
3276 	  (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0))
3277 	break;
3278       if (chunksize < 0)
3279 	break;
3280 
3281       if (match_four_chars((uint8_t *)hdrbuf, I_CHAN))
3282 	{
3283 	  chans = mus_char_to_bint((uint8_t *)(hdrbuf + 8));
3284 	  chans = (chans & 0x01) +
3285 	          ((chans & 0x02) >> 1) +
3286 	          ((chans & 0x04) >> 2) +
3287                   ((chans & 0x08) >> 3);
3288 	  /* what in heaven's name is this?  Each bit corresponds to a channel? */
3289 	}
3290       else
3291 	{
3292 	  if (match_four_chars((uint8_t *)hdrbuf, I_VHDR))
3293 	    {
3294 	      /* num_samples (int) at hdrbuf + 8 */
3295 	      srate = mus_char_to_ubshort((uint8_t *)(hdrbuf + 20));
3296 	      original_sample_type = hdrbuf[23];
3297 	      if (original_sample_type != 0)
3298 		sample_type = MUS_UNKNOWN_SAMPLE;
3299 	    }
3300 	  else
3301 	    {
3302 	      if ((match_four_chars((uint8_t *)hdrbuf, I_ANNO)) ||
3303 		  (match_four_chars((uint8_t *)hdrbuf, I_NAME)))
3304 		{
3305 		  comment_start = offset + 8;
3306 		  comment_end = comment_start + chunksize - 1;
3307 		}
3308 	      else
3309 		{
3310 		  if (match_four_chars((uint8_t *)hdrbuf, I_BODY))
3311 		    {
3312 		      data_size = chunksize;
3313 		      data_location = offset + 12;
3314 		      happy = false;
3315 		    }
3316 		}
3317 	    }
3318 	}
3319       chunkloc = (8 + chunksize);
3320       if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */
3321     }
3322 
3323   if (data_location == 0)
3324     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no BODY chunk?", filename));
3325 
3326   if (data_size > true_file_length)
3327     {
3328       data_size = true_file_length - data_location;
3329       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
3330     }
3331   data_size = mus_bytes_to_samples(sample_type, data_size);
3332 
3333   return(MUS_NO_ERROR);
3334 }
3335 
3336 
3337 /* ------------------------------------ VOC --------------------------------------
3338  *
3339  *   0: "Creative Voice File" followed by a couple ctrl-Z ('32) (swapped data)
3340  *  20: header end (short) {8svx, 26 = data_offset, 0x10a = version, ((~version + 0x1234) & 0xffff) = 0x1129}
3341  * [20]: first block:
3342  *     block code, 1 = data, 0 = end, 9 = data_16 (2 = continue, 3 = silence, 4 = marker, 5 = text, 6 = loop, 7 = loop-end, 8 = extended)
3343  *     block len as 24 bit int(?)
3344  *     if data, then rate code (byte), then data (assuming 8-bit unsigned, mono)
3345  *     if data_16, long srate, byte: data size (8 or 16), byte chans
3346  *     if text, ascii text (a comment)
3347  *     if extended (8) precedes 1 (data): 8 4 then time constant (short), byte: packing code (0), byte chans (0 = mono)
3348  *
3349  * apparently always little_endian
3350  * updated extensively 29-Aug-95 from sox10 voc.c
3351  */
3352 
read_voc_header(const char * filename,int fd)3353 static int read_voc_header(const char *filename, int fd)
3354 {
3355   mus_long_t curbase;
3356   int voc_extended, bits, code;
3357   bool happy = true;
3358 
3359   sample_type = MUS_UBYTE;
3360   chans = 1;
3361   voc_extended = 0;
3362   true_file_length = SEEK_FILE_LENGTH(fd);
3363   curbase = mus_char_to_lshort((uint8_t *)(hdrbuf + 20));
3364   if (true_file_length < curbase)
3365     return(mus_error(MUS_HEADER_READ_FAILED, "%s: block location %" print_mus_long " > file length: %" print_mus_long, filename, curbase, true_file_length));
3366 
3367   lseek(fd, curbase, SEEK_SET);
3368   header_read(fd, hdrbuf, HDRBUFSIZ);
3369 
3370   while (happy)
3371     {
3372       int type, len;
3373       type = (int)(hdrbuf[0]);
3374       len = (((int)hdrbuf[3]) << 16) + (((int)hdrbuf[2]) << 8) + (((int)hdrbuf[1]));
3375       if (type == 1) /* voc_data */
3376 	{
3377 	  data_size = len - 1; /* was -3 */
3378 	  data_location = curbase + 6;
3379 	  if (voc_extended == 0)
3380 	    {
3381 	      srate = (int)(1000000.0 / (256 - ((int)(hdrbuf[4] & 0xff))));
3382 	      original_sample_type = hdrbuf[5];
3383 	      if (hdrbuf[5] == 0)
3384 		sample_type = MUS_UBYTE;
3385 	      else sample_type = MUS_UNKNOWN_SAMPLE;
3386 	    }
3387 	  happy = false;
3388 	}
3389       else
3390 	{
3391 	  if (type == 9) /* voc_data_16 */
3392 	    {
3393 	      data_size = len - 1; /* was -3 */
3394 	      data_location = curbase + 6;
3395 	      srate = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
3396 	      bits = ((int)hdrbuf[8]);
3397 	      if (bits == 8)
3398 		{
3399 		  code = mus_char_to_lshort((uint8_t *)(hdrbuf + 10));
3400 		  if (code == 6)
3401 		    sample_type = MUS_ALAW;
3402 		  else
3403 		    if (code == 7)
3404 		      sample_type = MUS_MULAW;
3405 		    else sample_type = MUS_UBYTE;
3406 		}
3407 	      else
3408 		if (bits == 16)
3409 		  sample_type = MUS_LSHORT;
3410 		else sample_type = MUS_UNKNOWN_SAMPLE;
3411 	      chans = (int)hdrbuf[9];
3412 	      if (chans == 0) chans = 1;
3413 	      happy = false;
3414 	    }
3415 	  else
3416 	    {
3417 	      if (((len + curbase) < true_file_length) && (type != 0))
3418 		{
3419 		  if (type == 5) /* voc_text */
3420 		    {
3421 		      comment_start = curbase + 4;
3422 		      comment_end = comment_start + len - 1;
3423 		    }
3424 		  else
3425 		    {
3426 		      if (type == 8) /* voc_extended */
3427 			{
3428 			  /* should voc_extended be set to 1 here? */
3429 			  srate = (256000000 / (65536 - mus_char_to_lshort((uint8_t *)(hdrbuf + 4))));
3430 			  if ((int)(hdrbuf[7]) == 0) chans = 1; else chans = 2;
3431 			  if ((int)(hdrbuf[6]) != 0) sample_type = MUS_UNKNOWN_SAMPLE;
3432 			}
3433 		      /* I'd add loop support here if I had any example sound files to test with */
3434 		    }
3435 		  if (seek_and_read(fd, (uint8_t *)hdrbuf, curbase + len + 4, HDRBUFSIZ) <= 0)
3436 		    return(mus_error(MUS_HEADER_READ_FAILED, "%s voc header: ran off end of file", filename));
3437 		  curbase += len;
3438 		}
3439 	      else happy = false;
3440 	    }
3441 	}
3442     }
3443 
3444   if (data_location == 0)
3445     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no data(type 1 or 9) chunk?", filename));
3446 
3447   if ((data_size > true_file_length) || (data_size < (mus_long_t)(true_file_length / 10))) /* some VOC files seem to have completely bogus lengths */
3448     {
3449       data_size = true_file_length - data_location;
3450       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
3451     }
3452   data_size = mus_bytes_to_samples(sample_type, data_size);
3453 
3454   return(MUS_NO_ERROR);
3455 }
3456 
3457 
3458 
3459 /* ------------------------------------ TwinVQ ------------------------------------
3460  *
3461  * from Audio Tools Library (atl.zip) at http://jfaul.de/atl.
3462  * a chunked header for proprietary (and apparently obsolete?) compressed data
3463  *
3464  * 0: "TWIN"
3465  * 4: version id (string)
3466  * 12: header size ["cardinal" -> bint]
3467  * common chunk header (4 of ID, bint size)
3468  * 24: channels (bint: 0=mono 1=stereo)
3469  * bitrate (bint)
3470  * 32: srate (bint khz 11, 22, 44 else *1000)
3471  * security (bint 0)
3472  * filesize (bint bytes)
3473  * possible chunks: NAME COMT AUTH (c) FILE ALBM DATA
3474  */
3475 
3476 /* Monkey files start with "MAC ", but this is yet another compression-oriented format, I think (APE?) */
3477 
read_twinvq_header(const char * filename,int fd)3478 static int read_twinvq_header(const char *filename, int fd)
3479 {
3480   sample_type = MUS_UNKNOWN_SAMPLE;
3481   data_location = mus_char_to_bint((uint8_t *)(hdrbuf + 12)) + 16 + 8;
3482   chans = 1 + mus_char_to_bint((uint8_t *)(hdrbuf + 24));
3483   srate = mus_char_to_bint((uint8_t *)(hdrbuf + 32));
3484   if (srate == 11) srate = 11025; else
3485     if (srate == 22) srate = 22050; else
3486       if (srate == 44) srate = 44100; else
3487 	srate = 48000;
3488   true_file_length = SEEK_FILE_LENGTH(fd);
3489   data_size = (true_file_length - data_location);
3490   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
3491   return(MUS_NO_ERROR);
3492 }
3493 
3494 
3495 /* ------------------------------------ SDIF ------------------------------------
3496  *
3497  * not usable in this context -- even the apparently non-existent 1TDS (sampled data)
3498  *   format consists of a sequence of chunks, each of any size.
3499  *   Why invent an uncompressed format that makes random access impossible?
3500  */
3501 
read_sdif_header(const char * filename,int fd)3502 static int read_sdif_header(const char *filename, int fd)
3503 {
3504   static const uint8_t I_1FQ0[4] = {'1','F','Q','0'};
3505   static const uint8_t I_1STF[4] = {'1','S','T','F'};
3506   static const uint8_t I_1PIC[4] = {'1','P','I','C'};
3507   static const uint8_t I_1TRC[4] = {'1','T','R','C'};
3508   static const uint8_t I_1HRM[4] = {'1','H','R','M'};
3509   static const uint8_t I_1RES[4] = {'1','R','E','S'};
3510   static const uint8_t I_1TDS[4] = {'1','T','D','S'};  /* samples -- all others are useless */
3511   static const char *sdif_names[7] = {"fundamental frequency", "FFT", "spectral peak", "sinusoidal track", "harmonic track", "resonance", "unknown"};
3512 
3513   int offset;
3514   offset = 16;
3515   while (true)
3516     {
3517       int size;
3518       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 32) <= 0)
3519 	return(mus_error(MUS_HEADER_READ_FAILED, "%s, sdif header: chunks confused at %d", filename, offset));
3520       size = mus_char_to_bint((uint8_t *)(hdrbuf + 4)) + 8;
3521 
3522       if (match_four_chars((uint8_t *)hdrbuf, I_1TDS))
3523 	break;
3524       else
3525 	{
3526 	  int type = 0;
3527 	  if (match_four_chars((uint8_t *)hdrbuf, I_1FQ0))
3528 	    type = 0;
3529 	  else if (match_four_chars((uint8_t *)hdrbuf, I_1STF))
3530 	    type = 1;
3531 	  else if (match_four_chars((uint8_t *)hdrbuf, I_1PIC))
3532 	    type = 2;
3533 	  else if (match_four_chars((uint8_t *)hdrbuf, I_1TRC))
3534 	    type = 3;
3535 	  else if (match_four_chars((uint8_t *)hdrbuf, I_1HRM))
3536 	    type = 4;
3537 	  else if (match_four_chars((uint8_t *)hdrbuf, I_1RES))
3538 	    type = 5;
3539 	  else type = 6;
3540 	  return(mus_error(MUS_HEADER_READ_FAILED, "this SDIF file contains %s data, not sampled sound", sdif_names[type]));
3541 	}
3542       /* unreachable */
3543       offset += size;
3544     }
3545   return(MUS_HEADER_READ_FAILED);
3546 }
3547 
3548 
3549 #if G7XX
3550 /* ------------------------------------ NVF ------------------------------------
3551  */
3552 
read_nvf_header(const char * filename,int fd)3553 static int read_nvf_header(const char *filename, int fd)
3554 {
3555   static const uint8_t I_VFMT[4] = {'V','F','M','T'};  /* Nomad II Creative NVF */
3556 
3557   /* info from nvftools by Tom Mander: */
3558   /*
3559     Numbers stored little-endian.
3560 
3561     bytes 0-3:   "NVF "                 magic number
3562     bytes 4-7:    0x00000001            NVF version number?
3563     bytes 8-11:   0x00000020            size of rest of header
3564     bytes 12-15:  "VFMT"                VFMT chunk h
3565     bytes 16-19:  0x00000001            VFMT version number?
3566     bytes 20-23:  0x00000014            size of reset of VFMT header
3567     bytes 24-27:  0x00007D00            32000 bit/s bitrate
3568     bytes 28-29:  0x0001                channels
3569     bytes 30-31:  0x0000                unknown
3570     bytes 32-35:  0x00001F40            8000kHz sample rate
3571     bytes 36-39:  0x00003E80            16000
3572     bytes 40-41:  0x0002                width in bytes of uncompressed data?
3573     bytes 42-43:  0x0010                width in bits of compressed data?
3574 
3575     The rest of the data is G.721 data nibble packing big-endian, 4bits per
3576     sample (nibble) single channel at 32kbit. When the Nomad records an NVF
3577     file it does it in 92 sample (46 byte) framples or 0.0115sec.
3578   */
3579   if (mus_char_to_lint((uint8_t *)(hdrbuf + 4)) != 1) return(mus_error(MUS_HEADER_READ_FAILED, "%s: NVF[4] != 1", filename));
3580   if (!(match_four_chars((uint8_t *)(hdrbuf + 12), I_VFMT))) return(mus_error(MUS_HEADER_READ_FAILED, "%s: no VFMT chunk", filename));
3581   sample_type = MUS_UNKNOWN_SAMPLE; /* g721 --translate elsewhere */
3582   chans = 1;
3583   srate = 8000;
3584   data_location = 44;
3585   true_file_length = SEEK_FILE_LENGTH(fd);
3586   data_size = (true_file_length - data_location) * 2; /* 4 bit samps? */
3587   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
3588   return(MUS_NO_ERROR);
3589 }
3590 #endif
3591 
3592 
3593 
3594 /* ------------------------------------ ADC ------------------------------------
3595  * also known as OGI format
3596  * TIMIT format is identical except it omits the sample type field (header size claims to be bytes)
3597  *
3598  * from ad.h and other files, ogitools-v1.0.tar.gz
3599  * we'll look for the big/little endian sequence (short) 8 1 1-or-2 given big/little decision
3600  *
3601  * 0: header size in shorts (8 = 16 bytes) (OGI says this is in bytes)
3602  * 2: version (1)
3603  * 4: chans
3604  * 6: rate (srate = 4000000/rate)
3605  * 8: samples (int) -- seems to be off by 2 -- are they counting ints here?
3606  * 12: sample type (0 = big-endian)
3607  * 16: data start
3608 */
3609 
read_adc_header(const char * filename,int fd)3610 static int read_adc_header(const char *filename, int fd)
3611 {
3612   bool little;
3613   little = (mus_char_to_uninterpreted_int((uint8_t *)(hdrbuf + 12)) != 0); /* 0 = big endian */
3614   data_location = 16;
3615   if (little) sample_type = MUS_LSHORT; else sample_type = MUS_BSHORT;
3616   chans = big_or_little_endian_short((uint8_t *)(hdrbuf + 4), little);
3617   srate = 4000000 / big_or_little_endian_short((uint8_t *)(hdrbuf + 6), little);
3618   data_size = 2 * big_or_little_endian_int((uint8_t *)(hdrbuf + 8), little);
3619   comment_start = 0;
3620   comment_end = 0;
3621   true_file_length = SEEK_FILE_LENGTH(fd);
3622   if (data_size > true_file_length)
3623     {
3624       data_size = true_file_length - data_location;
3625       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
3626     }
3627   data_size = mus_bytes_to_samples(sample_type, data_size);
3628   return(MUS_NO_ERROR);
3629 }
3630 
3631 
3632 
3633 /* ------------------------------------ AVR --------------------------------------
3634  *
3635  *   0: "2BIT"
3636  *   4: sample name (null padded ASCII)
3637  *  12: chans (short) (0 = mono, -1 = stereo)
3638  *  14: sample size (8 or 16 bit) (short) (value is 8, 12, or 16)
3639  *  16: sample type (signed or unsigned) (short) (0 = unsigned, -1 = signed)
3640  *  18: loop (on/off), 20: midi (-1 = no MIDI)
3641  *  22: srate
3642  *      avr.txt has:
3643  *      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
3644  *      23: sample rate	in Hertz (as a 3 byte quantity??)
3645  *  26: length in samples
3646  *  30: loop beg, 34: loop end, 38: midi (keyboard split), 40: compression, 42: nada ("reserved"), 44: name
3647  *  64: comment (limited to 64 bytes)
3648  * 128: data start
3649  *
3650  * the Atari .avr files appear to be 8000 Hz, mono, 8-bit linear unsigned data with an unknown header of 128 words
3651  * apparently there was a change in format sometime in the 90's.
3652  *
3653  * The actual avr files I've found on the net are either garbled, or
3654  * something is wrong with this definition (taken from CMJ and www.wotsit.org's avr.txt).
3655  * SGI dmconvert assumes big-endian here -- this is an Atari format, so it's probably safe to assume big-endian.
3656  */
3657 
read_avr_header(const char * filename,int fd)3658 static int read_avr_header(const char *filename, int fd)
3659 {
3660   int dsize, dsigned, i;
3661   chans = mus_char_to_bshort((uint8_t *)(hdrbuf + 12));
3662   if (chans == 0) chans = 1; else if (chans == -1) chans = 2; else return(mus_error(MUS_HEADER_READ_FAILED, "%s chans: %d", filename, chans));
3663   data_location = 128;
3664   data_size = mus_char_to_bint((uint8_t *)(hdrbuf + 26));
3665   srate = mus_char_to_ubshort((uint8_t *)(hdrbuf + 24));
3666   dsize = mus_char_to_bshort((uint8_t *)(hdrbuf + 14));
3667   dsigned = mus_char_to_bshort((uint8_t *)(hdrbuf + 16));
3668   if (dsize == 16)
3669     {
3670       if (dsigned == 0)
3671 	sample_type = MUS_UBSHORT;
3672       else sample_type = MUS_BSHORT;
3673     }
3674   else
3675     {
3676       if (dsize == 8)
3677 	{
3678 	  if (dsigned == 0)
3679 	    sample_type = MUS_UBYTE;
3680 	  else sample_type = MUS_BYTE;
3681 	}
3682       else return(mus_error(MUS_HEADER_READ_FAILED, "%s: unknown sample type", filename));
3683     }
3684   if (seek_and_read(fd, (uint8_t *)hdrbuf, 64, 64) <= 0)
3685     return(mus_error(MUS_HEADER_READ_FAILED, "%s avr header: ran off end of file", filename));
3686   comment_start = 64;
3687   i = 0;
3688   while ((i < 64) && (hdrbuf[i] != 0)) i++;
3689   comment_end = 64 + (i - 1);
3690   true_file_length = SEEK_FILE_LENGTH(fd);
3691   if (data_size > true_file_length)
3692     {
3693       data_size = true_file_length - data_location;
3694       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
3695     }
3696   data_size = mus_bytes_to_samples(sample_type, data_size);
3697   return(MUS_NO_ERROR);
3698 }
3699 
3700 
3701 
3702 /* ------------------------------------ SNDT -------------------------------------
3703  *
3704  * this taken from sndrtool.c (sox-10): (modified 6-Feb-98)
3705  *   0: "SOUND" (or off by two throughout if not "0x1a"?)
3706  *   5: 0x1a
3707  *   6-7: 0
3708  *   8-11: nsamps (at 12)
3709  *  12-15: 0
3710  *  16-19: nsamps
3711  *  20-21: srate (little endian short) (at 22)
3712  *  22-23: 0
3713  *  24-25: 10
3714  *  26-27: 4
3715  *  28-> : <filename> "- File created by Sound Exchange"
3716  *  .->95: 0 ?
3717  */
3718 
3719 /* similar is Sounder format:
3720  * 0: 0
3721  * 2: short srate (little endian)
3722  * 4: 10
3723  * 6: 4
3724  * then data
3725  * but this format can't be distinguished from a raw sound file
3726  */
3727 
read_sndt_header(const char * filename,int fd)3728 static int read_sndt_header(const char *filename, int fd)
3729 {
3730   if (hdrbuf[4] != 'D') return(mus_error(MUS_HEADER_READ_FAILED, "%s: SNDT[4] != 'D'", filename));
3731   sample_type = MUS_UBYTE;
3732   chans = 1;
3733   srate = mus_char_to_ulshort((uint8_t *)(hdrbuf + 20));
3734   data_location = 126;
3735   data_size = mus_char_to_lint((uint8_t *)(hdrbuf + 8));
3736   if (data_size < 0) data_size = mus_char_to_lint((uint8_t *)(hdrbuf + 10));
3737   if (srate <= 1) srate = mus_char_to_ulshort((uint8_t *)(hdrbuf + 22));
3738   true_file_length = SEEK_FILE_LENGTH(fd);
3739   if (data_size > true_file_length)
3740     {
3741       data_size = true_file_length - data_location;
3742       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
3743     }
3744   return(MUS_NO_ERROR);
3745 }
3746 
3747 
3748 
3749 /* ------------------------------------ Covox v8 -------------------------------------
3750  *
3751  *  0: 377 125 377 252 377 125 377 252 x x 0's to 16
3752  * then 8-bit unsigned data
3753  */
3754 
read_covox_header(const char * filename,int fd)3755 static int read_covox_header(const char *filename, int fd)
3756 {
3757   sample_type = MUS_UBYTE;
3758   chans = 1;
3759   data_location = 16;
3760   srate = 8000;
3761   true_file_length = SEEK_FILE_LENGTH(fd);
3762   data_size = true_file_length - data_location;
3763   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
3764   return(MUS_NO_ERROR);
3765 }
3766 
3767 
3768 
3769 /* ------------------------------------ SMP -------------------------------------
3770  *
3771  *  0: "SOUND SAMPLE DATA "
3772  * 18: "2.1 "
3773  * 22-81: comment
3774  * 82-111: sample name
3775  * header 112 bytes
3776  * long samples (bytes = samples*2)
3777  * then data start
3778  * data
3779  * always little endian
3780  */
3781 
read_smp_header(const char * filename,int fd)3782 static int read_smp_header(const char *filename, int fd)
3783 {
3784   sample_type = MUS_LSHORT;
3785   chans = 1;
3786   comment_start = 22;
3787   comment_end = 81;
3788   data_location = 116;
3789   lseek(fd, 112, SEEK_SET);
3790   if (read(fd, hdrbuf, 4) != 4) return(mus_error(MUS_HEADER_READ_FAILED, "%s: SMP header truncated?", filename));
3791   data_size = (mus_char_to_lint((uint8_t *)hdrbuf));
3792   sample_type = MUS_LSHORT; /* just a guess */
3793   srate = 8000; /* docs mention an srate floating around at the end of the file, but I can't find it in any example */
3794   true_file_length = SEEK_FILE_LENGTH(fd);
3795   if ((data_size * 2) > true_file_length)
3796     {
3797       data_size = (true_file_length - data_location) / 2;
3798       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
3799     }
3800   return(MUS_NO_ERROR);
3801 }
3802 
3803 
3804 
3805 /* ------------------------------------ SPPACK -------------------------------------
3806  *
3807  * from AF docs:
3808  *         Bytes   Type    Contents
3809  *     0   160    char   Text strings (2 * 80)
3810  *   160    80    char   Command line
3811  *   240     2    int    Domain (1-time, 2-freq, 3-qfreq)
3812  *   242     2    int    Frample size
3813  *   244     4    float  Sampling frequency
3814  *   252     2    int    File identifier (i.e. #o100 #o303)
3815  *   254     2    int    Data type (0xfc0e = sampled data file)
3816  *   256     2    int    Resolution (in bits 8, 16)
3817  *   258     2    int    Companding flag
3818  *   272   240    char   Text strings (3 * 80)
3819  *   512   ...    --     Audio data
3820  *
3821  * at least one program is writing these headers using little endian data...
3822  */
3823 
read_sppack_header(const char * filename,int fd)3824 static int read_sppack_header(const char *filename, int fd)
3825 {
3826   int typ;
3827   data_location = 512;
3828   chans = 1;
3829   lseek(fd, 240, SEEK_SET);
3830   if (read(fd, hdrbuf, 22) != 22) return(mus_error(MUS_HEADER_READ_FAILED, "%s SPPACK header truncated?", filename));
3831   typ = mus_char_to_bshort((uint8_t *)hdrbuf);
3832   sample_type = MUS_UNKNOWN_SAMPLE;
3833   if (typ == 1)
3834     {
3835       if (((hdrbuf[254]) == 252) && ((hdrbuf[255]) == 14)) /* #xfc and #x0e */
3836 	{
3837 	  int bits;
3838 	  float sr;
3839 	  typ = mus_char_to_bshort((uint8_t *)(hdrbuf + 18));
3840 	  bits = mus_char_to_bshort((uint8_t *)(hdrbuf + 16));
3841 	  sr = mus_char_to_bfloat((uint8_t *)(hdrbuf + 4));
3842 	  srate = (int)sr;
3843 	  switch (typ)
3844 	    {
3845 	    case 1: if (bits == 16) sample_type = MUS_BSHORT; else sample_type = MUS_BYTE; break;
3846 	    case 2: sample_type = MUS_ALAW; break;
3847 	    case 3: sample_type = MUS_MULAW; break;
3848 	    default: sample_type = MUS_UNKNOWN_SAMPLE; break;
3849 	    }
3850 	  data_size = SEEK_FILE_LENGTH(fd);
3851 	  data_size = mus_bytes_to_samples(sample_type, data_size - 512);
3852 	  comment_start = 0;
3853 	  comment_end = 0;
3854 	}
3855     }
3856   true_file_length = SEEK_FILE_LENGTH(fd);
3857   if (true_file_length < data_location)
3858     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
3859   if (data_size > mus_bytes_to_samples(sample_type, true_file_length))
3860     data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location);
3861   return(MUS_NO_ERROR);
3862 }
3863 
3864 
3865 
3866 /* ------------------------------------ ESPS (Entropic Signal Processing System) -------------------------------------
3867  *
3868  * specs at ftp.entropic.com (also known as "SD" format)
3869  * from AFgetInfoES.c:
3870  *
3871  *       Bytes     Type    Contents
3872  *      8 -> 11    --     Header size (bytes)
3873  *     12 -> 15    int    Sampled data record size
3874  *     16 -> 19    int    File identifier: 0x00006a1a or 0x1a6a0000
3875  *     40 -> 65    char   File creation date
3876  *    124 -> 127   int    Number of samples
3877  *    132 -> 135   int    Number of doubles in a data record
3878  *    136 -> 139   int    Number of floats in a data record
3879  *    140 -> 143   int    Number of longs in a data record
3880  *    144 -> 147   int    Number of shorts in a data record
3881  *    148 -> 151   int    Number of chars in a data record
3882  *    160 -> 167   char   User name
3883  *    333 -> H-1   --     "Generic" header items, including "record_freq" {followed by a "double8"=64-bit ?}
3884  *      H -> ...   --     Audio data
3885  */
3886 
read_esps_header(const char * filename,int fd)3887 static int read_esps_header(const char *filename, int fd)
3888 {
3889   char str[80];
3890   bool happy = true;
3891   mus_long_t curbase, hend;
3892   int k, j, n, chars, floats, shorts, doubles;
3893   int64_t bytes;
3894   bool little;
3895   little = (hdrbuf[18] == 0);
3896   if (little)
3897     data_location = mus_char_to_lint((uint8_t *)(hdrbuf + 8));
3898   else data_location = mus_char_to_bint((uint8_t *)(hdrbuf + 8));
3899   true_file_length = SEEK_FILE_LENGTH(fd);
3900   data_size = true_file_length - data_location;
3901   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
3902   srate = 8000;
3903   chans = 1;
3904   lseek(fd, 132, SEEK_SET);
3905   header_read(fd, hdrbuf, HDRBUFSIZ);
3906   if (little)
3907     {
3908       doubles = mus_char_to_lint((uint8_t *)hdrbuf);
3909       floats = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
3910       shorts = mus_char_to_lint((uint8_t *)(hdrbuf + 12));
3911       chars = mus_char_to_lint((uint8_t *)(hdrbuf + 16));
3912     }
3913   else
3914     {
3915       doubles = mus_char_to_bint((uint8_t *)hdrbuf);
3916       floats = mus_char_to_bint((uint8_t *)(hdrbuf + 4));
3917       shorts = mus_char_to_bint((uint8_t *)(hdrbuf + 12));
3918       chars = mus_char_to_bint((uint8_t *)(hdrbuf + 16));
3919     }
3920   if (shorts != 0)
3921     {
3922       sample_type = ((little) ? MUS_LSHORT : MUS_BSHORT);
3923       chans = shorts;
3924     }
3925   else
3926     {
3927       if (doubles != 0)
3928 	{
3929 	  sample_type = ((little) ? MUS_LDOUBLE_UNSCALED : MUS_BDOUBLE_UNSCALED);
3930 	  chans = doubles;
3931 	}
3932       else
3933 	{
3934 	  if (floats != 0)
3935 	    {
3936 	      sample_type = ((little) ? MUS_LFLOAT_UNSCALED : MUS_BFLOAT_UNSCALED);
3937 	      chans = floats;
3938 	    }
3939 	  else
3940 	    {
3941 	      if (chars != 0)
3942 		{
3943 		  sample_type = MUS_BYTE; /* ?? */
3944 		  chans = chars;
3945 		}
3946 	    }
3947 	}
3948     }
3949   /* search for "record_freq" to get srate */
3950   lseek(fd, 333, SEEK_SET);
3951   header_read(fd, hdrbuf, HDRBUFSIZ);
3952   curbase = 333;
3953   hend = curbase + HDRBUFSIZ;
3954   k = 0;
3955   n = 0;
3956   for (j = 0; j < 80; j++) str[j] =' ';
3957   while (happy)
3958     {
3959       str[k] = hdrbuf[n];
3960       if ((str[k] == 'q') || (str[k] == 3) || ((curbase + n + 1) >= data_location) || (k == 78))
3961 	{ /* 3 = C-C marks end of record (?) */
3962 	  str[k + 1] = 0;
3963 	  if (strcmp(str, "record_freq") == 0)
3964 	    {
3965 	      if (seek_and_read(fd, (uint8_t *)hdrbuf, curbase + n, 32) <= 0)
3966 		return(mus_error(MUS_HEADER_READ_FAILED, "%s esps header: ran off end of file", filename));
3967 	      n = 0;
3968 	      if (little)
3969 		srate = (int)mus_char_to_ldouble((uint8_t *)(hdrbuf + 8));
3970 	      else srate = (int)mus_char_to_bdouble((uint8_t *)(hdrbuf + 8));
3971 	      happy = false;
3972 	    }
3973 	  if ((curbase + n + 1) >= data_location) happy = false;
3974 	  k = 0;
3975 	}
3976       else
3977 	k++;
3978       n++;
3979       if (n >= hend)
3980 	{
3981 	  curbase += hend;
3982 	  n = 0;
3983 	  bytes = read(fd, hdrbuf, HDRBUFSIZ);
3984 	  if (bytes != HDRBUFSIZ) break;
3985 	  hend = HDRBUFSIZ;
3986 	}
3987     }
3988   if (srate == 0) srate = 8000;
3989   data_size = mus_bytes_to_samples(sample_type, data_size);
3990   return(MUS_NO_ERROR);
3991 }
3992 
3993 
3994 
3995 /* ------------------------------------ INRS -------------------------------------
3996  *
3997  *   from AFgetInfoIN.c:
3998  *
3999  *    INRS-Telecommunications audio file:
4000  *       Bytes     Type    Contents
4001  *      0 ->  3    float  Sampling Frequency (VAX float format)
4002  *      6 -> 25    char   Creation time (e.g. Jun 12 16:52:50 1990)
4003  *     26 -> 29    int    Number of speech samples in the file (? -- old INRS files omit this)
4004  *   The data in an INRS-Telecommunications audio file is in 16-bit integer (little-endian)
4005  *   format. Header is always 512 bytes.  Always mono.
4006  *
4007  */
4008 
read_inrs_header(const char * filename,int fd,int loc)4009 static int read_inrs_header(const char *filename, int fd, int loc)
4010 {
4011   true_file_length = SEEK_FILE_LENGTH(fd);
4012   comment_start = 6;
4013   comment_end = 25;
4014   sample_type = MUS_LSHORT;
4015   srate = loc;
4016   chans = 1;
4017   data_location = 512;
4018   true_file_length = SEEK_FILE_LENGTH(fd);
4019   if (true_file_length < data_location)
4020     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
4021   data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location);
4022   return(MUS_NO_ERROR);
4023 }
4024 
4025 
4026 
4027 /* ------------------------------------ MAUD -------------------------------------
4028  *
4029  * very similar to AIFF:
4030  *  "MHDR" => 4: chunksize (32)
4031  *            8: samples
4032  *           12: bits
4033  *           14: ditto
4034  *           16: clock freq
4035  *           20: clock div (srate = freq/div)
4036  *           22: chan info (0 = mono, 1 = stereo)
4037  *           24: ditto(?!)
4038  *           26: format (0 = unsigned 8 or signed 16 (see bits), 2 = alaw, 3 = mulaw)
4039  *           28-40: unused
4040  *  "MDAT" => data
4041  *  "ANNO" => comment
4042  *
4043  * according to /usr/share/magic, this stands for "MacroSystem Audio"
4044  */
4045 
read_maud_header(const char * filename,int fd)4046 static int read_maud_header(const char *filename, int fd)
4047 {
4048   static const uint8_t I_MHDR[4] = {'M','H','D','R'};
4049   static const uint8_t I_MDAT[4] = {'M','D','A','T'};
4050 
4051   int offset, chunkloc;
4052   bool happy = true;
4053   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)hdrbuf);
4054   chunkloc = 12;
4055   offset = 0;
4056   sample_type = MUS_BYTE;
4057   srate = 0;
4058   chans = 1;
4059   update_form_size = mus_char_to_bint((uint8_t *)(hdrbuf + 4));
4060   while (happy)
4061     {
4062       int chunksize;
4063       offset += chunkloc;
4064       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 32) <= 0)
4065 	return(mus_error(MUS_HEADER_READ_FAILED, "%s maud header: chunks confused at %d", filename, offset));
4066       chunksize = mus_char_to_bint((uint8_t *)(hdrbuf + 4));
4067       if ((chunksize == 0) && /* can be empty data chunk? */
4068 	  (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0))
4069 	break;
4070       if (chunksize < 0)
4071 	break;
4072       if (match_four_chars((uint8_t *)hdrbuf, I_MHDR))
4073 	{
4074 	  int num, den;
4075 	  data_size = mus_char_to_bint((uint8_t *)(hdrbuf + 8));
4076 	  num = mus_char_to_bint((uint8_t *)(hdrbuf + 16));
4077 	  den = mus_char_to_bshort((uint8_t *)(hdrbuf + 20));
4078 	  if (den == 0) den = 1;
4079 	  srate = (int)(num / den);
4080 	  num = mus_char_to_bshort((uint8_t *)(hdrbuf + 12));
4081 	  den = mus_char_to_bshort((uint8_t *)(hdrbuf + 26));
4082 	  if (num == 8)
4083 	    {
4084 	      switch (den)
4085 		{
4086 		case 0: sample_type = MUS_UBYTE; break;
4087 		case 2: sample_type = MUS_ALAW; break;
4088 		case 3: sample_type = MUS_MULAW; break;
4089 		default: sample_type = MUS_UNKNOWN_SAMPLE; break;
4090 		}
4091 	    }
4092 	  else sample_type = MUS_BSHORT;
4093 	  num = mus_char_to_bshort((uint8_t *)(hdrbuf + 22));
4094 	  if (num == 0) chans = 1; else chans = 2;
4095 	}
4096       else
4097 	{
4098 	  if (match_four_chars((uint8_t *)hdrbuf, I_ANNO))
4099 	    {
4100 	      comment_start = offset + 8;
4101 	      comment_end = comment_start + chunksize - 1;
4102 	    }
4103 	  else
4104 	    {
4105 	      if (match_four_chars((uint8_t *)hdrbuf, I_MDAT))
4106 		{
4107 		  data_location = offset + 12;
4108 		  happy = false;
4109 		}
4110 	    }
4111 	}
4112       chunkloc = (8 + chunksize);
4113       if (chunksize & 1) chunkloc++; /* extra null appended to odd-length chunks */
4114     }
4115   if (data_location == 0)
4116     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no MDAT chunk?", filename));
4117   true_file_length = SEEK_FILE_LENGTH(fd);
4118   if (data_size > true_file_length)
4119     {
4120       data_size = true_file_length - data_location;
4121       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4122     }
4123   data_size = mus_bytes_to_samples(sample_type, data_size);
4124   return(MUS_NO_ERROR);
4125 }
4126 
4127 
4128 
4129 /* ------------------------------------ CSL -------------------------------------
4130  *
4131  * "Computerized Speech Labs -- this info taken from wavesurfer/snack
4132  *
4133  * very similar to AIFF:
4134  * 0: FORM
4135  * 4: DS16 (kinda weird)
4136  * 8: size (int le)
4137  * 12: chunks
4138  *     HEDR or HDR8
4139  *     4: size (int)
4140  *     samp: short, chans: 1 at 36 if not (int) -1, chans: 2?
4141  *     srate at 28 (le int?)
4142  * other chunks: SD_B, SDA_ SDAB with data bytes as data followed by data
4143  */
4144 
read_csl_header(const char * filename,int fd)4145 static int read_csl_header(const char *filename, int fd)
4146 {
4147   static const uint8_t I_HEDR[4] = {'H','E','D','R'};
4148   static const uint8_t I_HDR8[4] = {'H','D','R','8'};
4149   static const uint8_t I_SDA_[4] = {'S','D','A','_'};
4150   static const uint8_t I_SDAB[4] = {'S','D','A','B'};
4151   static const uint8_t I_SD_B[4] = {'S','D','_','B'};
4152   static const uint8_t I_NOTE[4] = {'N','O','T','E'};
4153 
4154   int offset, chunkloc;
4155   bool happy = true;
4156   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)hdrbuf);
4157   chunkloc = 12;
4158   offset = 0;
4159   sample_type = MUS_LSHORT;
4160   srate = 0;
4161   chans = 1;
4162   update_form_size = mus_char_to_lint((uint8_t *)(hdrbuf + 8));
4163   while (happy)
4164     {
4165       int chunksize;
4166       offset += chunkloc;
4167       if (seek_and_read(fd, (uint8_t *)hdrbuf, offset, 64) <= 0)
4168 	return(mus_error(MUS_HEADER_READ_FAILED, "%s csl header: chunks confused at %d", filename, offset));
4169       chunksize = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
4170       if ((chunksize == 0) && /* can be empty data chunk? */
4171 	  (hdrbuf[0] == 0) && (hdrbuf[1] == 0) && (hdrbuf[2] == 0) && (hdrbuf[3] == 0))
4172 	break;
4173       if (chunksize < 0)
4174 	break;
4175       if ((match_four_chars((uint8_t *)hdrbuf, I_HEDR)) ||
4176 	  (match_four_chars((uint8_t *)hdrbuf, I_HDR8)))
4177 	{
4178 	  /* 8..20: date as ascii */
4179 	  /* 32: data length (int) in bytes */
4180 	  if ((mus_char_to_lshort((uint8_t *)(hdrbuf + 36)) != -1) && /* these are maxamps, -1=none */
4181 	      (mus_char_to_lshort((uint8_t *)(hdrbuf + 38)) != -1))
4182 	    chans = 2;
4183 	  srate = mus_char_to_lint((uint8_t *)(hdrbuf + 28));
4184 	}
4185       else
4186 	{
4187 	  if (match_four_chars((uint8_t *)hdrbuf, I_NOTE))
4188 	    {
4189 	      comment_start = offset + 8;
4190 	      comment_end = comment_start + chunksize - 1;
4191 	    }
4192 	  else
4193 	    {
4194 	      if ((match_four_chars((uint8_t *)hdrbuf, I_SDA_)) ||
4195 		  (match_four_chars((uint8_t *)hdrbuf, I_SDAB)) ||
4196 		  (match_four_chars((uint8_t *)hdrbuf, I_SD_B)))
4197 		{
4198 		  data_location = offset + 8;
4199 		  data_size = mus_char_to_lint((uint8_t *)(hdrbuf + 4));
4200 		  happy = false;
4201 		}
4202 	    }
4203 	}
4204       chunkloc = (8 + chunksize);
4205       if (chunksize & 1) chunkloc++;
4206     }
4207   if (data_location == 0)
4208     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no SDxx chunk?", filename));
4209   true_file_length = SEEK_FILE_LENGTH(fd);
4210   if (data_size > true_file_length)
4211     {
4212       data_size = true_file_length - data_location;
4213       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4214     }
4215   data_size = mus_bytes_to_samples(sample_type, data_size);
4216   return(MUS_NO_ERROR);
4217 }
4218 
4219 
4220 
4221 /* ------------------------------------ snack SMP -------------------------------------
4222  *
4223  * there's apparently yet another "smp" format (from nist??)
4224  * file = samp
4225  * sftot = 22050
4226  * msb = last
4227  * nchans = 1
4228  * preemph = none
4229  * born = snack
4230  * msb = last here -> little endian?
4231  * data at 1024
4232  */
4233 
read_file_samp_header(const char * filename,int fd)4234 static int read_file_samp_header(const char *filename, int fd)
4235 {
4236   int i = 0;
4237   uint8_t *locbuf;
4238   data_location = 1024;
4239   chans = 1;
4240   srate = 8000;
4241   sample_type = MUS_LSHORT;
4242   lseek(fd, 10, SEEK_SET);
4243   locbuf = (uint8_t *)calloc(1024, sizeof(uint8_t));
4244   header_read(fd, locbuf, 1024);
4245   while (i < 1024)
4246     {
4247       if (strncmp((char *)(locbuf + i), "sftot", 5) == 0)
4248 	sscanf((const char *)(&locbuf[i + 6]), "%12d", &srate);
4249       if (strncmp((char *)(locbuf + i), "nchans", 6) == 0)
4250 	sscanf((const char *)(&locbuf[i + 7]), "%12d", &chans);
4251       if (strncmp((char *)(locbuf + i), "msb", 3) == 0)
4252 	if (strncmp((char *)(locbuf + i + 4), "first", 5) == 0)
4253 	  sample_type = MUS_BSHORT;
4254       while ((i < 1024) && (locbuf[i] != 10) && (locbuf[i] != 0)) i++;
4255       i++;
4256     }
4257   free(locbuf);
4258   true_file_length = SEEK_FILE_LENGTH(fd);
4259   if (true_file_length < data_location)
4260     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
4261   data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location);
4262   return(MUS_NO_ERROR);
4263 }
4264 
4265 
4266 
4267 /* ------------------------------------ Sound Designer I -------------------------------------
4268  *
4269  * complicated and defined in terms of Pascal records, so the following is a stab in the dark:
4270  *
4271  * 0:    1336 (i.e. header size)
4272  * 764:  comment (str255)
4273  * 1020: sample rate (long)
4274  * 1028: data size (short)
4275  * 1030: a code string describing the data type (i.e. "linear") (str32)
4276  * 1064: user comment (str255)
4277  *
4278  * file type: 'SFIL'
4279  *
4280  * always big_endian
4281  */
4282 
read_sd1_header(const char * filename,int fd)4283 static int read_sd1_header(const char *filename, int fd)
4284 {
4285   int n;
4286   chans = 1;
4287   data_location = 1336;
4288   lseek(fd, 1020, SEEK_SET);
4289   if (read(fd, hdrbuf, 64) != 64) return(mus_error(MUS_HEADER_READ_FAILED, "%s Sound Designer I header truncated?", filename));
4290   srate = mus_char_to_bint((uint8_t *)hdrbuf);
4291   n = mus_char_to_bshort((uint8_t *)(hdrbuf + 8));
4292   if (n == 16)
4293     sample_type = MUS_BSHORT;
4294   else sample_type = MUS_BYTE;
4295   true_file_length = SEEK_FILE_LENGTH(fd);
4296   if (true_file_length < data_location)
4297     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
4298   data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location);
4299   n = ((uint8_t)hdrbuf[44]);
4300   if (n != 0)
4301     {
4302       comment_start = 1064;
4303       comment_end = comment_start + n - 1;
4304     }
4305   return(MUS_NO_ERROR);
4306 }
4307 
4308 
4309 
4310 /* ------------------------------------ PSION alaw -------------------------------------
4311  *
4312  * 0: "ALawSoundFile**"
4313  * 16: version
4314  * 18: length (bytes)
4315  * 22: padding
4316  * 24: repeats
4317  * 26-32: nada
4318  * 32: data
4319  *
4320  * always mono 8-bit alaw 8000 Hz. All the examples on the psion net site appear to be little endian.
4321  */
4322 
read_psion_header(const char * filename,int fd)4323 static int read_psion_header(const char *filename, int fd)
4324 {
4325   if ((hdrbuf[13] != '*') || (hdrbuf[14] != '*')) return(mus_error(MUS_HEADER_READ_FAILED, "%s: PSION[13, 14] != '*'", filename));
4326   chans = 1;
4327   data_location = 32;
4328   srate = 8000;
4329   sample_type = MUS_ALAW;
4330   data_size = mus_char_to_lint((uint8_t *)(hdrbuf + 18)); /* always little-endian? */
4331   true_file_length = SEEK_FILE_LENGTH(fd);
4332   if (data_size > true_file_length)
4333     {
4334       data_size = true_file_length - data_location;
4335       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4336     }
4337   data_size = mus_bytes_to_samples(sample_type, data_size);
4338   return(MUS_NO_ERROR);
4339 }
4340 
4341 
4342 
4343 /* ------------------------------------ Gravis Ultrasound Patch -------------------------------------
4344  *
4345  * http://www.gravis.com/Public/sdk/PATCHKIT.ZIP
4346  *
4347  * header [128], instruments [62], layers [49], waveheaders (nested)
4348  * always little endian, actual files don't match exactly with any documentation
4349  *
4350  * Header block:
4351  *   0:  "GF1PATCH100" or "GF1PATCH110"
4352  *   12: "ID#000002"
4353  *   22: comment (copyright notice) (60 bytes ASCIZ)
4354  *   82: number of instruments
4355  *   83: number of voices
4356  *   84: wave channels
4357  *   85: number of waves
4358  *   87: vol
4359  *   89: size?
4360  *   93: reserved (36? bytes)
4361  *
4362  * Instrument block:
4363  *   0: id
4364  *   2: name (16 bytes)
4365  *   18: size
4366  *   22: number of layers
4367  *   23: reserved (40? bytes)
4368  *
4369  * Layer block:
4370  *   0: "previous"
4371  *   1: id
4372  *   2: size
4373  *   6: number of wave samples
4374  *  10: reserved (40? bytes)
4375  *
4376  * Wave block:
4377  *   0: name (7 bytes ASCIZ)
4378  *   7: "fractions"
4379  *   8: data size of wave sample
4380  *  12: loop start
4381  *  16: loop end
4382  *  20: sample rate
4383  *  22: low freq
4384  *  26: high freq
4385  *  30: root freq
4386  *  34: tune
4387  *  36: balance
4388  *  37: envelope data (6+6 bytes I think)
4389  *  49: tremolo and vibrato data (6 bytes)
4390  *  55: mode bit 0: 8/16, 1: signed/unsigned
4391  *  56: scale freq
4392  *  58: scale factor
4393  *  60: reserved (36 bytes)
4394  *  followed by data presumably
4395  */
4396 
read_gravis_header(const char * filename,int fd)4397 static int read_gravis_header(const char *filename, int fd)
4398 {
4399   int mode;
4400   chans = hdrbuf[84];
4401   if (chans == 0) chans = 1;
4402   comment_start = 22;
4403   comment_end = 81;
4404   lseek(fd, 239, SEEK_SET); /* try to jump to wave sample block (128+62+49) */
4405   header_read(fd, hdrbuf, 128);
4406   srate = mus_char_to_ulshort((uint8_t *)(hdrbuf + 20));
4407   data_size = mus_char_to_ulshort((uint8_t *)(hdrbuf + 8));
4408   mode = hdrbuf[55];
4409   if (mode & 1)
4410     {
4411       if (mode & 2)
4412 	sample_type = MUS_ULSHORT;
4413       else sample_type = MUS_LSHORT;
4414     }
4415   else
4416     {
4417       if (mode & 2)
4418 	sample_type = MUS_UBYTE;
4419       else sample_type = MUS_BYTE;
4420     }
4421   data_location = 337;
4422   true_file_length = SEEK_FILE_LENGTH(fd);
4423   if (data_size > true_file_length)
4424     {
4425       data_size = true_file_length - data_location;
4426       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4427     }
4428   data_size = mus_bytes_to_samples(sample_type, data_size);
4429   return(MUS_NO_ERROR);
4430 }
4431 
4432 
4433 
4434 /* ------------------------------------ Goldwave -------------------------------------
4435  *
4436  * http://web.cs.mun.ca/~chris3/goldwave/goldwave.html
4437  */
4438 
read_goldwave_header(const char * filename,int fd)4439 static int read_goldwave_header(const char *filename, int fd)
4440 {
4441   chans = 1;
4442   data_location = 28;
4443   sample_type = MUS_LSHORT;
4444   data_size = mus_char_to_lint((uint8_t *)(hdrbuf + 22));
4445   true_file_length = SEEK_FILE_LENGTH(fd);
4446   if (true_file_length < data_location)
4447     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
4448   if ((data_size <= 24) || (data_size > true_file_length))
4449     data_size = (true_file_length - data_location) / 2;
4450   else data_size /= 2;
4451   srate = mus_char_to_lint((uint8_t *)(hdrbuf + 18));
4452   return(MUS_NO_ERROR);
4453 }
4454 
4455 
4456 /* ------------------------------------ Sonic Resource Foundry -------------------------------------
4457  *
4458  * more reverse engineering...
4459  * http://www.sfoundry.com/
4460  */
4461 
read_srfs_header(const char * filename,int fd)4462 static int read_srfs_header(const char *filename, int fd)
4463 {
4464   chans = 1; /* might be short at header[4] */
4465   data_location = 32;
4466   true_file_length = SEEK_FILE_LENGTH(fd);
4467   if (true_file_length < data_location)
4468     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
4469   data_size = (true_file_length - data_location) / 2;
4470   srate = mus_char_to_lint((uint8_t *)(hdrbuf + 6));
4471   sample_type = MUS_LSHORT;
4472   return(MUS_NO_ERROR);
4473 }
4474 
4475 
4476 
4477 /* ------------------------------------ Quicktime -------------------------------------
4478  *
4479  * infinitely complicated -- see Quicktime File Format doc from Apple.
4480  * there's no relation between this document and actual files -- a bizarre joke?
4481  */
4482 
read_qt_header(const char * filename,int fd)4483 static int read_qt_header(const char *filename, int fd)
4484 {
4485   chans = 1;
4486   data_location = 12;
4487   true_file_length = SEEK_FILE_LENGTH(fd);
4488   data_size = (true_file_length - data_location);
4489   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4490   srate = 11025; /* ?? */
4491   sample_type = MUS_UBYTE;
4492   return(MUS_NO_ERROR);
4493 }
4494 
4495 
4496 
4497 /* ------------------------------------ SBStudioII -------------------------------------
4498  *
4499  * from a file created by Convert 1.4
4500  * 0: SND <space>
4501  * 8: file size - 8
4502  * SNNA SNIN SNDT blocks:
4503  *
4504  * built in blocks, other names are SNIN, SNDT
4505  * need to scan for SNDT, block length, data
4506  * SNNA len name
4507  * supposedly ends with END (but my examples don't)
4508  * SNIN:
4509  *   num (2), reserved (2), tuning (1), vol (2), type (2) bit 0: 1 = PCM, bit 1: 1 = 16, 0 = 8 (then loop data)
4510  * info from Pac.txt (pac.zip) at http://www.wotsit.org/music.htm
4511  */
4512 
read_sbstudio_header(const char * filename,int fd)4513 static int read_sbstudio_header(const char *filename, int fd)
4514 {
4515   static const uint8_t I_SNIN[4] = {'S','N','I','N'};
4516   static const uint8_t I_SNNA[4] = {'S','N','N','A'};
4517   static const uint8_t I_SNDT[4] = {'S','N','D','T'};
4518 
4519   int i, tmp;
4520   bool happy = true;
4521   uint8_t *bp;
4522   chans = 1;
4523   srate = 8000; /* no sampling rate field in this header */
4524   sample_type = MUS_UNKNOWN_SAMPLE;
4525   true_file_length = SEEK_FILE_LENGTH(fd);
4526   i = 8;
4527   bp = (uint8_t *)(hdrbuf + 8);
4528   while (happy)
4529     {
4530       if (match_four_chars(bp, I_SNDT))
4531 	{
4532 	  data_size = mus_char_to_lint((uint8_t *)(bp + 4));
4533 	  data_location = i + 8;
4534 	  happy = false;
4535 	}
4536       else
4537 	{
4538 	  if (match_four_chars(bp, I_SNIN))
4539 	    {
4540 	      tmp = mus_char_to_lshort((uint8_t *)(bp + 15));
4541 	      if ((tmp & 1) == 0)
4542 		sample_type = MUS_UNKNOWN_SAMPLE;
4543 	      else
4544 		{
4545 		  if ((tmp & 2) == 0)
4546 		    sample_type = MUS_BYTE;
4547 		  else sample_type = MUS_LSHORT;
4548 		}
4549 	      i += 26;
4550 	      bp += 26;
4551 	    }
4552 	  else
4553 	    {
4554 	      if (match_four_chars(bp, I_SNNA))
4555 		{
4556 		  tmp = mus_char_to_lint((uint8_t *)(bp + 4));
4557 		  i += tmp;
4558 		  bp += tmp;
4559 		}
4560 	      else
4561 		{
4562 		  i++;
4563 		  bp++;
4564 		}
4565 	    }
4566 	}
4567       if (i >= HDRBUFSIZ)
4568 	{
4569 	  sample_type = MUS_UNKNOWN_SAMPLE;
4570 	  happy = false;
4571 	}
4572     }
4573   if (data_location == 0)
4574     return(mus_error(MUS_HEADER_READ_FAILED, "%s: no SNDT chunk?", filename));
4575   if ((data_size == 0) || (sample_type == MUS_UNKNOWN_SAMPLE))
4576     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data size or sample type bogus", filename));
4577   if (data_size > true_file_length)
4578     {
4579       data_size = true_file_length - data_location;
4580       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4581     }
4582   data_size = mus_bytes_to_samples(sample_type, data_size);
4583   return(MUS_NO_ERROR);
4584 }
4585 
4586 
4587 
4588 /* ------------------------------------ Delusion Sound -------------------------------------
4589  *
4590  * more reverse engineering...
4591  * from a file created by Convert 1.4
4592  * 0: DDSF
4593  * 5: name (text)
4594  * 55: data
4595  * probaby similar to DMF format described in Dmf-form.txt but I don't see any other block names in the data
4596  */
4597 
read_delusion_header(const char * filename,int fd)4598 static int read_delusion_header(const char *filename, int fd)
4599 {
4600   if ((hdrbuf[4] != 1) || (hdrbuf[5] > 128) || (hdrbuf[6] > 128) || (hdrbuf[7] > 128))
4601     return(mus_error(MUS_HEADER_READ_FAILED, "%s DDSF name bogus", filename));
4602   chans = 1;
4603   data_location = 55;
4604   true_file_length = SEEK_FILE_LENGTH(fd);
4605   data_size = (true_file_length - data_location);
4606   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4607   srate = 8000;
4608   sample_type = MUS_LSHORT;
4609   data_size = mus_bytes_to_samples(sample_type, data_size);
4610   return(MUS_NO_ERROR);
4611 }
4612 
4613 
4614 
4615 /* ------------------------------------ Farandole Composer WaveSample -------------------------------------
4616  *
4617  * 0: FSM 254
4618  *    libmodplug load_far.cpp uses: #define FARFILEMAGIC	0xFE524146 ("FAR="?)
4619  * 4: name (text) (32 bytes)
4620  * 36: 10, 13, 26 or something like that
4621  * 39: len?
4622  * 40: volume
4623  * 41: looping data
4624  * 49: type (0 = 8-bit, else 16)
4625  * 50: loop mode
4626  * 51: data
4627  * described in Fsm.txt and Far-form.txt http://www.wotsit.org/music.htm
4628  */
4629 
read_farandole_header(const char * filename,int fd)4630 static int read_farandole_header(const char *filename, int fd)
4631 {
4632   chans = 1;
4633   data_location = 51;
4634   true_file_length = SEEK_FILE_LENGTH(fd);
4635   data_size = (true_file_length - data_location);
4636   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4637   srate = 8000;
4638   if (hdrbuf[49] == 0)
4639     sample_type = MUS_BYTE;
4640   else sample_type = MUS_LSHORT;
4641   data_size = mus_bytes_to_samples(sample_type, data_size);
4642   return(MUS_NO_ERROR);
4643 }
4644 
4645 
4646 
4647 /* ------------------------------------ Yamaha TX-16W -------------------------------------
4648  *
4649  * ftp://ftp.t0.or.at/pub/sound/tx16w/samples.yamaha
4650  * ftp://ftp.t0.or.at/pub/sound/tx16w/faq/tx16w.tec
4651  * http://www.t0.or.at/~mpakesch/tx16w/
4652  *
4653  * from tx16w.c sox 12.15: (7-Oct-98) (Mark Lakata and Leigh Smith)
4654  *  char filetype[6] "LM8953"
4655  *  nulls[10],
4656  *  dummy_aeg[6]
4657  *  format 0x49 = looped, 0xC9 = non-looped
4658  *  sample_rate 1 = 33 kHz, 2 = 50 kHz, 3 = 16 kHz
4659  *  atc_length[3] if sample rate 0, [2]&0xfe = 6: 33kHz, 0x10:50, 0xf6: 16, depending on [5] but to heck with it
4660  *  rpt_length[3] (these are for looped samples, attack and loop lengths)
4661  *  unused[2]
4662  */
4663 
read_tx16w_header(const char * filename,int fd)4664 static int read_tx16w_header(const char *filename, int fd)
4665 {
4666   if ((hdrbuf[4] != '5') || (hdrbuf[5] != '3')) return(mus_error(MUS_HEADER_READ_FAILED, "%s TX16 magic number bogus", filename));
4667   chans = 1;
4668   data_location = 32;
4669   true_file_length = SEEK_FILE_LENGTH(fd);
4670   data_size = (true_file_length - data_location);
4671   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4672   srate = 16000;
4673   if (hdrbuf[23] == 1) srate = 33000;
4674   else if (hdrbuf[23] == 2) srate = 50000;
4675   else if (hdrbuf[23] == 3) srate = 16000;
4676   else if (hdrbuf[23] == 0)
4677     {
4678       if ((hdrbuf[26] & 0xFE) == 6) srate = 33000;
4679       else if ((hdrbuf[26] & 0xFE) == 0x10) srate = 50000;
4680       else if ((hdrbuf[26] & 0xFE) == 0xf6) srate = 16000;
4681     }
4682   original_sample_type = MUS_UNKNOWN_SAMPLE;
4683   sample_type = MUS_UNKNOWN_SAMPLE;
4684   data_size = (mus_long_t)((double)data_size / 1.5);
4685   if (hdrbuf[22] == 0x49)
4686     {
4687       loop_modes[0] = 1;
4688       loop_starts[0] = ((hdrbuf[26] & 1) << 16) + (hdrbuf[25] << 8) + hdrbuf[24];
4689       loop_ends[0] = loop_starts[0] + ((hdrbuf[29] & 1) << 16) + (hdrbuf[28] << 8) + hdrbuf[27];
4690     }
4691   return(MUS_NO_ERROR);
4692 }
4693 
4694 
4695 
4696 /* ------------------------------------ Yamaha SY-85 and SY-99 -------------------------------------
4697  *
4698  * more reverse engineering...
4699  * 0: SY85 (SY80 is SY-99) SY85ALL SY80 SYALL
4700  * 5: name ("WAVE1")
4701  * (26 int len)
4702  * (33: comment or prompt?)
4703  * data in 16-bit little endian (?)
4704  */
4705 
read_sy85_header(const char * filename,int fd)4706 static int read_sy85_header(const char *filename, int fd)
4707 {
4708   if ((hdrbuf[4] != ' ') && (hdrbuf[4] != 'A')) return(mus_error(MUS_HEADER_READ_FAILED, "%s: unknown magic number", filename));
4709   chans = 1;
4710   data_location = 1024;
4711   true_file_length = SEEK_FILE_LENGTH(fd);
4712   data_size = (true_file_length - data_location);
4713   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4714   srate = 8000; /* unknown */
4715   sample_type = MUS_BSHORT; /* not right */
4716   data_size = mus_bytes_to_samples(sample_type, data_size);
4717   return(MUS_NO_ERROR);
4718 }
4719 
4720 
4721 
4722 /* ------------------------------------ Kurzweil 2000 -------------------------------------
4723  *
4724  * "PRAM" then header len as big endian int??
4725  * from krz2tx.c (Mark Lakata)
4726  */
read_kurzweil_2000_header(const char * filename,int fd)4727 static int read_kurzweil_2000_header(const char *filename, int fd)
4728 {
4729   chans = 1;
4730   data_location = mus_char_to_bint((uint8_t *)(hdrbuf + 4));
4731   true_file_length = SEEK_FILE_LENGTH(fd);
4732   data_size = (true_file_length - data_location);
4733   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4734   srate = 44100; /* unknown */
4735   sample_type = MUS_BSHORT;
4736   data_size = mus_bytes_to_samples(sample_type, data_size);
4737   return(MUS_NO_ERROR);
4738 }
4739 
4740 
4741 
4742 /* ------------------------------------ Korg -------------------------------------
4743  *
4744  * "SMP1" -- guessing on the rest
4745  */
read_korg_header(const char * filename,int fd)4746 static int read_korg_header(const char *filename, int fd)
4747 {
4748   chans = 1;
4749   data_location = 70;
4750   true_file_length = SEEK_FILE_LENGTH(fd);
4751   data_size = (true_file_length - data_location);
4752   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4753   srate = mus_char_to_bint((uint8_t *)(hdrbuf + 48));
4754   sample_type = MUS_BSHORT;
4755   data_size = mus_bytes_to_samples(sample_type, data_size);
4756   return(MUS_NO_ERROR);
4757 }
4758 
4759 
4760 
4761 /* ------------------------------------ Maui -------------------------------------
4762  *
4763  * "Maui" -- guessing on the rest
4764  */
read_maui_header(const char * filename,int fd)4765 static int read_maui_header(const char *filename, int fd)
4766 {
4767   lseek(fd, 420, SEEK_SET);
4768   if (read(fd, hdrbuf, 64) != 64) return(mus_error(MUS_HEADER_READ_FAILED, "%s truncated maui header?", filename));
4769   chans = 1;
4770   data_location = 776;
4771   true_file_length = SEEK_FILE_LENGTH(fd);
4772   if (true_file_length < data_location)
4773     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
4774   data_size = mus_char_to_lint((uint8_t *)(hdrbuf + 8));
4775   if ((data_size * 2) > true_file_length)
4776     data_size = (true_file_length - data_location) / 2;
4777   srate = mus_char_to_lint((uint8_t *)(hdrbuf));
4778   sample_type = MUS_LSHORT;
4779   return(MUS_NO_ERROR);
4780 }
4781 
4782 
4783 
4784 /* ------------------------------------ Impulse Tracker -------------------------------------
4785  *
4786  * data from its2raw.c by Ben Collver
4787  * 0:  IMPS
4788  * 4:  filename (12 bytes)
4789  * 17: global vol
4790  * 18: flags (1: 16-bit or 8(0), 2: stereo or mono(0)
4791  * 19: default vol
4792  * 20: sample name (26 bytes)
4793  * 46: convert
4794  * 47: default pan
4795  * 48: length (samps)
4796  * 52: loop start
4797  * 56: loop end
4798  * 60: srate
4799  * 64: sustain loop start
4800  * 68: sustain loop end
4801  * 72: data location
4802  * 76: vib speed
4803  * 77: vib depth
4804  * 78: vib wave
4805  * 79: vib rate
4806  */
read_impulsetracker_header(const char * filename,int fd)4807 static int read_impulsetracker_header(const char *filename, int fd)
4808 {
4809   if (hdrbuf[18] & 4) chans = 2; else chans = 1;
4810   if (hdrbuf[18] & 2) sample_type = MUS_LSHORT; else sample_type = MUS_BYTE;
4811   data_location = mus_char_to_lint((uint8_t *)(hdrbuf + 72));
4812   true_file_length = SEEK_FILE_LENGTH(fd);
4813   if (true_file_length < data_location)
4814     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
4815   data_size = (true_file_length - data_location);
4816   srate = mus_char_to_lint((uint8_t *)(hdrbuf + 60));
4817   data_size = mus_bytes_to_samples(sample_type, data_size);
4818   return(MUS_NO_ERROR);
4819 }
4820 
4821 #if 0
4822 /* ------------------------------------ AKAI 3? -------------------------------------
4823  */
4824 static int read_akai3_header(const char *filename, int fd)
4825 {
4826   chans = 1;
4827   data_location = 192;
4828   true_file_length = SEEK_FILE_LENGTH(fd);
4829   data_size = (true_file_length - data_location);
4830   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4831   if (hdrbuf[1] == 0) srate = 22050; else srate = 44100;
4832   sample_type = MUS_LSHORT;
4833   data_size = mus_bytes_to_samples(sample_type, data_size);
4834   return(MUS_NO_ERROR);
4835 }
4836 #endif
4837 
4838 
4839 
4840 /* ------------------------------------ AKAI 4 -------------------------------------
4841  *
4842  * 1, 4, info from Paul Kellet -- lost the url ("MPC-2000")
4843  */
read_akai4_header(const char * filename,int fd)4844 static int read_akai4_header(const char *filename, int fd)
4845 {
4846   chans = hdrbuf[21] + 1;
4847   data_location = 42;
4848   true_file_length = SEEK_FILE_LENGTH(fd);
4849   data_size = (true_file_length - data_location);
4850   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4851   srate = mus_char_to_ulshort((uint8_t *)(hdrbuf + 40));
4852   sample_type = MUS_LSHORT;
4853   data_size = mus_bytes_to_samples(sample_type, data_size);
4854   return(MUS_NO_ERROR);
4855 }
4856 
4857 
4858 
4859 /* ------------------------------------ PVF (portable voice format) -------------------------------------
4860  *
4861  * info from mgetty-voice-1.1.22/voice/libpvf/lib.c
4862  * this is a modem-related interchange format
4863  *
4864  * PVF1\n
4865  * 1 11025 32\n
4866  * then data
4867  * PVF1 = binary data, PVF2 = ascii
4868  * chans | srate | sample size
4869  */
4870 
read_pvf_header(const char * filename,int fd)4871 static int read_pvf_header(const char *filename, int fd)
4872 {
4873   char *buf;
4874   int bits, i;
4875   if (hdrbuf[4] != '\n') return(mus_error(MUS_HEADER_READ_FAILED, "PVF header messed up"));
4876   type_specifier = mus_char_to_uninterpreted_int((uint8_t *)hdrbuf);
4877   buf = (char *)(hdrbuf + 5);
4878   sscanf(buf, "%12d %12d %12d", &chans, &srate, &bits);
4879   if (chans < 1) chans = 1;
4880   if (srate < 0) srate = 8000;
4881   if (bits < 8) bits = 8;
4882   for (i = 6; i < INITIAL_READ_SIZE; i++)
4883     if (hdrbuf[i] == '\n')
4884       {
4885 	data_location = i + 1;
4886 	break;
4887       }
4888   if (data_location == 0)
4889     return(mus_error(MUS_HEADER_READ_FAILED, "%s PVF header bad data location", filename));
4890   if (match_four_chars((uint8_t *)hdrbuf, I_PVF2))
4891     {
4892       sample_type = MUS_UNKNOWN_SAMPLE; /* ascii text */
4893       return(mus_error(MUS_HEADER_READ_FAILED, "%s PVF header unknown sample type", filename));
4894     }
4895   /* big endian data -- they're using htonl etc */
4896   if (bits == 8)
4897     sample_type = MUS_BYTE;
4898   else
4899     if (bits == 16)
4900       sample_type = MUS_BSHORT;
4901     else sample_type = MUS_BINT;
4902   true_file_length = SEEK_FILE_LENGTH(fd);
4903   data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location);
4904   return(MUS_NO_ERROR);
4905 }
4906 
4907 
4908 
4909 /* ------------------------------------ Ultratracker WaveSample -------------------------------------
4910  *
4911  * 0..31: name (32 = ctrl-Z?)
4912  * 33: PMUWFD (but docs say this is "dos name" -- perhaps we can't recognize this header type reliably)
4913  * 44: 4 ints giving loop and size data
4914  * 60: vol
4915  * 61: "bidi" 0|8|24->8 bit else 16 -- but actual example has 0 with 16-bit
4916  * 62: finetune
4917  * 64: data (or 68?)
4918  * described in Ult-form.txt http://www.wotsit.org/music.htm
4919  */
4920 
read_ultratracker_header(const char * filename,int fd)4921 static int read_ultratracker_header(const char *filename, int fd)
4922 {
4923   chans = 1;
4924   data_location = 64;
4925   true_file_length = SEEK_FILE_LENGTH(fd);
4926   if (true_file_length < data_location)
4927     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
4928   data_size = (true_file_length - data_location);
4929   srate = 8000;
4930   sample_type = MUS_LSHORT;
4931   data_size = mus_bytes_to_samples(sample_type, data_size);
4932   return(MUS_NO_ERROR);
4933 }
4934 
4935 
4936 
4937 /* ------------------------------------ Sample dump exchange -------------------------------------
4938  *
4939  * 0: SDX:
4940  * sdx2tx.c (Mark Lakata) reads from 4 for 26 (^z), then
4941  * version (1)
4942  * comment as pascal-style string (byte len, bytes chars)
4943  * then 23 bytes:
4944  *  0: packing (0 = pcm)
4945  *  1: midi channel
4946  *  2 + 256*[3]: sample number
4947  *  4: sample type (15: 16 bit unsigned(?), 8: 8bit unsigned(?)
4948  *  5: sample rate (big int?)
4949  *  9: sample length
4950  * 13: loop start
4951  * 17: loop end
4952  * 21: loop type
4953  * 22: reserved
4954  */
4955 
read_sample_dump_header(const char * filename,int fd)4956 static int read_sample_dump_header(const char *filename, int fd)
4957 {
4958   int i, len;
4959   for (i = 4; i < HDRBUFSIZ; i++) if (hdrbuf[i] == 26) break;
4960   len = hdrbuf[i + 2];
4961   if (len > 0)
4962     {
4963       comment_start = i + 3;
4964       comment_end = i + 3 + len;
4965       }
4966   seek_and_read(fd, (uint8_t *)hdrbuf, i + 3 + len, HDRBUFSIZ);
4967   srate = mus_char_to_lint((uint8_t *)(hdrbuf + 5));
4968   loop_modes[0] = 0;
4969   if (hdrbuf[21] == 0)
4970     {
4971       loop_modes[0] = 1;
4972       loop_starts[0] = mus_char_to_lint((uint8_t *)(hdrbuf + 13));
4973       loop_ends[0] = mus_char_to_lint((uint8_t *)(hdrbuf + 17));
4974     }
4975   /* data_size = mus_char_to_lint((uint8_t *)(hdrbuf + 9)); */
4976   if ((srate < 100) || (srate > 100000)) srate = 8000;
4977   chans = 1;
4978   data_location = i + 3 + len + 23;
4979   true_file_length = SEEK_FILE_LENGTH(fd);
4980   data_size = (true_file_length - data_location);
4981   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
4982   if (hdrbuf[0] == 0)
4983     sample_type = MUS_ULSHORT;
4984   else sample_type = MUS_UNKNOWN_SAMPLE;
4985   data_size = mus_bytes_to_samples(sample_type, data_size);
4986   return(MUS_NO_ERROR);
4987 }
4988 
4989 
4990 
4991 /* ------------------------------------ Digiplayer ST3 -------------------------------------
4992  *
4993  * 0: 1 (use 'SCRS' at 76)
4994  * 1: name
4995  * 13: nada
4996  * 14: "paragraph" offset of sample data
4997  * 16: length in bytes (looks like #samples in the actual files...)
4998  * 20: loop start
4999  * 24: loop end
5000  * 28: vol
5001  * 29: ?
5002  * 30: 0 = unpacked, 1 = DP30ADPCM
5003  * 31: bits: 0 = loop, 1 = stereo (chans not interleaved!), 2 = 16-bit samples (little endian)
5004  * 32: freq
5005  * 36: nada
5006  * 40: nada
5007  * 42: 512
5008  * 44: date?
5009  * 48: sample name (28 char ASCIZ)
5010  * 76: 'SCRS'
5011  * 80: data starts
5012  *
5013  * info from http://www.wotsit.org/ S3m-form.txt
5014  */
5015 
read_digiplayer_header(const char * filename,int fd)5016 static int read_digiplayer_header(const char *filename, int fd)
5017 {
5018   chans = 1;
5019   data_location = 80;
5020   true_file_length = SEEK_FILE_LENGTH(fd);
5021   data_size = (true_file_length - data_location);
5022   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
5023   srate = 8000;
5024   sample_type = MUS_ULSHORT;
5025   if (hdrbuf[30] & 2) chans = 2;
5026   if (hdrbuf[30] & 1)
5027     sample_type = MUS_UNKNOWN_SAMPLE;
5028   else
5029     {
5030       if (hdrbuf[30] & 4) sample_type = MUS_UBYTE; /* may be backwards -- using Convert 1.4 output here */
5031     }
5032   data_size = mus_bytes_to_samples(sample_type, data_size);
5033   return(MUS_NO_ERROR);
5034 }
5035 
5036 
5037 
5038 /* ------------------------------------ CSRE adf -------------------------------------
5039  *
5040  * Info from Stuart Rosen
5041  *
5042  * 0-7: CSRE40
5043  * 8:   samples in file (long)
5044  * 12:  center line(?) (long)
5045  * 16:  start channel(?) (unsigned)
5046  * 18:  bits -- 12 or 16 (unsigned) -- is 12 bit sample file packed?
5047  * 20:  number system (0 = signed, 1 = unsigned)
5048  * 22:  srate in kHz (float)
5049  * 26:  peak sample in file (long) (can be 0)
5050  * 30-511: comment possibly
5051  *
5052  * probably always little-endian (S.R. reads each sample using sizeof(int) -> 16 bits I think)
5053  * if 12-bit unsigned we need to handle the offset somewhere
5054  */
5055 
read_adf_header(const char * filename,int fd)5056 static int read_adf_header(const char *filename, int fd)
5057 {
5058   int bits, numsys;
5059   lseek(fd, 0, SEEK_SET);
5060   if ((hdrbuf[4] != '4') || (hdrbuf[5] != '0')) return(mus_error(MUS_HEADER_READ_FAILED, "%s csre header bad magic number", filename));
5061   if (read(fd, hdrbuf, 30) != 30) return(mus_error(MUS_HEADER_READ_FAILED, "%s csre header truncated?", filename));
5062   chans = 1;
5063   numsys = mus_char_to_ulshort((uint8_t *)(hdrbuf + 20));
5064   bits = mus_char_to_ulshort((uint8_t *)(hdrbuf + 18));
5065   if ((bits == 16) || (bits == 12))
5066     {
5067       if (numsys == 0)
5068 	sample_type = MUS_LSHORT;
5069       else sample_type = MUS_ULSHORT;
5070     }
5071   else sample_type = MUS_UNKNOWN_SAMPLE;
5072   srate = (int)(1000 * mus_char_to_lfloat((uint8_t *)(hdrbuf + 22)));
5073   data_size = mus_char_to_lint((uint8_t *)(hdrbuf + 8));
5074   data_location = 512;
5075   true_file_length = SEEK_FILE_LENGTH(fd);
5076   if (true_file_length < data_location)
5077     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
5078   if (data_size > mus_bytes_to_samples(sample_type, true_file_length - data_location))
5079     data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location);
5080   return(MUS_NO_ERROR);
5081 }
5082 
5083 
5084 
5085 /* ------------------------------------ Diamondware -------------------------------------
5086  *
5087  * info from Keith Weiner at DiamondWare (www.dw.com):
5088  *
5089  * 0-22:   DWD Header Byte "DiamondWare Digitized\n\0"
5090  * 23:     1A (EOF to abort printing of file)
5091  * 24:     Major version number
5092  * 25:     Minor version number
5093  * 26-29:  Unique sound ID (checksum XOR timestamp)
5094  * 30:     Reserved
5095  * 31:     Compression type (0 = none)
5096  * 32-33:  Sampling rate (in Hz)
5097  * 34:     Number of channels (1 = mono, 2 = stereo) (interleaved)
5098  * 35:     Number of bits per sample (8, 16) (all data signed)
5099  * 36-37:  Absolute value of largest sample in file
5100  * 38-41:  length of data section (in bytes)
5101  * 42-45:  # samples (16-bit stereo is 4 bytes/sample)
5102  * 46-49:  Offset of data from start of file (in bytes)
5103  * 50-53:  Reserved for future expansion (markers)
5104  * 54-55:  Padding
5105  * 56:offset -- additional text: field = value
5106  *  suggested fields: TITLE, ORGARTIST, GENRE, KEYWORDS, ORGMEDIUM, EDITOR, DIGITIZER, COMMENT, SUBJECT, COPYRIGHT, SOFTWARE, CREATEDATE
5107  *
5108  * since this is all Windows/DOS oriented, I'll assume little-endian byte order.
5109  */
5110 
read_diamondware_header(const char * filename,int fd)5111 static int read_diamondware_header(const char *filename, int fd)
5112 {
5113   chans = hdrbuf[34];
5114   if (hdrbuf[31] == 0)
5115     {
5116       if (hdrbuf[35] == 8) sample_type = MUS_BYTE;
5117       else sample_type = MUS_LSHORT;
5118     }
5119   else
5120     {
5121       sample_type = MUS_UNKNOWN_SAMPLE;
5122       return(mus_error(MUS_HEADER_READ_FAILED, "%s unknown sample type", filename));
5123     }
5124   srate = mus_char_to_ulshort((uint8_t *)(hdrbuf + 32));
5125   data_size = mus_char_to_lint((uint8_t *)(hdrbuf + 38));
5126   data_location = mus_char_to_lint((uint8_t *)(hdrbuf + 46));
5127   true_file_length = SEEK_FILE_LENGTH(fd);
5128   if (true_file_length < data_location)
5129     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
5130   if (data_size > true_file_length - data_location)
5131     data_size = true_file_length - data_location;
5132   data_size = mus_bytes_to_samples(sample_type, data_size);
5133   return(MUS_NO_ERROR);
5134 }
5135 
5136 
5137 
5138 /* ------------------------------------ Ensoniq Paris -------------------------------------
5139  * _paf -> Ensoniq Paris?  (this info from libaudiofile)
5140  *  0   paf (or fap)
5141  *  4  version (0)
5142  *  8  endianness (0 = big)
5143  * 12  rate (uint32_t)
5144  * 16  format (0: 16-bit linear, 24-bit linear)
5145  * 20  channels
5146  * 24  source (an encoded comment)
5147  * 2048 data (24 bit files are compressed)
5148  */
5149 
read_paf_header(const char * filename,int fd)5150 static int read_paf_header(const char *filename, int fd)
5151 {
5152   int form;
5153   bool little = false;
5154   sample_type = MUS_UNKNOWN_SAMPLE;
5155   if (mus_char_to_bint((uint8_t *)(hdrbuf + 8))) little = true;
5156   if (little)
5157     {
5158       srate = mus_char_to_ulint((uint8_t *)(hdrbuf + 12));
5159       form = mus_char_to_ulint((uint8_t *)(hdrbuf + 16));
5160       if (form == 0) sample_type = MUS_LSHORT;
5161       if (form == 2) sample_type = MUS_BYTE;
5162       chans = mus_char_to_ulint((uint8_t *)(hdrbuf + 20));
5163     }
5164   else
5165     {
5166       srate = mus_char_to_ubint((uint8_t *)(hdrbuf + 12));
5167       form = mus_char_to_ubint((uint8_t *)(hdrbuf + 16));
5168       if (form == 0) sample_type = MUS_BSHORT;
5169       if (form == 2) sample_type = MUS_BYTE;
5170       chans = mus_char_to_ubint((uint8_t *)(hdrbuf + 20));
5171     }
5172   data_location = 2048;
5173   true_file_length = SEEK_FILE_LENGTH(fd);
5174   if (true_file_length < data_location)
5175     return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_location %" print_mus_long " > file length: %" print_mus_long, filename, data_location, true_file_length));
5176   if (sample_type != MUS_UNKNOWN_SAMPLE)
5177     data_size = mus_bytes_to_samples(sample_type, true_file_length - 2048);
5178   return(MUS_NO_ERROR);
5179 }
5180 
5181 
5182 
5183 /* ------------------------------------ Comdisco SPW -------------------------------------
5184  * info from AFsp libtsp/AF/nucleus/AFgetSWpar.c
5185  *
5186  * header is text as in NIST:
5187  *
5188  *   $SIGNAL_FILE 9\n (12 chars)
5189  *   $USER_COMMENT
5190  *   <comment line(s)>
5191  *   $COMMON_INFO
5192  *   SPW Version        = 3.10
5193  *   System Type        = <machine> (e.g. "sun4", "hp700")
5194  *   Sampling Frequency = <Sfreq>   (e.g. "8000")
5195  *   Starting Time      = 0
5196  *   $DATA_INFO
5197  *   Number of points   = <Nsamp>   (e.g. "2000")
5198  *   Signal Type        = <type>    ("Double", "Float", "Fixed-point", "Integer", "Logical")
5199  *   Fixed Point Format = <16, 0, t> <16, 16, t> <8, 8, t> <8, 0, t> (optional)
5200  *   Complex Format     = Real_Imag (optional)
5201  *   $DATA <data_type>              ("ASCII", "BINARY")
5202  *
5203  * the fixed point <n, m, b> is decoded as n = number of bits total per sample, m = integer bits, b = t: signed, u: unsigned
5204  * if $DATA ASCII, data is ascii text as in IEEE text files.
5205  * There are other complications as well.  We'll just hack up a stop-gap until someone complains.
5206  */
5207 
read_comdisco_header(const char * filename,int fd)5208 static int read_comdisco_header(const char *filename, int fd)
5209 {
5210   /* need to grab a line at a time, call strcmp over and over.  This is very tedious. */
5211   char *line;
5212   int i, j, k, m, n, curend, offset, len, type, d_size = 0;
5213   bool happy = true, little, commenting;
5214 
5215   k = 15;
5216   line = (char *)calloc(257, sizeof(char));
5217   little = false;
5218   offset = 0;
5219   type = 0;
5220   srate = 0;
5221   curend = INITIAL_READ_SIZE;
5222   commenting = false;
5223   while (happy)
5224     {
5225       for (i = 0; i < 256; i++)
5226 	{
5227 	  if (k == curend)
5228 	    {
5229 	      offset += curend;
5230 	      if (read(fd, hdrbuf, HDRBUFSIZ) != HDRBUFSIZ)
5231 		{
5232 		  free(line);
5233 		  return(mus_error(MUS_HEADER_READ_FAILED, "%s comdisco header truncated?", filename));
5234 		}
5235 	      k = 0;
5236 	      curend = HDRBUFSIZ;
5237 	    }
5238 	  if (hdrbuf[k] == '\n')
5239 	    {
5240 	      k++;
5241 	      break;
5242 	    }
5243 	  line[i] = hdrbuf[k++];
5244 	}
5245       line[i] = '\0';
5246       if ((strcmp(line, "$DATA BINARY") == 0) ||
5247 	  (strcmp(line, "$DATA ASCII") == 0))
5248 	{
5249 	  happy = false;
5250 	  data_location = offset + k;
5251 	}
5252       if (strcmp(line, "$USER_COMMENT") == 0)
5253 	{
5254 	  comment_start = offset + k;
5255 	  commenting = true;
5256 	}
5257       else
5258 	{
5259 	  if (commenting)
5260 	    {
5261 	      if (line[0] == '$')
5262 		{
5263 		  comment_end = offset + k - 2 - strlen(line);
5264 		  commenting = false;
5265 		}
5266 	    }
5267 	}
5268       if (line[0] != '$')
5269 	{
5270 	  char portion[32];
5271 	  char value[32];
5272 	  len = strlen(line);
5273 	  for (j = 0; j < 8; j++)
5274 	    portion[j] = line[j];
5275 	  portion[8] ='\0';
5276 	  for (j = 8; j < len; j++)
5277 	    if (line[j] == '=')
5278 	      break;
5279 	  for (n = 0, m = j + 2; m < len; m++, n++)
5280 	    value[n] = line[m];
5281 	  value[n] ='\0';
5282 	  if (strcmp(portion, "Sampling") == 0) sscanf(value, "%12d", &srate); else
5283 	  if (strcmp(portion, "Number o") == 0) sscanf(value, "%12d", &d_size); else
5284 	  if (strcmp(portion, "Signal T") == 0) {if (value[1] == 'o') type = 2; else if (value[1] == 'l') type = 1;} else
5285 	  if (strcmp(portion, "Fixed Po") == 0) {if (value[1] == '8') type = 3;}
5286 	}
5287     }
5288 
5289   /* now clean up this mess */
5290   if (data_location == 0) {free(line); return(mus_error(MUS_HEADER_READ_FAILED, "%s: no $DATA BINARY field?", filename));}
5291   if (srate == 0) {free(line); return(mus_error(MUS_HEADER_READ_FAILED, "%s: srate == 0", filename));}
5292   chans = 1;
5293   if (d_size != 0) data_size = (mus_long_t)d_size;
5294   switch (type)
5295     {
5296     case 0: if (little) sample_type = MUS_LSHORT; else sample_type = MUS_BSHORT; break;
5297     case 1: if (little) sample_type = MUS_LFLOAT; else sample_type = MUS_BFLOAT; break;
5298     case 2: if (little) sample_type = MUS_LDOUBLE; else sample_type = MUS_BDOUBLE; break;
5299     case 3: sample_type = MUS_BYTE; break;
5300     }
5301   true_file_length = SEEK_FILE_LENGTH(fd);
5302   if (data_size > mus_bytes_to_samples(sample_type, true_file_length - data_location))
5303     data_size = mus_bytes_to_samples(sample_type, true_file_length - data_location);
5304   free(line);
5305   return(MUS_NO_ERROR);
5306 }
5307 
5308 
5309 
5310 /* ------------------------------------ MS ASF -------------------------------------
5311  *
5312  * asf format is described at http://www.microsoft.com/asf/specs.htm
5313  * http://www.microsoft.com/asf/spec3/ASF0198ps.exe
5314  *
5315  * this header is completely insane
5316  */
5317 
read_asf_header(const char * filename,int fd)5318 static int read_asf_header(const char *filename, int fd)
5319 {
5320   /* a chunked sample type, so not really acceptable here or elsewhere -- needs to be unchunked */
5321   int len, ilen = 0, i, j, bits = 0;
5322   bool asf_huge = false, present;
5323   /* apparently "huge" has some meaning in Windoze C */
5324 
5325   len = mus_char_to_lint((uint8_t *)(hdrbuf + 16)); /* actually 64 bits */
5326   i = (128+64) / 8;
5327   srate = 0;
5328   chans = 0;
5329 
5330   while (i < len)
5331     {
5332       seek_and_read(fd, (uint8_t *)hdrbuf, i, HDRBUFSIZ);
5333       if ((uint32_t)(hdrbuf[1]) == 0x29)
5334 	switch (hdrbuf[0])
5335 	  {
5336 	  case 0xd0:
5337 	    asf_huge = (hdrbuf[((128+64+128+64+64+64+64+32)/8)] & 2);
5338 	    break;
5339 
5340 	  case 0xd4:
5341 	    present = ((hdrbuf[16+8+16+8+8+ 4+4+4+4+ 4+4] >> 3) & 0x3);
5342 	    if (present)
5343 	      j = 16+8+16+8+8+ 4+4+4+4+ 4+4+ 4+ (4+4+4) + 2;
5344 	    else j = 16+8+16+8+8+ 4+4+4+4+ 4+4+ 4+ 2;
5345 	    srate = mus_char_to_lint((uint8_t *)(hdrbuf + j+11+36));
5346 	    bits = mus_char_to_lint((uint8_t *)(hdrbuf + j+11+32));
5347 	    chans = mus_char_to_ulshort((uint8_t *)(hdrbuf + j+65));
5348 	    original_sample_type = mus_char_to_lint((uint8_t *)(hdrbuf + j+11));
5349 	    break;
5350 
5351 	  default:
5352 	    break;
5353 	  }
5354       ilen = mus_char_to_lint((uint8_t *)(hdrbuf + 16));
5355       if (ilen <= 0) break;
5356       if ((chans > 0) && (srate > 0)) break;
5357       i += ilen;
5358     }
5359   i = len;
5360   seek_and_read(fd, (uint8_t *)hdrbuf, i, HDRBUFSIZ);
5361   sample_type = MUS_UNKNOWN_SAMPLE;
5362   if (((uint32_t)(hdrbuf[1]) == 0x29) && ((uint32_t)(hdrbuf[0]) == 0xd2))
5363     {
5364       int a_huge = 2;
5365       ilen = mus_char_to_lint((uint8_t *)(hdrbuf + 16));
5366       if (asf_huge) a_huge = 4;
5367       data_location = i + 20 + a_huge + 2+4+3+1;
5368       if (bits == 0) bits = 8;
5369       sample_type = wave_to_sndlib_format(original_sample_type, bits, true);
5370     }
5371   else return(mus_error(MUS_HEADER_READ_FAILED, "%s: unknown sample type", filename));
5372   data_size = ilen - data_location;
5373   true_file_length = SEEK_FILE_LENGTH(fd);
5374   if (data_size > true_file_length)
5375     {
5376       data_size = true_file_length - data_location;
5377       if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
5378     }
5379   data_size = mus_bytes_to_samples(sample_type, data_size);
5380   return(MUS_NO_ERROR);
5381 }
5382 
5383 
5384 /* ------------------------------------ Sox -------------------------------------
5385  *  sox now has its own format (intended as an intermediate file)
5386  *    0: .SoX or .XoS
5387  *    4: header_bytes (int)
5388  *    8: num_samples (int64_t)
5389  *    16: srate (double)
5390  *    24: chans (int)
5391  *    28: comment bytes (int)
5392  *    32: comment... [if any]
5393  *    header_bytes: data (always 32-bit int in native format)
5394  */
5395 
read_sox_header(const char * filename,int fd)5396 static int read_sox_header(const char *filename, int fd)
5397 {
5398   int comment_len;
5399   mus_long_t samps;
5400 
5401   if (match_four_chars((uint8_t *)(hdrbuf + 0), I_dSoX))
5402     {
5403       sample_type = MUS_LINTN;
5404       samps = mus_char_to_llong((uint8_t *)(hdrbuf + 8));
5405       srate = (int)mus_char_to_ldouble((uint8_t *)(hdrbuf + 16));
5406       little_endian = true;
5407     }
5408   else
5409     { /* untested */
5410       sample_type = MUS_BINTN;
5411       samps = mus_char_to_blong((uint8_t *)(hdrbuf + 8));
5412       srate = (int)mus_char_to_bdouble((uint8_t *)(hdrbuf + 16));
5413       little_endian = false;
5414     }
5415 
5416   data_location = 4 + big_or_little_endian_int((uint8_t *)(hdrbuf + 4), little_endian);
5417   chans = big_or_little_endian_int((uint8_t *)(hdrbuf + 24), little_endian);
5418   comment_len = big_or_little_endian_int((uint8_t *)(hdrbuf + 28), little_endian);
5419   if (comment_len > 0)
5420     {
5421       comment_start = 32;
5422       comment_end = comment_start + comment_len;
5423     }
5424   true_file_length = SEEK_FILE_LENGTH(fd);
5425   data_size = (true_file_length - data_location);
5426   if (data_size < 0) return(mus_error(MUS_HEADER_READ_FAILED, "%s: data_size = %" print_mus_long "?", filename, data_size));
5427   data_size = mus_bytes_to_samples(sample_type, data_size);
5428   if (samps < data_size) data_size = samps;
5429   return(MUS_NO_ERROR);
5430 }
5431 
5432 
5433 
5434 /* ------------------------------------ Matlab 5 ------------------------------------- */
5435 /* info from the matlab site, Gary Scavone's site, and wotsit.org "Mat-File Format" in matlab.zip
5436  *
5437  * 128 byte header starting with "MATLAB 5.0 MAT-file"
5438  * 124: version (normally 0x100)
5439  * 126: endianess (the chars 'M' and 'I')
5440  * data chunked much like aiff -- 8 bytes: type | number-of-bytes, followed by data
5441  *   4 bytes type: 1: s8 2: u8 3: s16 4: u16 5: s32 6: u32
5442  *                 7: IEEE 754 single 9: IEEE 754 double 12: s64 13: u64
5443  *                 14: array (15 compressed?)
5444  *   4 bytes size: (not including the tag)
5445  *   array types: 6: double 7:float
5446  *
5447  * I'll assume a sound file is stored as a matlab array
5448  * and each separate array is a channel (non-interleaved, so if chans>1 we have to pre-translate it).
5449  *
5450  */
5451 
read_matlab_5_header(const char * filename,int fd)5452 static int read_matlab_5_header(const char *filename, int fd)
5453 {
5454   int i, type, loc, size;
5455   /* bool swapped = false; */
5456   comment_start = 0;
5457   comment_end = 124;
5458 
5459   for (i = 1; i < 124; i++)
5460     if (hdrbuf[i] == 0)
5461       {
5462 	comment_end = i;
5463 	break;
5464       }
5465 
5466   /* if (mus_char_to_lshort((uint8_t *)(hdrbuf + 126)) == 0x494d) swapped = true; */
5467   /* byte swapping not handled yet */
5468 
5469   type = mus_char_to_lint((uint8_t *)(hdrbuf + 128));
5470   if (type != 14)
5471     return(mus_error(MUS_HEADER_READ_FAILED, "%s: unknown Matlab sample type (%d)", filename, type));
5472 
5473   /* chunksize = mus_char_to_lint((uint8_t *)(hdrbuf + 132)); */
5474 
5475   /* now grovel through the array header */
5476   /*   assume the "flags" are not interesting */
5477   /*   assume "dimensions" = number of samples, but we'll pick that up from the data size */
5478   /*   do we care about the original variable name? */
5479 
5480   /* should we try to handle multiple signals in a file?  as separate channels? */
5481 
5482   loc = 136 + 32 + 8;
5483   size = mus_char_to_lint((uint8_t *)(hdrbuf + 172)); /* var name len -- need to round up to multiple of 8 */
5484   i = size % 8;
5485   if (i == 0)
5486     loc += size;
5487   else loc += size + 8 - i;
5488 
5489   type = mus_char_to_lint((uint8_t *)(hdrbuf + loc));
5490   if (type == 9)
5491     sample_type = MUS_LDOUBLE;
5492   else sample_type = MUS_LFLOAT;
5493   data_size = mus_char_to_lint((uint8_t *)(hdrbuf + loc + 4));
5494 
5495   chans = 1;
5496   srate = 44100; /* a plausible guess */
5497 
5498   true_file_length = SEEK_FILE_LENGTH(fd);
5499   return(MUS_NO_ERROR);
5500 }
5501 
5502 
5503 
5504 
5505 /* ------------------------------------ no header ------------------------------------- */
5506 
5507 static int raw_header_srate = 44100;
5508 static int raw_header_chans = 2;
5509 static mus_sample_t raw_header_sample_type = MUS_BSHORT;
5510 
read_no_header(int fd)5511 static int read_no_header(int fd)
5512 {
5513   srate = raw_header_srate;
5514   chans = raw_header_chans;
5515   sample_type = raw_header_sample_type;
5516   data_location = 0;
5517   data_size = SEEK_FILE_LENGTH(fd);
5518   true_file_length = data_size;
5519   data_size = mus_bytes_to_samples(sample_type, data_size);
5520   return(MUS_NO_ERROR);
5521 }
5522 
5523 
mus_header_set_raw_defaults(int sr,int chn,mus_sample_t samp_type)5524 void mus_header_set_raw_defaults(int sr, int chn, mus_sample_t samp_type)
5525 {
5526   if (sr > 0) raw_header_srate = sr;
5527   if (chn > 0) raw_header_chans = chn;
5528   if (mus_is_sample_type(samp_type)) raw_header_sample_type = samp_type;
5529 }
5530 
5531 
mus_header_raw_defaults(int * sr,int * chn,mus_sample_t * samp_type)5532 void mus_header_raw_defaults(int *sr, int *chn, mus_sample_t *samp_type)
5533 {
5534   (*sr) = raw_header_srate;
5535   (*chn) = raw_header_chans;
5536   (*samp_type) = raw_header_sample_type;
5537 }
5538 
5539 
5540 
5541 /* ------------------------------------ all together now ------------------------------------ */
5542 
mus_header_read_1(const char * filename,int fd)5543 static int mus_header_read_1(const char *filename, int fd)
5544 {
5545   static const uint8_t I_HCOM[4] = {'H','C','O','M'};
5546   static const uint8_t I_FSSD[4] = {'F','S','S','D'};
5547   static const uint8_t I_8SVX[4] = {'8','S','V','X'};
5548   static const uint8_t I_16SV[4] = {'1','6','S','V'};
5549   static const uint8_t I_VOC1[4] = {'t','i','v','e'};
5550   static const uint8_t I_Soun[4] = {'S','o','u','n'};
5551   static const uint8_t I_MAUD[4] = {'M','A','U','D'};
5552   static const uint8_t I_mdat[4] = {'m','d','a','t'};  /* quicktime */
5553   static const uint8_t I_sfbk[4] = {'s','f','b','k'};  /* SoundFont 2.0 */
5554   static const uint8_t I_ATCH[4] = {'A','T','C','H'};
5555   static const uint8_t I_NAL_[4] = {'N','A','L','_'};
5556   static const uint8_t I__WAV[4] = {' ','S','A','M'};
5557   static const uint8_t I_ondW[4] = {'o','n','d','W'};
5558   static const uint8_t I_SDXc[4] = {'S','D','X',':'};  /* Sample dump exchange format */
5559   static const uint8_t I_AVI_[4] = {'A','V','I',' '};  /* RIFF AVI */
5560   static const uint8_t I_ones[4] = {(uint8_t)'\377',(uint8_t)'\377',(uint8_t)'\377',(uint8_t)'\377'};
5561   static const uint8_t I_zeros[4] = {'\0','\0','\0','\0'};
5562   static const uint8_t I_asf0[4] = {(uint8_t)'\321','\051',(uint8_t)'\342',(uint8_t)'\326'};
5563   static const uint8_t I_asf1[4] = {(uint8_t)'\332','\065',(uint8_t)'\321','\021'};
5564   static const uint8_t I_asf2[4] = {(uint8_t)'\220','\064','\000',(uint8_t)'\240'};
5565   static const uint8_t I_asf3[4] = {(uint8_t)'\311','\003','\111',(uint8_t)'\276'};
5566   static const uint8_t I_DS16[4] = {'D','S','1','6'};  /* CSL */
5567   static const uint8_t I__sam[4] = {'=','s','a','m'};
5568   static const uint8_t I_OggS[4] = {'O','g','g','S'};  /* Ogg-related files, apparently -- ogg123 has "vorbis" instead of "Speex" */
5569   static const uint8_t I_fLaC[4] = {'f','L','a','C'};  /* FLAC */
5570   static const uint8_t I_TTA1[4] = {'T','T','A','1'};  /* ttaenc */
5571   static const uint8_t I_wvpk[4] = {'w','v','p','k'};  /* wavpack */
5572   static const uint8_t I_MATL[4] = {'M','A','T','L'};  /* matlab 5.0 */
5573   static const uint8_t I_AB_5[4] = {'A','B',' ','5'};
5574 
5575   #define NINRS	7
5576   static const uint32_t I_INRS[NINRS] = {0xcb460020, 0xd0465555, 0xfa460000, 0x1c470040, 0x3b470080, 0x7a470000, 0x9c470040};
5577   static int inrs_srates[NINRS] = {6500, 6667, 8000, 10000, 12000, 16000, 20000};
5578 
5579   /* returns 0 on success (at least to the extent that we can report the header type), -1 for error */
5580   int i, loc = 0;
5581   int64_t bytes;
5582 
5583   header_type = MUS_UNKNOWN_HEADER;
5584   sample_type = MUS_UNKNOWN_SAMPLE;
5585   comment_start = 0;
5586   comment_end = 0;
5587   data_size = 0;
5588   data_location = 0;
5589 
5590   if (loop_modes)
5591     {
5592       loop_modes[0] = 0;
5593       loop_modes[1] = 0;
5594     }
5595 
5596   bytes = (int64_t)read(fd, hdrbuf, INITIAL_READ_SIZE);
5597   /* if it's a 0 length file we need to get out */
5598   if (bytes < 0)
5599     return(mus_error(MUS_HEADER_READ_FAILED, "%s: %s", filename, (errno) ? STRERROR(errno) : "bytes read < 0?"));
5600 
5601   if (bytes == 0)
5602     {
5603       header_type = MUS_RAW;
5604       srate = raw_header_srate;
5605       chans = raw_header_chans;
5606       sample_type = raw_header_sample_type;
5607       data_location = 0;
5608       true_file_length = 0;
5609       return(MUS_NO_ERROR);
5610     }
5611 
5612   if (bytes < 4)
5613     {
5614       header_type = MUS_RAW;
5615       return(read_no_header(fd));
5616     }
5617 
5618   if ((match_four_chars((uint8_t *)hdrbuf, I_DSND)) ||
5619       (match_four_chars((uint8_t *)hdrbuf, I_DECN)))
5620     {
5621       if (bytes < 24)
5622 	return(mus_error(MUS_HEADER_READ_FAILED, "%s NeXT header truncated? found only %" print_mus_long " bytes", filename, bytes));
5623       header_type = MUS_NEXT;
5624       return(read_next_header(filename, fd));
5625     }
5626 
5627   if (match_four_chars((uint8_t *)hdrbuf, I_FORM))
5628     {
5629       /* next 4 bytes are apparently the file size or something equally useless */
5630       if (bytes < 12)
5631 	return(mus_error(MUS_HEADER_READ_FAILED, "%s AIFF header truncated? found only %" print_mus_long " bytes", filename, bytes));
5632 
5633       if (match_four_chars((uint8_t *)(hdrbuf + 8), I_AIFF))
5634 	{
5635 	  header_type = MUS_AIFF;
5636 	  return(read_aiff_header(filename, fd, 0));
5637 	}
5638 
5639       if (match_four_chars((uint8_t *)(hdrbuf + 8), I_AIFC))
5640 	{
5641 	  header_type = MUS_AIFC;
5642 	  return(read_aiff_header(filename, fd, 0));
5643 	}
5644 
5645       if (match_four_chars((uint8_t *)(hdrbuf + 8), I_8SVX))
5646 	{
5647 	  header_type = MUS_SVX;
5648 	  return(read_8svx_header(filename, fd, true));
5649 	}
5650 
5651       if (match_four_chars((uint8_t *)(hdrbuf + 8), I_16SV))
5652 	{
5653 	  header_type = MUS_SVX;
5654 	  return(read_8svx_header(filename, fd, false));
5655 	}
5656 
5657       if (match_four_chars((uint8_t *)(hdrbuf + 8), I_MAUD))
5658 	{
5659 	  header_type = MUS_MAUD;
5660 	  return(read_maud_header(filename, fd));
5661 	}
5662 
5663       /* apparently SAMP here -> sampled audio data (?) */
5664 
5665       if (match_four_chars((uint8_t *)(hdrbuf + 4), I_DS16))
5666 	{
5667 	  header_type = MUS_CSL;
5668 	  return(read_csl_header(filename, fd));
5669 	}
5670       return(mus_error(MUS_HEADER_READ_FAILED,	"%s: unrecognized \"FORM\" (i.e. AIFF) header",	filename));
5671     }
5672 
5673   if ((match_four_chars((uint8_t *)hdrbuf, I_RIFF)) ||
5674       (match_four_chars((uint8_t *)hdrbuf, I_RIFX)))
5675     {
5676       if (bytes < 12)
5677 	return(mus_error(MUS_HEADER_READ_FAILED, "%s RIFF header truncated? found only %" print_mus_long " bytes", filename, bytes));
5678 
5679       if (match_four_chars((uint8_t *)(hdrbuf + 8), I_WAVE))
5680 	{
5681 	  header_type = MUS_RIFF;
5682 	  return(read_riff_header(filename, fd));
5683 	}
5684 
5685       if (match_four_chars((uint8_t *)(hdrbuf + 8), I_sfbk))
5686 	{
5687 	  header_type = MUS_SOUNDFONT;
5688 	  return(read_soundfont_header(filename, fd));
5689 	}
5690 
5691       if (match_four_chars((uint8_t *)(hdrbuf + 8), I_AVI_))
5692 	{
5693 	  header_type = MUS_AVI;
5694 	  return(read_avi_header(filename, fd));
5695 	}
5696 
5697       return(mus_error(MUS_HEADER_READ_FAILED, "%s: unrecognized \"RIFF\" (i.e. 'wave') header", filename));
5698     }
5699 
5700   if (match_four_chars((uint8_t *)hdrbuf, I_RF64))
5701     {
5702       header_type = MUS_RF64;
5703       if (bytes < 28)
5704 	return(mus_error(MUS_HEADER_READ_FAILED, "%s RF64 header truncated? found only %" print_mus_long " bytes", filename, bytes));
5705       if ((mus_char_to_lint((uint8_t *)(hdrbuf + 4)) != -1) ||
5706 	  (!(match_four_chars((uint8_t *)(hdrbuf + 8), I_WAVE))))
5707 	return(mus_error(MUS_HEADER_READ_FAILED, "%s: messed up RF64 header", filename));
5708       return(read_rf64_header(filename, fd));
5709     }
5710 
5711   if ((equal_big_or_little_endian((uint8_t *)hdrbuf, I_IRCAM_VAX)) ||
5712       (equal_big_or_little_endian((uint8_t *)hdrbuf, I_IRCAM_SUN)) ||
5713       (equal_big_or_little_endian((uint8_t *)hdrbuf, I_IRCAM_MIPS)) ||
5714       (equal_big_or_little_endian((uint8_t *)hdrbuf, I_IRCAM_NEXT)))
5715     {
5716       if (bytes < 24)
5717 	return(mus_error(MUS_HEADER_READ_FAILED, "%s IRCAM header truncated? found only %" print_mus_long " bytes", filename, bytes));
5718       header_type = MUS_IRCAM;
5719       return(read_ircam_header(filename, fd));
5720     }
5721 
5722   if (match_four_chars((uint8_t *)hdrbuf, I_NIST))
5723     {
5724       header_type = MUS_NIST;
5725       return(read_nist_header(filename, fd));
5726     }
5727 
5728   if (match_four_chars((uint8_t *)hdrbuf, I_caff))
5729     {
5730       if (bytes < 32) /* INITIAL_READ_SIZE */
5731 	return(mus_error(MUS_HEADER_READ_FAILED, "%s CAFF header truncated? found only %" print_mus_long " bytes", filename, bytes));
5732       header_type = MUS_CAFF;
5733       return(read_caff_header(fd));
5734     }
5735 
5736   if ((match_four_chars((uint8_t *)hdrbuf, I_MATL)) &&
5737       (match_four_chars((uint8_t *)(hdrbuf + 4), I_AB_5)))
5738     {
5739       if (bytes < 128) /* INITIAL_READ_SIZE=256 */
5740 	return(mus_error(MUS_HEADER_READ_FAILED, "%s Matlab header truncated? found only %" print_mus_long " bytes", filename, bytes));
5741       header_type = MUS_MATLAB;
5742       return(read_matlab_5_header(filename, fd));
5743     }
5744 
5745   if (match_four_chars((uint8_t *)hdrbuf, I_SOUN))
5746     {
5747       static const uint8_t I_D_SA[4] = {'D',' ','S','A'};
5748       static const uint8_t I_MPLE[4] = {'M','P','L','E'};
5749       if ((match_four_chars((uint8_t *)(hdrbuf + 4), I_D_SA)) &&
5750 	  (match_four_chars((uint8_t *)(hdrbuf + 8), I_MPLE)))
5751 	{
5752 	  header_type = MUS_SMP;
5753 	  return(read_smp_header(filename, fd));
5754 	}
5755       else
5756 	{
5757 	  header_type = MUS_SNDT;
5758 	  return(read_sndt_header(filename, fd));
5759 	}
5760     }
5761 
5762   if ((match_four_chars((uint8_t *)hdrbuf, I_dSoX)) ||
5763       (match_four_chars((uint8_t *)hdrbuf, I_XoSd)))
5764     {
5765       header_type = MUS_SOX;
5766       return(read_sox_header(filename, fd));
5767     }
5768 
5769   if ((match_four_chars((uint8_t *)hdrbuf, I_VOC0)) &&
5770       (match_four_chars((uint8_t *)(hdrbuf + 4), I_VOC1)))
5771     {
5772       if (bytes < 24)
5773 	return(mus_error(MUS_HEADER_READ_FAILED, "%s VOC header truncated? found only %" print_mus_long " bytes", filename, bytes));
5774       header_type = MUS_VOC;
5775       return(read_voc_header(filename, fd));
5776     }
5777 
5778   if (match_four_chars((uint8_t *)hdrbuf, I_AVR_))
5779     {
5780       header_type = MUS_AVR;
5781       return(read_avr_header(filename, fd));
5782     }
5783 
5784   if (mus_char_to_bshort((uint8_t *)hdrbuf) == 1336)
5785     {
5786       header_type = MUS_SD1;
5787       return(read_sd1_header(filename, fd));
5788     }
5789 
5790   if ((match_four_chars((uint8_t *)hdrbuf, I_ALaw)) &&
5791       (match_four_chars((uint8_t *)(hdrbuf + 4), I_Soun)))
5792     {
5793       header_type = MUS_PSION;
5794       return(read_psion_header(filename, fd));
5795     }
5796 
5797   if ((match_four_chars((uint8_t *)hdrbuf, I_GF1P)) &&
5798       (match_four_chars((uint8_t *)(hdrbuf + 4), I_ATCH)))
5799     {
5800       header_type = MUS_GRAVIS;
5801       return(read_gravis_header(filename, fd));
5802     }
5803 
5804   if ((match_four_chars((uint8_t *)hdrbuf, I_DSIG)) &&
5805       (match_four_chars((uint8_t *)(hdrbuf + 4), I_NAL_)))
5806     {
5807       header_type = MUS_COMDISCO;
5808       return(read_comdisco_header(filename, fd));
5809     }
5810 
5811   if ((match_four_chars((uint8_t *)hdrbuf, I_GOLD)) &&
5812       (match_four_chars((uint8_t *)(hdrbuf + 4), I__WAV)))
5813     {
5814       header_type = MUS_GOLDWAVE;
5815       return(read_goldwave_header(filename, fd));
5816     }
5817 
5818   if ((match_four_chars((uint8_t *)hdrbuf, I_Diam)) &&
5819       (match_four_chars((uint8_t *)(hdrbuf + 4), I_ondW)))
5820     {
5821       header_type = MUS_DIAMONDWARE;
5822       return(read_diamondware_header(filename, fd));
5823     }
5824 
5825   if (match_four_chars((uint8_t *)hdrbuf, I_SRFS))
5826     {
5827       header_type = MUS_SRFS;
5828       return(read_srfs_header(filename, fd));
5829     }
5830 
5831   if (match_four_chars((uint8_t *)hdrbuf, I_CSRE))
5832     {
5833       header_type = MUS_ADF;
5834       return(read_adf_header(filename, fd));
5835     }
5836 
5837   if (match_four_chars((uint8_t *)hdrbuf, I_fLaC))
5838     {
5839       header_type = MUS_FLAC;
5840       return(MUS_NO_ERROR);
5841     }
5842 
5843   if (match_four_chars((uint8_t *)hdrbuf, I_ajkg))
5844     {
5845       header_type = MUS_SHORTEN;
5846       return(MUS_NO_ERROR);
5847     }
5848 
5849   if (match_four_chars((uint8_t *)hdrbuf, I_TTA1))
5850     {
5851       header_type = MUS_TTA;
5852       return(MUS_NO_ERROR);
5853     }
5854 
5855   if (match_four_chars((uint8_t *)hdrbuf, I_wvpk))
5856     {
5857       header_type = MUS_WAVPACK;
5858       return(MUS_NO_ERROR);
5859     }
5860 
5861   if (match_four_chars((uint8_t *)hdrbuf, I_OggS))
5862     {
5863       if ((hdrbuf[29] == 'v') && (hdrbuf[30] == 'o') && (hdrbuf[31] == 'r'))
5864 	header_type = MUS_OGG;
5865       else
5866 	{
5867 	  if ((hdrbuf[28] == 'S') && (hdrbuf[29] == 'p') && (hdrbuf[30] == 'e'))
5868 	    header_type = MUS_SPEEX;
5869 	}
5870       return(MUS_NO_ERROR);
5871     }
5872 
5873   if ((match_four_chars((uint8_t *)hdrbuf, I_file)) &&
5874       (match_four_chars((uint8_t *)(hdrbuf + 4), I__sam)))
5875     {
5876       header_type = MUS_FILE_SAMP;
5877       return(read_file_samp_header(filename, fd));
5878     }
5879 
5880   if ((hdrbuf[0] == 0xf0) && (hdrbuf[1] == 0x7e) && (hdrbuf[3] == 0x01))
5881     {
5882       header_type = MUS_MIDI_SAMPLE_DUMP;
5883       chans = 1;
5884       srate = (int)(1.0e9 / (double)((hdrbuf[7] + (hdrbuf[8] << 7) + (hdrbuf[9] << 14))));
5885       data_size = (hdrbuf[10] + (hdrbuf[11] << 7) + (hdrbuf[12] << 14));
5886       /* since this file type has embedded blocks, we have to translate it elsewhere */
5887       return(MUS_NO_ERROR);
5888     }
5889 
5890   if (mus_char_to_ubint((uint8_t *)hdrbuf) == 0xAAAAAAAA)
5891     {
5892       header_type = MUS_MUS10;
5893       return(MUS_NO_ERROR);
5894     }
5895 
5896   if ((match_four_chars((uint8_t *)hdrbuf, I_SPIB)) ||
5897       (match_four_chars((uint8_t *)hdrbuf, I_S___)))
5898     {
5899       header_type = MUS_IEEE;
5900       return(MUS_NO_ERROR);
5901     }
5902 
5903   if (match_four_chars((uint8_t *)hdrbuf, I_riff))
5904     {
5905       header_type = MUS_SOUNDFORGE;
5906       return(read_soundforge_header(filename, fd));
5907     }
5908 
5909   if ((match_four_chars((uint8_t *)hdrbuf, I_PVF1)) ||
5910       (match_four_chars((uint8_t *)hdrbuf, I_PVF2)))
5911     {
5912       header_type = MUS_PVF;
5913       return(read_pvf_header(filename, fd));
5914     }
5915 
5916   if (match_four_chars((uint8_t *)hdrbuf, I_MThd))
5917     {
5918       header_type = MUS_MIDI;
5919       return(MUS_ERROR);
5920     }
5921 
5922   if (match_four_chars((uint8_t *)hdrbuf, I_SND_))
5923     {
5924       header_type = MUS_SBSTUDIOII;
5925       return(read_sbstudio_header(filename, fd));
5926     }
5927 
5928   if (match_four_chars((uint8_t *)hdrbuf, I_FSMt))
5929     {
5930       header_type = MUS_FARANDOLE;
5931       return(read_farandole_header(filename, fd));
5932     }
5933 
5934   if (match_four_chars((uint8_t *)hdrbuf, I_SDXc))
5935     {
5936       header_type = MUS_SAMPLE_DUMP;
5937       return(read_sample_dump_header(filename, fd));
5938     }
5939 
5940   if (match_four_chars((uint8_t *)hdrbuf, I_DDSF))
5941     {
5942       header_type = MUS_DELUSION;
5943       return(read_delusion_header(filename, fd));
5944     }
5945 
5946   if (match_four_chars((uint8_t *)hdrbuf, I_LM89))
5947     {
5948       header_type = MUS_YAMAHA_TX16W;
5949       return(read_tx16w_header(filename, fd));
5950     }
5951 
5952   if (match_four_chars((uint8_t *)hdrbuf, I_SY85))
5953     {
5954       header_type = MUS_YAMAHA_SY85;
5955       return(read_sy85_header(filename, fd));
5956     }
5957 
5958   if (match_four_chars((uint8_t *)hdrbuf, I_SY80))
5959     {
5960       header_type = MUS_YAMAHA_SY99;
5961       return(read_sy85_header(filename, fd));
5962     }
5963 
5964   if (match_four_chars((uint8_t *)hdrbuf, I_PRAM))
5965     {
5966       header_type = MUS_KURZWEIL_2000;
5967       return(read_kurzweil_2000_header(filename, fd));
5968     }
5969 
5970   if (match_four_chars((uint8_t *)hdrbuf, I_SMP1))
5971     {
5972       header_type = MUS_KORG;
5973       return(read_korg_header(filename, fd));
5974     }
5975 
5976   if (match_four_chars((uint8_t *)hdrbuf, I_Maui))
5977     {
5978       header_type = MUS_MAUI;
5979       return(read_maui_header(filename, fd));
5980     }
5981 
5982   if (match_four_chars((uint8_t *)hdrbuf, I_IMPS))
5983     {
5984       header_type = MUS_IMPULSETRACKER;
5985       return(read_impulsetracker_header(filename, fd));
5986     }
5987 
5988   if (match_four_chars((uint8_t *)(hdrbuf + 35), I_UWFD))
5989     {
5990       header_type = MUS_ULTRATRACKER;
5991       return(read_ultratracker_header(filename, fd));
5992     }
5993 
5994   if (match_four_chars((uint8_t *)(hdrbuf + 76), I_SCRS))
5995     {
5996       header_type = MUS_DIGIPLAYER;
5997       return(read_digiplayer_header(filename, fd));
5998     }
5999 
6000   if (match_four_chars((uint8_t *)hdrbuf, I_covox))
6001     {
6002       header_type = MUS_COVOX;
6003       return(read_covox_header(filename, fd));
6004     }
6005 
6006   if ((match_four_chars((uint8_t *)hdrbuf, I__PAF)) ||
6007       (match_four_chars((uint8_t *)hdrbuf, I_FAP_)))
6008     {
6009       header_type = MUS_PAF;
6010       return(read_paf_header(filename, fd));
6011     }
6012 
6013   if (match_four_chars((uint8_t *)hdrbuf, I_SDIF))
6014     {
6015       header_type = MUS_SDIF;
6016       return(read_sdif_header(filename, fd));
6017     }
6018 
6019 #if G7XX
6020   if (match_four_chars((uint8_t *)hdrbuf, I_NVF_))
6021     {
6022       header_type = MUS_NVF;
6023       return(read_nvf_header(filename, fd));
6024     }
6025 #endif
6026 
6027   if (match_four_chars((uint8_t *)hdrbuf, I_TWIN))
6028     {
6029       header_type = MUS_TWINVQ;
6030       return(read_twinvq_header(filename, fd));
6031     }
6032 
6033   /* ESPS is either 0x00006a1a or 0x1a6a0000 at byte 16 */
6034   if (equal_big_or_little_endian((uint8_t *)(hdrbuf + 16), 0x00006a1a))
6035     {
6036       header_type = MUS_ESPS;
6037       return(read_esps_header(filename, fd));
6038     }
6039 
6040   if ((hdrbuf[252] == 64) && (hdrbuf[253] == 195)) /* #o100 and #o303 */
6041     {
6042       header_type = MUS_SPPACK;
6043       return(read_sppack_header(filename, fd));
6044     }
6045 
6046   if ((match_four_chars((uint8_t *)(hdrbuf + 65), I_FSSD)) &&
6047       (match_four_chars((uint8_t *)(hdrbuf + 128), I_HCOM)))
6048     {
6049       header_type = MUS_HCOM;
6050       return(MUS_NO_ERROR);
6051     }
6052 
6053 #if MUS_LITTLE_ENDIAN
6054   if (mus_char_to_uninterpreted_int((uint8_t *)hdrbuf) == 0x01000800)
6055 #else
6056   if (mus_char_to_uninterpreted_int((uint8_t *)hdrbuf) == 0x00080001)
6057 #endif
6058     {
6059       header_type = MUS_ADC;
6060       return(read_adc_header(filename, fd));
6061     }
6062 
6063   if ((match_four_chars((uint8_t *)hdrbuf, I_ones)) &&
6064       (match_four_chars((uint8_t *)(hdrbuf + 12), I_FORM)))
6065     {
6066       /* possibly an OMF file with an embedded AIFF data file -- this is just a guess... */
6067       header_type = MUS_OMF;
6068       return(read_aiff_header(filename, fd, 12));
6069       /* another (apparently) along these lines is TOC */
6070     }
6071 
6072   if ((match_four_chars((uint8_t *)hdrbuf, I_zeros)) &&
6073       (match_four_chars((uint8_t *)(hdrbuf + 4), I_mdat)))
6074     {
6075       /* possibly quicktime?? */
6076       header_type = MUS_QUICKTIME;
6077       return(read_qt_header(filename, fd));
6078     }
6079 
6080   if ((hdrbuf[0] == 1) && (hdrbuf[1] == 4)) /* name follows --check? */
6081     {
6082       header_type = MUS_AKAI4;
6083       return(read_akai4_header(filename, fd));
6084     }
6085 
6086 #if 0
6087   if ((hdrbuf[0] == 3) && (hdrbuf[16] == 128))
6088     {
6089       header_type = MUS_AKAI4;
6090       return(read_akai3_header(filename, fd));
6091     }
6092 #endif
6093 
6094   for (i = 0; i < NINRS; i++)
6095     {
6096       if (equal_big_or_little_endian((uint8_t *)hdrbuf, I_INRS[i]))
6097 	{
6098 	  loc = inrs_srates[i];
6099 	  header_type = MUS_INRS;
6100 	  return(read_inrs_header(filename, fd, loc));
6101 	}
6102     }
6103 
6104   if ((match_four_chars((uint8_t *)hdrbuf, I_asf0)) &&
6105       (match_four_chars((uint8_t *)(hdrbuf + 4), I_asf1)) &&
6106       (match_four_chars((uint8_t *)(hdrbuf + 8), I_asf2)) &&
6107       (match_four_chars((uint8_t *)(hdrbuf + 12), I_asf3)))
6108     {
6109       header_type = MUS_ASF;
6110       return(read_asf_header(filename, fd));
6111     }
6112 
6113   /* SMS files start with 767 (4-byte int, apparently in native order) */
6114 
6115   /* try to catch mpeg... */
6116   {
6117     int len;
6118     len = strlen(filename);
6119     if (len > 4)
6120       {
6121 	if (strcmp((const char *)(filename + len - 4), ".mp3") == 0)
6122 	  {
6123 	    header_type = MUS_MPEG;
6124 	    return(MUS_NO_ERROR);
6125 	  }
6126       }
6127   }
6128 
6129   header_type = MUS_RAW;
6130   return(read_no_header(fd));
6131 }
6132 
6133 
6134 static int local_error_type = MUS_NO_ERROR;
6135 static char *local_error_msg = NULL;
6136 static mus_error_handler_t *old_error_handler;
6137 
local_mus_error(int type,char * msg)6138 static void local_mus_error(int type, char *msg)
6139 {
6140   local_error_type = type;
6141   if (local_error_msg)
6142     free(local_error_msg);
6143   if (msg)
6144     local_error_msg = mus_strdup(msg);
6145   else local_error_msg = NULL;
6146 }
6147 
6148 
mus_header_read(const char * name)6149 int mus_header_read(const char *name)
6150 {
6151   int fd, err = 0;
6152   fd = mus_file_open_read(name);
6153   if (fd == -1)
6154     return(mus_error(MUS_CANT_OPEN_FILE, "can't open %s: %s", name, STRERROR(errno)));
6155   old_error_handler = mus_error_set_handler(local_mus_error);
6156   err = mus_header_read_1(name, fd);
6157   CLOSE(fd, name);
6158   mus_error_set_handler(old_error_handler);
6159   if (err != MUS_NO_ERROR)
6160     return(mus_error(local_error_type, "%s", local_error_msg)); /* pass error info on up the chain now that we've cleaned up the open file descriptor */
6161   return(err);
6162 }
6163 
6164 
6165 static mus_header_write_hook_t *mus_header_write_hook = NULL;
6166 
mus_header_write_set_hook(mus_header_write_hook_t * new_hook)6167 mus_header_write_hook_t *mus_header_write_set_hook(mus_header_write_hook_t *new_hook)
6168 {
6169   mus_header_write_hook_t *old_hook;
6170   old_hook = mus_header_write_hook;
6171   mus_header_write_hook = new_hook;
6172   return(old_hook);
6173 }
6174 
6175 
mus_header_write(const char * name,mus_header_t type,int in_srate,int in_chans,mus_long_t loc,mus_long_t size_in_samples,mus_sample_t samp_type,const char * comment,int len)6176 int mus_header_write(const char *name, mus_header_t type, int in_srate, int in_chans, mus_long_t loc,
6177 		     mus_long_t size_in_samples, mus_sample_t samp_type, const char *comment, int len)
6178 {
6179   /* the "loc" arg is a mistake -- just always set it to 0 */
6180 
6181   int fd, err = MUS_NO_ERROR;
6182   mus_long_t siz;
6183 
6184   fd = mus_file_create(name);
6185   if (fd == -1)
6186     return(mus_error(MUS_CANT_OPEN_FILE, "can't write %s: %s", name, STRERROR(errno)));
6187 
6188   if (mus_header_write_hook)
6189     (*mus_header_write_hook)(name);
6190 
6191   siz = mus_samples_to_bytes(samp_type, size_in_samples);
6192   switch (type)
6193     {
6194     case MUS_RAW: case MUS_IRCAM: case MUS_NEXT: case MUS_RIFF: case MUS_RF64: case MUS_CAFF:
6195       break;
6196 
6197     default:
6198       if (siz > BIGGEST_4_BYTE_SIGNED_INT)
6199 	{
6200 	  err = MUS_BAD_SIZE;
6201 	  siz = BIGGEST_4_BYTE_SIGNED_INT;
6202 	}
6203       break;
6204     }
6205 
6206   switch (type)
6207     {
6208     case MUS_NEXT:  err = mus_header_write_next_header(fd, in_srate, in_chans, loc, siz, samp_type, comment, len);  break;
6209     case MUS_AIFC:  err = write_aif_header(fd, in_srate, in_chans, siz, samp_type, comment, len, true);             break;
6210     case MUS_AIFF:  err = write_aif_header(fd, in_srate, in_chans, siz, samp_type, comment, len, false);            break;
6211     case MUS_RF64:  err = write_rf64_header(fd, in_srate, in_chans, siz, samp_type, comment, len);                  break;
6212     case MUS_CAFF:  err = write_caff_header(fd, in_srate, in_chans, siz, samp_type);                                break;
6213     case MUS_IRCAM: err = write_ircam_header(fd, in_srate, in_chans, samp_type, comment, len);                      break;
6214     case MUS_NIST:  err = write_nist_header(fd, in_srate, in_chans, siz, samp_type);                                break;
6215 
6216     case MUS_RIFF:
6217       err = write_riff_header(fd, in_srate, in_chans, siz, samp_type, comment, len);
6218       if (err != MUS_NO_ERROR)
6219 	{
6220 	  CLOSE(fd, name);
6221 	  return(mus_error(err,  "can't write %s header for %s (fd: %d, sample type: %s, srate: %d, chans: %d)",
6222 			   mus_header_type_name(type),
6223 			   name, fd,
6224 			   mus_sample_type_short_name(samp_type),
6225 			   in_srate, in_chans));
6226 	}
6227       break;
6228 
6229     case MUS_RAW:
6230       data_location = 0;
6231       data_size = mus_bytes_to_samples(samp_type, siz);
6232       srate = in_srate;
6233       chans = in_chans;
6234       header_type = MUS_RAW;
6235       sample_type = samp_type;
6236       break;
6237 
6238     default:
6239       CLOSE(fd, name);
6240       return(mus_error(MUS_UNSUPPORTED_HEADER_TYPE,  "can't write %s header for %s", mus_header_type_name(type), name));
6241       break;
6242     }
6243 
6244   CLOSE(fd, name);
6245   return(err);
6246 }
6247 
6248 
mus_write_header(const char * name,mus_header_t type,int in_srate,int in_chans,mus_long_t size_in_samples,mus_sample_t samp_type,const char * comment)6249 int mus_write_header(const char *name, mus_header_t type, int in_srate, int in_chans, mus_long_t size_in_samples, mus_sample_t samp_type, const char *comment)
6250 {
6251   int len = 0;
6252   if (comment)
6253     len = strlen(comment);
6254   return(mus_header_write(name, type, in_srate, in_chans, 0, size_in_samples, samp_type, comment, len));
6255 }
6256 
6257 
mus_header_change_data_size(const char * filename,mus_header_t type,mus_long_t size)6258 int mus_header_change_data_size(const char *filename, mus_header_t type, mus_long_t size) /* in bytes */
6259 {
6260   /* the read header at sample update (sound-close) time could be avoided if the
6261    *   ssnd_location (etc) were saved and passed in -- perhaps an added optimized
6262    *   header change data size?  Means saving the relevant data, and exporting it
6263    *  from headers.c. Can we guarantee consistency here?
6264    */
6265 
6266   int fd, err = MUS_NO_ERROR;
6267   switch (type)
6268     {
6269     case MUS_AIFF:
6270     case MUS_AIFC:
6271     case MUS_NIST:
6272     case MUS_RIFF:
6273     case MUS_RF64:
6274       err = mus_header_read(filename);
6275       break;
6276     default:
6277       break;
6278     }
6279   if (err == MUS_ERROR) return(err);
6280 
6281   fd = mus_file_reopen_write(filename);
6282   if (fd == -1) return(mus_error(MUS_HEADER_WRITE_FAILED, "%s: %s", filename, STRERROR(errno)));
6283 
6284   if (size < 0)
6285     {
6286       CLOSE(fd, filename);
6287       return(mus_error(MUS_BAD_SIZE, "%s: change size to %" print_mus_long "?", filename, size));
6288     }
6289 
6290   switch (type)
6291     {
6292     case MUS_NEXT:
6293       if (size > (mus_long_t)(BIGGEST_4_BYTE_UNSIGNED_INT))
6294 	{
6295 	  err = MUS_BAD_SIZE;
6296 	  size = BIGGEST_4_BYTE_UNSIGNED_INT;
6297 	}
6298       lseek(fd, 8L, SEEK_SET);
6299       mus_bint_to_char((uint8_t *)(hdrbuf + 0), (uint32_t)size);
6300       header_write(fd, hdrbuf, 4);
6301       break;
6302 
6303     case MUS_AIFC:
6304     case MUS_AIFF:
6305       /* we apparently have to make sure the form size and the data size are correct
6306        * assumed here that we'll only be updating our own AIFF files
6307        * There are 3 such locations -- the second word of the file which is the overall form size,
6308        * the framples variable in the COMM chunk, and the chunk-size variable in the SSND chunk
6309        * an unexpected hassle for CLM is that we can open/close the output file many times if running mix,
6310        * so we have to update the various size fields taking into account the old size
6311        */
6312       /* read sets current update_form_size, data_size, sample_type, update_framples_location, update_ssnd_location */
6313       if (size > BIGGEST_4_BYTE_SIGNED_INT)
6314 	{
6315 	  err = MUS_BAD_SIZE;
6316 	  mus_print("%s size: %" print_mus_long " is too large for %s headers", filename, size, mus_header_type_name(type));
6317 	  size = BIGGEST_4_BYTE_SIGNED_INT;
6318 	}
6319       lseek(fd, 4L, SEEK_SET);
6320       mus_bint_to_char((uint8_t *)hdrbuf, (int)size + update_form_size - mus_samples_to_bytes(sample_type, data_size));
6321       /* cancel old data_size from previous possible write */
6322       header_write(fd, hdrbuf, 4);
6323       lseek(fd, update_framples_location, SEEK_SET);
6324       mus_ubint_to_char((uint8_t *)hdrbuf, (uint32_t)size / (chans * mus_bytes_per_sample(sample_type)));
6325       header_write(fd, hdrbuf, 4);
6326       lseek(fd, update_ssnd_location, SEEK_SET);
6327       mus_ubint_to_char((uint8_t *)hdrbuf, (uint32_t)size + 8);
6328       header_write(fd, hdrbuf, 4);
6329       break;
6330 
6331     case MUS_RIFF:
6332       /* read sets current update_form_size, sample_type, data_size, update_ssnd_location */
6333       if (size > BIGGEST_4_BYTE_SIGNED_INT)
6334 	{
6335 	  CLOSE(fd, filename);
6336 	  return(mus_header_convert_riff_to_rf64(filename, size));
6337 	}
6338       lseek(fd, 4L, SEEK_SET);
6339       mus_lint_to_char((uint8_t *)hdrbuf, (uint32_t)size + update_form_size - mus_samples_to_bytes(sample_type, data_size));
6340       header_write(fd, hdrbuf, 4);
6341       lseek(fd, update_ssnd_location, SEEK_SET);
6342       mus_ulint_to_char((uint8_t *)hdrbuf, (uint32_t)size);
6343       header_write(fd, hdrbuf, 4);
6344       break;
6345 
6346     case MUS_RF64:
6347       /* read sets current update_form_size, sample_type, data_size, update_ssnd_location, update_rf64_location */
6348       /* assume here that this really is an rf64 file (i.e. -1 for form size and data chunk size */
6349       lseek(fd, update_rf64_location, SEEK_SET);
6350       mus_llong_to_char((uint8_t *)hdrbuf, data_location + size - 8); /* 25-June-07 */
6351       mus_llong_to_char((uint8_t *)(hdrbuf + 8), size);
6352       mus_llong_to_char((uint8_t *)(hdrbuf + 16), size);
6353       header_write(fd, hdrbuf, 24);
6354       break;
6355 
6356     case MUS_IRCAM:
6357     case MUS_RAW:
6358       /* size is implicit in file size */
6359       break;
6360 
6361     case MUS_NIST:
6362       /* read sets current srate, chans, sample_type */
6363       if (size > BIGGEST_4_BYTE_SIGNED_INT)
6364 	{
6365 	  err = MUS_BAD_SIZE;
6366 	  mus_print("%s size: %" print_mus_long " is too large for %s headers", filename, size, mus_header_type_name(type));
6367 	  size = BIGGEST_4_BYTE_SIGNED_INT;
6368 	}
6369       lseek(fd, 0L, SEEK_SET);
6370       write_nist_header(fd, mus_header_srate(), mus_header_chans(), size, mus_header_sample_type());
6371       break;
6372 
6373     case MUS_CAFF:
6374       if (update_framples_location < 56) update_framples_location = 56;
6375       lseek(fd, update_framples_location, SEEK_SET);
6376       mus_blong_to_char((uint8_t *)(hdrbuf + 0), size);
6377       header_write(fd, hdrbuf, 8);
6378       break;
6379 
6380     default:
6381       CLOSE(fd, filename);
6382       return(mus_error(MUS_UNSUPPORTED_HEADER_TYPE, "mus_header_change_data_size: can't update %s headers", mus_header_type_name(type)));
6383       break;
6384     }
6385 
6386   CLOSE(fd, filename);
6387   return(err);
6388 }
6389 
6390 
mus_header_change_chans(const char * filename,mus_header_t type,int new_chans)6391 int mus_header_change_chans(const char *filename, mus_header_t type, int new_chans)
6392 {
6393   int err = MUS_NO_ERROR, fd;
6394   mus_long_t new_framples;
6395   switch (type)
6396     {
6397     case MUS_AIFF:
6398     case MUS_AIFC:
6399     case MUS_NIST:
6400     case MUS_RIFF:
6401     case MUS_RF64:
6402       err = mus_header_read(filename);
6403       break;
6404     default:
6405       break;
6406     }
6407   if (err == MUS_ERROR) return(err);
6408   fd = mus_file_reopen_write(filename);
6409   if (fd == -1)
6410     return(mus_error(MUS_CANT_OPEN_FILE, "mus_header_change_chans for %s failed: %s", filename, STRERROR(errno)));
6411   switch (type)
6412     {
6413     case MUS_NEXT:
6414       lseek(fd, 20L, SEEK_SET);
6415       mus_bint_to_char((uint8_t *)hdrbuf, new_chans);
6416       header_write(fd, hdrbuf, 4);
6417       break;
6418 
6419     case MUS_IRCAM:
6420       lseek(fd, 8L, SEEK_SET);
6421       if (little_endian)
6422 	mus_lint_to_char((uint8_t *)hdrbuf, new_chans);
6423       else mus_bint_to_char((uint8_t *)hdrbuf, new_chans);
6424       header_write(fd, hdrbuf, 4);
6425       break;
6426 
6427     case MUS_NIST:
6428       lseek(fd, 0L, SEEK_SET);
6429       write_nist_header(fd, srate, new_chans, mus_bytes_per_sample(sample_type) * data_size, sample_type);
6430       /* header size is always 1024, so this is safe */
6431       break;
6432 
6433     case MUS_AIFF: case MUS_AIFC:
6434       lseek(fd, update_framples_location - 2, SEEK_SET);
6435       new_framples = data_size / new_chans;
6436       mus_bshort_to_char((uint8_t *)hdrbuf, new_chans);
6437       mus_bint_to_char((uint8_t *)(hdrbuf + 2), new_framples);
6438       header_write(fd, hdrbuf, 6);
6439       break;
6440 
6441     case MUS_RIFF:
6442     case MUS_RF64:
6443       lseek(fd, update_framples_location - 2, SEEK_SET);
6444       if (little_endian)
6445 	mus_lshort_to_char((uint8_t *)hdrbuf, new_chans);
6446       else mus_bshort_to_char((uint8_t *)hdrbuf, new_chans);
6447       header_write(fd, hdrbuf, 2);
6448       break;
6449 
6450     case MUS_CAFF:
6451       lseek(fd, 44L, SEEK_SET);
6452       mus_bint_to_char((uint8_t *)hdrbuf, new_chans);
6453       header_write(fd, hdrbuf, 4);
6454       /* we should probably also change bytes_per_packet at 36, but... */
6455       break;
6456 
6457     default: break;
6458     }
6459   CLOSE(fd, filename);
6460   return(err);
6461 }
6462 
6463 
mus_header_change_srate(const char * filename,mus_header_t type,int new_srate)6464 int mus_header_change_srate(const char *filename, mus_header_t type, int new_srate)
6465 {
6466   int err = MUS_NO_ERROR, fd;
6467   switch (type)
6468     {
6469     case MUS_AIFF:
6470     case MUS_AIFC:
6471     case MUS_NIST:
6472     case MUS_RIFF:
6473     case MUS_RF64:
6474       err = mus_header_read(filename);
6475       break;
6476     default:
6477       break;
6478     }
6479   if (err == MUS_ERROR) return(err);
6480   fd = mus_file_reopen_write(filename);
6481   if (fd == -1)
6482     return(mus_error(MUS_CANT_OPEN_FILE, "mus_header_change_srate for %s failed: %s", filename, STRERROR(errno)));
6483   switch (type)
6484     {
6485     case MUS_NEXT:
6486       lseek(fd, 16L, SEEK_SET);
6487       mus_bint_to_char((uint8_t *)hdrbuf, new_srate);
6488       header_write(fd, hdrbuf, 4);
6489       break;
6490 
6491     case MUS_IRCAM:
6492       lseek(fd, 4L, SEEK_SET);
6493       if (little_endian)
6494 	mus_lfloat_to_char((uint8_t *)hdrbuf, (float)new_srate);
6495       else mus_bfloat_to_char((uint8_t *)hdrbuf, (float)new_srate);
6496       header_write(fd, hdrbuf, 4);
6497       break;
6498 
6499     case MUS_NIST:
6500       lseek(fd, 0L, SEEK_SET);
6501       write_nist_header(fd, new_srate, chans, mus_bytes_per_sample(sample_type) * data_size, sample_type);
6502       break;
6503 
6504     case MUS_AIFF:
6505     case MUS_AIFC:
6506       lseek(fd, update_framples_location + 6, SEEK_SET);
6507       double_to_ieee_80((double)new_srate, (uint8_t *)hdrbuf);
6508       header_write(fd, hdrbuf, 10);
6509       break;
6510 
6511     case MUS_RIFF:
6512     case MUS_RF64:
6513       lseek(fd, update_framples_location, SEEK_SET);
6514       if (little_endian)
6515 	mus_lint_to_char((uint8_t *)hdrbuf, new_srate);
6516       else mus_bint_to_char((uint8_t *)hdrbuf, new_srate);
6517       header_write(fd, hdrbuf, 4);
6518       break;
6519 
6520     case MUS_CAFF:
6521       lseek(fd, 20, SEEK_SET);
6522       mus_bdouble_to_char((uint8_t *)hdrbuf, (double)new_srate);
6523       header_write(fd, hdrbuf, 8);
6524       break;
6525 
6526     default: break;
6527     }
6528   CLOSE(fd, filename);
6529   return(err);
6530 }
6531 
6532 
mus_header_change_type(const char * filename,mus_header_t new_type,mus_sample_t new_format)6533 int mus_header_change_type(const char *filename, mus_header_t new_type, mus_sample_t new_format)
6534 {
6535   int err;
6536   /* open temp, write header, copy data, replace original with temp */
6537   err = mus_header_read(filename);
6538   if (err == MUS_NO_ERROR)
6539     {
6540       if (header_type != new_type)
6541 	{
6542 	  int ofd, ifd, len;
6543 	  int64_t nbytes;
6544 	  mus_long_t loc;
6545 	  uint8_t *buf = NULL;
6546 	  char *new_file, *comment = NULL;
6547 
6548 	  if ((header_type == MUS_RIFF) &&
6549 	      (new_type == MUS_RF64))
6550 	    return(mus_header_convert_riff_to_rf64(filename, data_size));
6551 
6552 	  len = strlen(filename) + 5;
6553 	  new_file = (char *)malloc(len * sizeof(char));
6554 	  snprintf(new_file, len, "%s.tmp", filename);
6555 	  loc = mus_header_data_location();
6556 	  if (new_type != MUS_RAW)
6557 	    {
6558 	      if (comment_end > comment_start)
6559 		{
6560 		  mus_long_t clen;
6561 		  clen = comment_end - comment_start + 1;
6562 		  comment = (char *)calloc(clen + 1, sizeof(char));
6563 		  ifd = mus_file_open_read(filename);
6564 		  lseek(ifd, comment_start, SEEK_SET);
6565 		  header_read(ifd, (uint8_t *)comment, clen);
6566 		  CLOSE(ifd, filename);
6567 		}
6568 	      data_size = data_size * mus_bytes_per_sample(sample_type) / mus_bytes_per_sample(new_format);
6569 	      mus_write_header(new_file, new_type, srate, chans, data_size, new_format, comment);
6570 	    }
6571 	  else mus_file_create(new_file);
6572 	  ifd = mus_file_open_read(filename);
6573 	  lseek(ifd, loc, SEEK_SET);
6574 	  ofd = mus_file_reopen_write(new_file);
6575 	  lseek(ofd, 0L, SEEK_END);
6576 	  buf = (uint8_t *)calloc(8192, sizeof(uint8_t));
6577 	  while ((nbytes = read(ifd, buf, 8192))) header_write(ofd, buf, (int)nbytes);
6578 	  CLOSE(ifd, filename);
6579 	  CLOSE(ofd, new_file);
6580 	  free(buf);
6581 	  if (comment) free(comment);
6582 	  rename(new_file, filename);
6583 	  free(new_file);
6584 	}
6585     }
6586   return(err);
6587 }
6588 
6589 
mus_header_change_sample_type(const char * filename,mus_header_t type,mus_sample_t new_format)6590 int mus_header_change_sample_type(const char *filename, mus_header_t type, mus_sample_t new_format)
6591 {
6592   int err = MUS_NO_ERROR, fd, fr;
6593   mus_long_t old_bytes;
6594   switch (type)
6595     {
6596     case MUS_AIFF:
6597     case MUS_AIFC:
6598     case MUS_NIST:
6599     case MUS_RIFF:
6600     case MUS_RF64:
6601       err = mus_header_read(filename);
6602       break;
6603     default:
6604       break;
6605     }
6606 
6607   if (err == MUS_ERROR) return(err);
6608   fd = mus_file_reopen_write(filename);
6609   if (fd == -1)
6610     return(mus_error(MUS_CANT_OPEN_FILE, "mus_header_change_sample_type for %s failed: %s", filename, STRERROR(errno)));
6611 
6612   switch (type)
6613     {
6614     case MUS_NEXT:
6615       lseek(fd, 12L, SEEK_SET);
6616       mus_bint_to_char((uint8_t *)hdrbuf, sndlib_format_to_next(new_format));
6617       header_write(fd, hdrbuf, 4);
6618       break;
6619 
6620     case MUS_IRCAM:
6621       lseek(fd, 12L, SEEK_SET);
6622       mus_bint_to_char((uint8_t *)hdrbuf, sndlib_format_to_ircam(new_format));
6623       header_write(fd, hdrbuf, 4);
6624       break;
6625 
6626     case MUS_NIST:
6627       lseek(fd, 0L, SEEK_SET);
6628       write_nist_header(fd, srate, chans, mus_bytes_per_sample(sample_type) * data_size, new_format);
6629       break;
6630 
6631     case MUS_AIFF:
6632     case MUS_AIFC:
6633       old_bytes = data_size * mus_bytes_per_sample(sample_type);
6634       lseek(fd, update_framples_location, SEEK_SET);
6635       mus_bint_to_char((uint8_t *)hdrbuf, old_bytes / (chans * mus_bytes_per_sample(new_format)));
6636       mus_bshort_to_char((uint8_t *)(hdrbuf + 4), sndlib_format_to_aiff_bits(new_format));
6637       header_write(fd, hdrbuf, 6);
6638       if (header_type == MUS_AIFC)
6639 	{
6640 	  const char *str;
6641 	  str = sndlib_format_to_aifc_name(new_format);
6642 	  lseek(fd, update_framples_location + 16, SEEK_SET);
6643 	  write_four_chars((uint8_t *)(hdrbuf + 0), (const uint8_t *)str);
6644 	  (*(uint8_t *)(hdrbuf + 4)) = 4; /* final pad null not accounted-for */
6645 	  write_four_chars((uint8_t *)(hdrbuf + 5), (const uint8_t *)str);
6646 	  (*(uint8_t *)(hdrbuf + 9)) = 0;
6647 	  header_write(fd, hdrbuf, 10);
6648 	}
6649       break;
6650 
6651     case MUS_RIFF:
6652     case MUS_RF64:
6653       lseek(fd, update_framples_location + 24, SEEK_SET);
6654       if (little_endian)
6655 	mus_lshort_to_char((uint8_t *)hdrbuf, sndlib_format_to_aiff_bits(new_format));
6656       else mus_bshort_to_char((uint8_t *)hdrbuf, sndlib_format_to_aiff_bits(new_format));
6657       header_write(fd, hdrbuf, 2);
6658       lseek(fd, update_framples_location + 10, SEEK_SET);
6659       switch (new_format)
6660 	{
6661 	case MUS_MULAW:
6662 	  fr = 7;
6663 	  break;
6664 
6665 	case MUS_ALAW:
6666 	  fr = 6;
6667 	  break;
6668 
6669 	case MUS_UBYTE:
6670 	case MUS_LSHORT: case MUS_L24INT: case MUS_LINT:
6671 	case MUS_BSHORT: case MUS_B24INT: case MUS_BINT:
6672 	  fr = 1;
6673 	  break;
6674 
6675 	case MUS_LFLOAT: case MUS_LDOUBLE:
6676 	case MUS_BFLOAT: case MUS_BDOUBLE:
6677 	  fr = 3;
6678 	  break;
6679 
6680 	default: fr = 0; break;
6681 	}
6682       if (little_endian)
6683 	mus_lshort_to_char((uint8_t *)hdrbuf, fr);
6684       else mus_bshort_to_char((uint8_t *)hdrbuf, fr);
6685       header_write(fd, hdrbuf, 2);
6686       break;
6687 
6688     default: break;
6689     }
6690   CLOSE(fd, filename);
6691   return(err);
6692 }
6693 
6694 
mus_header_change_location(const char * filename,mus_header_t type,mus_long_t new_location)6695 int mus_header_change_location(const char *filename, mus_header_t type, mus_long_t new_location)
6696 {
6697   /* only Next/Sun changeable in this regard */
6698   int err = MUS_NO_ERROR, fd;
6699   fd = mus_file_reopen_write(filename);
6700   if (fd == -1)
6701     return(mus_error(MUS_CANT_OPEN_FILE, "mus_header_change_location for %s failed: %s", filename, STRERROR(errno)));
6702   if (type == MUS_NEXT)
6703     {
6704       lseek(fd, 4L, SEEK_SET);
6705       mus_bint_to_char((uint8_t *)hdrbuf, new_location);
6706       header_write(fd, hdrbuf, 4);
6707     }
6708   CLOSE(fd, filename);
6709   return(err);
6710 }
6711 
6712 
mus_header_change_comment(const char * filename,mus_header_t type,const char * new_comment)6713 int mus_header_change_comment(const char *filename, mus_header_t type, const char *new_comment)
6714 {
6715   int err;
6716   err = mus_header_read(filename);
6717   if (err == MUS_NO_ERROR)
6718     {
6719       int fd;
6720       bool need_ripple = false;
6721       switch (type)
6722 	{
6723 	case MUS_IRCAM:
6724 	  {
6725 	    int len = 0;
6726 	    fd = mus_file_reopen_write(filename);
6727 	    lseek(fd, 16L, SEEK_SET);
6728 	    if (new_comment) len = strlen(new_comment);
6729 	    write_ircam_comment(fd, new_comment, len);
6730 	    CLOSE(fd, filename);
6731 	  }
6732 	  break;
6733 
6734 	case MUS_NEXT:
6735 	  fd = mus_file_reopen_write(filename);
6736 	  lseek(fd, 24L, SEEK_SET);
6737 	  if (!new_comment)
6738 	    write_next_comment(fd, new_comment, 0, data_location); /* erase old possibly */
6739 	  else
6740 	    {
6741 	      if ((comment_start != comment_end) &&
6742 		  ((int)(data_location - 24) >= (int)strlen(new_comment)))
6743 		write_next_comment(fd, new_comment, strlen(new_comment), data_location); /* there's room to overwrite old comment */
6744 	      else need_ripple = true;
6745 	    }
6746 	  CLOSE(fd, filename);
6747 	  break;
6748 
6749 	default:
6750 	  need_ripple = true;
6751 	  break;
6752 	}
6753       if (need_ripple)
6754 	{
6755 	  /* open temp, write header, copy data, replace original with temp */
6756 	  char *new_file;
6757 	  int ofd, ifd, len;
6758 	  mus_long_t loc;
6759 	  int64_t nbytes;
6760 	  uint8_t *buf;
6761 	  len = strlen(filename) + 5;
6762 	  new_file = (char *)malloc(len * sizeof(char));
6763 	  snprintf(new_file, len, "%s.tmp", filename);
6764 	  loc = mus_header_data_location();
6765 	  mus_write_header(new_file, header_type, srate, chans, data_size, sample_type, new_comment);
6766 	  ifd = mus_file_open_read(filename);
6767 	  lseek(ifd, loc, SEEK_SET);
6768 	  ofd = mus_file_reopen_write(new_file);
6769 	  lseek(ofd, 0L, SEEK_END);
6770 	  buf = (uint8_t *)calloc(8192, sizeof(uint8_t));
6771 	  while ((nbytes = read(ifd, buf, 8192))) header_write(ofd, buf, (int)nbytes);
6772 	  CLOSE(ifd, filename);
6773 	  CLOSE(ofd, new_file);
6774 	  free(buf);
6775 	  rename(new_file, filename);
6776 	  free(new_file);
6777 	}
6778     }
6779   return(err);
6780 }
6781 
6782 
mus_header_writable(mus_header_t type,mus_sample_t samp_type)6783 bool mus_header_writable(mus_header_t type, mus_sample_t samp_type) /* MUS_IGNORE_SAMPLE to ignore sample type for this call */
6784 {
6785   switch (type)
6786     {
6787     case MUS_NEXT:
6788       if (samp_type == MUS_UNKNOWN_SAMPLE) return(false);
6789       return(true);
6790       break;
6791 
6792     case MUS_NIST:
6793       if (samp_type == MUS_IGNORE_SAMPLE) return(true);
6794       switch (samp_type)
6795 	{
6796 	case MUS_BYTE: case MUS_BSHORT: case MUS_B24INT: case MUS_BINT:
6797 	case MUS_LSHORT: case MUS_L24INT: case MUS_LINT:
6798 	  return(true); break;
6799 	default:
6800 	  return(false); break;
6801 	}
6802       break;
6803 
6804     case MUS_AIFC:
6805       if (samp_type == MUS_IGNORE_SAMPLE) return(true);
6806       switch (samp_type)
6807 	{
6808 	case MUS_BSHORT: case MUS_B24INT: case MUS_BINT:
6809 	case MUS_BYTE: case MUS_MULAW: case MUS_ALAW:
6810 	case MUS_BFLOAT: case MUS_BDOUBLE: case MUS_UBYTE: case MUS_UBSHORT:
6811 	case MUS_LSHORT: case MUS_L24INT: case MUS_LINT:
6812 	  return(true);
6813 	  break;
6814 	default:
6815 	  return(false);
6816 	  break;
6817 	}
6818       break;
6819 
6820     case MUS_AIFF:
6821       if (samp_type == MUS_IGNORE_SAMPLE) return(true);
6822       switch (samp_type)
6823 	{
6824 	case MUS_BSHORT: case MUS_B24INT: case MUS_BINT: case MUS_BYTE:
6825 	  return(true);
6826 	  break;
6827 	default:
6828 	  return(false);
6829 	  break;
6830 	}
6831       break;
6832 
6833     case MUS_RIFF:
6834     case MUS_RF64:
6835       if (samp_type == MUS_IGNORE_SAMPLE) return(true);
6836       switch (samp_type)
6837 	{
6838 	case MUS_MULAW: case MUS_ALAW: case MUS_UBYTE: case MUS_LFLOAT:
6839 	case MUS_LSHORT: case MUS_L24INT: case MUS_LINT: case MUS_LDOUBLE:
6840 	  return(true);
6841 	  break;
6842 	default:
6843 	  return(false);
6844 	  break;
6845 	}
6846       break;
6847 
6848     case MUS_IRCAM:
6849       if (samp_type == MUS_IGNORE_SAMPLE) return(true);
6850       switch (samp_type)
6851 	{
6852 	case MUS_MULAW: case MUS_ALAW: case MUS_BSHORT: case MUS_BINT: case MUS_BFLOAT:
6853 	  return(true);
6854 	  break;
6855 	default:
6856 	  return(false);
6857 	  break;
6858 	}
6859       break;
6860 
6861     case MUS_CAFF:
6862       if (samp_type == MUS_IGNORE_SAMPLE) return(true);
6863       switch (samp_type)
6864 	{
6865 	case MUS_MULAW: case MUS_ALAW: case MUS_BYTE:
6866 	case MUS_LFLOAT: case MUS_LSHORT: case MUS_L24INT: case MUS_LINTN: case MUS_LDOUBLE:
6867 	case MUS_BFLOAT: case MUS_BSHORT: case MUS_B24INT: case MUS_BINTN: case MUS_BDOUBLE:
6868 	  return(true);
6869 	  break;
6870 	default:
6871 	  return(false);
6872 	  break;
6873 	}
6874       break;
6875 
6876     case MUS_RAW:
6877       return(true);
6878       break;
6879 
6880     default:
6881       return(false);
6882       break;
6883     }
6884   return(false);
6885 }
6886 
6887 
6888 static char aifc_format[5];
6889 
6890 /* try to give some info on sample types that aren't supported by sndlib */
mus_header_original_sample_type_name(int samp_type,mus_header_t type)6891 const char *mus_header_original_sample_type_name(int samp_type, mus_header_t type)
6892 {
6893   switch (type)
6894     {
6895     case MUS_NEXT:
6896       switch (samp_type)
6897 	{
6898 	case 0: return("unspecified");
6899 	case 8: return("indirect");
6900 	case 9: return("nested");
6901  	case 10: return("dsp_core");
6902 	case 11: return("dsp_data_8");
6903 	case 12: return("dsp_data_16");
6904  	case 13: return("dsp_data_24");
6905 	case 14: return("dsp_data_32");
6906 	case 16: return("display");
6907 	case 17: return("mulaw_squelch");
6908 	case 18: return("emphasized");
6909 	case 19: return("compressed");
6910 	case 20: return("compressed_emphasized");
6911 	case 21: return("dsp_commands");
6912 	case 22: return("dsp_commands_samples");
6913  	case 23: return("adpcm_g721");
6914 	case 24: return("adpcm_g722");
6915 	case 25: return("adpcm_g723");
6916 	case 26: return("adpcm_g723_5");
6917 	case 28: return("aes");
6918 	case 29: return("delat_mulaw_8");
6919  	}
6920       break;
6921 
6922     case MUS_AIFC:
6923     case MUS_CAFF:
6924       aifc_format[4] = 0;
6925 #if MUS_LITTLE_ENDIAN
6926       snprintf(aifc_format, 5, "%c%c%c%c", samp_type & 0xff, (samp_type >> 8) & 0xff, (samp_type >> 16) & 0xff, (samp_type >> 24) & 0xff);
6927 #else
6928       snprintf(aifc_format, 5, "%c%c%c%c", (samp_type >> 24) & 0xff, (samp_type >> 16) & 0xff, (samp_type >> 8) & 0xff, samp_type & 0xff);
6929 #endif
6930       return(aifc_format);
6931       break;
6932 
6933     case MUS_PVF:
6934       if (type_specifier == mus_char_to_uninterpreted_int((unsigned const char *)I_PVF2))
6935 	return("ascii text");
6936       break;
6937 
6938     case MUS_RIFF:
6939     case MUS_RF64:
6940       switch (samp_type)
6941 	{
6942 	case 2: return("ADPCM");
6943 	case 4: return("VSELP");
6944 	case 5: return("IBM_CVSD");
6945 	case 0x10: return("OKI_ADPCM");
6946 	case 0x11: return("DVI_ADPCM");
6947 	case 0x12: return("MediaSpace_ADPCM");
6948 	case 0x13: return("Sierra_ADPCM");
6949 	case 0x14: return("G723_ADPCM");
6950 	case 0x15: return("DIGISTD");
6951 	case 0x16: return("DIGIFIX");
6952 	case 0x17: return("Dialogic ADPCM");
6953 	case 0x18: return("Mediavision ADPCM");
6954 	case 0x19: return("HP cu codec");
6955 	case 0x20: return("Yamaha_ADPCM");
6956 	case 0x21: return("SONARC");
6957 	case 0x22: return("DSPGroup_TrueSpeech");
6958 	case 0x23: return("EchoSC1");
6959 	case 0x24: return("AudioFile_AF36");
6960 	case 0x25: return("APTX");
6961 	case 0x26: return("AudioFile_AF10");
6962 	case 0x27: return("prosody 1612");
6963 	case 0x28: return("lrc");
6964 	case 0x30: return("Dolby_Ac2");
6965 	case 0x31: return("GSM610");
6966 	case 0x32: return("MSN audio codec");
6967 	case 0x33: return("Antext_ADPCM");
6968 	case 0x34: return("Control_res_vqlpc");
6969 	case 0x35: return("DIGIREAL");
6970 	case 0x36: return("DIGIADPCM");
6971 	case 0x37: return("Control_res_cr10");
6972 	case 0x38: return("NMS_VBXADPCM");
6973 	case 0x39: return("oland rdac");
6974 	case 0x3a: return("echo sc3");
6975 	case 0x3b: return("Rockwell adpcm");
6976 	case 0x3c: return("Rockwell digitalk codec");
6977 	case 0x3d: return("Xebec");
6978 	case 0x40: return("G721_ADPCM");
6979 	case 0x41: return("G728 CELP");
6980 	case 0x42: return("MS G723");
6981 	case 0x50: return("MPEG");
6982 	case 0x52: return("RT24");
6983 	case 0x53: return("PAC");
6984 	case 0x55: return("Mpeg layer 3");
6985 	case 0x59: return("Lucent G723");
6986 	case 0x60: return("Cirrus");
6987 	case 0x61: return("ESS Tech pcm");
6988 	case 0x62: return("voxware ");
6989 	case 0x63: return("canopus atrac");
6990 	case 0x64: return("G726");
6991 	case 0x65: return("G722");
6992 	case 0x66: return("DSAT");
6993 	case 0x67: return("DSAT display");
6994 	case 0x69: return("voxware ");
6995 	case 0x70: return("voxware ac8 ");
6996 	case 0x71: return("voxware ac10 ");
6997 	case 0x72: return("voxware ac16");
6998 	case 0x73: return("voxware ac20");
6999 	case 0x74: return("voxware rt24");
7000 	case 0x75: return("voxware rt29");
7001 	case 0x76: return("voxware rt29hw");
7002 	case 0x77: return("voxware vr12 ");
7003 	case 0x78: return("voxware vr18");
7004 	case 0x79: return("voxware tq40");
7005 	case 0x80: return("softsound");
7006 	case 0x81: return("voxware tq60 ");
7007 	case 0x82: return("MS RT24");
7008 	case 0x83: return("G729A");
7009 	case 0x84: return("MVI_MVI2");
7010 	case 0x85: return("DF G726");
7011 	case 0x86: return("DF GSM610");
7012 	case 0x88: return("isaudio");
7013 	case 0x89: return("onlive");
7014 	case 0x91: return("sbc24");
7015 	case 0x92: return("dolby ac3 spdif");
7016 	case 0x97: return("zyxel adpcm");
7017 	case 0x98: return("philips lpcbb");
7018 	case 0x99: return("packed");
7019 	case 0x100: return("rhetorex adpcm");
7020 	case 0x101: return("Irat");
7021 	case 0x102: return("IBM_alaw?");
7022 	case 0x103: return("IBM_ADPCM?");
7023 	case 0x111: return("vivo G723");
7024 	case 0x112: return("vivo siren");
7025 	case 0x123: return("digital g273");
7026 	case 0x200: return("Creative_ADPCM");
7027 	case 0x202: return("Creative fastspeech 8");
7028 	case 0x203: return("Creative fastspeech 10");
7029 	case 0x220: return("quarterdeck");
7030 	case 0x300: return("FM_TOWNS_SND");
7031 	case 0x400: return("BTV digital");
7032 	case 0x680: return("VME vmpcm");
7033 	case 0x1000: return("OLIGSM");
7034 	case 0x1001: return("OLIADPCM");
7035 	case 0x1002: return("OLICELP");
7036 	case 0x1003: return("OLISBC");
7037 	case 0x1004: return("OLIOPR");
7038 	case 0x1100: return("LH codec");
7039 	case 0x1400: return("Norris");
7040 	case 0x1401: return("isaudio");
7041 	case 0x1500: return("Soundspace musicompression");
7042 	case 0x2000: return("DVM");
7043 	}
7044       break;
7045 
7046     default: break;
7047     }
7048   return("unknown"); /* NULL here isn't safe -- Sun segfaults */
7049 }
7050 
7051 
mus_header_no_header(const char * filename)7052 bool mus_header_no_header(const char *filename)
7053 {
7054   int fd;
7055   int64_t bytes;
7056   bool ok = false;
7057   fd = mus_file_open_read(filename);
7058   if (fd == -1)
7059     return(mus_error(MUS_CANT_OPEN_FILE, "mus_header: can't open %s: %s", filename, STRERROR(errno)));
7060   bytes = (int64_t)read(fd, hdrbuf, INITIAL_READ_SIZE);
7061   CLOSE(fd, filename);
7062   if (bytes > 4)
7063     ok = ((match_four_chars((uint8_t *)hdrbuf, I_DSND)) ||
7064 	  (match_four_chars((uint8_t *)hdrbuf, I_DECN)) ||
7065 	  (match_four_chars((uint8_t *)hdrbuf, I_FORM)) ||
7066 	  (match_four_chars((uint8_t *)hdrbuf, I_RIFF)) ||
7067 	  (match_four_chars((uint8_t *)hdrbuf, I_RIFX)) ||
7068 	  (match_four_chars((uint8_t *)hdrbuf, I_RF64)) ||
7069 	  (match_four_chars((uint8_t *)hdrbuf, I_caff)) ||
7070 	  (equal_big_or_little_endian((uint8_t *)hdrbuf, I_IRCAM_VAX)) ||
7071 	  (equal_big_or_little_endian((uint8_t *)hdrbuf, I_IRCAM_SUN)) ||
7072 	  (equal_big_or_little_endian((uint8_t *)hdrbuf, I_IRCAM_MIPS)) ||
7073 	  (equal_big_or_little_endian((uint8_t *)hdrbuf, I_IRCAM_NEXT)) ||
7074 	  (match_four_chars((uint8_t *)hdrbuf, I_NIST)) ||
7075 	  (match_four_chars((uint8_t *)hdrbuf, I_SOUN)) ||
7076 	  (match_four_chars((uint8_t *)hdrbuf, I_VOC0)) ||
7077 	  (match_four_chars((uint8_t *)hdrbuf, I_AVR_)) ||
7078 	  (mus_char_to_bshort((uint8_t *)hdrbuf) == 1336) ||
7079 	  (match_four_chars((uint8_t *)hdrbuf, I_ALaw)) ||
7080 	  (match_four_chars((uint8_t *)hdrbuf, I_GF1P)) ||
7081 	  (match_four_chars((uint8_t *)hdrbuf, I_DSIG)) ||
7082 	  (match_four_chars((uint8_t *)hdrbuf, I_GOLD)) ||
7083 	  (match_four_chars((uint8_t *)hdrbuf, I_Diam)) ||
7084 	  (match_four_chars((uint8_t *)hdrbuf, I_SRFS)) ||
7085 	  (match_four_chars((uint8_t *)hdrbuf, I_CSRE)) ||
7086 	  (match_four_chars((uint8_t *)hdrbuf, I_file)) ||
7087 	  ((hdrbuf[0] == 0xf0) && (hdrbuf[1] == 0x7e) && (hdrbuf[3] == 0x01)) ||
7088 	  (equal_big_or_little_endian((uint8_t *)(hdrbuf + 16), 0x00006a1a)) ||
7089 	  (match_four_chars((uint8_t *)hdrbuf, I_SPIB)) ||
7090 	  (match_four_chars((uint8_t *)hdrbuf, I_S___)) ||
7091 	  (match_four_chars((uint8_t *)hdrbuf, I_riff)) ||
7092 	  (match_four_chars((uint8_t *)hdrbuf, I_PVF1)) ||
7093 	  (match_four_chars((uint8_t *)hdrbuf, I_PVF2)) ||
7094 	  (match_four_chars((uint8_t *)hdrbuf, I_MThd)) ||
7095 	  (match_four_chars((uint8_t *)hdrbuf, I_SND_)) ||
7096 	  (match_four_chars((uint8_t *)hdrbuf, I_FSMt)) ||
7097 	  (match_four_chars((uint8_t *)hdrbuf, I_DDSF)) ||
7098 	  (match_four_chars((uint8_t *)hdrbuf, I_LM89)) ||
7099 	  (match_four_chars((uint8_t *)hdrbuf, I_SY85)) ||
7100 	  (match_four_chars((uint8_t *)hdrbuf, I_SY80)) ||
7101 	  (match_four_chars((uint8_t *)hdrbuf, I_PRAM)) ||
7102 	  (match_four_chars((uint8_t *)(hdrbuf + 35), I_UWFD)) ||
7103 	  (match_four_chars((uint8_t *)(hdrbuf + 76), I_SCRS)) ||
7104 	  (match_four_chars((uint8_t *)hdrbuf, I_covox)) ||
7105 	  (match_four_chars((uint8_t *)hdrbuf, I__PAF)) ||
7106 	  (match_four_chars((uint8_t *)hdrbuf, I_FAP_)) ||
7107 	  (match_four_chars((uint8_t *)hdrbuf, I_TWIN)) ||
7108 	  (match_four_chars((uint8_t *)hdrbuf, I_IMPS)) ||
7109 	  (match_four_chars((uint8_t *)hdrbuf, I_SMP1)) ||
7110 	  (match_four_chars((uint8_t *)hdrbuf, I_Maui)) ||
7111 	  (match_four_chars((uint8_t *)hdrbuf, I_SDIF)) ||
7112 	  (match_four_chars((uint8_t *)hdrbuf, I_ajkg))
7113 #if G7XX
7114 	  || (match_four_chars((uint8_t *)hdrbuf, I_NVF_))
7115 #endif
7116 	  );
7117   return(!ok);
7118 }
7119 
7120 
mus_header_set_aiff_loop_info(int * data)7121 void mus_header_set_aiff_loop_info(int *data)
7122 {
7123   /* include modes */
7124   if (data)
7125     {
7126       loop_starts[0] = data[0];
7127       loop_ends[0] = data[1];
7128       loop_starts[1] = data[2];
7129       loop_ends[1] = data[3];
7130       base_note = data[4];
7131       base_detune = data[5];
7132       loop_modes[0] = data[6];
7133       loop_modes[1] = data[7];
7134     }
7135   else
7136     {
7137       loop_modes[0] = 0;
7138       loop_modes[1] = 0;
7139     }
7140 }
7141 
7142 
mus_is_header_type(int n)7143 bool mus_is_header_type(int n)
7144 {
7145   switch (n)
7146     {
7147     case MUS_NEXT: case MUS_AIFC: case MUS_RIFF: case MUS_RF64: case MUS_BICSF: case MUS_NIST:
7148     case MUS_INRS: case MUS_ESPS: case MUS_SVX: case MUS_VOC: case MUS_SNDT: case MUS_RAW: case MUS_SOX:
7149     case MUS_SMP: case MUS_AVR: case MUS_IRCAM: case MUS_SD1: case MUS_SPPACK: case MUS_MUS10:
7150     case MUS_HCOM: case MUS_PSION: case MUS_MAUD: case MUS_IEEE: case MUS_MATLAB: case MUS_ADC:
7151     case MUS_MIDI: case MUS_SOUNDFONT: case MUS_GRAVIS: case MUS_COMDISCO: case MUS_GOLDWAVE:
7152     case MUS_SRFS: case MUS_MIDI_SAMPLE_DUMP: case MUS_DIAMONDWARE: case MUS_ADF: case MUS_SBSTUDIOII:
7153     case MUS_DELUSION: case MUS_FARANDOLE: case MUS_SAMPLE_DUMP: case MUS_ULTRATRACKER:
7154     case MUS_YAMAHA_SY85: case MUS_YAMAHA_TX16W: case MUS_DIGIPLAYER: case MUS_COVOX: case MUS_AVI:
7155     case MUS_OMF: case MUS_QUICKTIME: case MUS_ASF: case MUS_YAMAHA_SY99: case MUS_KURZWEIL_2000:
7156     case MUS_AIFF: case MUS_PAF: case MUS_CSL: case MUS_FILE_SAMP: case MUS_PVF: case MUS_SOUNDFORGE:
7157     case MUS_TWINVQ: case MUS_AKAI4: case MUS_IMPULSETRACKER: case MUS_KORG: case MUS_CAFF:
7158     case MUS_MAUI: case MUS_SDIF: case MUS_OGG: case MUS_FLAC: case MUS_SPEEX: case MUS_MPEG:
7159     case MUS_SHORTEN: case MUS_TTA: case MUS_WAVPACK:
7160 #if G7XX
7161     case MUS_NVF:
7162 #endif
7163       return(true);
7164       break;
7165     }
7166   return(false);
7167 }
7168 
7169 
mus_is_sample_type(int n)7170 bool mus_is_sample_type(int n)
7171 {
7172   switch (n)
7173     {
7174     case MUS_BSHORT: case MUS_MULAW: case MUS_BYTE: case MUS_BFLOAT: case MUS_BINT: case MUS_ALAW:
7175     case MUS_UBYTE: case MUS_B24INT: case MUS_BDOUBLE: case MUS_LSHORT: case MUS_LINT: case MUS_LFLOAT:
7176     case MUS_LDOUBLE: case MUS_UBSHORT: case MUS_ULSHORT: case MUS_L24INT: case MUS_BINTN: case MUS_LINTN:
7177     case MUS_BFLOAT_UNSCALED: case MUS_LFLOAT_UNSCALED: case MUS_BDOUBLE_UNSCALED: case MUS_LDOUBLE_UNSCALED:
7178       return(true);
7179       break;
7180     }
7181   return(false);
7182 }
7183 
7184 
7185