• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 ** Copyright (C) 1999-2019 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 
20 #include	"sfconfig.h"
21 
22 #include	<stdio.h>
23 #include	<stdlib.h>
24 #include	<string.h>
25 #include	<ctype.h>
26 #include	<time.h>
27 #include	<inttypes.h>
28 
29 #include	"sndfile.h"
30 #include	"sfendian.h"
31 #include	"common.h"
32 #include	"wavlike.h"
33 
34 /*------------------------------------------------------------------------------
35  * Macros to handle big/little endian issues.
36  */
37 
38 #define RIFF_MARKER		(MAKE_MARKER ('R', 'I', 'F', 'F'))
39 #define RIFX_MARKER		(MAKE_MARKER ('R', 'I', 'F', 'X'))
40 #define WAVE_MARKER		(MAKE_MARKER ('W', 'A', 'V', 'E'))
41 #define fmt_MARKER		(MAKE_MARKER ('f', 'm', 't', ' '))
42 #define fact_MARKER		(MAKE_MARKER ('f', 'a', 'c', 't'))
43 
44 #define cue_MARKER		(MAKE_MARKER ('c', 'u', 'e', ' '))
45 #define slnt_MARKER		(MAKE_MARKER ('s', 'l', 'n', 't'))
46 #define wavl_MARKER		(MAKE_MARKER ('w', 'a', 'v', 'l'))
47 #define plst_MARKER		(MAKE_MARKER ('p', 'l', 's', 't'))
48 #define smpl_MARKER		(MAKE_MARKER ('s', 'm', 'p', 'l'))
49 #define iXML_MARKER		(MAKE_MARKER ('i', 'X', 'M', 'L'))
50 #define levl_MARKER		(MAKE_MARKER ('l', 'e', 'v', 'l'))
51 #define MEXT_MARKER		(MAKE_MARKER ('M', 'E', 'X', 'T'))
52 #define acid_MARKER		(MAKE_MARKER ('a', 'c', 'i', 'd'))
53 #define strc_MARKER		(MAKE_MARKER ('s', 't', 'r', 'c'))
54 #define afsp_MARKER		(MAKE_MARKER ('a', 'f', 's', 'p'))
55 #define clm_MARKER		(MAKE_MARKER ('c', 'l', 'm', ' '))
56 #define elmo_MARKER		(MAKE_MARKER ('e', 'l', 'm', 'o'))
57 #define FLLR_MARKER		(MAKE_MARKER ('F', 'L', 'L', 'R'))
58 
59 #define minf_MARKER		(MAKE_MARKER ('m', 'i', 'n', 'f'))
60 #define elm1_MARKER		(MAKE_MARKER ('e', 'l', 'm', '1'))
61 #define regn_MARKER		(MAKE_MARKER ('r', 'e', 'g', 'n'))
62 #define ovwf_MARKER		(MAKE_MARKER ('o', 'v', 'w', 'f'))
63 #define umid_MARKER		(MAKE_MARKER ('u', 'm', 'i', 'd'))
64 #define SyLp_MARKER		(MAKE_MARKER ('S', 'y', 'L', 'p'))
65 #define Cr8r_MARKER		(MAKE_MARKER ('C', 'r', '8', 'r'))
66 #define JUNK_MARKER		(MAKE_MARKER ('J', 'U', 'N', 'K'))
67 #define PMX_MARKER		(MAKE_MARKER ('_', 'P', 'M', 'X'))
68 #define inst_MARKER		(MAKE_MARKER ('i', 'n', 's', 't'))
69 #define AFAn_MARKER		(MAKE_MARKER ('A', 'F', 'A', 'n'))
70 
71 
72 /* Weird WAVPACK marker which can show up at the start of the DATA section. */
73 #define wvpk_MARKER (MAKE_MARKER ('w', 'v', 'p', 'k'))
74 #define OggS_MARKER (MAKE_MARKER ('O', 'g', 'g', 'S'))
75 
76 /* ID3v1 trailer which can show up at the end and erronerously look like a chunk. */
77 #define TAG__MARKER (MAKE_MARKER ('T', 'A', 'G', 0))
78 #define TAG__MARKER_MASK (MAKE_MARKER (0xff, 0xff, 0xff, 0))
79 
80 #define WAVLIKE_PEAK_CHUNK_SIZE(ch) 	(2 * sizeof (int) + ch * (sizeof (float) + sizeof (int)))
81 
82 
83 enum
84 {	HAVE_RIFF	= 1 << 0,
85 	HAVE_WAVE	= 1 << 1,
86 	HAVE_fmt	= 1 << 2,
87 	HAVE_fact	= 1 << 3,
88 	HAVE_PEAK	= 1 << 4,
89 	HAVE_data	= 1 << 5,
90 	HAVE_other	= 1 << 6
91 } ;
92 
93 
94 /*  known WAVEFORMATEXTENSIBLE GUIDS  */
95 static const EXT_SUBFORMAT MSGUID_SUBTYPE_PCM =
96 {	0x00000001, 0x0000, 0x0010, {	0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
97 } ;
98 
99 #if 0
100 static const EXT_SUBFORMAT MSGUID_SUBTYPE_MS_ADPCM =
101 {	0x00000002, 0x0000, 0x0010, {	0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
102 } ;
103 #endif
104 
105 static const EXT_SUBFORMAT MSGUID_SUBTYPE_IEEE_FLOAT =
106 {	0x00000003, 0x0000, 0x0010, {	0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
107 } ;
108 
109 static const EXT_SUBFORMAT MSGUID_SUBTYPE_ALAW =
110 {	0x00000006, 0x0000, 0x0010, {	0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
111 } ;
112 
113 static const EXT_SUBFORMAT MSGUID_SUBTYPE_MULAW =
114 {	0x00000007, 0x0000, 0x0010, {	0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
115 } ;
116 
117 /*
118 ** the next two are from
119 ** http://dream.cs.bath.ac.uk/researchdev/wave-ex/bformat.html
120 */
121 static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM =
122 {	0x00000001, 0x0721, 0x11d3, {	0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 }
123 } ;
124 
125 static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT =
126 {	0x00000003, 0x0721, 0x11d3, {	0x86, 0x44, 0xC8, 0xC1, 0xCA, 0x00, 0x00, 0x00 }
127 } ;
128 
129 
130 #if 0
131 /* maybe interesting one day to read the following through sf_read_raw */
132 /* http://www.bath.ac.uk/~masrwd/pvocex/pvocex.html */
133 static const EXT_SUBFORMAT MSGUID_SUBTYPE_PVOCEX =
134 {	0x8312B9C2, 0x2E6E, 0x11d4, {	0xA8, 0x24, 0xDE, 0x5B, 0x96, 0xC3, 0xAB, 0x21 }
135 } ;
136 #endif
137 
138 /*------------------------------------------------------------------------------
139 ** Private static functions.
140 */
141 
142 static int	wav_read_header		(SF_PRIVATE *psf, int *blockalign, int *framesperblock) ;
143 static int	wav_write_header	(SF_PRIVATE *psf, int calc_length) ;
144 
145 static int	wav_write_tailer (SF_PRIVATE *psf) ;
146 static int	wav_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
147 static int	wav_close (SF_PRIVATE *psf) ;
148 
149 static int	wav_read_smpl_chunk (SF_PRIVATE *psf, uint32_t chunklen) ;
150 static int	wav_read_acid_chunk (SF_PRIVATE *psf, uint32_t chunklen) ;
151 
152 static int wav_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info) ;
153 static SF_CHUNK_ITERATOR * wav_next_chunk_iterator (SF_PRIVATE *psf, SF_CHUNK_ITERATOR * iterator) ;
154 static int wav_get_chunk_size (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ;
155 static int wav_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ;
156 
157 /*------------------------------------------------------------------------------
158 ** Public function.
159 */
160 
161 int
wav_open(SF_PRIVATE * psf)162 wav_open	(SF_PRIVATE *psf)
163 {	WAVLIKE_PRIVATE * wpriv ;
164 	int	format, subformat, error, blockalign = 0, framesperblock = 0 ;
165 
166 	if ((wpriv = calloc (1, sizeof (WAVLIKE_PRIVATE))) == NULL)
167 		return SFE_MALLOC_FAILED ;
168 	psf->container_data = wpriv ;
169 
170 	wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ;
171 	psf->strings.flags = SF_STR_ALLOW_START | SF_STR_ALLOW_END ;
172 
173 	if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
174 	{	if ((error = wav_read_header (psf, &blockalign, &framesperblock)))
175 			return error ;
176 
177 		psf->next_chunk_iterator = wav_next_chunk_iterator ;
178 		psf->get_chunk_size = wav_get_chunk_size ;
179 		psf->get_chunk_data = wav_get_chunk_data ;
180 		} ;
181 
182 	subformat = SF_CODEC (psf->sf.format) ;
183 
184 	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
185 	{	if (psf->is_pipe)
186 			return SFE_NO_PIPE_WRITE ;
187 
188 		wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ;
189 
190 		format = SF_CONTAINER (psf->sf.format) ;
191 		if (format != SF_FORMAT_WAV && format != SF_FORMAT_WAVEX)
192 			return	SFE_BAD_OPEN_FORMAT ;
193 
194 		psf->blockwidth = psf->bytewidth * psf->sf.channels ;
195 
196 		/* RIFF WAVs are little-endian, RIFX WAVs are big-endian, default to little */
197 		psf->endian = SF_ENDIAN (psf->sf.format) ;
198 		if (CPU_IS_BIG_ENDIAN && psf->endian == SF_ENDIAN_CPU)
199 			psf->endian = SF_ENDIAN_BIG ;
200 		else if (psf->endian != SF_ENDIAN_BIG)
201 			psf->endian = SF_ENDIAN_LITTLE ;
202 
203 		if (psf->file.mode != SFM_RDWR || psf->filelength < 44)
204 		{	psf->filelength = 0 ;
205 			psf->datalength = 0 ;
206 			psf->dataoffset = 0 ;
207 			psf->sf.frames = 0 ;
208 			} ;
209 
210 #if (ENABLE_EXPERIMENTAL_CODE == 0)
211 		/* For now, don't support writing MPEGLAYER3 WAVs, as we can't guarentee that
212 		** such a file written by libsndfile would have the same length when opened again.
213 		*/
214 		if (subformat == SF_FORMAT_MPEG_LAYER_III)
215 			return SFE_UNSUPPORTED_ENCODING ;
216 #endif
217 
218 		if (subformat == SF_FORMAT_IMA_ADPCM || subformat == SF_FORMAT_MS_ADPCM)
219 		{	blockalign = wavlike_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
220 			framesperblock = -1 ; /* Corrected later. */
221 			} ;
222 
223 		/* By default, add the peak chunk to floating point files. Default behaviour
224 		** can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
225 		*/
226 		if (psf->file.mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
227 		{	if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
228 				return SFE_MALLOC_FAILED ;
229 			psf->peak_info->peak_loc = SF_PEAK_START ;
230 			} ;
231 
232 		psf->write_header	= wav_write_header ;
233 		psf->set_chunk		= wav_set_chunk ;
234 		} ;
235 
236 	psf->container_close = wav_close ;
237 	psf->command = wav_command ;
238 
239 	switch (subformat)
240 	{	case SF_FORMAT_PCM_U8 :
241 		case SF_FORMAT_PCM_16 :
242 		case SF_FORMAT_PCM_24 :
243 		case SF_FORMAT_PCM_32 :
244 					error = pcm_init (psf) ;
245 					break ;
246 
247 		case SF_FORMAT_ULAW :
248 					error = ulaw_init (psf) ;
249 					break ;
250 
251 		case SF_FORMAT_ALAW :
252 					error = alaw_init (psf) ;
253 					break ;
254 
255 		/* Lite remove start */
256 		case SF_FORMAT_FLOAT :
257 					error = float32_init (psf) ;
258 					break ;
259 
260 		case SF_FORMAT_DOUBLE :
261 					error = double64_init (psf) ;
262 					break ;
263 
264 		case SF_FORMAT_IMA_ADPCM :
265 					error = wavlike_ima_init (psf, blockalign, framesperblock) ;
266 					break ;
267 
268 		case SF_FORMAT_MS_ADPCM :
269 					error = wavlike_msadpcm_init (psf, blockalign, framesperblock) ;
270 					break ;
271 
272 		case SF_FORMAT_G721_32 :
273 					error = g72x_init (psf) ;
274 					break ;
275 
276 		case SF_FORMAT_NMS_ADPCM_16 :
277 		case SF_FORMAT_NMS_ADPCM_24 :
278 		case SF_FORMAT_NMS_ADPCM_32 :
279 					error = nms_adpcm_init (psf) ;
280 					break ;
281 
282 		/* Lite remove end */
283 
284 		case SF_FORMAT_GSM610 :
285 					error = gsm610_init (psf) ;
286 					break ;
287 
288 		case SF_FORMAT_MPEG_LAYER_III :
289 					error = mpeg_init (psf, SF_BITRATE_MODE_CONSTANT, SF_FALSE) ;
290 					break ;
291 
292 		default : 	return SFE_UNIMPLEMENTED ;
293 		} ;
294 
295 	if (psf->file.mode == SFM_WRITE || (psf->file.mode == SFM_RDWR && psf->filelength == 0))
296 		return psf->write_header (psf, SF_FALSE) ;
297 
298 	return error ;
299 } /* wav_open */
300 
301 /*=========================================================================
302 ** Private functions.
303 */
304 
305 static int
wav_read_header(SF_PRIVATE * psf,int * blockalign,int * framesperblock)306 wav_read_header	(SF_PRIVATE *psf, int *blockalign, int *framesperblock)
307 {	WAVLIKE_PRIVATE	*wpriv ;
308 	WAV_FMT		*wav_fmt ;
309 	FACT_CHUNK	fact_chunk ;
310 	uint32_t	marker, chunk_size = 0, RIFFsize = 0, done = 0 ;
311 	int			parsestage = 0, error, format = 0 ;
312 
313 	if (psf->is_pipe == 0 && psf->filelength > 0xFFFFFFFFLL)
314 		psf_log_printf (psf, "Warning : filelength > 0xffffffff. This is bad!!!!\n") ;
315 
316 	if ((wpriv = psf->container_data) == NULL)
317 		return SFE_INTERNAL ;
318 	wav_fmt = &wpriv->wav_fmt ;
319 
320 	/* Set position to start of file to begin reading header. */
321 	psf_binheader_readf (psf, "pmj", 0, &marker, -4) ;
322 	psf->header.indx = 0 ;
323 
324 	/* RIFX signifies big-endian format for all header and data  to prevent
325 	** lots of code copying here, we'll set the psf->rwf_endian flag once here,
326 	** and never specify endian-ness for all other header ops/
327 	*/
328 	psf->rwf_endian = (marker == RIFF_MARKER) ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;
329 
330 	while (! done)
331 	{	size_t jump = chunk_size & 1 ;
332 
333 		marker = chunk_size = 0 ;
334 		psf_binheader_readf (psf, "jm4", jump, &marker, &chunk_size) ;
335 		if (marker == 0)
336 		{	sf_count_t pos = psf_ftell (psf) ;
337 			psf_log_printf (psf, "Have 0 marker at position %D (0x%x).\n", pos, pos) ;
338 			break ;
339 			} ;
340 
341 		psf_store_read_chunk_u32 (&psf->rchunks, marker, psf_ftell (psf), chunk_size) ;
342 
343 		switch (marker)
344 		{	case RIFF_MARKER :
345 			case RIFX_MARKER :
346 					if (parsestage)
347 						return SFE_WAV_NO_RIFF ;
348 
349 					parsestage |= HAVE_RIFF ;
350 
351 					RIFFsize = chunk_size ;
352 
353 					if (psf->fileoffset > 0 && psf->filelength > RIFFsize + 8)
354 					{	/* Set file length. */
355 						psf->filelength = RIFFsize + 8 ;
356 						if (marker == RIFF_MARKER)
357 							psf_log_printf (psf, "RIFF : %u\n", RIFFsize) ;
358 						else
359 							psf_log_printf (psf, "RIFX : %u\n", RIFFsize) ;
360 						}
361 					else if (psf->filelength < RIFFsize + 2 * SIGNED_SIZEOF (marker))
362 					{	if (marker == RIFF_MARKER)
363 							psf_log_printf (psf, "RIFF : %u (should be %D)\n", RIFFsize, psf->filelength - 2 * SIGNED_SIZEOF (marker)) ;
364 						else
365 							psf_log_printf (psf, "RIFX : %u (should be %D)\n", RIFFsize, psf->filelength - 2 * SIGNED_SIZEOF (marker)) ;
366 
367 						RIFFsize = psf->filelength - 2 * SIGNED_SIZEOF (RIFFsize) ;
368 						}
369 					else
370 					{	if (marker == RIFF_MARKER)
371 							psf_log_printf (psf, "RIFF : %u\n", RIFFsize) ;
372 						else
373 							psf_log_printf (psf, "RIFX : %u\n", RIFFsize) ;
374 					} ;
375 
376 					psf_binheader_readf (psf, "m", &marker) ;
377 					if (marker != WAVE_MARKER)
378 						return SFE_WAV_NO_WAVE ;
379 					parsestage |= HAVE_WAVE ;
380 					psf_log_printf (psf, "WAVE\n") ;
381 					chunk_size = 0 ;
382 					break ;
383 
384 			case fmt_MARKER :
385 					if ((parsestage & (HAVE_RIFF | HAVE_WAVE)) != (HAVE_RIFF | HAVE_WAVE))
386 						return SFE_WAV_NO_FMT ;
387 
388 					/* If this file has a SECOND fmt chunk, I don't want to know about it. */
389 					if (parsestage & HAVE_fmt)
390 						break ;
391 
392 					parsestage |= HAVE_fmt ;
393 
394 					psf_log_printf (psf, "fmt  : %d\n", chunk_size) ;
395 
396 					if ((error = wavlike_read_fmt_chunk (psf, chunk_size)))
397 						return error ;
398 
399 					format = wav_fmt->format ;
400 					break ;
401 
402 			case data_MARKER :
403 					if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt))
404 						return SFE_WAV_NO_DATA ;
405 
406 					if (psf->file.mode == SFM_RDWR && (parsestage & HAVE_other) != 0)
407 						return SFE_RDWR_BAD_HEADER ;
408 
409 					parsestage |= HAVE_data ;
410 
411 					psf->datalength = chunk_size ;
412 					if (psf->datalength & 1)
413 						psf_log_printf (psf, "*** 'data' chunk should be an even number of bytes in length.\n") ;
414 
415 					psf->dataoffset = psf_ftell (psf) ;
416 
417 					if (psf->dataoffset > 0)
418 					{	if (chunk_size == 0 && RIFFsize == 8 && psf->filelength > 44)
419 						{	psf_log_printf (psf, "*** Looks like a WAV file which wasn't closed properly. Fixing it.\n") ;
420 							psf->datalength = psf->filelength - psf->dataoffset ;
421 							} ;
422 
423 						if (psf->datalength > psf->filelength - psf->dataoffset)
424 						{	psf_log_printf (psf, "data : %D (should be %D)\n", psf->datalength, psf->filelength - psf->dataoffset) ;
425 							psf->datalength = psf->filelength - psf->dataoffset ;
426 							}
427 						else
428 							psf_log_printf (psf, "data : %D\n", psf->datalength) ;
429 
430 						/* Only set dataend if there really is data at the end. */
431 						if (psf->datalength + psf->dataoffset < psf->filelength)
432 							psf->dataend = psf->datalength + psf->dataoffset ;
433 
434 						psf->datalength += chunk_size & 1 ;
435 						chunk_size = 0 ;
436 						} ;
437 
438 					if (! psf->sf.seekable || psf->dataoffset < 0)
439 						break ;
440 
441 					/* Seek past data and continue reading header. */
442 					psf_fseek (psf, psf->datalength, SEEK_CUR) ;
443 
444 					if (psf_ftell (psf) != psf->datalength + psf->dataoffset)
445 						psf_log_printf (psf, "*** psf_fseek past end error ***\n") ;
446 					break ;
447 
448 			case fact_MARKER :
449 					if ((parsestage & (HAVE_RIFF | HAVE_WAVE)) != (HAVE_RIFF | HAVE_WAVE))
450 						return SFE_WAV_BAD_FACT ;
451 
452 					parsestage |= HAVE_fact ;
453 
454 					if ((parsestage & HAVE_fmt) != HAVE_fmt)
455 						psf_log_printf (psf, "*** Should have 'fmt ' chunk before 'fact'\n") ;
456 
457 					psf_binheader_readf (psf, "4", & (fact_chunk.frames)) ;
458 
459 					if (chunk_size > SIGNED_SIZEOF (fact_chunk))
460 						psf_binheader_readf (psf, "j", (int) (chunk_size - SIGNED_SIZEOF (fact_chunk))) ;
461 
462 					if (chunk_size)
463 						psf_log_printf (psf, "%M : %u\n", marker, chunk_size) ;
464 					else
465 						psf_log_printf (psf, "%M : %u (should not be zero)\n", marker, chunk_size) ;
466 
467 					psf_log_printf (psf, "  frames  : %d\n", fact_chunk.frames) ;
468 					break ;
469 
470 			case PEAK_MARKER :
471 					if ((parsestage & (HAVE_RIFF | HAVE_WAVE | HAVE_fmt)) != (HAVE_RIFF | HAVE_WAVE | HAVE_fmt))
472 						return SFE_WAV_PEAK_B4_FMT ;
473 
474 					parsestage |= HAVE_PEAK ;
475 
476 					psf_log_printf (psf, "%M : %u\n", marker, chunk_size) ;
477 					if ((error = wavlike_read_peak_chunk (psf, chunk_size)) != 0)
478 						return error ;
479 					psf->peak_info->peak_loc = ((parsestage & HAVE_data) == 0) ? SF_PEAK_START : SF_PEAK_END ;
480 					break ;
481 
482 			case cue_MARKER :
483 					parsestage |= HAVE_other ;
484 
485 					{	uint32_t thisread, bytesread, cue_count, position, offset ;
486 						int id, chunk_id, chunk_start, block_start, cue_index ;
487 
488 						bytesread = psf_binheader_readf (psf, "4", &cue_count) ;
489 						psf_log_printf (psf, "%M : %u\n", marker, chunk_size) ;
490 
491 						if (cue_count > 2500) /* 2500 is close to the largest number of cues possible because of block sizes */
492 						{	psf_log_printf (psf, "  Count : %u (skipping)\n", cue_count) ;
493 							psf_binheader_readf (psf, "j", chunk_size - bytesread) ;
494 							break ;
495 							} ;
496 
497 						psf_log_printf (psf, "  Count : %d\n", cue_count) ;
498 
499 						if (psf->cues)
500 						{	free (psf->cues) ;
501 							psf->cues = NULL ;
502 							} ;
503 
504 						if ((psf->cues = psf_cues_alloc (cue_count)) == NULL)
505 							return SFE_MALLOC_FAILED ;
506 
507 						cue_index = 0 ;
508 
509 						while (cue_count)
510 						{
511 							if ((thisread = psf_binheader_readf (psf, "e44m444", &id, &position, &chunk_id, &chunk_start, &block_start, &offset)) == 0)
512 								break ;
513 							bytesread += thisread ;
514 
515 							if (cue_index < 10) /* avoid swamping log buffer with cues */
516 								psf_log_printf (psf,	"   Cue ID : %2d"
517 											"  Pos : %5u  Chunk : %M"
518 											"  Chk Start : %d  Blk Start : %d"
519 											"  Offset : %5d\n",
520 										id, position, chunk_id, chunk_start, block_start, offset) ;
521 							else if (cue_index == 10)
522 								psf_log_printf (psf,	"   (Skipping)\n") ;
523 
524 							psf->cues->cue_points [cue_index].indx = id ;
525 							psf->cues->cue_points [cue_index].position = position ;
526 							psf->cues->cue_points [cue_index].fcc_chunk = chunk_id ;
527 							psf->cues->cue_points [cue_index].chunk_start = chunk_start ;
528 							psf->cues->cue_points [cue_index].block_start = block_start ;
529 							psf->cues->cue_points [cue_index].sample_offset = offset ;
530 							psf->cues->cue_points [cue_index].name [0] = '\0' ;
531 							cue_count -- ;
532 							cue_index ++ ;
533 							} ;
534 
535 						if (bytesread != chunk_size)
536 						{	psf_log_printf (psf, "**** Chunk size weirdness (%d != %d)\n", chunk_size, bytesread) ;
537 							psf_binheader_readf (psf, "j", chunk_size - bytesread) ;
538 							} ;
539 						} ;
540 					break ;
541 
542 			case smpl_MARKER :
543 					parsestage |= HAVE_other ;
544 
545 					psf_log_printf (psf, "smpl : %u\n", chunk_size) ;
546 
547 					if ((error = wav_read_smpl_chunk (psf, chunk_size)))
548 						return error ;
549 					break ;
550 
551 			case acid_MARKER :
552 					parsestage |= HAVE_other ;
553 
554 					psf_log_printf (psf, "acid : %u\n", chunk_size) ;
555 
556 					if ((error = wav_read_acid_chunk (psf, chunk_size)))
557 						return error ;
558 					break ;
559 
560 			case INFO_MARKER :
561 			case LIST_MARKER :
562 					parsestage |= HAVE_other ;
563 
564 					if ((error = wavlike_subchunk_parse (psf, marker, chunk_size)) != 0)
565 						return error ;
566 					break ;
567 
568 			case bext_MARKER :
569 					/*
570 					The 'bext' chunk can actually be updated, so don't need to set this.
571 					parsestage |= HAVE_other ;
572 					*/
573 					if ((error = wavlike_read_bext_chunk (psf, chunk_size)))
574 						return error ;
575 					break ;
576 
577 			case PAD_MARKER :
578 					/*
579 					We can eat into a 'PAD ' chunk if we need to.
580 					parsestage |= HAVE_other ;
581 					*/
582 					psf_log_printf (psf, "%M : %u\n", marker, chunk_size) ;
583 					psf_binheader_readf (psf, "j", chunk_size) ;
584 					break ;
585 
586 			case cart_MARKER:
587 					if ((error = wavlike_read_cart_chunk (psf, chunk_size)))
588 						return error ;
589 					break ;
590 
591 			case iXML_MARKER : /* See http://en.wikipedia.org/wiki/IXML */
592 			case strc_MARKER : /* Multiple of 32 bytes. */
593 			case afsp_MARKER :
594 			case clm_MARKER :
595 			case elmo_MARKER :
596 			case levl_MARKER :
597 			case plst_MARKER :
598 			case minf_MARKER :
599 			case elm1_MARKER :
600 			case regn_MARKER :
601 			case ovwf_MARKER :
602 			case inst_MARKER :
603 			case AFAn_MARKER :
604 			case umid_MARKER :
605 			case SyLp_MARKER :
606 			case Cr8r_MARKER :
607 			case JUNK_MARKER :
608 			case PMX_MARKER :
609 			case DISP_MARKER :
610 			case MEXT_MARKER :
611 			case FLLR_MARKER :
612 					psf_log_printf (psf, "%M : %u\n", marker, chunk_size) ;
613 					psf_binheader_readf (psf, "j", chunk_size) ;
614 					break ;
615 
616 			default :
617 					if (chunk_size >= 0xffff0000)
618 					{	done = SF_TRUE ;
619 						psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D with length %u. Exiting parser.\n", marker, psf_ftell (psf) - 8, chunk_size) ;
620 						break ;
621 						} ;
622 
623 					if ((marker & TAG__MARKER_MASK) == TAG__MARKER &&
624 						psf_ftell (psf) - 8 + 128 == psf->filelength)
625 					{	psf_log_printf (psf, "*** Hit ID3v1 trailer. Exiting parser.\n") ;
626 						chunk_size = 128 ;
627 						done = SF_TRUE ;
628 						parsestage |= HAVE_other ;
629 						break ;
630 						} ;
631 
632 					if (psf_isprint ((marker >> 24) & 0xFF) && psf_isprint ((marker >> 16) & 0xFF)
633 						&& psf_isprint ((marker >> 8) & 0xFF) && psf_isprint (marker & 0xFF))
634 					{	psf_log_printf (psf, "*** %M : %u (unknown marker)\n", marker, chunk_size) ;
635 						psf_binheader_readf (psf, "j", chunk_size) ;
636 						break ;
637 						} ;
638 					if (psf_ftell (psf) & 0x03)
639 					{	psf_log_printf (psf, "  Unknown chunk marker at position %D. Resynching.\n", psf_ftell (psf) - 8) ;
640 						psf_binheader_readf (psf, "j", -3) ;
641 						/* File is too messed up so we prevent editing in RDWR mode here. */
642 						parsestage |= HAVE_other ;
643 						break ;
644 						} ;
645 					psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D. Exiting parser.\n", marker, psf_ftell (psf) - 8) ;
646 					done = SF_TRUE ;
647 					break ;
648 			} ;	/* switch (marker) */
649 
650 		if (chunk_size >= psf->filelength)
651 		{	psf_log_printf (psf, "*** Chunk size %u > file length %D. Exiting parser.\n", chunk_size, psf->filelength) ;
652 			break ;
653 			} ;
654 
655 		if (! psf->sf.seekable && (parsestage & HAVE_data))
656 			break ;
657 
658 		if (psf_ftell (psf) >= psf->filelength - SIGNED_SIZEOF (chunk_size))
659 		{	psf_log_printf (psf, "End\n") ;
660 			break ;
661 			} ;
662 		} ; /* while (1) */
663 
664 	if (psf->dataoffset <= 0)
665 		return SFE_WAV_NO_DATA ;
666 
667 	if (psf->sf.channels < 1)
668 		return SFE_CHANNEL_COUNT_ZERO ;
669 
670 	if (psf->sf.channels > SF_MAX_CHANNELS)
671 		return SFE_CHANNEL_COUNT ;
672 
673 	if (format != WAVE_FORMAT_PCM && (parsestage & HAVE_fact) == 0)
674 		psf_log_printf (psf, "**** All non-PCM format files should have a 'fact' chunk.\n") ;
675 
676 	/* WAVs can be little or big endian */
677 	psf->endian = psf->rwf_endian ;
678 
679 	psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
680 
681 	if (psf->is_pipe == 0)
682 	{	/*
683 		** Check for 'wvpk' at the start of the DATA section. Not able to
684 		** handle this.
685 		*/
686 		psf_binheader_readf (psf, "4", &marker) ;
687 		if (marker == wvpk_MARKER || marker == OggS_MARKER)
688 			return SFE_WAV_WVPK_DATA ;
689 		} ;
690 
691 	/* Seek to start of DATA section. */
692 	psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
693 
694 	if (psf->blockwidth)
695 	{	if (psf->filelength - psf->dataoffset < psf->datalength)
696 			psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
697 		else
698 			psf->sf.frames = psf->datalength / psf->blockwidth ;
699 		} ;
700 
701 	switch (format)
702 	{	case WAVE_FORMAT_EXTENSIBLE :
703 			if (psf->sf.format == (SF_FORMAT_WAVEX | SF_FORMAT_MS_ADPCM))
704 			{	*blockalign = wav_fmt->msadpcm.blockalign ;
705 				*framesperblock = wav_fmt->msadpcm.samplesperblock ;
706 				} ;
707 			break ;
708 
709 		case WAVE_FORMAT_NMS_VBXADPCM :
710 			switch (wav_fmt->min.bitwidth)
711 			{	case 2 :
712 					psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16 ;
713 					break ;
714 				case 3 :
715 					psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24 ;
716 					break ;
717 				case 4 :
718 					psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32 ;
719 					break ;
720 
721 				default :
722 					return SFE_UNIMPLEMENTED ;
723 				}
724 				break ;
725 
726 		case WAVE_FORMAT_PCM :
727 					psf->sf.format = SF_FORMAT_WAV | u_bitwidth_to_subformat (psf->bytewidth * 8) ;
728 					break ;
729 
730 		case WAVE_FORMAT_MULAW :
731 		case IBM_FORMAT_MULAW :
732 					psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ULAW) ;
733 					break ;
734 
735 		case WAVE_FORMAT_ALAW :
736 		case IBM_FORMAT_ALAW :
737 					psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_ALAW) ;
738 					break ;
739 
740 		case WAVE_FORMAT_MS_ADPCM :
741 					psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM) ;
742 					*blockalign = wav_fmt->msadpcm.blockalign ;
743 					*framesperblock = wav_fmt->msadpcm.samplesperblock ;
744 					break ;
745 
746 		case WAVE_FORMAT_IMA_ADPCM :
747 					psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM) ;
748 					*blockalign = wav_fmt->ima.blockalign ;
749 					*framesperblock = wav_fmt->ima.samplesperblock ;
750 					break ;
751 
752 		case WAVE_FORMAT_GSM610 :
753 					psf->sf.format = (SF_FORMAT_WAV | SF_FORMAT_GSM610) ;
754 					break ;
755 
756 		case WAVE_FORMAT_IEEE_FLOAT :
757 					psf->sf.format = SF_FORMAT_WAV ;
758 					psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ;
759 					break ;
760 
761 		case WAVE_FORMAT_G721_ADPCM :
762 					psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_G721_32 ;
763 					break ;
764 
765 		case WAVE_FORMAT_MPEGLAYER3 :
766 					psf->sf.format = SF_FORMAT_WAV | SF_FORMAT_MPEG_LAYER_III ;
767 					if (parsestage & HAVE_fact)
768 						psf->sf.frames = fact_chunk.frames ;
769 					break ;
770 
771 		default : return SFE_UNIMPLEMENTED ;
772 		} ;
773 
774 	if (wpriv->fmt_is_broken)
775 		wavlike_analyze (psf) ;
776 
777 	/* Only set the format endian-ness if its non-standard big-endian. */
778 	if (psf->endian == SF_ENDIAN_BIG)
779 		psf->sf.format |= SF_ENDIAN_BIG ;
780 
781 	return 0 ;
782 } /* wav_read_header */
783 
784 static int
wav_write_fmt_chunk(SF_PRIVATE * psf)785 wav_write_fmt_chunk (SF_PRIVATE *psf)
786 {	int subformat, fmt_size, add_fact_chunk = 0 ;
787 
788 	subformat = SF_CODEC (psf->sf.format) ;
789 
790 	switch (subformat)
791 	{	case SF_FORMAT_PCM_U8 :
792 		case SF_FORMAT_PCM_16 :
793 		case SF_FORMAT_PCM_24 :
794 		case SF_FORMAT_PCM_32 :
795 					fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
796 
797 					/* fmt : format, channels, samplerate */
798 					psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_PCM), BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ;
799 					/*  fmt : bytespersec */
800 					psf_binheader_writef (psf, "4", BHW4 (psf->sf.samplerate * psf->bytewidth * psf->sf.channels)) ;
801 					/*  fmt : blockalign, bitwidth */
802 					psf_binheader_writef (psf, "22", BHW2 (psf->bytewidth * psf->sf.channels), BHW2 (psf->bytewidth * 8)) ;
803 					break ;
804 
805 		case SF_FORMAT_FLOAT :
806 		case SF_FORMAT_DOUBLE :
807 					fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
808 
809 					/* fmt : format, channels, samplerate */
810 					psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_IEEE_FLOAT), BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ;
811 					/*  fmt : bytespersec */
812 					psf_binheader_writef (psf, "4", BHW4 (psf->sf.samplerate * psf->bytewidth * psf->sf.channels)) ;
813 					/*  fmt : blockalign, bitwidth */
814 					psf_binheader_writef (psf, "22", BHW2 (psf->bytewidth * psf->sf.channels), BHW2 (psf->bytewidth * 8)) ;
815 
816 					add_fact_chunk = SF_TRUE ;
817 					break ;
818 
819 		case SF_FORMAT_ULAW :
820 					fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 ;
821 
822 					/* fmt : format, channels, samplerate */
823 					psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_MULAW), BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ;
824 					/*  fmt : bytespersec */
825 					psf_binheader_writef (psf, "4", BHW4 (psf->sf.samplerate * psf->bytewidth * psf->sf.channels)) ;
826 					/*  fmt : blockalign, bitwidth, extrabytes */
827 					psf_binheader_writef (psf, "222", BHW2 (psf->bytewidth * psf->sf.channels), BHW2 (8), BHW2 (0)) ;
828 
829 					add_fact_chunk = SF_TRUE ;
830 					break ;
831 
832 		case SF_FORMAT_ALAW :
833 					fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 ;
834 
835 					/* fmt : format, channels, samplerate */
836 					psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_ALAW), BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ;
837 					/*  fmt : bytespersec */
838 					psf_binheader_writef (psf, "4", BHW4 (psf->sf.samplerate * psf->bytewidth * psf->sf.channels)) ;
839 					/*  fmt : blockalign, bitwidth, extrabytes */
840 					psf_binheader_writef (psf, "222", BHW2 (psf->bytewidth * psf->sf.channels), BHW2 (8), BHW2 (0)) ;
841 
842 					add_fact_chunk = SF_TRUE ;
843 					break ;
844 
845 		/* Lite remove start */
846 		case SF_FORMAT_IMA_ADPCM :
847 					{	int blockalign, framesperblock, bytespersec ;
848 
849 						blockalign		= wavlike_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
850 						framesperblock	= 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
851 						bytespersec		= (psf->sf.samplerate * blockalign) / framesperblock ;
852 
853 						/* fmt chunk. */
854 						fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
855 
856 						/* fmt : size, WAV format type, channels, samplerate, bytespersec */
857 						psf_binheader_writef (psf, "42244", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_IMA_ADPCM),
858 									BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate), BHW4 (bytespersec)) ;
859 
860 						/* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
861 						psf_binheader_writef (psf, "2222", BHW2 (blockalign), BHW2 (4), BHW2 (2), BHW2 (framesperblock)) ;
862 						} ;
863 
864 					add_fact_chunk = SF_TRUE ;
865 					break ;
866 
867 		case SF_FORMAT_MS_ADPCM :
868 					{	int	blockalign, framesperblock, bytespersec, extrabytes ;
869 
870 						blockalign		= wavlike_srate2blocksize (psf->sf.samplerate * psf->sf.channels) ;
871 						framesperblock	= 2 + 2 * (blockalign - 7 * psf->sf.channels) / psf->sf.channels ;
872 						bytespersec		= (psf->sf.samplerate * blockalign) / framesperblock ;
873 
874 						/* fmt chunk. */
875 						extrabytes	= 2 + 2 + WAVLIKE_MSADPCM_ADAPT_COEFF_COUNT * (2 + 2) ;
876 						fmt_size	= 2 + 2 + 4 + 4 + 2 + 2 + 2 + extrabytes ;
877 
878 						/* fmt : size, WAV format type, channels. */
879 						psf_binheader_writef (psf, "422", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_MS_ADPCM), BHW2 (psf->sf.channels)) ;
880 
881 						/* fmt : samplerate, bytespersec. */
882 						psf_binheader_writef (psf, "44", BHW4 (psf->sf.samplerate), BHW4 (bytespersec)) ;
883 
884 						/* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
885 						psf_binheader_writef (psf, "22222", BHW2 (blockalign), BHW2 (4), BHW2 (extrabytes), BHW2 (framesperblock), BHW2 (7)) ;
886 
887 						wavlike_msadpcm_write_adapt_coeffs (psf) ;
888 						} ;
889 
890 					add_fact_chunk = SF_TRUE ;
891 					break ;
892 
893 
894 		case SF_FORMAT_G721_32 :
895 					/* fmt chunk. */
896 					fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
897 
898 					/* fmt : size, WAV format type, channels, samplerate, bytespersec */
899 					psf_binheader_writef (psf, "42244", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_G721_ADPCM),
900 								BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate), BHW4 (psf->sf.samplerate * psf->sf.channels / 2)) ;
901 
902 					/* fmt : blockalign, bitwidth, extrabytes, auxblocksize. */
903 					psf_binheader_writef (psf, "2222", BHW2 (64), BHW2 (4), BHW2 (2), BHW2 (0)) ;
904 
905 					add_fact_chunk = SF_TRUE ;
906 					break ;
907 
908 		case SF_FORMAT_NMS_ADPCM_16 :
909 		case SF_FORMAT_NMS_ADPCM_24 :
910 		case SF_FORMAT_NMS_ADPCM_32 :
911 					{	int bytespersec, blockalign, bitwidth ;
912 
913 						bitwidth 	= subformat == SF_FORMAT_NMS_ADPCM_16 ? 2 : subformat == SF_FORMAT_NMS_ADPCM_24 ? 3 : 4 ;
914 						blockalign 	= 20 * bitwidth + 2 ;
915 						bytespersec	= psf->sf.samplerate * blockalign / 160 ;
916 
917 						/* fmt chunk. */
918 						fmt_size = 2 + 2 + 4 + 4 + 2 + 2 ;
919 
920 						/* fmt : format, channels, samplerate */
921 						psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_NMS_VBXADPCM),
922 									BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ;
923 						/*  fmt : bytespersec, blockalign, bitwidth */
924 						psf_binheader_writef (psf, "422", BHW4 (bytespersec), BHW2 (blockalign), BHW2 (bitwidth)) ;
925 
926 						add_fact_chunk = SF_TRUE ;
927 						break ;
928 						}
929 
930 		/* Lite remove end */
931 
932 		case SF_FORMAT_GSM610 :
933 					{	int	blockalign, framesperblock, bytespersec ;
934 
935 						blockalign		= WAVLIKE_GSM610_BLOCKSIZE ;
936 						framesperblock	= WAVLIKE_GSM610_SAMPLES ;
937 						bytespersec		= (psf->sf.samplerate * blockalign) / framesperblock ;
938 
939 						/* fmt chunk. */
940 						fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 ;
941 
942 						/* fmt : size, WAV format type, channels. */
943 						psf_binheader_writef (psf, "422", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_GSM610), BHW2 (psf->sf.channels)) ;
944 
945 						/* fmt : samplerate, bytespersec. */
946 						psf_binheader_writef (psf, "44", BHW4 (psf->sf.samplerate), BHW4 (bytespersec)) ;
947 
948 						/* fmt : blockalign, bitwidth, extrabytes, framesperblock. */
949 						psf_binheader_writef (psf, "2222", BHW2 (blockalign), BHW2 (0), BHW2 (2), BHW2 (framesperblock)) ;
950 						} ;
951 
952 					add_fact_chunk = SF_TRUE ;
953 					break ;
954 
955 #if (ENABLE_EXPERIMENTAL_CODE == 0)
956 		case SF_FORMAT_MPEG_LAYER_III :
957 					{	int bytespersec, blockalign, flags, blocksize, samplesperblock, codecdelay ;
958 
959 						/* Intended to be set as the average sample rate.
960 						** TODO: Maybe re-write this on close with final average
961 						** byterate? */
962 						bytespersec		= psf->byterate (psf) ;
963 
964 						/* Average block size. Info only I think. */
965 						blocksize		= (1152 * bytespersec) / psf->sf.samplerate ;
966 
967 						/* Can be set to block size IFF the block size is
968 						** constant, set to 1 otherwise. Constant sized
969 						** MPEG block streams are uncommon (CBR @ 32kHz and
970 						** 48kHz only. Meh. */
971 						blockalign		= 1 ;
972 
973 						/* TODO: Only flags defined are padding-type. I /think/
974 						** Lame does ISO style padding by default, which has a
975 						** flag value of 0.
976 						*/
977 						flags			= 0 ;
978 
979 						/* Should only vary per MPEG 1.0/2.0 vs '2.5'.
980 						** TODO: Move this out to MPEG specific place? */
981 						samplesperblock	= psf->sf.samplerate >= 32000 ? 1152 : 576 ;
982 
983 						/* Set as 0 if unknown.
984 						** TODO: Plumb this cleanly from Lame.
985 						*/
986 						codecdelay		= 0 ;
987 
988 						/* fmt chunk. */
989 						fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 + 4 + 2 + 2 + 2 ;
990 
991 						/* fmt : size, WAV format type, channels. */
992 						psf_binheader_writef (psf, "422", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_MPEGLAYER3), BHW2 (psf->sf.channels)) ;
993 
994 						/* fmt : samplerate, bytespersec. */
995 						psf_binheader_writef (psf, "44", BHW4 (psf->sf.samplerate), BHW4 (bytespersec)) ;
996 
997 						/* fmt : blockalign, bitwidth, extrabytes, id. */
998 						psf_binheader_writef (psf, "2222", BHW2 (blockalign), BHW2 (0), BHW2 (12), BHW2 (1)) ;
999 
1000 						/* fmt : flags, blocksize, samplesperblock, codecdelay */
1001 						psf_binheader_writef (psf, "4222", BHW4 (flags), BHW2 (blocksize), BHW2 (samplesperblock), BHW2 (codecdelay)) ;
1002 						} ;
1003 
1004 					add_fact_chunk = SF_TRUE ;
1005 					break ;
1006 #endif
1007 
1008 		default : 	return SFE_UNIMPLEMENTED ;
1009 		} ;
1010 
1011 	if (add_fact_chunk)
1012 		psf_binheader_writef (psf, "tm48", BHWm (fact_MARKER), BHW4 (4), BHW8 (psf->sf.frames)) ;
1013 
1014 	return 0 ;
1015 } /* wav_write_fmt_chunk */
1016 
1017 static int
wavex_write_fmt_chunk(SF_PRIVATE * psf)1018 wavex_write_fmt_chunk (SF_PRIVATE *psf)
1019 {	WAVLIKE_PRIVATE	*wpriv ;
1020 	int subformat, fmt_size ;
1021 
1022 	if ((wpriv = psf->container_data) == NULL)
1023 		return SFE_INTERNAL ;
1024 
1025 	subformat = SF_CODEC (psf->sf.format) ;
1026 
1027 	/* initial section (same for all, it appears) */
1028 	switch (subformat)
1029 	{	case SF_FORMAT_PCM_U8 :
1030 		case SF_FORMAT_PCM_16 :
1031 		case SF_FORMAT_PCM_24 :
1032 		case SF_FORMAT_PCM_32 :
1033 		case SF_FORMAT_FLOAT :
1034 		case SF_FORMAT_DOUBLE :
1035 		case SF_FORMAT_ULAW :
1036 		case SF_FORMAT_ALAW :
1037 			fmt_size = 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 + 4 + 4 + 2 + 2 + 8 ;
1038 
1039 			/* fmt : format, channels, samplerate */
1040 			psf_binheader_writef (psf, "4224", BHW4 (fmt_size), BHW2 (WAVE_FORMAT_EXTENSIBLE), BHW2 (psf->sf.channels), BHW4 (psf->sf.samplerate)) ;
1041 			/*  fmt : bytespersec */
1042 			psf_binheader_writef (psf, "4", BHW4 (psf->sf.samplerate * psf->bytewidth * psf->sf.channels)) ;
1043 			/*  fmt : blockalign, bitwidth */
1044 			psf_binheader_writef (psf, "22", BHW2 (psf->bytewidth * psf->sf.channels), BHW2 (psf->bytewidth * 8)) ;
1045 
1046 			/* cbSize 22 is sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX) */
1047 			psf_binheader_writef (psf, "2", BHW2 (22)) ;
1048 
1049 			/* wValidBitsPerSample, for our use same as bitwidth as we use it fully */
1050 			psf_binheader_writef (psf, "2", BHW2 (psf->bytewidth * 8)) ;
1051 
1052 			/* For an Ambisonic file set the channel mask to zero.
1053 			** Otherwise use a default based on the channel count.
1054 			*/
1055 			if (wpriv->wavex_ambisonic != SF_AMBISONIC_NONE)
1056 				psf_binheader_writef (psf, "4", BHW4 (0)) ;
1057 			else if (wpriv->wavex_channelmask != 0)
1058 				psf_binheader_writef (psf, "4", BHW4 (wpriv->wavex_channelmask)) ;
1059 			else
1060 			{	/*
1061 				** Ok some liberty is taken here to use the most commonly used channel masks
1062 				** instead of "no mapping". If you really want to use "no mapping" for 8 channels and less
1063 				** please don't use wavex. (otherwise we'll have to create a new SF_COMMAND)
1064 				*/
1065 				switch (psf->sf.channels)
1066 				{	case 1 :	/* center channel mono */
1067 						psf_binheader_writef (psf, "4", BHW4 (0x4)) ;
1068 						break ;
1069 
1070 					case 2 :	/* front left and right */
1071 						psf_binheader_writef (psf, "4", BHW4 (0x1 | 0x2)) ;
1072 						break ;
1073 
1074 					case 4 :	/* Quad */
1075 						psf_binheader_writef (psf, "4", BHW4 (0x1 | 0x2 | 0x10 | 0x20)) ;
1076 						break ;
1077 
1078 					case 6 :	/* 5.1 */
1079 						psf_binheader_writef (psf, "4", BHW4 (0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20)) ;
1080 						break ;
1081 
1082 					case 8 :	/* 7.1 */
1083 						psf_binheader_writef (psf, "4", BHW4 (0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x40 | 0x80)) ;
1084 						break ;
1085 
1086 					default :	/* 0 when in doubt , use direct out, ie NO mapping*/
1087 						psf_binheader_writef (psf, "4", BHW4 (0x0)) ;
1088 						break ;
1089 					} ;
1090 				} ;
1091 			break ;
1092 
1093 		case SF_FORMAT_MS_ADPCM : /* Todo, GUID exists might have different header as per wav_write_header */
1094 		default :
1095 			return SFE_UNIMPLEMENTED ;
1096 		} ;
1097 
1098 	/* GUID section, different for each */
1099 
1100 	switch (subformat)
1101 	{	case SF_FORMAT_PCM_U8 :
1102 		case SF_FORMAT_PCM_16 :
1103 		case SF_FORMAT_PCM_24 :
1104 		case SF_FORMAT_PCM_32 :
1105 			wavlike_write_guid (psf, wpriv->wavex_ambisonic == SF_AMBISONIC_NONE ?
1106 						&MSGUID_SUBTYPE_PCM : &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM) ;
1107 			break ;
1108 
1109 		case SF_FORMAT_FLOAT :
1110 		case SF_FORMAT_DOUBLE :
1111 			wavlike_write_guid (psf, wpriv->wavex_ambisonic == SF_AMBISONIC_NONE ?
1112 						&MSGUID_SUBTYPE_IEEE_FLOAT : &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT) ;
1113 			break ;
1114 
1115 		case SF_FORMAT_ULAW :
1116 			wavlike_write_guid (psf, &MSGUID_SUBTYPE_MULAW) ;
1117 			break ;
1118 
1119 		case SF_FORMAT_ALAW :
1120 			wavlike_write_guid (psf, &MSGUID_SUBTYPE_ALAW) ;
1121 			break ;
1122 
1123 #if 0
1124 		/* This is dead code due to return in previous switch statement. */
1125 		case SF_FORMAT_MS_ADPCM : /* todo, GUID exists */
1126 			wavlike_write_guid (psf, &MSGUID_SUBTYPE_MS_ADPCM) ;
1127 			break ;
1128 			return SFE_UNIMPLEMENTED ;
1129 #endif
1130 
1131 		default : return SFE_UNIMPLEMENTED ;
1132 		} ;
1133 
1134 	psf_binheader_writef (psf, "tm48", BHWm (fact_MARKER), BHW4 (4), BHW8 (psf->sf.frames)) ;
1135 
1136 	return 0 ;
1137 } /* wavex_write_fmt_chunk */
1138 
1139 
1140 static int
wav_write_header(SF_PRIVATE * psf,int calc_length)1141 wav_write_header (SF_PRIVATE *psf, int calc_length)
1142 {	sf_count_t	current ;
1143 	int 		error, has_data = SF_FALSE ;
1144 
1145 	current = psf_ftell (psf) ;
1146 
1147 	if (current > psf->dataoffset)
1148 		has_data = SF_TRUE ;
1149 
1150 	if (calc_length)
1151 	{	psf->filelength = psf_get_filelen (psf) ;
1152 
1153 		psf->datalength = psf->filelength - psf->dataoffset ;
1154 
1155 		if (psf->dataend)
1156 			psf->datalength -= psf->filelength - psf->dataend ;
1157 		else if (psf->bytewidth > 0 && psf->sf.seekable == SF_TRUE)
1158 			psf->datalength = psf->sf.frames * psf->bytewidth * psf->sf.channels ;
1159 		} ;
1160 
1161 	/* Reset the current header length to zero. */
1162 	psf->header.ptr [0] = 0 ;
1163 	psf->header.indx = 0 ;
1164 	psf_fseek (psf, 0, SEEK_SET) ;
1165 
1166 	/*
1167 	** RIFX signifies big-endian format for all header and data.
1168 	** To prevent lots of code copying here, we'll set the psf->rwf_endian flag
1169 	** once here, and never specify endian-ness for all other header operations.
1170 	*/
1171 
1172 	/* RIFF/RIFX marker, length, WAVE and 'fmt ' markers. */
1173 
1174 	if (psf->endian == SF_ENDIAN_LITTLE)
1175 		psf_binheader_writef (psf, "etm8", BHWm (RIFF_MARKER), BHW8 ((psf->filelength < 8) ? 8 : psf->filelength - 8)) ;
1176 	else
1177 		psf_binheader_writef (psf, "Etm8", BHWm (RIFX_MARKER), BHW8 ((psf->filelength < 8) ? 8 : psf->filelength - 8)) ;
1178 
1179 	/* WAVE and 'fmt ' markers. */
1180 	psf_binheader_writef (psf, "mm", BHWm (WAVE_MARKER), BHWm (fmt_MARKER)) ;
1181 
1182 	/* Write the 'fmt ' chunk. */
1183 	switch (SF_CONTAINER (psf->sf.format))
1184 	{	case SF_FORMAT_WAV :
1185 				if ((error = wav_write_fmt_chunk (psf)) != 0)
1186 					return error ;
1187 				break ;
1188 
1189 		case SF_FORMAT_WAVEX :
1190 				if ((error = wavex_write_fmt_chunk (psf)) != 0)
1191 					return error ;
1192 				break ;
1193 
1194 		default :
1195 				return SFE_UNIMPLEMENTED ;
1196 		} ;
1197 
1198 	/* The LIST/INFO chunk. */
1199 	if (psf->strings.flags & SF_STR_LOCATE_START)
1200 		wavlike_write_strings (psf, SF_STR_LOCATE_START) ;
1201 
1202 	if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_START)
1203 		wavlike_write_peak_chunk (psf) ;
1204 
1205 	if (psf->broadcast_16k != NULL)
1206 		wavlike_write_bext_chunk (psf) ;
1207 
1208 	if (psf->cart_16k != NULL)
1209 		wavlike_write_cart_chunk (psf) ;
1210 
1211 	if (psf->cues != NULL)
1212 	{	uint32_t k ;
1213 
1214 		psf_binheader_writef (psf, "em44", BHWm (cue_MARKER), BHW4 (4 + psf->cues->cue_count * 6 * 4), BHW4 (psf->cues->cue_count)) ;
1215 
1216 		for (k = 0 ; k < psf->cues->cue_count ; k++)
1217 			psf_binheader_writef (psf, "e44m444", BHW4 (psf->cues->cue_points [k].indx), BHW4 (psf->cues->cue_points [k].position),
1218 						BHWm (psf->cues->cue_points [k].fcc_chunk), BHW4 (psf->cues->cue_points [k].chunk_start),
1219 						BHW4 (psf->cues->cue_points [k].block_start), BHW4 (psf->cues->cue_points [k].sample_offset)) ;
1220 		} ;
1221 
1222 	if (psf->instrument != NULL)
1223 	{	int		tmp ;
1224 		double	dtune = (double) (0x40000000) / 25.0 ;
1225 
1226 		psf_binheader_writef (psf, "m4", BHWm (smpl_MARKER), BHW4 (9 * 4 + psf->instrument->loop_count * 6 * 4)) ;
1227 		psf_binheader_writef (psf, "44", BHW4 (0), BHW4 (0)) ; /* Manufacturer zero is everyone */
1228 		tmp = (int) (1.0e9 / psf->sf.samplerate) ; /* Sample period in nano seconds */
1229 		psf_binheader_writef (psf, "44", BHW4 (tmp), BHW4 (psf->instrument->basenote)) ;
1230 		tmp = (uint32_t) (psf->instrument->detune * dtune + 0.5) ;
1231 		psf_binheader_writef (psf, "4", BHW4 (tmp)) ;
1232 		psf_binheader_writef (psf, "44", BHW4 (0), BHW4 (0)) ; /* SMTPE format */
1233 		psf_binheader_writef (psf, "44", BHW4 (psf->instrument->loop_count), BHW4 (0)) ;
1234 
1235 		/* Make sure we don't read past the loops array end. */
1236 		if (psf->instrument->loop_count > ARRAY_LEN (psf->instrument->loops))
1237 			psf->instrument->loop_count = ARRAY_LEN (psf->instrument->loops) ;
1238 
1239 		for (tmp = 0 ; tmp < psf->instrument->loop_count ; tmp++)
1240 		{	int type ;
1241 
1242 			type = psf->instrument->loops [tmp].mode ;
1243 			type = (type == SF_LOOP_FORWARD ? 0 : type == SF_LOOP_BACKWARD ? 2 : type == SF_LOOP_ALTERNATING ? 1 : 32) ;
1244 
1245 			psf_binheader_writef (psf, "44", BHW4 (tmp), BHW4 (type)) ;
1246 			psf_binheader_writef (psf, "44", BHW4 (psf->instrument->loops [tmp].start), BHW4 (psf->instrument->loops [tmp].end - 1)) ;
1247 			psf_binheader_writef (psf, "44", BHW4 (0), BHW4 (psf->instrument->loops [tmp].count)) ;
1248 			} ;
1249 		} ;
1250 
1251 	/* Write custom headers. */
1252 	if (psf->wchunks.used > 0)
1253 		wavlike_write_custom_chunks (psf) ;
1254 
1255 	if (psf->header.indx + 16 < psf->dataoffset)
1256 	{	/* Add PAD data if necessary. */
1257 		size_t k = psf->dataoffset - (psf->header.indx + 16) ;
1258 		psf_binheader_writef (psf, "m4z", BHWm (PAD_MARKER), BHW4 (k), BHWz (k)) ;
1259 		} ;
1260 
1261 	psf_binheader_writef (psf, "tm8", BHWm (data_MARKER), BHW8 (psf->datalength)) ;
1262 	psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;
1263 	if (psf->error)
1264 		return psf->error ;
1265 
1266 	if (has_data && psf->dataoffset != psf->header.indx)
1267 	{	psf_log_printf (psf, "Oooops : has_data && psf->dataoffset != psf->header.indx\n") ;
1268 		return psf->error = SFE_INTERNAL ;
1269 		} ;
1270 
1271 	psf->dataoffset = psf->header.indx ;
1272 
1273 	if (! has_data)
1274 		psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
1275 	else if (current > 0)
1276 		psf_fseek (psf, current, SEEK_SET) ;
1277 
1278 	return psf->error ;
1279 } /* wav_write_header */
1280 
1281 
1282 static int
wav_write_tailer(SF_PRIVATE * psf)1283 wav_write_tailer (SF_PRIVATE *psf)
1284 {
1285 	/* Reset the current header buffer length to zero. */
1286 	psf->header.ptr [0] = 0 ;
1287 	psf->header.indx = 0 ;
1288 
1289 	if (psf->bytewidth > 0 && psf->sf.seekable == SF_TRUE)
1290 	{	psf->datalength = psf->sf.frames * psf->bytewidth * psf->sf.channels ;
1291 		psf->dataend = psf->dataoffset + psf->datalength ;
1292 		} ;
1293 
1294 	if (psf->dataend > 0)
1295 		psf_fseek (psf, psf->dataend, SEEK_SET) ;
1296 	else
1297 		psf->dataend = psf_fseek (psf, 0, SEEK_END) ;
1298 
1299 	if (psf->dataend & 1)
1300 		psf_binheader_writef (psf, "z", BHWz (1)) ;
1301 
1302 	/* Add a PEAK chunk if requested. */
1303 	if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_END)
1304 		wavlike_write_peak_chunk (psf) ;
1305 
1306 	if (psf->strings.flags & SF_STR_LOCATE_END)
1307 		wavlike_write_strings (psf, SF_STR_LOCATE_END) ;
1308 
1309 	/* Write the tailer. */
1310 	if (psf->header.indx > 0)
1311 		psf_fwrite (psf->header.ptr, psf->header.indx, 1, psf) ;
1312 
1313 	return 0 ;
1314 } /* wav_write_tailer */
1315 
1316 static int
wav_close(SF_PRIVATE * psf)1317 wav_close (SF_PRIVATE *psf)
1318 {
1319 	if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
1320 	{	wav_write_tailer (psf) ;
1321 
1322 		if (psf->file.mode == SFM_RDWR)
1323 		{	sf_count_t current = psf_ftell (psf) ;
1324 
1325 			/*
1326 			**	If the mode is RDWR and the current position is less than the
1327 			**	filelength, truncate the file.
1328 			*/
1329 
1330 			if (current < psf->filelength)
1331 			{	psf_ftruncate (psf, current) ;
1332 				psf->filelength = current ;
1333 				} ;
1334 			} ;
1335 
1336 		psf->write_header (psf, SF_TRUE) ;
1337 		} ;
1338 
1339 	return 0 ;
1340 } /* wav_close */
1341 
1342 static int
wav_command(SF_PRIVATE * psf,int command,void * UNUSED (data),int datasize)1343 wav_command (SF_PRIVATE *psf, int command, void * UNUSED (data), int datasize)
1344 {	WAVLIKE_PRIVATE	*wpriv ;
1345 
1346 	if ((wpriv = psf->container_data) == NULL)
1347 		return SFE_INTERNAL ;
1348 
1349 	switch (command)
1350 	{	case SFC_WAVEX_SET_AMBISONIC :
1351 			if ((SF_CONTAINER (psf->sf.format)) == SF_FORMAT_WAVEX)
1352 			{	if (datasize == SF_AMBISONIC_NONE)
1353 					wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ;
1354 				else if (datasize == SF_AMBISONIC_B_FORMAT)
1355 					wpriv->wavex_ambisonic = SF_AMBISONIC_B_FORMAT ;
1356 				else
1357 					return 0 ;
1358 				} ;
1359 			return wpriv->wavex_ambisonic ;
1360 
1361 		case SFC_WAVEX_GET_AMBISONIC :
1362 			return wpriv->wavex_ambisonic ;
1363 
1364 		case SFC_SET_CHANNEL_MAP_INFO :
1365 			wpriv->wavex_channelmask = wavlike_gen_channel_mask (psf->channel_map, psf->sf.channels) ;
1366 			return (wpriv->wavex_channelmask != 0) ;
1367 
1368 		default :
1369 			break ;
1370 	} ;
1371 
1372 	return 0 ;
1373 } /* wav_command */
1374 
1375 static int
wav_read_smpl_chunk(SF_PRIVATE * psf,uint32_t chunklen)1376 wav_read_smpl_chunk (SF_PRIVATE *psf, uint32_t chunklen)
1377 {	char buffer [512] ;
1378 	uint32_t thisread, bytesread = 0, dword, sampler_data, loop_count, actually_loop_count = 0 ;
1379 	uint32_t note, pitch, start, end, type = -1, count ;
1380 	int j, k ;
1381 
1382 	chunklen += (chunklen & 1) ;
1383 
1384 	bytesread += psf_binheader_readf (psf, "4", &dword) ;
1385 	psf_log_printf (psf, "  Manufacturer : %X\n", dword) ;
1386 
1387 	bytesread += psf_binheader_readf (psf, "4", &dword) ;
1388 	psf_log_printf (psf, "  Product      : %u\n", dword) ;
1389 
1390 	bytesread += psf_binheader_readf (psf, "4", &dword) ;
1391 	psf_log_printf (psf, "  Period       : %u nsec\n", dword) ;
1392 
1393 	bytesread += psf_binheader_readf (psf, "4", &note) ;
1394 	psf_log_printf (psf, "  Midi Note    : %u\n", note) ;
1395 
1396 	bytesread += psf_binheader_readf (psf, "4", &pitch) ;
1397 	if (pitch != 0)
1398 	{	snprintf (buffer, sizeof (buffer), "%f",
1399 					(1.0 * 0x80000000) / ((uint32_t) pitch)) ;
1400 		psf_log_printf (psf, "  Pitch Fract. : %s\n", buffer) ;
1401 		}
1402 	else
1403 		psf_log_printf (psf, "  Pitch Fract. : 0\n") ;
1404 
1405 	bytesread += psf_binheader_readf (psf, "4", &dword) ;
1406 	psf_log_printf (psf, "  SMPTE Format : %u\n", dword) ;
1407 
1408 	bytesread += psf_binheader_readf (psf, "4", &dword) ;
1409 	snprintf (buffer, sizeof (buffer), "%02"PRIu32 ":%02"PRIu32 ":%02"PRIu32
1410 				" %02"PRIu32 "", (dword >> 24) & 0x7F, (dword >> 16) & 0x7F,
1411 				(dword >> 8) & 0x7F, dword & 0x7F) ;
1412 	psf_log_printf (psf, "  SMPTE Offset : %s\n", buffer) ;
1413 
1414 	bytesread += psf_binheader_readf (psf, "4", &loop_count) ;
1415 	psf_log_printf (psf, "  Loop Count   : %u\n", loop_count) ;
1416 
1417 	if (loop_count == 0 && chunklen == bytesread)
1418 		return 0 ;
1419 
1420 	/* Sampler Data holds the number of data bytes after the CUE chunks which
1421 	** is not actually CUE data. Display value after CUE data.
1422 	*/
1423 	bytesread += psf_binheader_readf (psf, "4", &sampler_data) ;
1424 
1425 	if (psf->instrument)
1426 	{	psf_log_printf (psf, "  Found more than one SMPL chunk, using last one.\n") ;
1427 		free (psf->instrument) ;
1428 		psf->instrument = NULL ;
1429 		} ;
1430 	if ((psf->instrument = psf_instrument_alloc ()) == NULL)
1431 		return SFE_MALLOC_FAILED ;
1432 
1433 	psf->instrument->loop_count = loop_count ;
1434 
1435 	for (j = 0 ; loop_count > 0 && chunklen - bytesread >= 24 ; j ++)
1436 	{	if ((thisread = psf_binheader_readf (psf, "4", &dword)) == 0)
1437 			break ;
1438 		bytesread += thisread ;
1439 		psf_log_printf (psf, "    Cue ID : %2u", dword) ;
1440 
1441 		bytesread += psf_binheader_readf (psf, "4", &type) ;
1442 		psf_log_printf (psf, "  Type : %2u", type) ;
1443 
1444 		bytesread += psf_binheader_readf (psf, "4", &start) ;
1445 		psf_log_printf (psf, "  Start : %5u", start) ;
1446 
1447 		bytesread += psf_binheader_readf (psf, "4", &end) ;
1448 		psf_log_printf (psf, "  End : %5u", end) ;
1449 
1450 		bytesread += psf_binheader_readf (psf, "4", &dword) ;
1451 		psf_log_printf (psf, "  Fraction : %5u", dword) ;
1452 
1453 		bytesread += psf_binheader_readf (psf, "4", &count) ;
1454 		psf_log_printf (psf, "  Count : %5u\n", count) ;
1455 
1456 		if (j < ARRAY_LEN (psf->instrument->loops))
1457 		{	psf->instrument->loops [j].start = start ;
1458 			psf->instrument->loops [j].end = end + 1 ;
1459 			psf->instrument->loops [j].count = count ;
1460 
1461 			switch (type)
1462 			{	case 0 :
1463 					psf->instrument->loops [j].mode = SF_LOOP_FORWARD ;
1464 					break ;
1465 				case 1 :
1466 					psf->instrument->loops [j].mode = SF_LOOP_ALTERNATING ;
1467 					break ;
1468 				case 2 :
1469 					psf->instrument->loops [j].mode = SF_LOOP_BACKWARD ;
1470 					break ;
1471 				default:
1472 					psf->instrument->loops [j].mode = SF_LOOP_NONE ;
1473 					break ;
1474 				} ;
1475 			} ;
1476 		actually_loop_count ++ ;
1477 		} ;
1478 
1479 	if (actually_loop_count > ARRAY_LEN (psf->instrument->loops))
1480 	{
1481 		psf_log_printf (psf, "*** Warning, actual Loop Points count exceeds %u, changing Loop Count from %u to %u\n", ARRAY_LEN (psf->instrument->loops), loop_count, ARRAY_LEN (psf->instrument->loops)) ;
1482 		psf->instrument->loop_count = ARRAY_LEN (psf->instrument->loops) ;
1483 		}
1484 	else if (loop_count != actually_loop_count)
1485 	{	psf_log_printf (psf, "*** Warning, actual Loop Points count != Loop Count, changing Loop Count from %u to %u\n", loop_count, actually_loop_count) ;
1486 		psf->instrument->loop_count = actually_loop_count ;
1487 		} ;
1488 
1489 	if (chunklen - bytesread == 0)
1490 	{	if (sampler_data != 0)
1491 			psf_log_printf (psf, "  Sampler Data : %u (should be 0)\n", sampler_data) ;
1492 		else
1493 			psf_log_printf (psf, "  Sampler Data : %u\n", sampler_data) ;
1494 		}
1495 	else
1496 	{	if (sampler_data != chunklen - bytesread)
1497 		{	psf_log_printf (psf, "  Sampler Data : %u (should have been %u)\n", sampler_data, chunklen - bytesread) ;
1498 			sampler_data = chunklen - bytesread ;
1499 			}
1500 		else
1501 			psf_log_printf (psf, "  Sampler Data : %u\n", sampler_data) ;
1502 
1503 		psf_log_printf (psf, "      ") ;
1504 		for (k = 0 ; k < (int) sampler_data ; k++)
1505 		{	char ch ;
1506 
1507 			if (k > 0 && (k % 20) == 0)
1508 				psf_log_printf (psf, "\n      ") ;
1509 
1510 			if ((thisread = psf_binheader_readf (psf, "1", &ch)) == 0)
1511 				break ;
1512 			bytesread += thisread ;
1513 			psf_log_printf (psf, "%02X ", ch & 0xFF) ;
1514 			} ;
1515 
1516 		psf_log_printf (psf, "\n") ;
1517 		} ;
1518 
1519 	psf->instrument->basenote = note ;
1520 	psf->instrument->detune = (int8_t) (pitch / (0x40000000 / 25.0) + 0.5) ;
1521 	psf->instrument->gain = 1 ;
1522 	psf->instrument->velocity_lo = psf->instrument->key_lo = 0 ;
1523 	psf->instrument->velocity_hi = psf->instrument->key_hi = 127 ;
1524 
1525 	return 0 ;
1526 } /* wav_read_smpl_chunk */
1527 
1528 /*
1529 ** The acid chunk goes a little something like this:
1530 **
1531 ** 4 bytes          'acid'
1532 ** 4 bytes (int)     length of chunk starting at next byte
1533 **
1534 ** 4 bytes (int)     type of file:
1535 **        this appears to be a bit mask,however some combinations
1536 **        are probably impossible and/or qualified as "errors"
1537 **
1538 **        0x01 On: One Shot         Off: Loop
1539 **        0x02 On: Root note is Set Off: No root
1540 **        0x04 On: Stretch is On,   Off: Strech is OFF
1541 **        0x08 On: Disk Based       Off: Ram based
1542 **        0x10 On: ??????????       Off: ????????? (Acidizer puts that ON)
1543 **
1544 ** 2 bytes (short)      root note
1545 **        if type 0x10 is OFF : [C,C#,(...),B] -> [0x30 to 0x3B]
1546 **        if type 0x10 is ON  : [C,C#,(...),B] -> [0x3C to 0x47]
1547 **         (both types fit on same MIDI pitch albeit different octaves, so who cares)
1548 **
1549 ** 2 bytes (short)      ??? always set to 0x8000
1550 ** 4 bytes (float)      ??? seems to be always 0
1551 ** 4 bytes (int)        number of beats
1552 ** 2 bytes (short)      meter denominator   //always 4 in SF/ACID
1553 ** 2 bytes (short)      meter numerator     //always 4 in SF/ACID
1554 **                      //are we sure about the order?? usually its num/denom
1555 ** 4 bytes (float)      tempo
1556 **
1557 */
1558 
1559 static int
wav_read_acid_chunk(SF_PRIVATE * psf,uint32_t chunklen)1560 wav_read_acid_chunk (SF_PRIVATE *psf, uint32_t chunklen)
1561 {	char buffer [512] ;
1562 	uint32_t bytesread = 0 ;
1563 	int	beats, flags ;
1564 	short rootnote, q1, meter_denom, meter_numer ;
1565 	float q2, tempo ;
1566 
1567 	chunklen += (chunklen & 1) ;
1568 
1569 	bytesread += psf_binheader_readf (psf, "422f", &flags, &rootnote, &q1, &q2) ;
1570 
1571 	snprintf (buffer, sizeof (buffer), "%f", q2) ;
1572 
1573 	psf_log_printf (psf, "  Flags     : 0x%04x (%s,%s,%s,%s,%s)\n", flags,
1574 			(flags & 0x01) ? "OneShot" : "Loop",
1575 			(flags & 0x02) ? "RootNoteValid" : "RootNoteInvalid",
1576 			(flags & 0x04) ? "StretchOn" : "StretchOff",
1577 			(flags & 0x08) ? "DiskBased" : "RAMBased",
1578 			(flags & 0x10) ? "??On" : "??Off") ;
1579 
1580 	psf_log_printf (psf, "  Root note : 0x%x\n  ????      : 0x%04x\n  ????      : %s\n",
1581 				rootnote, q1, buffer) ;
1582 
1583 	bytesread += psf_binheader_readf (psf, "422f", &beats, &meter_denom, &meter_numer, &tempo) ;
1584 	snprintf (buffer, sizeof (buffer), "%f", tempo) ;
1585 	psf_log_printf (psf, "  Beats     : %d\n  Meter     : %d/%d\n  Tempo     : %s\n",
1586 				beats, meter_numer, meter_denom, buffer) ;
1587 
1588 	psf_binheader_readf (psf, "j", chunklen - bytesread) ;
1589 
1590 	if (psf->loop_info)
1591 	{	psf_log_printf (psf, "  Found existing loop info, using last one.\n") ;
1592 		free (psf->loop_info) ;
1593 		psf->loop_info = NULL ;
1594 		} ;
1595 	if ((psf->loop_info = calloc (1, sizeof (SF_LOOP_INFO))) == NULL)
1596 		return SFE_MALLOC_FAILED ;
1597 
1598 	psf->loop_info->time_sig_num	= meter_numer ;
1599 	psf->loop_info->time_sig_den	= meter_denom ;
1600 	psf->loop_info->loop_mode		= (flags & 0x01) ? SF_LOOP_NONE : SF_LOOP_FORWARD ;
1601 	psf->loop_info->num_beats		= beats ;
1602 	psf->loop_info->bpm				= tempo ;
1603 	psf->loop_info->root_key		= (flags & 0x02) ? rootnote : -1 ;
1604 
1605 	return 0 ;
1606 } /* wav_read_acid_chunk */
1607 
1608 /*==============================================================================
1609 */
1610 
1611 static int
wav_set_chunk(SF_PRIVATE * psf,const SF_CHUNK_INFO * chunk_info)1612 wav_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info)
1613 {	return psf_save_write_chunk (&psf->wchunks, chunk_info) ;
1614 } /* wav_set_chunk */
1615 
1616 static SF_CHUNK_ITERATOR *
wav_next_chunk_iterator(SF_PRIVATE * psf,SF_CHUNK_ITERATOR * iterator)1617 wav_next_chunk_iterator (SF_PRIVATE *psf, SF_CHUNK_ITERATOR * iterator)
1618 {	return psf_next_chunk_iterator (&psf->rchunks, iterator) ;
1619 } /* wav_next_chunk_iterator */
1620 
1621 static int
wav_get_chunk_size(SF_PRIVATE * psf,const SF_CHUNK_ITERATOR * iterator,SF_CHUNK_INFO * chunk_info)1622 wav_get_chunk_size (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info)
1623 {	int indx ;
1624 
1625 	if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0)
1626 		return SFE_UNKNOWN_CHUNK ;
1627 
1628 	chunk_info->datalen = psf->rchunks.chunks [indx].len ;
1629 
1630 	return SFE_NO_ERROR ;
1631 } /* wav_get_chunk_size */
1632 
1633 static int
wav_get_chunk_data(SF_PRIVATE * psf,const SF_CHUNK_ITERATOR * iterator,SF_CHUNK_INFO * chunk_info)1634 wav_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info)
1635 {	int indx ;
1636 	sf_count_t pos ;
1637 
1638 	if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0)
1639 		return SFE_UNKNOWN_CHUNK ;
1640 
1641 	if (chunk_info->data == NULL)
1642 		return SFE_BAD_CHUNK_DATA_PTR ;
1643 
1644 	chunk_info->id_size = psf->rchunks.chunks [indx].id_size ;
1645 	memcpy (chunk_info->id, psf->rchunks.chunks [indx].id, sizeof (chunk_info->id) / sizeof (*chunk_info->id)) ;
1646 
1647 	pos = psf_ftell (psf) ;
1648 	psf_fseek (psf, psf->rchunks.chunks [indx].offset, SEEK_SET) ;
1649 	psf_fread (chunk_info->data, SF_MIN (chunk_info->datalen, psf->rchunks.chunks [indx].len), 1, psf) ;
1650 	psf_fseek (psf, pos, SEEK_SET) ;
1651 
1652 	return SFE_NO_ERROR ;
1653 } /* wav_get_chunk_data */
1654