Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

7086 linhas
245KB

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