wav.c
上传用户:shw771010
上传日期:2022-01-05
资源大小:991k
文件大小:57k
源码类别:

Audio

开发平台:

Unix_Linux

  1. /*
  2. ** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
  3. ** Copyright (C) 2004-2005 David Viens <davidv@plogue.com>
  4. **
  5. ** This program is free software; you can redistribute it and/or modify
  6. ** it under the terms of the GNU Lesser General Public License as published by
  7. ** the Free Software Foundation; either version 2.1 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. ** GNU Lesser General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU Lesser General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  18. */
  19. #include "sfconfig.h"
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <ctype.h>
  24. #include <time.h>
  25. #include <inttypes.h>
  26. #include "sndfile.h"
  27. #include "sfendian.h"
  28. #include "common.h"
  29. #include "wav_w64.h"
  30. /*------------------------------------------------------------------------------
  31.  * Macros to handle big/little endian issues.
  32.  */
  33. #define RIFF_MARKER  (MAKE_MARKER ('R', 'I', 'F', 'F'))
  34. #define RIFX_MARKER  (MAKE_MARKER ('R', 'I', 'F', 'X'))
  35. #define WAVE_MARKER  (MAKE_MARKER ('W', 'A', 'V', 'E'))
  36. #define fmt_MARKER  (MAKE_MARKER ('f', 'm', 't', ' '))
  37. #define data_MARKER  (MAKE_MARKER ('d', 'a', 't', 'a'))
  38. #define fact_MARKER  (MAKE_MARKER ('f', 'a', 'c', 't'))
  39. #define PEAK_MARKER  (MAKE_MARKER ('P', 'E', 'A', 'K'))
  40. #define cue_MARKER  (MAKE_MARKER ('c', 'u', 'e', ' '))
  41. #define LIST_MARKER  (MAKE_MARKER ('L', 'I', 'S', 'T'))
  42. #define slnt_MARKER  (MAKE_MARKER ('s', 'l', 'n', 't'))
  43. #define wavl_MARKER  (MAKE_MARKER ('w', 'a', 'v', 'l'))
  44. #define INFO_MARKER  (MAKE_MARKER ('I', 'N', 'F', 'O'))
  45. #define plst_MARKER  (MAKE_MARKER ('p', 'l', 's', 't'))
  46. #define adtl_MARKER  (MAKE_MARKER ('a', 'd', 't', 'l'))
  47. #define labl_MARKER  (MAKE_MARKER ('l', 'a', 'b', 'l'))
  48. #define ltxt_MARKER  (MAKE_MARKER ('l', 't', 'x', 't'))
  49. #define note_MARKER  (MAKE_MARKER ('n', 'o', 't', 'e'))
  50. #define smpl_MARKER  (MAKE_MARKER ('s', 'm', 'p', 'l'))
  51. #define bext_MARKER  (MAKE_MARKER ('b', 'e', 'x', 't'))
  52. #define iXML_MARKER  (MAKE_MARKER ('i', 'X', 'M', 'L'))
  53. #define levl_MARKER  (MAKE_MARKER ('l', 'e', 'v', 'l'))
  54. #define MEXT_MARKER  (MAKE_MARKER ('M', 'E', 'X', 'T'))
  55. #define DISP_MARKER  (MAKE_MARKER ('D', 'I', 'S', 'P'))
  56. #define acid_MARKER  (MAKE_MARKER ('a', 'c', 'i', 'd'))
  57. #define strc_MARKER  (MAKE_MARKER ('s', 't', 'r', 'c'))
  58. #define PAD_MARKER  (MAKE_MARKER ('P', 'A', 'D', ' '))
  59. #define afsp_MARKER  (MAKE_MARKER ('a', 'f', 's', 'p'))
  60. #define clm_MARKER  (MAKE_MARKER ('c', 'l', 'm', ' '))
  61. #define elmo_MARKER  (MAKE_MARKER ('e', 'l', 'm', 'o'))
  62. #define cart_MARKER  (MAKE_MARKER ('c', 'a', 'r', 't'))
  63. #define exif_MARKER  (MAKE_MARKER ('e', 'x', 'i', 'f'))
  64. #define ever_MARKER  (MAKE_MARKER ('e', 'v', 'e', 'r'))
  65. #define etim_MARKER  (MAKE_MARKER ('e', 't', 'i', 'm'))
  66. #define ecor_MARKER  (MAKE_MARKER ('e', 'c', 'o', 'r'))
  67. #define emdl_MARKER  (MAKE_MARKER ('e', 'm', 'd', 'l'))
  68. #define emnt_MARKER  (MAKE_MARKER ('e', 'm', 'n', 't'))
  69. #define erel_MARKER  (MAKE_MARKER ('e', 'r', 'e', 'l'))
  70. #define eucm_MARKER  (MAKE_MARKER ('e', 'u', 'c', 'm'))
  71. #define ISFT_MARKER  (MAKE_MARKER ('I', 'S', 'F', 'T'))
  72. #define ICRD_MARKER  (MAKE_MARKER ('I', 'C', 'R', 'D'))
  73. #define ICOP_MARKER  (MAKE_MARKER ('I', 'C', 'O', 'P'))
  74. #define IARL_MARKER  (MAKE_MARKER ('I', 'A', 'R', 'L'))
  75. #define IART_MARKER  (MAKE_MARKER ('I', 'A', 'R', 'T'))
  76. #define INAM_MARKER  (MAKE_MARKER ('I', 'N', 'A', 'M'))
  77. #define IENG_MARKER  (MAKE_MARKER ('I', 'E', 'N', 'G'))
  78. #define IART_MARKER  (MAKE_MARKER ('I', 'A', 'R', 'T'))
  79. #define ICOP_MARKER  (MAKE_MARKER ('I', 'C', 'O', 'P'))
  80. #define IPRD_MARKER  (MAKE_MARKER ('I', 'P', 'R', 'D'))
  81. #define ISRC_MARKER  (MAKE_MARKER ('I', 'S', 'R', 'C'))
  82. #define ISBJ_MARKER  (MAKE_MARKER ('I', 'S', 'B', 'J'))
  83. #define ICMT_MARKER  (MAKE_MARKER ('I', 'C', 'M', 'T'))
  84. /* Weird WAVPACK marker which can show up at the start of the DATA section. */
  85. #define wvpk_MARKER (MAKE_MARKER ('w', 'v', 'p', 'k'))
  86. #define OggS_MARKER (MAKE_MARKER ('O', 'g', 'g', 'S'))
  87. #define WAV_PEAK_CHUNK_SIZE(ch)  (2 * sizeof (int) + ch * (sizeof (float) + sizeof (int)))
  88. #define WAV_BEXT_MIN_CHUNK_SIZE 602
  89. #define WAV_BEXT_MAX_CHUNK_SIZE (10 * 1024)
  90. enum
  91. { HAVE_RIFF = 0x01,
  92. HAVE_WAVE = 0x02,
  93. HAVE_fmt = 0x04,
  94. HAVE_fact = 0x08,
  95. HAVE_PEAK = 0x10,
  96. HAVE_data = 0x20,
  97. HAVE_other = 0x80000000
  98. } ;
  99. /*  known WAVEFORMATEXTENSIBLE GUIDS  */
  100. static const EXT_SUBFORMAT MSGUID_SUBTYPE_PCM =
  101. { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
  102. } ;
  103. static const EXT_SUBFORMAT MSGUID_SUBTYPE_MS_ADPCM =
  104. { 0x00000002, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
  105. } ;
  106. static const EXT_SUBFORMAT MSGUID_SUBTYPE_IEEE_FLOAT =
  107. { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
  108. } ;
  109. static const EXT_SUBFORMAT MSGUID_SUBTYPE_ALAW =
  110. { 0x00000006, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
  111. } ;
  112. static const EXT_SUBFORMAT MSGUID_SUBTYPE_MULAW =
  113. { 0x00000007, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
  114. } ;
  115. /*
  116. ** the next two are from
  117. ** http://dream.cs.bath.ac.uk/researchdev/wave-ex/bformat.html
  118. */
  119. static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM =
  120. { 0x00000001, 0x0721, 0x11d3, { 0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 }
  121. } ;
  122. static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT =
  123. { 0x00000003, 0x0721, 0x11d3, { 0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 }
  124. } ;
  125. #if 0
  126. /* maybe interesting one day to read the following through sf_read_raw */
  127. /* http://www.bath.ac.uk/~masrwd/pvocex/pvocex.html */
  128. static const EXT_SUBFORMAT MSGUID_SUBTYPE_PVOCEX =
  129. { 0x8312B9C2, 0x2E6E, 0x11d4, { 0xA8, 0x24, 0xDE, 0x5B, 0x96, 0xC3, 0xAB, 0x21 }
  130. } ;
  131. #endif
  132. /*------------------------------------------------------------------------------
  133. ** Private static functions.
  134. */
  135. static int wav_read_header  (SF_PRIVATE *psf, int *blockalign, int *framesperblock) ;
  136. static int wav_write_header (SF_PRIVATE *psf, int calc_length) ;
  137. static int wav_write_tailer (SF_PRIVATE *psf) ;
  138. static void wav_write_strings (SF_PRIVATE *psf, int location) ;
  139. static int wav_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
  140. static int wav_close (SF_PRIVATE *psf) ;
  141. static int  wav_subchunk_parse  (SF_PRIVATE *psf, int chunk) ;
  142. static int  exif_subchunk_parse  (SF_PRIVATE *psf, unsigned int length) ;
  143. static int wav_read_smpl_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
  144. static int wav_read_acid_chunk (SF_PRIVATE *psf, unsigned int chunklen) ;
  145. /*------------------------------------------------------------------------------
  146. ** Public function.
  147. */
  148. int
  149. wav_open  (SF_PRIVATE *psf)
  150. { WAV_PRIVATE * wpriv ;
  151. int format, subformat, error, blockalign = 0, framesperblock = 0 ;
  152. if ((wpriv = calloc (1, sizeof (WAV_PRIVATE))) == NULL)
  153. return SFE_MALLOC_FAILED ;
  154. psf->container_data = wpriv ;
  155. wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ;
  156. psf->str_flags = SF_STR_ALLOW_START | SF_STR_ALLOW_END ;
  157. if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
  158. { if ((error = wav_read_header (psf, &blockalign, &framesperblock)))
  159. return error ;
  160. } ;
  161. subformat = SF_CODEC (psf->sf.format) ;
  162. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  163. { if (psf->is_pipe)
  164. return SFE_NO_PIPE_WRITE ;
  165. wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ;
  166. format = SF_CONTAINER (psf->sf.format) ;
  167. if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX)
  168. return SFE_BAD_OPEN_FORMAT ;
  169. psf->blockwidth = psf->bytewidth * psf->sf.channels ;
  170. /* RIFF WAVs are little-endian, RIFX WAVs are big-endian, default to little */
  171. psf->endian = SF_ENDIAN (psf->sf.format) ;
  172. if (CPU_IS_BIG_ENDIAN && psf->endian == SF_ENDIAN_CPU)
  173. psf->endian = SF_ENDIAN_BIG ;
  174. else if (psf->endian != SF_ENDIAN_BIG)
  175. psf->endian = SF_ENDIAN_LITTLE ;
  176. if (psf->file.mode != SFM_RDWR || psf->filelength < 44)
  177. { psf->filelength = 0 ;
  178. psf->datalength = 0 ;
  179. psf->dataoffset = 0 ;
  180. psf->sf.frames = 0 ;
  181. } ;
  182. if (subformat == SF_FORMAT_IMA_ADPCM || subformat == SF_FORMAT_MS_ADPCM)
  183. { blockalign = wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
  184. framesperblock = -1 ; /* Corrected later. */
  185. } ;
  186. /* By default, add the peak chunk to floating point files. Default behaviour
  187. ** can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
  188. */
  189. if (psf->file.mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
  190. { if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
  191. return SFE_MALLOC_FAILED ;
  192. psf->peak_info->peak_loc = SF_PEAK_START ;
  193. } ;
  194. psf->write_header = wav_write_header ;
  195. } ;
  196. psf->container_close = wav_close ;
  197. psf->command = wav_command ;
  198. switch (subformat)
  199. { case SF_FORMAT_PCM_U8 :
  200. case SF_FORMAT_PCM_16 :
  201. case SF_FORMAT_PCM_24 :
  202. case SF_FORMAT_PCM_32 :
  203. error = pcm_init (psf) ;
  204. break ;
  205. case SF_FORMAT_ULAW :
  206. error = ulaw_init (psf) ;
  207. break ;
  208. case SF_FORMAT_ALAW :
  209. error = alaw_init (psf) ;
  210. break ;
  211. /* Lite remove start */
  212. case SF_FORMAT_FLOAT :
  213. error = float32_init (psf) ;
  214. break ;
  215. case SF_FORMAT_DOUBLE :
  216. error = double64_init (psf) ;
  217. break ;
  218. case SF_FORMAT_IMA_ADPCM :
  219. error = wav_w64_ima_init (psf, blockalign, framesperblock) ;
  220. break ;
  221. case SF_FORMAT_MS_ADPCM :
  222. error = wav_w64_msadpcm_init (psf, blockalign, framesperblock) ;
  223. break ;
  224. case SF_FORMAT_G721_32 :
  225. error = g72x_init (psf) ;
  226. break ;
  227. /* Lite remove end */
  228. case SF_FORMAT_GSM610 :
  229. error = gsm610_init (psf) ;
  230. break ;
  231. default :  return SFE_UNIMPLEMENTED ;
  232. } ;
  233. if (psf->file.mode == SFM_WRITE || (psf->file.mode == SFM_RDWR && psf->filelength == 0))
  234. return psf->write_header (psf, SF_FALSE) ;
  235. return error ;
  236. } /* wav_open */
  237. /*=========================================================================
  238. ** Private functions.
  239. */
  240. static int
  241. wav_read_header  (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
  242. { WAV_PRIVATE *wpriv ;
  243. WAV_FMT *wav_fmt ;
  244. FACT_CHUNK fact_chunk ;
  245. unsigned dword = 0, marker, RIFFsize, done = 0 ;
  246. int parsestage = 0, error, format = 0 ;
  247. char *cptr ;
  248. if (psf->filelength > SF_PLATFORM_S64 (0xffffffff))
  249. psf_log_printf (psf, "Warning : filelength > 0xffffffff. This is bad!!!!n") ;
  250. if ((wpriv = psf->container_data) == NULL)
  251. return SFE_INTERNAL ;
  252. wav_fmt = &wpriv->wav_fmt ;
  253. /* Set position to start of file to begin reading header. */
  254. psf_binheader_readf (psf, "p", 0) ;
  255. while (! done)
  256. { psf_binheader_readf (psf, "m", &marker) ;
  257. switch (marker)
  258. { case RIFF_MARKER :
  259. case RIFX_MARKER :
  260. if (parsestage)
  261. return SFE_WAV_NO_RIFF ;
  262. parsestage |= HAVE_RIFF ;
  263. /* RIFX signifies big-endian format for all header and data
  264. ** to prevent lots of code copying here, we'll set the psf->rwf_endian
  265. ** flag once here, and never specify endian-ness for all other header ops
  266. */
  267. if (marker == RIFF_MARKER)
  268. psf->rwf_endian = SF_ENDIAN_LITTLE ;
  269. else
  270. psf->rwf_endian = SF_ENDIAN_BIG ;
  271. psf_binheader_readf (psf, "4", &RIFFsize) ;
  272. if (psf->fileoffset > 0 && psf->filelength > RIFFsize + 8)
  273. { /* Set file length. */
  274. psf->filelength = RIFFsize + 8 ;
  275. if (marker == RIFF_MARKER)
  276. psf_log_printf (psf, "RIFF : %un", RIFFsize) ;
  277. else
  278. psf_log_printf (psf, "RIFX : %un", RIFFsize) ;
  279. }
  280. else if (psf->filelength < RIFFsize + 2 * SIGNED_SIZEOF (dword))
  281. { if (marker == RIFF_MARKER)
  282. psf_log_printf (psf, "RIFF : %u (should be %D)n", RIFFsize, psf->filelength - 2 * SIGNED_SIZEOF (dword)) ;
  283. else
  284. psf_log_printf (psf, "RIFX : %u (should be %D)n", RIFFsize, psf->filelength - 2 * SIGNED_SIZEOF (dword)) ;
  285. RIFFsize = dword ;
  286. }
  287. else
  288. { if (marker == RIFF_MARKER)
  289. psf_log_printf (psf, "RIFF : %un", RIFFsize) ;
  290. else
  291. psf_log_printf (psf, "RIFX : %un", RIFFsize) ;
  292. } ;
  293. break ;
  294. case WAVE_MARKER :
  295. if ((parsestage & HAVE_RIFF) != HAVE_RIFF)
  296. return SFE_WAV_NO_WAVE ;
  297. parsestage |= HAVE_WAVE ;
  298. psf_log_printf (psf, "WAVEn") ;
  299. break ;
  300. case fmt_MARKER :
  301. if ((parsestage & (HAVE_RIFF | HAVE_WAVE)) != (HAVE_RIFF | HAVE_WAVE))
  302. return SFE_WAV_NO_FMT ;
  303. /* If this file has a SECOND fmt chunk, I don't want to know about it. */
  304. if (parsestage & HAVE_fmt)
  305. break ;
  306. parsestage |= HAVE_fmt ;
  307. psf_binheader_readf (psf, "4", &dword) ;
  308. psf_log_printf (psf, "fmt  : %dn", dword) ;
  309. if ((error = wav_w64_read_fmt_chunk (psf, dword)))
  310. return error ;
  311. format = wav_fmt->format ;
  312. break ;
  313. case data_MARKER :
  314. if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt))
  315. return SFE_WAV_NO_DATA ;
  316. if (psf->file.mode == SFM_RDWR && (parsestage & HAVE_other) != 0)
  317. return SFE_RDWR_BAD_HEADER ;
  318. parsestage |= HAVE_data ;
  319. psf_binheader_readf (psf, "4", &dword) ;
  320. psf->datalength = dword ;
  321. psf->dataoffset = psf_ftell (psf) ;
  322. if (psf->dataoffset > 0)
  323. { if (dword == 0 && RIFFsize == 8 && psf->filelength > 44)
  324. { psf_log_printf (psf, "*** Looks like a WAV file which wasn't closed properly. Fixing it.n") ;
  325. psf->datalength = psf->filelength - psf->dataoffset ;
  326. } ;
  327. if (psf->datalength > psf->filelength - psf->dataoffset)
  328. { psf_log_printf (psf, "data : %D (should be %D)n", psf->datalength, psf->filelength - psf->dataoffset) ;
  329. psf->datalength = psf->filelength - psf->dataoffset ;
  330. }
  331. else
  332. psf_log_printf (psf, "data : %Dn", psf->datalength) ;
  333. /* Only set dataend if there really is data at the end. */
  334. if (psf->datalength + psf->dataoffset < psf->filelength)
  335. psf->dataend = psf->datalength + psf->dataoffset ;
  336. if (format == WAVE_FORMAT_MS_ADPCM && psf->datalength % 2)
  337. { psf->datalength ++ ;
  338. psf_log_printf (psf, "*** Data length odd. Increasing it by 1.n") ;
  339. } ;
  340. } ;
  341. if (! psf->sf.seekable || psf->dataoffset < 0)
  342. break ;
  343. /* Seek past data and continue reading header. */
  344. psf_fseek (psf, psf->datalength, SEEK_CUR) ;
  345. if (psf_ftell (psf) != psf->datalength + psf->dataoffset)
  346. psf_log_printf (psf, "*** psf_fseek past end error ***n") ;
  347. break ;
  348. case fact_MARKER :
  349. if ((parsestage & (HAVE_RIFF | HAVE_WAVE)) != (HAVE_RIFF | HAVE_WAVE))
  350. return SFE_WAV_BAD_FACT ;
  351. parsestage |= HAVE_fact ;
  352. if ((parsestage & HAVE_fmt) != HAVE_fmt)
  353. psf_log_printf (psf, "*** Should have 'fmt ' chunk before 'fact'n") ;
  354. psf_binheader_readf (psf, "44", &dword, & (fact_chunk.frames)) ;
  355. if (dword > SIGNED_SIZEOF (fact_chunk))
  356. psf_binheader_readf (psf, "j", (int) (dword - SIGNED_SIZEOF (fact_chunk))) ;
  357. if (dword)
  358. psf_log_printf (psf, "%M : %dn", marker, dword) ;
  359. else
  360. psf_log_printf (psf, "%M : %d (should not be zero)n", marker, dword) ;
  361. psf_log_printf (psf, "  frames  : %dn", fact_chunk.frames) ;
  362. break ;
  363. case PEAK_MARKER :
  364. if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt))
  365. return SFE_WAV_PEAK_B4_FMT ;
  366. parsestage |= HAVE_PEAK ;
  367. psf_binheader_readf (psf, "4", &dword) ;
  368. psf_log_printf (psf, "%M : %dn", marker, dword) ;
  369. if (dword != WAV_PEAK_CHUNK_SIZE (psf->sf.channels))
  370. { psf_binheader_readf (psf, "j", dword) ;
  371. psf_log_printf (psf, "*** File PEAK chunk size doesn't fit with number of channels (%d).n", psf->sf.channels) ;
  372. return SFE_WAV_BAD_PEAK ;
  373. } ;
  374. if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
  375. return SFE_MALLOC_FAILED ;
  376. /* read in rest of PEAK chunk. */
  377. psf_binheader_readf (psf, "44", & (psf->peak_info->version), & (psf->peak_info->timestamp)) ;
  378. if (psf->peak_info->version != 1)
  379. psf_log_printf (psf, "  version    : %d *** (should be version 1)n", psf->peak_info->version) ;
  380. else
  381. psf_log_printf (psf, "  version    : %dn", psf->peak_info->version) ;
  382. psf_log_printf (psf, "  time stamp : %dn", psf->peak_info->timestamp) ;
  383. psf_log_printf (psf, "    Ch   Position       Valuen") ;
  384. cptr = psf->u.cbuf ;
  385. for (dword = 0 ; dword < (unsigned) psf->sf.channels ; dword++)
  386. { float value ;
  387. unsigned int position ;
  388. psf_binheader_readf (psf, "f4", &value, &position) ;
  389. psf->peak_info->peaks [dword].value = value ;
  390. psf->peak_info->peaks [dword].position = position ;
  391. snprintf (cptr, sizeof (psf->u.cbuf), "    %2d   %-12" PRId64 "   %gn",
  392. dword, psf->peak_info->peaks [dword].position, psf->peak_info->peaks [dword].value) ;
  393. cptr [sizeof (psf->u.cbuf) - 1] = 0 ;
  394. psf_log_printf (psf, "%s", cptr) ;
  395. } ;
  396. psf->peak_info->peak_loc = ((parsestage & HAVE_data) == 0) ? SF_PEAK_START : SF_PEAK_END ;
  397. break ;
  398. case cue_MARKER :
  399. parsestage |= HAVE_other ;
  400. { unsigned bytesread, cue_count ;
  401. int id, position, chunk_id, chunk_start, block_start, offset ;
  402. bytesread = psf_binheader_readf (psf, "44", &dword, &cue_count) ;
  403. bytesread -= 4 ; /* Remove bytes for first dword. */
  404. psf_log_printf (psf, "%M : %un", marker, dword) ;
  405. if (cue_count > 10)
  406. { psf_log_printf (psf, "  Count : %d (skipping)n", cue_count) ;
  407. psf_binheader_readf (psf, "j", cue_count * 24) ;
  408. break ;
  409. } ;
  410. psf_log_printf (psf, "  Count : %dn", cue_count) ;
  411. while (cue_count)
  412. { bytesread += psf_binheader_readf (psf, "444444", &id, &position,
  413. &chunk_id, &chunk_start, &block_start, &offset) ;
  414. psf_log_printf (psf, "   Cue ID : %2d"
  415.  "  Pos : %5u  Chunk : %M"
  416.  "  Chk Start : %d  Blk Start : %d"
  417.  "  Offset : %5dn",
  418. id, position, chunk_id, chunk_start, block_start, offset) ;
  419. cue_count -- ;
  420. } ;
  421. if (bytesread != dword)
  422. { psf_log_printf (psf, "**** Chunk size weirdness (%d != %d)n", dword, bytesread) ;
  423. psf_binheader_readf (psf, "j", dword - bytesread) ;
  424. } ;
  425. } ;
  426. break ;
  427. case smpl_MARKER :
  428. parsestage |= HAVE_other ;
  429. psf_binheader_readf (psf, "4", &dword) ;
  430. psf_log_printf (psf, "smpl : %un", dword) ;
  431. if ((error = wav_read_smpl_chunk (psf, dword)))
  432. return error ;
  433. break ;
  434. case acid_MARKER :
  435. parsestage |= HAVE_other ;
  436. psf_binheader_readf (psf, "4", &dword) ;
  437. psf_log_printf (psf, "acid : %un", dword) ;
  438. if ((error = wav_read_acid_chunk (psf, dword)))
  439. return error ;
  440. break ;
  441. case INFO_MARKER :
  442. case LIST_MARKER :
  443. parsestage |= HAVE_other ;
  444. if ((error = wav_subchunk_parse (psf, marker)) != 0)
  445. return error ;
  446. break ;
  447. case bext_MARKER :
  448. /*
  449. The 'bext' chunk can actually be updated, so don't need to set this.
  450. parsestage |= HAVE_other ;
  451. */
  452. psf_binheader_readf (psf, "4", &dword) ;
  453. if ((error = wav_read_bext_chunk (psf, dword)))
  454. return error ;
  455. break ;
  456. case PAD_MARKER :
  457. /*
  458. We can eat into a 'PAD ' chunk if we need to.
  459. parsestage |= HAVE_other ;
  460. */
  461. psf_binheader_readf (psf, "4", &dword) ;
  462. psf_log_printf (psf, "%M : %un", marker, dword) ;
  463. dword += (dword & 1) ;
  464. psf_binheader_readf (psf, "j", dword) ;
  465. break ;
  466. case iXML_MARKER : /* See http://en.wikipedia.org/wiki/IXML */
  467. case strc_MARKER : /* Multiple of 32 bytes. */
  468. case afsp_MARKER :
  469. case clm_MARKER :
  470. case elmo_MARKER :
  471. case cart_MARKER :
  472. case levl_MARKER :
  473. case plst_MARKER :
  474. case DISP_MARKER :
  475. case MEXT_MARKER :
  476. parsestage |= HAVE_other ;
  477. psf_binheader_readf (psf, "4", &dword) ;
  478. psf_log_printf (psf, "%M : %un", marker, dword) ;
  479. dword += (dword & 1) ;
  480. psf_binheader_readf (psf, "j", dword) ;
  481. break ;
  482. default :
  483. parsestage |= HAVE_other ;
  484. if (psf_isprint ((marker >> 24) & 0xFF) && psf_isprint ((marker >> 16) & 0xFF)
  485. && psf_isprint ((marker >> 8) & 0xFF) && psf_isprint (marker & 0xFF))
  486. { psf_binheader_readf (psf, "4", &dword) ;
  487. psf_log_printf (psf, "*** %M : %d (unknown marker)n", marker, dword) ;
  488. psf_binheader_readf (psf, "j", dword) ;
  489. break ;
  490. } ;
  491. if (psf_ftell (psf) & 0x03)
  492. { psf_log_printf (psf, "  Unknown chunk marker at position %d. Resynching.n", dword - 4) ;
  493. psf_binheader_readf (psf, "j", -3) ;
  494. break ;
  495. } ;
  496. psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D. Exiting parser.n", marker, psf_ftell (psf) - 4) ;
  497. done = SF_TRUE ;
  498. break ;
  499. } ; /* switch (dword) */
  500. if (! psf->sf.seekable && (parsestage & HAVE_data))
  501. break ;
  502. if (psf_ftell (psf) >= psf->filelength - SIGNED_SIZEOF (dword))
  503. { psf_log_printf (psf, "Endn") ;
  504. break ;
  505. } ;
  506. } ; /* while (1) */
  507. if (psf->dataoffset <= 0)
  508. return SFE_WAV_NO_DATA ;
  509. /* WAVs can be little or big endian */
  510. psf->endian = psf->rwf_endian ;
  511. psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
  512. if (psf->is_pipe == 0)
  513. { /*
  514. ** Check for 'wvpk' at the start of the DATA section. Not able to
  515. ** handle this.
  516. */
  517. psf_binheader_readf (psf, "4", &marker) ;
  518. if (marker == wvpk_MARKER || marker == OggS_MARKER)
  519. return SFE_WAV_WVPK_DATA ;
  520. } ;
  521. /* Seek to start of DATA section. */
  522. psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
  523. if (psf->blockwidth)
  524. { if (psf->filelength - psf->dataoffset < psf->datalength)
  525. psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
  526. else
  527. psf->sf.frames = psf->datalength / psf->blockwidth ;
  528. } ;
  529. switch (format)
  530. { case WAVE_FORMAT_EXTENSIBLE :
  531. if (psf->sf.format == (SF_FORMAT_WAVEX | SF_FORMAT_MS_ADPCM))
  532. { *blockalign = wav_fmt->msadpcm.blockalign ;
  533. *framesperblock = wav_fmt->msadpcm.samplesperblock ;
  534. } ;
  535. break ;
  536. case WAVE_FORMAT_PCM :
  537. psf->sf.format = SF_FORMAT_WAV | u_bitwidth_to_subformat (psf->bytewidth * 8) ;
  538. break ;
  539. case WAVE_FORMAT_MULAW :
  540. case IBM_FORMAT_MULAW :
  541. psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ULAW) ;
  542. break ;
  543. case WAVE_FORMAT_ALAW :
  544. case IBM_FORMAT_ALAW :
  545. psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ALAW) ;
  546. break ;
  547. case WAVE_FORMAT_MS_ADPCM :
  548. psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM) ;
  549. *blockalign = wav_fmt->msadpcm.blockalign ;
  550. *framesperblock = wav_fmt->msadpcm.samplesperblock ;
  551. break ;
  552. case WAVE_FORMAT_IMA_ADPCM :
  553. psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM) ;
  554. *blockalign = wav_fmt->ima.blockalign ;
  555. *framesperblock = wav_fmt->ima.samplesperblock ;
  556. break ;
  557. case WAVE_FORMAT_GSM610 :
  558. psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_GSM610) ;
  559. break ;
  560. case WAVE_FORMAT_IEEE_FLOAT :
  561. psf->sf.format = SF_FORMAT_WAV ;
  562. psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ;
  563. break ;
  564. case WAVE_FORMAT_G721_ADPCM :
  565. psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_G721_32 ;
  566. break ;
  567. default : return SFE_UNIMPLEMENTED ;
  568. } ;
  569. if (wpriv->fmt_is_broken)
  570. wav_w64_analyze (psf) ;
  571. /* Only set the format endian-ness if its non-standard big-endian. */
  572. if (psf->endian == SF_ENDIAN_BIG)
  573. psf->sf.format |= SF_ENDIAN_BIG ;
  574. return 0 ;
  575. } /* wav_read_header */
  576. static int
  577. wav_write_fmt_chunk (SF_PRIVATE *psf)
  578. { int subformat, fmt_size, add_fact_chunk = 0 ;
  579. subformat = SF_CODEC (psf->sf.format) ;
  580. switch (subformat)
  581. { case SF_FORMAT_PCM_U8 :
  582. case SF_FORMAT_PCM_16 :
  583. case SF_FORMAT_PCM_24 :
  584. case SF_FORMAT_PCM_32 :
  585. fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
  586. /* fmt : format, channels, samplerate */
  587. psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_PCM, psf->sf.channels, psf->sf.samplerate) ;
  588. /*  fmt : bytespersec */
  589. psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
  590. /*  fmt : blockalign, bitwidth */
  591. psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ;
  592. break ;
  593. case SF_FORMAT_FLOAT :
  594. case SF_FORMAT_DOUBLE :
  595. fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
  596. /* fmt : format, channels, samplerate */
  597. psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_IEEE_FLOAT, psf->sf.channels, psf->sf.samplerate) ;
  598. /*  fmt : bytespersec */
  599. psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
  600. /*  fmt : blockalign, bitwidth */
  601. psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ;
  602. add_fact_chunk = SF_TRUE ;
  603. break ;
  604. case SF_FORMAT_ULAW :
  605. fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
  606. /* fmt : format, channels, samplerate */
  607. psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_MULAW, psf->sf.channels, psf->sf.samplerate) ;
  608. /*  fmt : bytespersec */
  609. psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
  610. /*  fmt : blockalign, bitwidth */
  611. psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, 8) ;
  612. add_fact_chunk = SF_TRUE ;
  613. break ;
  614. case SF_FORMAT_ALAW :
  615. fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
  616. /* fmt : format, channels, samplerate */
  617. psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_ALAW, psf->sf.channels, psf->sf.samplerate) ;
  618. /*  fmt : bytespersec */
  619. psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
  620. /*  fmt : blockalign, bitwidth */
  621. psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, 8) ;
  622. add_fact_chunk = SF_TRUE ;
  623. break ;
  624. /* Lite remove start */
  625. case SF_FORMAT_IMA_ADPCM :
  626. { int blockalign, framesperblock, bytespersec ;
  627. blockalign = wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
  628. framesperblock = 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
  629. bytespersec = (psf->sf.samplerate * blockalign) / framesperblock ;
  630. /* fmt chunk. */
  631. fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
  632. /* fmt : size, WAV format type, channels, samplerate, bytespersec */
  633. psf_binheader_writef (psf, "42244", fmt_size, WAVE_FORMAT_IMA_ADPCM,
  634. psf->sf.channels, psf->sf.samplerate, bytespersec) ;
  635. /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
  636. psf_binheader_writef (psf, "2222", blockalign, 4, 2, framesperblock) ;
  637. } ;
  638. add_fact_chunk = SF_TRUE ;
  639. break ;
  640. case SF_FORMAT_MS_ADPCM :
  641. { int blockalign, framesperblock, bytespersec, extrabytes ;
  642. blockalign = wav_w64_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
  643. framesperblock = 2 + 2 * (blockalign - 7 * psf->sf.channels) / psf->sf.channels ;
  644. bytespersec = (psf->sf.samplerate * blockalign) / framesperblock ;
  645. /* fmt chunk. */
  646. extrabytes = 2 + 2 + MSADPCM_ADAPT_COEFF_COUNT * (2 + 2) ;
  647. fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + extrabytes ;
  648. /* fmt : size, WAV format type, channels. */
  649. psf_binheader_writef (psf, "422", fmt_size, WAVE_FORMAT_MS_ADPCM, psf->sf.channels) ;
  650. /* fmt : samplerate, bytespersec. */
  651. psf_binheader_writef (psf, "44", psf->sf.samplerate, bytespersec) ;
  652. /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
  653. psf_binheader_writef (psf, "22222", blockalign, 4, extrabytes, framesperblock, 7) ;
  654. msadpcm_write_adapt_coeffs (psf) ;
  655. } ;
  656. add_fact_chunk = SF_TRUE ;
  657. break ;
  658. case SF_FORMAT_G721_32 :
  659. /* fmt chunk. */
  660. fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
  661. /* fmt : size, WAV format type, channels, samplerate, bytespersec */
  662. psf_binheader_writef (psf, "42244", fmt_size, WAVE_FORMAT_G721_ADPCM,
  663. psf->sf.channels, psf->sf.samplerate, psf->sf.samplerate * psf->sf.channels / 2) ;
  664. /* fmt : blockalign, bitwidth, extrabytes, auxblocksize. */
  665. psf_binheader_writef (psf, "2222", 64, 4, 2, 0) ;
  666. add_fact_chunk = SF_TRUE ;
  667. break ;
  668. /* Lite remove end */
  669. case SF_FORMAT_GSM610 :
  670. { int blockalign, framesperblock, bytespersec ;
  671. blockalign = WAV_W64_GSM610_BLOCKSIZE ;
  672. framesperblock = WAV_W64_GSM610_SAMPLES ;
  673. bytespersec = (psf->sf.samplerate * blockalign) / framesperblock ;
  674. /* fmt chunk. */
  675. fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
  676. /* fmt : size, WAV format type, channels. */
  677. psf_binheader_writef (psf, "422", fmt_size, WAVE_FORMAT_GSM610, psf->sf.channels) ;
  678. /* fmt : samplerate, bytespersec. */
  679. psf_binheader_writef (psf, "44", psf->sf.samplerate, bytespersec) ;
  680. /* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
  681. psf_binheader_writef (psf, "2222", blockalign, 0, 2, framesperblock) ;
  682. } ;
  683. add_fact_chunk = SF_TRUE ;
  684. break ;
  685. default :  return SFE_UNIMPLEMENTED ;
  686. } ;
  687. if (add_fact_chunk)
  688. psf_binheader_writef (psf, "tm48", fact_MARKER, 4, psf->sf.frames) ;
  689. return 0 ;
  690. } /* wav_write_fmt_chunk */
  691. static int
  692. wavex_write_fmt_chunk (SF_PRIVATE *psf)
  693. { WAV_PRIVATE *wpriv ;
  694. int subformat, fmt_size, add_fact_chunk = 0 ;
  695. if ((wpriv = psf->container_data) == NULL)
  696. return SFE_INTERNAL ;
  697. subformat = SF_CODEC (psf->sf.format) ;
  698. /* initial section (same for all, it appears) */
  699. switch (subformat)
  700. { case SF_FORMAT_PCM_U8 :
  701. case SF_FORMAT_PCM_16 :
  702. case SF_FORMAT_PCM_24 :
  703. case SF_FORMAT_PCM_32 :
  704. case SF_FORMAT_FLOAT :
  705. case SF_FORMAT_DOUBLE :
  706. case SF_FORMAT_ULAW :
  707. case SF_FORMAT_ALAW :
  708. fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 + 4 + 4 + 2 + 2 + 8 ;
  709. /* fmt : format, channels, samplerate */
  710. psf_binheader_writef (psf, "4224", fmt_size, WAVE_FORMAT_EXTENSIBLE, psf->sf.channels, psf->sf.samplerate) ;
  711. /*  fmt : bytespersec */
  712. psf_binheader_writef (psf, "4", psf->sf.samplerate * psf->bytewidth * psf->sf.channels) ;
  713. /*  fmt : blockalign, bitwidth */
  714. psf_binheader_writef (psf, "22", psf->bytewidth * psf->sf.channels, psf->bytewidth * 8) ;
  715. /* cbSize 22 is sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX) */
  716. psf_binheader_writef (psf, "2", 22) ;
  717. /* wValidBitsPerSample, for our use same as bitwidth as we use it fully */
  718. psf_binheader_writef (psf, "2", psf->bytewidth * 8) ;
  719. /* For an Ambisonic file set the channel mask to zero.
  720. ** Otherwise use a default based on the channel count.
  721. */
  722. if (wpriv->wavex_ambisonic != SF_AMBISONIC_NONE)
  723. psf_binheader_writef (psf, "4", 0) ;
  724. else if (wpriv->wavex_channelmask != 0)
  725. psf_binheader_writef (psf, "4", wpriv->wavex_channelmask) ;
  726. else
  727. { /*
  728. ** Ok some liberty is taken here to use the most commonly used channel masks
  729. ** instead of "no mapping". If you really want to use "no mapping" for 8 channels and less
  730. ** please don't use wavex. (otherwise we'll have to create a new SF_COMMAND)
  731. */
  732. switch (psf->sf.channels)
  733. { case 1 : /* center channel mono */
  734. psf_binheader_writef (psf, "4", 0x4) ;
  735. break ;
  736. case 2 : /* front left and right */
  737. psf_binheader_writef (psf, "4", 0x1 | 0x2) ;
  738. break ;
  739. case 4 : /* Quad */
  740. psf_binheader_writef (psf, "4", 0x1 | 0x2 | 0x10 | 0x20) ;
  741. break ;
  742. case 6 : /* 5.1 */
  743. psf_binheader_writef (psf, "4", 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20) ;
  744. break ;
  745. case 8 : /* 7.1 */
  746. psf_binheader_writef (psf, "4", 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x40 | 0x80) ;
  747. break ;
  748. default : /* 0 when in doubt , use direct out, ie NO mapping*/
  749. psf_binheader_writef (psf, "4", 0x0) ;
  750. break ;
  751. } ;
  752. } ;
  753. break ;
  754. case SF_FORMAT_MS_ADPCM : /* Todo, GUID exists might have different header as per wav_write_header */
  755. default :
  756. return SFE_UNIMPLEMENTED ;
  757. } ;
  758. /* GUID section, different for each */
  759. switch (subformat)
  760. { case SF_FORMAT_PCM_U8 :
  761. case SF_FORMAT_PCM_16 :
  762. case SF_FORMAT_PCM_24 :
  763. case SF_FORMAT_PCM_32 :
  764. wavex_write_guid (psf, wpriv->wavex_ambisonic == SF_AMBISONIC_NONE ?
  765. &MSGUID_SUBTYPE_PCM : &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM) ;
  766. break ;
  767. case SF_FORMAT_FLOAT :
  768. case SF_FORMAT_DOUBLE :
  769. wavex_write_guid (psf, wpriv->wavex_ambisonic == SF_AMBISONIC_NONE ?
  770. &MSGUID_SUBTYPE_IEEE_FLOAT : &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT) ;
  771. add_fact_chunk = SF_TRUE ;
  772. break ;
  773. case SF_FORMAT_ULAW :
  774. wavex_write_guid (psf, &MSGUID_SUBTYPE_MULAW) ;
  775. add_fact_chunk = SF_TRUE ;
  776. break ;
  777. case SF_FORMAT_ALAW :
  778. wavex_write_guid (psf, &MSGUID_SUBTYPE_ALAW) ;
  779. add_fact_chunk = SF_TRUE ;
  780. break ;
  781. #if 0
  782. /* This is dead code due to return in previous switch statement. */
  783. case SF_FORMAT_MS_ADPCM : /* todo, GUID exists */
  784. wavex_write_guid (psf, &MSGUID_SUBTYPE_MS_ADPCM) ;
  785. add_fact_chunk = SF_TRUE ;
  786. break ;
  787. return SFE_UNIMPLEMENTED ;
  788. #endif
  789. default : return SFE_UNIMPLEMENTED ;
  790. } ;
  791. if (add_fact_chunk)
  792. psf_binheader_writef (psf, "tm48", fact_MARKER, 4, psf->sf.frames) ;
  793. return 0 ;
  794. } /* wavex_write_fmt_chunk */
  795. static int
  796. wav_write_header (SF_PRIVATE *psf, int calc_length)
  797. { sf_count_t current ;
  798. int  k, error, has_data = SF_FALSE ;
  799. current = psf_ftell (psf) ;
  800. if (current > psf->dataoffset)
  801. has_data = SF_TRUE ;
  802. if (calc_length)
  803. { psf->filelength = psf_get_filelen (psf) ;
  804. psf->datalength = psf->filelength - psf->dataoffset ;
  805. if (psf->dataend)
  806. psf->datalength -= psf->filelength - psf->dataend ;
  807. if (psf->bytewidth > 0)
  808. psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
  809. } ;
  810. /* Reset the current header length to zero. */
  811. psf->header [0] = 0 ;
  812. psf->headindex = 0 ;
  813. psf_fseek (psf, 0, SEEK_SET) ;
  814. /*
  815. ** RIFX signifies big-endian format for all header and data.
  816. ** To prevent lots of code copying here, we'll set the psf->rwf_endian flag
  817. ** once here, and never specify endian-ness for all other header operations.
  818. */
  819. /* RIFF/RIFX marker, length, WAVE and 'fmt ' markers. */
  820. if (psf->endian == SF_ENDIAN_LITTLE)
  821. psf_binheader_writef (psf, "etm8", RIFF_MARKER, (psf->filelength < 8) ? 8 : psf->filelength - 8) ;
  822. else
  823. psf_binheader_writef (psf, "Etm8", RIFX_MARKER, (psf->filelength < 8) ? 8 : psf->filelength - 8) ;
  824. /* WAVE and 'fmt ' markers. */
  825. psf_binheader_writef (psf, "mm", WAVE_MARKER, fmt_MARKER) ;
  826. /* Write the 'fmt ' chunk. */
  827. switch (SF_CONTAINER (psf->sf.format))
  828. { case SF_FORMAT_WAV :
  829. if ((error = wav_write_fmt_chunk (psf)) != 0)
  830. return error ;
  831. break ;
  832. case SF_FORMAT_WAVEX :
  833. if ((error = wavex_write_fmt_chunk (psf)) != 0)
  834. return error ;
  835. break ;
  836. default :
  837. return SFE_UNIMPLEMENTED ;
  838. } ;
  839. /* The LIST/INFO chunk. */
  840. if (psf->str_flags & SF_STR_LOCATE_START)
  841. wav_write_strings (psf, SF_STR_LOCATE_START) ;
  842. if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_START)
  843. { psf_binheader_writef (psf, "m4", PEAK_MARKER, WAV_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
  844. psf_binheader_writef (psf, "44", 1, time (NULL)) ;
  845. for (k = 0 ; k < psf->sf.channels ; k++)
  846. psf_binheader_writef (psf, "ft8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
  847. } ;
  848. if (psf->broadcast_var != NULL)
  849. wav_write_bext_chunk (psf) ;
  850. if (psf->instrument != NULL)
  851. { int tmp ;
  852. double dtune = (double) (0x40000000) / 25.0 ;
  853. psf_binheader_writef (psf, "m4", smpl_MARKER, 9 * 4 + psf->instrument->loop_count * 6 * 4) ;
  854. psf_binheader_writef (psf, "44", 0, 0) ; /* Manufacturer zero is everyone */
  855. tmp = (int) (1.0e9 / psf->sf.samplerate) ; /* Sample period in nano seconds */
  856. psf_binheader_writef (psf, "44", tmp, psf->instrument->basenote) ;
  857. tmp = (unsigned int) (psf->instrument->detune * dtune + 0.5) ;
  858. psf_binheader_writef (psf, "4", tmp) ;
  859. psf_binheader_writef (psf, "44", 0, 0) ; /* SMTPE format */
  860. psf_binheader_writef (psf, "44", psf->instrument->loop_count, 0) ;
  861. for (tmp = 0 ; tmp < psf->instrument->loop_count ; tmp++)
  862. { int type ;
  863. type = psf->instrument->loops [tmp].mode ;
  864. type = (type == SF_LOOP_FORWARD ? 0 : type==SF_LOOP_BACKWARD ? 2 : type == SF_LOOP_ALTERNATING ? 1 : 32) ;
  865. psf_binheader_writef (psf, "44", tmp, type) ;
  866. psf_binheader_writef (psf, "44", psf->instrument->loops [tmp].start, psf->instrument->loops [tmp].end - 1) ;
  867. psf_binheader_writef (psf, "44", 0, psf->instrument->loops [tmp].count) ;
  868. } ;
  869. } ;
  870. if (psf->headindex + 16 < psf->dataoffset)
  871. { /* Add PAD data if necessary. */
  872. k = psf->dataoffset - (psf->headindex + 16) ;
  873. psf_binheader_writef (psf, "m4z", PAD_MARKER, k, make_size_t (k)) ;
  874. } ;
  875. psf_binheader_writef (psf, "tm8", data_MARKER, psf->datalength) ;
  876. psf_fwrite (psf->header, psf->headindex, 1, psf) ;
  877. if (psf->error)
  878. return psf->error ;
  879. if (has_data && psf->dataoffset != psf->headindex)
  880. { psf_log_printf (psf, "Oooops : has_data && psf->dataoffset != psf->headindexn") ;
  881. return psf->error = SFE_INTERNAL ;
  882. } ;
  883. psf->dataoffset = psf->headindex ;
  884. if (! has_data)
  885. psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
  886. else if (current > 0)
  887. psf_fseek (psf, current, SEEK_SET) ;
  888. return psf->error ;
  889. } /* wav_write_header */
  890. static int
  891. wav_write_tailer (SF_PRIVATE *psf)
  892. { int k ;
  893. /* Reset the current header buffer length to zero. */
  894. psf->header [0] = 0 ;
  895. psf->headindex = 0 ;
  896. if (psf->dataend > 0)
  897. psf_fseek (psf, psf->dataend, SEEK_SET) ;
  898. else
  899. psf->dataend = psf_fseek (psf, 0, SEEK_END) ;
  900. /* Add a PEAK chunk if requested. */
  901. if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_END)
  902. { psf_binheader_writef (psf, "m4", PEAK_MARKER, WAV_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
  903. psf_binheader_writef (psf, "44", 1, time (NULL)) ;
  904. for (k = 0 ; k < psf->sf.channels ; k++)
  905. psf_binheader_writef (psf, "f4", psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
  906. } ;
  907. if (psf->str_flags & SF_STR_LOCATE_END)
  908. wav_write_strings (psf, SF_STR_LOCATE_END) ;
  909. /* Write the tailer. */
  910. if (psf->headindex > 0)
  911. psf_fwrite (psf->header, psf->headindex, 1, psf) ;
  912. return 0 ;
  913. } /* wav_write_tailer */
  914. static void
  915. wav_write_strings (SF_PRIVATE *psf, int location)
  916. { int k, prev_head_index, saved_head_index ;
  917. if (psf_location_string_count (psf, location) == 0)
  918. return ;
  919. prev_head_index = psf->headindex + 4 ;
  920. psf_binheader_writef (psf, "m4m", LIST_MARKER, 0xBADBAD, INFO_MARKER) ;
  921. for (k = 0 ; k < SF_MAX_STRINGS ; k++)
  922. { if (psf->strings [k].type == 0)
  923. break ;
  924. if (psf->strings [k].type < 0 || psf->strings [k].flags != location)
  925. continue ;
  926. switch (psf->strings [k].type)
  927. { case SF_STR_SOFTWARE :
  928. psf_binheader_writef (psf, "ms", ISFT_MARKER, psf->strings [k].str) ;
  929. break ;
  930. case SF_STR_TITLE :
  931. psf_binheader_writef (psf, "ms", INAM_MARKER, psf->strings [k].str) ;
  932. break ;
  933. case SF_STR_COPYRIGHT :
  934. psf_binheader_writef (psf, "ms", ICOP_MARKER, psf->strings [k].str) ;
  935. break ;
  936. case SF_STR_ARTIST :
  937. psf_binheader_writef (psf, "ms", IART_MARKER, psf->strings [k].str) ;
  938. break ;
  939. case SF_STR_COMMENT :
  940. psf_binheader_writef (psf, "ms", ICMT_MARKER, psf->strings [k].str) ;
  941. break ;
  942. case SF_STR_DATE :
  943. psf_binheader_writef (psf, "ms", ICRD_MARKER, psf->strings [k].str) ;
  944. break ;
  945. default :
  946. break ;
  947. } ;
  948. } ;
  949. saved_head_index = psf->headindex ;
  950. psf->headindex = prev_head_index ;
  951. psf_binheader_writef (psf, "4", saved_head_index - prev_head_index - 4) ;
  952. psf->headindex = saved_head_index ;
  953. } /* wav_write_strings */
  954. static int
  955. wav_close (SF_PRIVATE *psf)
  956. {
  957. if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
  958. { wav_write_tailer (psf) ;
  959. if (psf->file.mode == SFM_RDWR)
  960. { sf_count_t current = psf_ftell (psf) ;
  961. /*
  962. ** If the mode is RDWR and the current position is less than the
  963. ** filelength, truncate the file.
  964. */
  965. if (current < psf->filelength)
  966. { psf_ftruncate (psf, current) ;
  967. psf->filelength = current ;
  968. } ;
  969. } ;
  970. psf->write_header (psf, SF_TRUE) ;
  971. } ;
  972. return 0 ;
  973. } /* wav_close */
  974. static int
  975. wav_command (SF_PRIVATE *psf, int command, void * UNUSED (data), int datasize)
  976. { WAV_PRIVATE *wpriv ;
  977. if ((wpriv = psf->container_data) == NULL)
  978. return SFE_INTERNAL ;
  979. switch (command)
  980. { case SFC_WAVEX_SET_AMBISONIC :
  981. if ((SF_CONTAINER (psf->sf.format)) == SF_FORMAT_WAVEX)
  982. { if (datasize == SF_AMBISONIC_NONE)
  983. wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ;
  984. else if (datasize == SF_AMBISONIC_B_FORMAT)
  985. wpriv->wavex_ambisonic = SF_AMBISONIC_B_FORMAT ;
  986. else
  987. return 0 ;
  988. } ;
  989. return wpriv->wavex_ambisonic ;
  990. case SFC_WAVEX_GET_AMBISONIC :
  991. return wpriv->wavex_ambisonic ;
  992. case SFC_SET_CHANNEL_MAP_INFO :
  993. wpriv->wavex_channelmask = wavex_gen_channel_mask (psf->channel_map, psf->sf.channels) ;
  994. return (wpriv->wavex_channelmask != 0) ;
  995. default :
  996. break ;
  997. } ;
  998. return 0 ;
  999. } /* wav_command */
  1000. static int
  1001. wav_subchunk_parse (SF_PRIVATE *psf, int chunk)
  1002. { sf_count_t current_pos ;
  1003. char *cptr ;
  1004. unsigned  dword, bytesread, length ;
  1005. current_pos = psf_fseek (psf, 0, SEEK_CUR) ;
  1006. bytesread = psf_binheader_readf (psf, "4", &length) ;
  1007. if (length <= 8)
  1008. { /* This case is for broken files generated by PEAK. */
  1009. psf_log_printf (psf, "%M : %d (weird length)n", chunk, length) ;
  1010. psf_binheader_readf (psf, "mj", &chunk, length - 4) ;
  1011. psf_log_printf (psf, "  %Mn", chunk) ;
  1012. return 0 ;
  1013. } ;
  1014. if (psf->headindex + length > SIGNED_SIZEOF (psf->header))
  1015. { psf_log_printf (psf, "%M : %d (too long)n", chunk, length) ;
  1016. psf_binheader_readf (psf, "j", length) ;
  1017. return 0 ;
  1018. } ;
  1019. if (current_pos + length > psf->filelength)
  1020. { psf_log_printf (psf, "%M : %d (should be %d)n", chunk, length, (int) (psf->filelength - current_pos)) ;
  1021. length = psf->filelength - current_pos ;
  1022. }
  1023. else
  1024. psf_log_printf (psf, "%M : %dn", chunk, length) ;
  1025. while (bytesread < length)
  1026. { bytesread += psf_binheader_readf (psf, "m", &chunk) ;
  1027. switch (chunk)
  1028. { case adtl_MARKER :
  1029. case INFO_MARKER :
  1030. /* These markers don't contain anything. */
  1031. psf_log_printf (psf, "  %Mn", chunk) ;
  1032. break ;
  1033. case data_MARKER :
  1034. psf_log_printf (psf, "  %M inside a LIST block??? Backing out.n", chunk) ;
  1035. /* Jump back four bytes and return to caller. */
  1036. psf_binheader_readf (psf, "j", -4) ;
  1037. return 0 ;
  1038. case ISFT_MARKER :
  1039. case ICOP_MARKER :
  1040. case IARL_MARKER :
  1041. case IART_MARKER :
  1042. case ICMT_MARKER :
  1043. case ICRD_MARKER :
  1044. case IENG_MARKER :
  1045. case INAM_MARKER :
  1046. case IPRD_MARKER :
  1047. case ISBJ_MARKER :
  1048. case ISRC_MARKER :
  1049. bytesread += psf_binheader_readf (psf, "4", &dword) ;
  1050. dword += (dword & 1) ;
  1051. if (dword >= SIGNED_SIZEOF (psf->u.cbuf))
  1052. { psf_log_printf (psf, "  *** %M : %d (too big)n", chunk, dword) ;
  1053. psf_binheader_readf (psf, "j", dword) ;
  1054. break ;
  1055. } ;
  1056. cptr = psf->u.cbuf ;
  1057. psf_binheader_readf (psf, "b", cptr, dword) ;
  1058. bytesread += dword ;
  1059. cptr [dword] = 0 ;
  1060. psf_log_printf (psf, "    %M : %sn", chunk, cptr) ;
  1061. break ;
  1062. case labl_MARKER :
  1063. { int mark_id ;
  1064. bytesread += psf_binheader_readf (psf, "44", &dword, &mark_id) ;
  1065. dword -= 4 ;
  1066. dword += (dword & 1) ;
  1067. if (dword < 1 || dword >= SIGNED_SIZEOF (psf->u.cbuf))
  1068. { psf_log_printf (psf, "  *** %M : %d (too big)n", chunk, dword) ;
  1069. psf_binheader_readf (psf, "j", dword) ;
  1070. break ;
  1071. } ;
  1072. cptr = psf->u.cbuf ;
  1073. psf_binheader_readf (psf, "b", cptr, dword) ;
  1074. bytesread += dword ;
  1075. cptr [dword] = 0 ;
  1076. psf_log_printf (psf, "    %M : %d : %sn", chunk, mark_id, cptr) ;
  1077. } ;
  1078. break ;
  1079. case DISP_MARKER :
  1080. case ltxt_MARKER :
  1081. case note_MARKER :
  1082. bytesread += psf_binheader_readf (psf, "4", &dword) ;
  1083. dword += (dword & 1) ;
  1084. psf_binheader_readf (psf, "j", dword) ;
  1085. bytesread += dword ;
  1086. psf_log_printf (psf, "    %M : %dn", chunk, dword) ;
  1087. break ;
  1088. case exif_MARKER :
  1089. psf_log_printf (psf, "  %Mn", chunk) ;
  1090. bytesread += exif_subchunk_parse (psf, length - bytesread) ;
  1091. break ;
  1092. case 0 :
  1093. /*
  1094. ** Four zero bytes where a marker was expected. Assume this means
  1095. ** the rest of the chunk is garbage.
  1096. */
  1097. psf_log_printf (psf, "    *** Found weird-ass zero marker. Jumping to end of chunk.n") ;
  1098. if (bytesread < length)
  1099. bytesread += psf_binheader_readf (psf, "j", length - bytesread + 4) ;
  1100. psf_log_printf (psf, "    *** Offset is now : 0x%Xn", psf_fseek (psf, 0, SEEK_CUR)) ;
  1101. return 0 ;
  1102. default :
  1103. psf_binheader_readf (psf, "4", &dword) ;
  1104. bytesread += sizeof (dword) ;
  1105. dword += (dword & 1) ;
  1106. psf_binheader_readf (psf, "j", dword) ;
  1107. bytesread += dword ;
  1108. psf_log_printf (psf, "    *** %M : %dn", chunk, dword) ;
  1109. if (dword > length)
  1110. return 0 ;
  1111. break ;
  1112. } ;
  1113. switch (chunk)
  1114. { case ISFT_MARKER :
  1115. psf_store_string (psf, SF_STR_SOFTWARE, psf->u.cbuf) ;
  1116. break ;
  1117. case ICOP_MARKER :
  1118. psf_store_string (psf, SF_STR_COPYRIGHT, psf->u.cbuf) ;
  1119. break ;
  1120. case INAM_MARKER :
  1121. psf_store_string (psf, SF_STR_TITLE, psf->u.cbuf) ;
  1122. break ;
  1123. case IART_MARKER :
  1124. psf_store_string (psf, SF_STR_ARTIST, psf->u.cbuf) ;
  1125. break ;
  1126. case ICMT_MARKER :
  1127. psf_store_string (psf, SF_STR_COMMENT, psf->u.cbuf) ;
  1128. break ;
  1129. case ICRD_MARKER :
  1130. psf_store_string (psf, SF_STR_DATE, psf->u.cbuf) ;
  1131. break ;
  1132. } ;
  1133. } ;
  1134. current_pos = psf_fseek (psf, 0, SEEK_CUR) - current_pos ;
  1135. if (current_pos - 4 != length)
  1136. psf_log_printf (psf, "**** Bad chunk length %d sbould be %Dn", length, current_pos - 4) ;
  1137. return 0 ;
  1138. } /* wav_subchunk_parse */
  1139. static int
  1140. wav_read_smpl_chunk (SF_PRIVATE *psf, unsigned int chunklen)
  1141. { unsigned int bytesread = 0, dword, sampler_data, loop_count ;
  1142. unsigned int note, start, end, type = -1, count ;
  1143. int j, k ;
  1144. chunklen += (chunklen & 1) ;
  1145. bytesread += psf_binheader_readf (psf, "4", &dword) ;
  1146. psf_log_printf (psf, "  Manufacturer : %Xn", dword) ;
  1147. bytesread += psf_binheader_readf (psf, "4", &dword) ;
  1148. psf_log_printf (psf, "  Product      : %un", dword) ;
  1149. bytesread += psf_binheader_readf (psf, "4", &dword) ;
  1150. psf_log_printf (psf, "  Period       : %u nsecn", dword) ;
  1151. bytesread += psf_binheader_readf (psf, "4", &note) ;
  1152. psf_log_printf (psf, "  Midi Note    : %un", note) ;
  1153. bytesread += psf_binheader_readf (psf, "4", &dword) ;
  1154. if (dword != 0)
  1155. { snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), "%f",
  1156.  (1.0 * 0x80000000) / ((unsigned int) dword)) ;
  1157. psf_log_printf (psf, "  Pitch Fract. : %sn", psf->u.cbuf) ;
  1158. }
  1159. else
  1160. psf_log_printf (psf, "  Pitch Fract. : 0n") ;
  1161. bytesread += psf_binheader_readf (psf, "4", &dword) ;
  1162. psf_log_printf (psf, "  SMPTE Format : %un", dword) ;
  1163. bytesread += psf_binheader_readf (psf, "4", &dword) ;
  1164. snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), "%02d:%02d:%02d %02d",
  1165.  (dword >> 24) & 0x7F, (dword >> 16) & 0x7F, (dword >> 8) & 0x7F, dword & 0x7F) ;
  1166. psf_log_printf (psf, "  SMPTE Offset : %sn", psf->u.cbuf) ;
  1167. bytesread += psf_binheader_readf (psf, "4", &loop_count) ;
  1168. psf_log_printf (psf, "  Loop Count   : %un", loop_count) ;
  1169. /* Sampler Data holds the number of data bytes after the CUE chunks which
  1170. ** is not actually CUE data. Display value after CUE data.
  1171. */
  1172. bytesread += psf_binheader_readf (psf, "4", &sampler_data) ;
  1173. if ((psf->instrument = psf_instrument_alloc ()) == NULL)
  1174. return SFE_MALLOC_FAILED ;
  1175. psf->instrument->loop_count = loop_count ;
  1176. for (j = 0 ; loop_count > 0 && chunklen - bytesread >= 24 ; j ++)
  1177. { bytesread += psf_binheader_readf (psf, "4", &dword) ;
  1178. psf_log_printf (psf, "    Cue ID : %2u", dword) ;
  1179. bytesread += psf_binheader_readf (psf, "4", &type) ;
  1180. psf_log_printf (psf, "  Type : %2u", type) ;
  1181. bytesread += psf_binheader_readf (psf, "4", &start) ;
  1182. psf_log_printf (psf, "  Start : %5u", start) ;
  1183. bytesread += psf_binheader_readf (psf, "4", &end) ;
  1184. psf_log_printf (psf, "  End : %5u", end) ;
  1185. bytesread += psf_binheader_readf (psf, "4", &dword) ;
  1186. psf_log_printf (psf, "  Fraction : %5u", dword) ;
  1187. bytesread += psf_binheader_readf (psf, "4", &count) ;
  1188. psf_log_printf (psf, "  Count : %5un", count) ;
  1189. if (j < ARRAY_LEN (psf->instrument->loops))
  1190. { psf->instrument->loops [j].start = start ;
  1191. psf->instrument->loops [j].end = end + 1 ;
  1192. psf->instrument->loops [j].count = count ;
  1193. switch (type)
  1194. { case 0 :
  1195. psf->instrument->loops [j].mode = SF_LOOP_FORWARD ;
  1196. break ;
  1197. case 1 :
  1198. psf->instrument->loops [j].mode = SF_LOOP_ALTERNATING ;
  1199. break ;
  1200. case 2 :
  1201. psf->instrument->loops [j].mode = SF_LOOP_BACKWARD ;
  1202. break ;
  1203. default:
  1204. psf->instrument->loops [j].mode = SF_LOOP_NONE ;
  1205. break ;
  1206. } ;
  1207. } ;
  1208. loop_count -- ;
  1209. } ;
  1210. if (chunklen - bytesread == 0)
  1211. { if (sampler_data != 0)
  1212. psf_log_printf (psf, "  Sampler Data : %u (should be 0)n", sampler_data) ;
  1213. else
  1214. psf_log_printf (psf, "  Sampler Data : %un", sampler_data) ;
  1215. }
  1216. else
  1217. { if (sampler_data != chunklen - bytesread)
  1218. { psf_log_printf (psf, "  Sampler Data : %u (should have been %u)n", sampler_data, chunklen - bytesread) ;
  1219. sampler_data = chunklen - bytesread ;
  1220. }
  1221. else
  1222. psf_log_printf (psf, "  Sampler Data : %un", sampler_data) ;
  1223. psf_log_printf (psf, "      ") ;
  1224. for (k = 0 ; k < (int) sampler_data ; k++)
  1225. { char ch ;
  1226. if (k > 0 && (k % 20) == 0)
  1227. psf_log_printf (psf, "n      ") ;
  1228. bytesread += psf_binheader_readf (psf, "1", &ch) ;
  1229. psf_log_printf (psf, "%02X ", ch & 0xFF) ;
  1230. } ;
  1231. psf_log_printf (psf, "n") ;
  1232. } ;
  1233. psf->instrument->basenote = note ;
  1234. psf->instrument->gain = 1 ;
  1235. psf->instrument->velocity_lo = psf->instrument->key_lo = 0 ;
  1236. psf->instrument->velocity_hi = psf->instrument->key_hi = 127 ;
  1237. return 0 ;
  1238. } /* wav_read_smpl_chunk */
  1239. /*
  1240. ** The acid chunk goes a little something like this:
  1241. **
  1242. ** 4 bytes          'acid'
  1243. ** 4 bytes (int)     length of chunk starting at next byte
  1244. **
  1245. ** 4 bytes (int)     type of file:
  1246. **        this appears to be a bit mask,however some combinations
  1247. **        are probably impossible and/or qualified as "errors"
  1248. **
  1249. **        0x01 On: One Shot         Off: Loop
  1250. **        0x02 On: Root note is Set Off: No root
  1251. **        0x04 On: Stretch is On,   Off: Strech is OFF
  1252. **        0x08 On: Disk Based       Off: Ram based
  1253. **        0x10 On: ??????????       Off: ????????? (Acidizer puts that ON)
  1254. **
  1255. ** 2 bytes (short)      root note
  1256. **        if type 0x10 is OFF : [C,C#,(...),B] -> [0x30 to 0x3B]
  1257. **        if type 0x10 is ON  : [C,C#,(...),B] -> [0x3C to 0x47]
  1258. **         (both types fit on same MIDI pitch albeit different octaves, so who cares)
  1259. **
  1260. ** 2 bytes (short)      ??? always set to 0x8000
  1261. ** 4 bytes (float)      ??? seems to be always 0
  1262. ** 4 bytes (int)        number of beats
  1263. ** 2 bytes (short)      meter denominator   //always 4 in SF/ACID
  1264. ** 2 bytes (short)      meter numerator     //always 4 in SF/ACID
  1265. **                      //are we sure about the order?? usually its num/denom
  1266. ** 4 bytes (float)      tempo
  1267. **
  1268. */
  1269. static int
  1270. wav_read_acid_chunk (SF_PRIVATE *psf, unsigned int chunklen)
  1271. { unsigned int bytesread = 0 ;
  1272. int beats, flags ;
  1273. short rootnote, q1, meter_denom, meter_numer ;
  1274. float q2, tempo ;
  1275. chunklen += (chunklen & 1) ;
  1276. bytesread += psf_binheader_readf (psf, "422f", &flags, &rootnote, &q1, &q2) ;
  1277. snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), "%f", q2) ;
  1278. psf_log_printf (psf, "  Flags     : 0x%04x (%s,%s,%s,%s,%s)n", flags,
  1279. (flags & 0x01) ? "OneShot" : "Loop",
  1280. (flags & 0x02) ? "RootNoteValid" : "RootNoteInvalid",
  1281. (flags & 0x04) ? "StretchOn" : "StretchOff",
  1282. (flags & 0x08) ? "DiskBased" : "RAMBased",
  1283. (flags & 0x10) ? "??On" : "??Off") ;
  1284. psf_log_printf (psf, "  Root note : 0x%xn  ????      : 0x%04xn  ????      : %sn",
  1285. rootnote, q1, psf->u.cbuf) ;
  1286. bytesread += psf_binheader_readf (psf, "422f", &beats, &meter_denom, &meter_numer, &tempo) ;
  1287. snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), "%f", tempo) ;
  1288. psf_log_printf (psf, "  Beats     : %dn  Meter     : %d/%dn  Tempo     : %sn",
  1289. beats, meter_numer, meter_denom, psf->u.cbuf) ;
  1290. psf_binheader_readf (psf, "j", chunklen - bytesread) ;
  1291. if ((psf->loop_info = calloc (1, sizeof (SF_LOOP_INFO))) == NULL)
  1292. return SFE_MALLOC_FAILED ;
  1293. psf->loop_info->time_sig_num = meter_numer ;
  1294. psf->loop_info->time_sig_den = meter_denom ;
  1295. psf->loop_info->loop_mode = (flags & 0x01) ? SF_LOOP_NONE : SF_LOOP_FORWARD ;
  1296. psf->loop_info->num_beats = beats ;
  1297. psf->loop_info->bpm = tempo ;
  1298. psf->loop_info->root_key = (flags & 0x02) ? rootnote : -1 ;
  1299. return 0 ;
  1300. } /* wav_read_acid_chunk */
  1301. int
  1302. wav_read_bext_chunk (SF_PRIVATE *psf, unsigned int chunksize)
  1303. {
  1304. SF_BROADCAST_INFO* b ;
  1305. unsigned int bytes = 0 ;
  1306. if (chunksize < WAV_BEXT_MIN_CHUNK_SIZE)
  1307. { psf_log_printf (psf, "bext : %u (should be >= %d)n", chunksize, WAV_BEXT_MIN_CHUNK_SIZE) ;
  1308. psf_binheader_readf (psf, "j", chunksize) ;
  1309. return 0 ;
  1310. } ;
  1311. if (chunksize > WAV_BEXT_MAX_CHUNK_SIZE)
  1312. { psf_log_printf (psf, "bext : %u (should be < %d)n", chunksize, WAV_BEXT_MAX_CHUNK_SIZE) ;
  1313. psf_binheader_readf (psf, "j", chunksize) ;
  1314. return 0 ;
  1315. } ;
  1316. psf_log_printf (psf, "bext : %un", chunksize) ;
  1317. if ((psf->broadcast_var = broadcast_var_alloc (chunksize + 128)) == NULL)
  1318. { psf->error = SFE_MALLOC_FAILED ;
  1319. return psf->error ;
  1320. } ;
  1321. b = & psf->broadcast_var->binfo ;
  1322. bytes += psf_binheader_readf (psf, "b", b->description, sizeof (b->description)) ;
  1323. bytes += psf_binheader_readf (psf, "b", b->originator, sizeof (b->originator)) ;
  1324. bytes += psf_binheader_readf (psf, "b", b->originator_reference, sizeof (b->originator_reference)) ;
  1325. bytes += psf_binheader_readf (psf, "b", b->origination_date, sizeof (b->origination_date)) ;
  1326. bytes += psf_binheader_readf (psf, "b", b->origination_time, sizeof (b->origination_time)) ;
  1327. bytes += psf_binheader_readf (psf, "442", &b->time_reference_low, &b->time_reference_high, &b->version) ;
  1328. bytes += psf_binheader_readf (psf, "bj", &b->umid, sizeof (b->umid), 190) ;
  1329. if (chunksize > WAV_BEXT_MIN_CHUNK_SIZE)
  1330. { /* File has coding history data. */
  1331. b->coding_history_size = chunksize - WAV_BEXT_MIN_CHUNK_SIZE ;
  1332. /* We do not parse the coding history */
  1333. bytes += psf_binheader_readf (psf, "b", b->coding_history, b->coding_history_size) ;
  1334. } ;
  1335. if (bytes < chunksize)
  1336. psf_binheader_readf (psf, "j", chunksize - bytes) ;
  1337. return 0 ;
  1338. } /* wav_read_bext_chunk */
  1339. int
  1340. wav_write_bext_chunk (SF_PRIVATE *psf)
  1341. { SF_BROADCAST_INFO *b ;
  1342. if (psf->broadcast_var == NULL)
  1343. return -1 ;
  1344. b = & psf->broadcast_var->binfo ;
  1345. psf_binheader_writef (psf, "m4", bext_MARKER, WAV_BEXT_MIN_CHUNK_SIZE + b->coding_history_size) ;
  1346. /*
  1347. ** Note that it is very important the the field widths of the SF_BROADCAST_INFO
  1348. ** struct match those for the bext chunk fields.
  1349. */
  1350. psf_binheader_writef (psf, "b", b->description, sizeof (b->description)) ;
  1351. psf_binheader_writef (psf, "b", b->originator, sizeof (b->originator)) ;
  1352. psf_binheader_writef (psf, "b", b->originator_reference, sizeof (b->originator_reference)) ;
  1353. psf_binheader_writef (psf, "b", b->origination_date, sizeof (b->origination_date)) ;
  1354. psf_binheader_writef (psf, "b", b->origination_time, sizeof (b->origination_time)) ;
  1355. psf_binheader_writef (psf, "442", b->time_reference_low, b->time_reference_high, b->version) ;
  1356. psf_binheader_writef (psf, "b", b->umid, sizeof (b->umid)) ;
  1357. psf_binheader_writef (psf, "z", make_size_t (190)) ;
  1358. if (b->coding_history_size > 0)
  1359. psf_binheader_writef (psf, "b", b->coding_history, make_size_t (b->coding_history_size)) ;
  1360. return 0 ;
  1361. } /* wav_write_bext_chunk */
  1362. static int
  1363. exif_fill_and_sink (SF_PRIVATE *psf, char* buf, size_t bufsz, size_t toread)
  1364. {
  1365. size_t bytesread = 0 ;
  1366. buf [0] = 0 ;
  1367. bufsz -= 1 ;
  1368. if (toread < bufsz)
  1369. bufsz = toread ;
  1370. bytesread = psf_binheader_readf (psf, "b", buf, bufsz) ;
  1371. buf [bufsz] = 0 ;
  1372. if (bytesread == bufsz && toread > bufsz)
  1373. bytesread += psf_binheader_readf (psf, "j", toread - bufsz) ;
  1374. return bytesread ;
  1375. } /* exif_fill_and_sink */
  1376. /*
  1377. ** Exif specification for audio files, at JEITA CP-3451 Exif 2.2 section 5
  1378. ** (Exif Audio File Specification) http://www.exif.org/Exif2-2.PDF
  1379. */
  1380. static int
  1381. exif_subchunk_parse (SF_PRIVATE *psf, unsigned int length)
  1382. { unsigned marker, dword, vmajor = -1, vminor = -1, bytesread = 0 ;
  1383. char buf [4096] ;
  1384. while (bytesread < length)
  1385. {
  1386. bytesread += psf_binheader_readf (psf, "m", &marker) ;
  1387. switch (marker)
  1388. {
  1389. case 0 : /* camera padding? */
  1390. break ;
  1391. case ever_MARKER :
  1392. bytesread += psf_binheader_readf (psf, "j4", 4, &dword) ;
  1393. vmajor = 10 * (((dword >> 24) & 0xff) - '0') + (((dword >> 16) & 0xff) - '0') ;
  1394. vminor = 10 * (((dword >> 8) & 0xff) - '0') + ((dword & 0xff) - '0') ;
  1395. psf_log_printf (psf, "    EXIF Version : %u.%02un", vmajor, vminor) ;
  1396. break ;
  1397. case emnt_MARKER : /* design information: null-terminated string */
  1398. case emdl_MARKER : /* model name ; null-terminated string */
  1399. case ecor_MARKER : /* manufacturer: null-terminated string */
  1400. case etim_MARKER : /* creation time: null-terminated string in the format "hour:minute:second.subsecond" */
  1401. case erel_MARKER : /* relation info: null-terminated string (filename) */
  1402. case eucm_MARKER : /* user comment: 4-byte size follows, then possibly unicode data */
  1403. psf_binheader_readf (psf, "4", &dword) ;
  1404. bytesread += sizeof (dword) ;
  1405. dword += (dword & 1) ;
  1406. if (dword >= sizeof (buf))
  1407. { psf_log_printf (psf, "*** Marker '%M' is too big %unn", marker, dword) ;
  1408. return bytesread ;
  1409. } ;
  1410. bytesread += exif_fill_and_sink (psf, buf, sizeof (buf), dword) ;
  1411. /* BAD - don't know what's going on here -- maybe a bug in the camera */
  1412. /* field should be NULL-terminated but there's no room for it with the reported number */
  1413. /*  example output:     emdl : 8 (EX-Z1050) */
  1414. if (marker == emdl_MARKER && dword == strlen (buf) /* should be >= strlen+1*/)
  1415. { psf_log_printf (psf, "    *** field size too small for string (sinking 2 bytes)n") ;
  1416. bytesread += psf_binheader_readf (psf, "j", 2) ;
  1417. } ;
  1418. psf_log_printf (psf, "    %M : %d (%s)n", marker, dword, buf) ;
  1419. if (dword > length)
  1420. return bytesread ;
  1421. break ;
  1422. default :
  1423. psf_log_printf (psf, "    *** %M (%d): -- ignored --n", marker, marker) ;
  1424. break ;
  1425. } ;
  1426. } ;
  1427. return bytesread ;
  1428. } /* exif_subchunk_parse */