2 ** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
3 ** Copyright (C) 2004-2005 David Viens <davidv@plogue.com>
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.
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.
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.
32 /* Known WAVEFORMATEXTENSIBLE GUIDS. */
33 static const EXT_SUBFORMAT MSGUID_SUBTYPE_PCM
=
34 { 0x00000001, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
37 static const EXT_SUBFORMAT MSGUID_SUBTYPE_MS_ADPCM
=
38 { 0x00000002, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
41 static const EXT_SUBFORMAT MSGUID_SUBTYPE_IEEE_FLOAT
=
42 { 0x00000003, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
45 static const EXT_SUBFORMAT MSGUID_SUBTYPE_ALAW
=
46 { 0x00000006, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
49 static const EXT_SUBFORMAT MSGUID_SUBTYPE_MULAW
=
50 { 0x00000007, 0x0000, 0x0010, { 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }
54 ** the next two are from
55 ** http://dream.cs.bath.ac.uk/researchdev/wave-ex/bformat.html
58 static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM
=
59 { 0x00000001, 0x0721, 0x11d3, { 0x86, 0x44, 0xc8, 0xc1, 0xca, 0x00, 0x00, 0x00 }
62 static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT
=
63 { 0x00000003, 0x0721, 0x11d3, { 0x86, 0x44, 0xc8, 0xc1, 0xca, 0x00, 0x00, 0x00 }
68 /* maybe interesting one day to read the following through sf_read_raw */
69 /* http://www.bath.ac.uk/~masrwd/pvocex/pvocex.html */
70 static const EXT_SUBFORMAT MSGUID_SUBTYPE_PVOCEX
=
71 { 0x8312b9c2, 0x2e6e, 0x11d4, { 0xa8, 0x24, 0xde, 0x5b, 0x96, 0xc3, 0xab, 0x21 }
75 /* This stores which bit in dwChannelMask maps to which channel */
76 static const struct chanmap_s
79 } channel_mask_bits
[] =
80 { /* WAVEFORMATEXTENSIBLE doesn't distuingish FRONT_LEFT from LEFT */
81 { SF_CHANNEL_MAP_LEFT
, "L" },
82 { SF_CHANNEL_MAP_RIGHT
, "R" },
83 { SF_CHANNEL_MAP_CENTER
, "C" },
84 { SF_CHANNEL_MAP_LFE
, "LFE" },
85 { SF_CHANNEL_MAP_REAR_LEFT
, "Ls" },
86 { SF_CHANNEL_MAP_REAR_RIGHT
, "Rs" },
87 { SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER
, "Lc" },
88 { SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER
, "Rc" },
89 { SF_CHANNEL_MAP_REAR_CENTER
, "Cs" },
90 { SF_CHANNEL_MAP_SIDE_LEFT
, "Sl" },
91 { SF_CHANNEL_MAP_SIDE_RIGHT
, "Sr" },
92 { SF_CHANNEL_MAP_TOP_CENTER
, "Tc" },
93 { SF_CHANNEL_MAP_TOP_FRONT_LEFT
, "Tfl" },
94 { SF_CHANNEL_MAP_TOP_FRONT_CENTER
, "Tfc" },
95 { SF_CHANNEL_MAP_TOP_FRONT_RIGHT
, "Tfr" },
96 { SF_CHANNEL_MAP_TOP_REAR_LEFT
, "Trl" },
97 { SF_CHANNEL_MAP_TOP_REAR_CENTER
, "Trc" },
98 { SF_CHANNEL_MAP_TOP_REAR_RIGHT
, "Trr" },
101 /*------------------------------------------------------------------------------
102 * Private static functions.
106 wavex_guid_equal (const EXT_SUBFORMAT
* first
, const EXT_SUBFORMAT
* second
)
107 { return !memcmp (first
, second
, sizeof (EXT_SUBFORMAT
)) ;
108 } /* wavex_guid_equal */
113 wav_w64_read_fmt_chunk (SF_PRIVATE
*psf
, int fmtsize
)
114 { WAV_PRIVATE
* wpriv
;
116 int bytesread
, k
, bytespersec
= 0 ;
118 if ((wpriv
= psf
->container_data
) == NULL
)
119 return SFE_INTERNAL
;
120 wav_fmt
= &wpriv
->wav_fmt
;
122 memset (wav_fmt
, 0, sizeof (WAV_FMT
)) ;
125 return SFE_WAV_FMT_SHORT
;
127 /* assume psf->rwf_endian is already properly set */
129 /* Read the minimal WAV file header here. */
130 bytesread
= psf_binheader_readf (psf
, "224422",
131 &(wav_fmt
->format
), &(wav_fmt
->min
.channels
),
132 &(wav_fmt
->min
.samplerate
), &(wav_fmt
->min
.bytespersec
),
133 &(wav_fmt
->min
.blockalign
), &(wav_fmt
->min
.bitwidth
)) ;
135 psf_log_printf (psf
, " Format : 0x%X => %s\n", wav_fmt
->format
, wav_w64_format_str (wav_fmt
->format
)) ;
136 psf_log_printf (psf
, " Channels : %d\n", wav_fmt
->min
.channels
) ;
137 psf_log_printf (psf
, " Sample Rate : %d\n", wav_fmt
->min
.samplerate
) ;
139 if (wav_fmt
->format
== WAVE_FORMAT_PCM
&& wav_fmt
->min
.blockalign
== 0
140 && wav_fmt
->min
.bitwidth
> 0 && wav_fmt
->min
.channels
> 0)
141 { wav_fmt
->min
.blockalign
= wav_fmt
->min
.bitwidth
/ 8 + (wav_fmt
->min
.bitwidth
% 8 > 0 ? 1 : 0) ;
142 wav_fmt
->min
.blockalign
*= wav_fmt
->min
.channels
;
143 psf_log_printf (psf
, " Block Align : 0 (should be %d)\n", wav_fmt
->min
.blockalign
) ;
146 psf_log_printf (psf
, " Block Align : %d\n", wav_fmt
->min
.blockalign
) ;
148 if (wav_fmt
->format
== WAVE_FORMAT_PCM
&& wav_fmt
->min
.bitwidth
== 24 &&
149 wav_fmt
->min
.blockalign
== 4 * wav_fmt
->min
.channels
)
150 { psf_log_printf (psf
, " Bit Width : 24\n") ;
152 psf_log_printf (psf
, "\n"
153 " Ambiguous information in 'fmt ' chunk. Possibile file types:\n"
154 " 0) Invalid IEEE float file generated by Syntrillium's Cooledit!\n"
155 " 1) File generated by ALSA's arecord containing 24 bit samples in 32 bit containers.\n"
156 " 2) 24 bit file with incorrect Block Align value.\n"
159 wpriv
->fmt_is_broken
= 1 ;
161 else if (wav_fmt
->min
.bitwidth
== 0)
162 { switch (wav_fmt
->format
)
163 { case WAVE_FORMAT_GSM610
:
164 case WAVE_FORMAT_IPP_ITU_G_723_1
:
165 psf_log_printf (psf
, " Bit Width : %d\n", wav_fmt
->min
.bitwidth
) ;
168 psf_log_printf (psf
, " Bit Width : %d (should not be 0)\n", wav_fmt
->min
.bitwidth
) ;
172 { switch (wav_fmt
->format
)
173 { case WAVE_FORMAT_GSM610
:
174 case WAVE_FORMAT_IPP_ITU_G_723_1
:
175 psf_log_printf (psf
, " Bit Width : %d (should be 0)\n", wav_fmt
->min
.bitwidth
) ;
178 psf_log_printf (psf
, " Bit Width : %d\n", wav_fmt
->min
.bitwidth
) ;
182 psf
->sf
.samplerate
= wav_fmt
->min
.samplerate
;
183 psf
->sf
.frames
= 0 ; /* Correct this when reading data chunk. */
184 psf
->sf
.channels
= wav_fmt
->min
.channels
;
186 switch (wav_fmt
->format
)
187 { case WAVE_FORMAT_PCM
:
188 case WAVE_FORMAT_IEEE_FLOAT
:
189 bytespersec
= wav_fmt
->min
.samplerate
* wav_fmt
->min
.blockalign
;
190 if (wav_fmt
->min
.bytespersec
!= (unsigned) bytespersec
)
191 psf_log_printf (psf
, " Bytes/sec : %d (should be %d)\n", wav_fmt
->min
.bytespersec
, bytespersec
) ;
193 psf_log_printf (psf
, " Bytes/sec : %d\n", wav_fmt
->min
.bytespersec
) ;
195 psf
->bytewidth
= BITWIDTH2BYTES (wav_fmt
->min
.bitwidth
) ;
198 case WAVE_FORMAT_ALAW
:
199 case WAVE_FORMAT_MULAW
:
200 if (wav_fmt
->min
.bytespersec
/ wav_fmt
->min
.blockalign
!= wav_fmt
->min
.samplerate
)
201 psf_log_printf (psf
, " Bytes/sec : %d (should be %d)\n", wav_fmt
->min
.bytespersec
, wav_fmt
->min
.samplerate
* wav_fmt
->min
.blockalign
) ;
203 psf_log_printf (psf
, " Bytes/sec : %d\n", wav_fmt
->min
.bytespersec
) ;
207 { bytesread
+= psf_binheader_readf (psf
, "2", &(wav_fmt
->size20
.extrabytes
)) ;
208 psf_log_printf (psf
, " Extra Bytes : %d\n", wav_fmt
->size20
.extrabytes
) ;
212 case WAVE_FORMAT_IMA_ADPCM
:
213 if (wav_fmt
->min
.bitwidth
!= 4)
214 return SFE_WAV_ADPCM_NOT4BIT
;
215 if (wav_fmt
->min
.channels
< 1 || wav_fmt
->min
.channels
> 2)
216 return SFE_WAV_ADPCM_CHANNELS
;
219 psf_binheader_readf (psf
, "22", &(wav_fmt
->ima
.extrabytes
), &(wav_fmt
->ima
.samplesperblock
)) ;
221 bytespersec
= (wav_fmt
->ima
.samplerate
* wav_fmt
->ima
.blockalign
) / wav_fmt
->ima
.samplesperblock
;
222 if (wav_fmt
->ima
.bytespersec
!= (unsigned) bytespersec
)
223 psf_log_printf (psf
, " Bytes/sec : %d (should be %d)\n", wav_fmt
->ima
.bytespersec
, bytespersec
) ;
225 psf_log_printf (psf
, " Bytes/sec : %d\n", wav_fmt
->ima
.bytespersec
) ;
228 psf_log_printf (psf
, " Extra Bytes : %d\n", wav_fmt
->ima
.extrabytes
) ;
229 psf_log_printf (psf
, " Samples/Block : %d\n", wav_fmt
->ima
.samplesperblock
) ;
232 case WAVE_FORMAT_MS_ADPCM
:
233 if (wav_fmt
->msadpcm
.bitwidth
!= 4)
234 return SFE_WAV_ADPCM_NOT4BIT
;
235 if (wav_fmt
->msadpcm
.channels
< 1 || wav_fmt
->msadpcm
.channels
> 2)
236 return SFE_WAV_ADPCM_CHANNELS
;
239 psf_binheader_readf (psf
, "222", &(wav_fmt
->msadpcm
.extrabytes
),
240 &(wav_fmt
->msadpcm
.samplesperblock
), &(wav_fmt
->msadpcm
.numcoeffs
)) ;
242 bytespersec
= (wav_fmt
->min
.samplerate
* wav_fmt
->min
.blockalign
) / wav_fmt
->msadpcm
.samplesperblock
;
243 if (wav_fmt
->min
.bytespersec
== (unsigned) bytespersec
)
244 psf_log_printf (psf
, " Bytes/sec : %d\n", wav_fmt
->min
.bytespersec
) ;
245 else if (wav_fmt
->min
.bytespersec
== (wav_fmt
->min
.samplerate
/ wav_fmt
->msadpcm
.samplesperblock
) * wav_fmt
->min
.blockalign
)
246 psf_log_printf (psf
, " Bytes/sec : %d (should be %d (MS BUG!))\n", wav_fmt
->min
.bytespersec
, bytespersec
) ;
248 psf_log_printf (psf
, " Bytes/sec : %d (should be %d)\n", wav_fmt
->min
.bytespersec
, bytespersec
) ;
251 psf_log_printf (psf
, " Extra Bytes : %d\n", wav_fmt
->msadpcm
.extrabytes
) ;
252 psf_log_printf (psf
, " Samples/Block : %d\n", wav_fmt
->msadpcm
.samplesperblock
) ;
253 if (wav_fmt
->msadpcm
.numcoeffs
> ARRAY_LEN (wav_fmt
->msadpcm
.coeffs
))
254 { psf_log_printf (psf
, " No. of Coeffs : %d (should be <= %d)\n", wav_fmt
->msadpcm
.numcoeffs
, ARRAY_LEN (wav_fmt
->msadpcm
.coeffs
)) ;
255 wav_fmt
->msadpcm
.numcoeffs
= ARRAY_LEN (wav_fmt
->msadpcm
.coeffs
) ;
258 psf_log_printf (psf
, " No. of Coeffs : %d\n", wav_fmt
->msadpcm
.numcoeffs
) ;
260 psf_log_printf (psf
, " Index Coeffs1 Coeffs2\n") ;
261 for (k
= 0 ; k
< wav_fmt
->msadpcm
.numcoeffs
; k
++)
263 psf_binheader_readf (psf
, "22", &(wav_fmt
->msadpcm
.coeffs
[k
].coeff1
), &(wav_fmt
->msadpcm
.coeffs
[k
].coeff2
)) ;
264 snprintf (psf
->u
.cbuf
, sizeof (psf
->u
.cbuf
), " %2d %7d %7d\n", k
, wav_fmt
->msadpcm
.coeffs
[k
].coeff1
, wav_fmt
->msadpcm
.coeffs
[k
].coeff2
) ;
265 psf_log_printf (psf
, psf
->u
.cbuf
) ;
269 case WAVE_FORMAT_GSM610
:
270 if (wav_fmt
->gsm610
.channels
!= 1 || wav_fmt
->gsm610
.blockalign
!= 65)
271 return SFE_WAV_GSM610_FORMAT
;
274 psf_binheader_readf (psf
, "22", &(wav_fmt
->gsm610
.extrabytes
), &(wav_fmt
->gsm610
.samplesperblock
)) ;
276 if (wav_fmt
->gsm610
.samplesperblock
!= 320)
277 return SFE_WAV_GSM610_FORMAT
;
279 bytespersec
= (wav_fmt
->gsm610
.samplerate
* wav_fmt
->gsm610
.blockalign
) / wav_fmt
->gsm610
.samplesperblock
;
280 if (wav_fmt
->gsm610
.bytespersec
!= (unsigned) bytespersec
)
281 psf_log_printf (psf
, " Bytes/sec : %d (should be %d)\n", wav_fmt
->gsm610
.bytespersec
, bytespersec
) ;
283 psf_log_printf (psf
, " Bytes/sec : %d\n", wav_fmt
->gsm610
.bytespersec
) ;
286 psf_log_printf (psf
, " Extra Bytes : %d\n", wav_fmt
->gsm610
.extrabytes
) ;
287 psf_log_printf (psf
, " Samples/Block : %d\n", wav_fmt
->gsm610
.samplesperblock
) ;
290 case WAVE_FORMAT_EXTENSIBLE
:
291 if (wav_fmt
->ext
.bytespersec
/ wav_fmt
->ext
.blockalign
!= wav_fmt
->ext
.samplerate
)
292 psf_log_printf (psf
, " Bytes/sec : %d (should be %d)\n", wav_fmt
->ext
.bytespersec
, wav_fmt
->ext
.samplerate
* wav_fmt
->ext
.blockalign
) ;
294 psf_log_printf (psf
, " Bytes/sec : %d\n", wav_fmt
->ext
.bytespersec
) ;
297 psf_binheader_readf (psf
, "224", &(wav_fmt
->ext
.extrabytes
), &(wav_fmt
->ext
.validbits
),
298 &(wav_fmt
->ext
.channelmask
)) ;
300 psf_log_printf (psf
, " Valid Bits : %d\n", wav_fmt
->ext
.validbits
) ;
302 if (wav_fmt
->ext
.channelmask
== 0)
303 psf_log_printf (psf
, " Channel Mask : 0x0 (should not be zero)\n") ;
307 wpriv
->wavex_channelmask
= wav_fmt
->ext
.channelmask
;
309 /* It's probably wise to ignore the channel mask if it is all zero */
310 free (psf
->channel_map
) ;
312 if ((psf
->channel_map
= calloc (psf
->sf
.channels
, sizeof (psf
->channel_map
[0]))) == NULL
)
313 return SFE_MALLOC_FAILED
;
315 /* Terminate the buffer we're going to append_snprintf into. */
316 psf
->u
.cbuf
[0] = 0 ;
318 for (bit
= k
= 0 ; bit
< ARRAY_LEN (channel_mask_bits
) ; bit
++)
320 if (wav_fmt
->ext
.channelmask
& (1 << bit
))
321 { if (k
> psf
->sf
.channels
)
322 { psf_log_printf (psf
, "*** More channel map bits than there are channels.\n") ;
326 psf
->channel_map
[k
++] = channel_mask_bits
[bit
].id
;
327 append_snprintf (psf
->u
.cbuf
, sizeof (psf
->u
.cbuf
), "%s, ", channel_mask_bits
[bit
].name
) ;
331 /* Remove trailing ", ". */
332 bit
= strlen (psf
->u
.cbuf
) ;
333 psf
->u
.cbuf
[--bit
] = 0 ;
334 psf
->u
.cbuf
[--bit
] = 0 ;
336 if (k
!= psf
->sf
.channels
)
337 { psf_log_printf (psf
, " Channel Mask : 0x%X\n", wav_fmt
->ext
.channelmask
) ;
338 psf_log_printf (psf
, "*** Less channel map bits than there are channels.\n") ;
341 psf_log_printf (psf
, " Channel Mask : 0x%X (%s)\n", wav_fmt
->ext
.channelmask
, psf
->u
.cbuf
) ;
344 bytesread
+= psf_binheader_readf (psf
, "422", &(wav_fmt
->ext
.esf
.esf_field1
), &(wav_fmt
->ext
.esf
.esf_field2
), &(wav_fmt
->ext
.esf
.esf_field3
)) ;
346 /* compare the esf_fields with each known GUID? and print? */
347 psf_log_printf (psf
, " Subformat\n") ;
348 psf_log_printf (psf
, " esf_field1 : 0x%X\n", wav_fmt
->ext
.esf
.esf_field1
) ;
349 psf_log_printf (psf
, " esf_field2 : 0x%X\n", wav_fmt
->ext
.esf
.esf_field2
) ;
350 psf_log_printf (psf
, " esf_field3 : 0x%X\n", wav_fmt
->ext
.esf
.esf_field3
) ;
351 psf_log_printf (psf
, " esf_field4 : ") ;
352 for (k
= 0 ; k
< 8 ; k
++)
353 { bytesread
+= psf_binheader_readf (psf
, "1", &(wav_fmt
->ext
.esf
.esf_field4
[k
])) ;
354 psf_log_printf (psf
, "0x%X ", wav_fmt
->ext
.esf
.esf_field4
[k
] & 0xFF) ;
356 psf_log_printf (psf
, "\n") ;
357 psf
->bytewidth
= BITWIDTH2BYTES (wav_fmt
->ext
.bitwidth
) ;
359 /* Compare GUIDs for known ones. */
360 if (wavex_guid_equal (&wav_fmt
->ext
.esf
, &MSGUID_SUBTYPE_PCM
))
361 { psf
->sf
.format
= SF_FORMAT_WAVEX
| u_bitwidth_to_subformat (psf
->bytewidth
* 8) ;
362 psf_log_printf (psf
, " format : pcm\n") ;
364 else if (wavex_guid_equal (&wav_fmt
->ext
.esf
, &MSGUID_SUBTYPE_MS_ADPCM
))
365 { psf
->sf
.format
= (SF_FORMAT_WAVEX
| SF_FORMAT_MS_ADPCM
) ;
366 psf_log_printf (psf
, " format : ms adpcm\n") ;
368 else if (wavex_guid_equal (&wav_fmt
->ext
.esf
, &MSGUID_SUBTYPE_IEEE_FLOAT
))
369 { psf
->sf
.format
= SF_FORMAT_WAVEX
| ((psf
->bytewidth
== 8) ? SF_FORMAT_DOUBLE
: SF_FORMAT_FLOAT
) ;
370 psf_log_printf (psf
, " format : IEEE float\n") ;
372 else if (wavex_guid_equal (&wav_fmt
->ext
.esf
, &MSGUID_SUBTYPE_ALAW
))
373 { psf
->sf
.format
= (SF_FORMAT_WAVEX
| SF_FORMAT_ALAW
) ;
374 psf_log_printf (psf
, " format : A-law\n") ;
376 else if (wavex_guid_equal (&wav_fmt
->ext
.esf
, &MSGUID_SUBTYPE_MULAW
))
377 { psf
->sf
.format
= (SF_FORMAT_WAVEX
| SF_FORMAT_ULAW
) ;
378 psf_log_printf (psf
, " format : u-law\n") ;
380 else if (wavex_guid_equal (&wav_fmt
->ext
.esf
, &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_PCM
))
381 { psf
->sf
.format
= SF_FORMAT_WAVEX
| u_bitwidth_to_subformat (psf
->bytewidth
* 8) ;
382 psf_log_printf (psf
, " format : pcm (Ambisonic B)\n") ;
383 wpriv
->wavex_ambisonic
= SF_AMBISONIC_B_FORMAT
;
385 else if (wavex_guid_equal (&wav_fmt
->ext
.esf
, &MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT
))
386 { psf
->sf
.format
= SF_FORMAT_WAVEX
| ((psf
->bytewidth
== 8) ? SF_FORMAT_DOUBLE
: SF_FORMAT_FLOAT
) ;
387 psf_log_printf (psf
, " format : IEEE float (Ambisonic B)\n") ;
388 wpriv
->wavex_ambisonic
= SF_AMBISONIC_B_FORMAT
;
391 return SFE_UNIMPLEMENTED
;
395 case WAVE_FORMAT_G721_ADPCM
:
396 psf_log_printf (psf
, " Bytes/sec : %d\n", wav_fmt
->g72x
.bytespersec
) ;
398 { bytesread
+= psf_binheader_readf (psf
, "22", &(wav_fmt
->g72x
.extrabytes
), &(wav_fmt
->g72x
.auxblocksize
)) ;
399 if (wav_fmt
->g72x
.extrabytes
== 0)
400 psf_log_printf (psf
, " Extra Bytes : %d (should be 2)\n", wav_fmt
->g72x
.extrabytes
) ;
402 psf_log_printf (psf
, " Extra Bytes : %d\n", wav_fmt
->g72x
.extrabytes
) ;
403 psf_log_printf (psf
, " Aux Blk Size : %d\n", wav_fmt
->g72x
.auxblocksize
) ;
405 else if (fmtsize
== 18)
406 { bytesread
+= psf_binheader_readf (psf
, "2", &(wav_fmt
->g72x
.extrabytes
)) ;
407 psf_log_printf (psf
, " Extra Bytes : %d%s\n", wav_fmt
->g72x
.extrabytes
, wav_fmt
->g72x
.extrabytes
!= 0 ? " (should be 0)" : "") ;
410 psf_log_printf (psf
, "*** 'fmt ' chunk should be bigger than this!\n") ;
414 psf_log_printf (psf
, "*** No 'fmt ' chunk dumper for this format!\n") ;
415 return SFE_WAV_BAD_FMT
;
418 if (bytesread
> fmtsize
)
419 { psf_log_printf (psf
, "*** wav_w64_read_fmt_chunk (bytesread > fmtsize)\n") ;
420 return SFE_WAV_BAD_FMT
;
423 psf_binheader_readf (psf
, "j", fmtsize
- bytesread
) ;
425 psf
->blockwidth
= wav_fmt
->min
.channels
* psf
->bytewidth
;
428 } /* wav_w64_read_fmt_chunk */
431 wavex_write_guid (SF_PRIVATE
*psf
, const EXT_SUBFORMAT
* subformat
)
433 psf_binheader_writef (psf
, "422b", subformat
->esf_field1
,
434 subformat
->esf_field2
, subformat
->esf_field3
,
435 subformat
->esf_field4
, make_size_t (8)) ;
436 } /* wavex_write_guid */
440 wavex_gen_channel_mask (const int *chan_map
, int channels
)
441 { int chan
, mask
= 0, bit
= -1, last_bit
= -1 ;
443 if (chan_map
== NULL
)
446 for (chan
= 0 ; chan
< channels
; chan
++)
449 for (k
= bit
+ 1 ; k
< ARRAY_LEN (channel_mask_bits
) ; k
++)
450 if (chan_map
[chan
] == channel_mask_bits
[k
].id
)
455 /* Check for bad sequence. */
464 } /* wavex_gen_channel_mask */
467 wav_w64_analyze (SF_PRIVATE
*psf
)
472 { psf_log_printf (psf
, "*** Error : Reading from a pipe. Can't analyze data section to figure out real data format.\n\n") ;
476 psf_log_printf (psf
, "---------------------------------------------------\n"
477 "Format is known to be broken. Using detection code.\n") ;
479 /* Code goes here. */
480 ad
.endianness
= SF_ENDIAN_LITTLE
;
481 ad
.channels
= psf
->sf
.channels
;
483 psf_fseek (psf
, 3 * 4 * 50, SEEK_SET
) ;
485 while (psf_fread (psf
->u
.ucbuf
, 1, 4096, psf
) == 4096)
486 { format
= audio_detect (psf
, &ad
, psf
->u
.ucbuf
, 4096) ;
491 /* Seek to start of DATA section. */
492 psf_fseek (psf
, psf
->dataoffset
, SEEK_SET
) ;
495 { psf_log_printf (psf
, "wav_w64_analyze : detection failed.\n") ;
500 { case SF_FORMAT_PCM_32
:
501 case SF_FORMAT_FLOAT
:
502 psf_log_printf (psf
, "wav_w64_analyze : found format : 0x%X\n", format
) ;
503 psf
->sf
.format
= (psf
->sf
.format
& ~SF_FORMAT_SUBMASK
) + format
;
505 psf
->blockwidth
= psf
->sf
.channels
* psf
->bytewidth
;
508 case SF_FORMAT_PCM_24
:
509 psf_log_printf (psf
, "wav_w64_analyze : found format : 0x%X\n", format
) ;
510 psf
->sf
.format
= (psf
->sf
.format
& ~SF_FORMAT_SUBMASK
) + format
;
512 psf
->blockwidth
= psf
->sf
.channels
* psf
->bytewidth
;
516 psf_log_printf (psf
, "wav_w64_analyze : unhandled format : 0x%X\n", format
) ;
521 } /* wav_w64_analyze */
523 /*==============================================================================
532 #define FORMAT_TYPE(x) { x, STR (x) }
534 static WAV_FORMAT_DESC wave_descs
[] =
535 { FORMAT_TYPE (WAVE_FORMAT_PCM
),
536 FORMAT_TYPE (WAVE_FORMAT_MS_ADPCM
),
537 FORMAT_TYPE (WAVE_FORMAT_IEEE_FLOAT
),
538 FORMAT_TYPE (WAVE_FORMAT_VSELP
),
539 FORMAT_TYPE (WAVE_FORMAT_IBM_CVSD
),
540 FORMAT_TYPE (WAVE_FORMAT_ALAW
),
541 FORMAT_TYPE (WAVE_FORMAT_MULAW
),
542 FORMAT_TYPE (WAVE_FORMAT_OKI_ADPCM
),
543 FORMAT_TYPE (WAVE_FORMAT_IMA_ADPCM
),
544 FORMAT_TYPE (WAVE_FORMAT_MEDIASPACE_ADPCM
),
545 FORMAT_TYPE (WAVE_FORMAT_SIERRA_ADPCM
),
546 FORMAT_TYPE (WAVE_FORMAT_G723_ADPCM
),
547 FORMAT_TYPE (WAVE_FORMAT_DIGISTD
),
548 FORMAT_TYPE (WAVE_FORMAT_DIGIFIX
),
549 FORMAT_TYPE (WAVE_FORMAT_DIALOGIC_OKI_ADPCM
),
550 FORMAT_TYPE (WAVE_FORMAT_MEDIAVISION_ADPCM
),
551 FORMAT_TYPE (WAVE_FORMAT_CU_CODEC
),
552 FORMAT_TYPE (WAVE_FORMAT_YAMAHA_ADPCM
),
553 FORMAT_TYPE (WAVE_FORMAT_SONARC
),
554 FORMAT_TYPE (WAVE_FORMAT_DSPGROUP_TRUESPEECH
),
555 FORMAT_TYPE (WAVE_FORMAT_ECHOSC1
),
556 FORMAT_TYPE (WAVE_FORMAT_AUDIOFILE_AF36
),
557 FORMAT_TYPE (WAVE_FORMAT_APTX
),
558 FORMAT_TYPE (WAVE_FORMAT_AUDIOFILE_AF10
),
559 FORMAT_TYPE (WAVE_FORMAT_PROSODY_1612
),
560 FORMAT_TYPE (WAVE_FORMAT_LRC
),
561 FORMAT_TYPE (WAVE_FORMAT_DOLBY_AC2
),
562 FORMAT_TYPE (WAVE_FORMAT_GSM610
),
563 FORMAT_TYPE (WAVE_FORMAT_MSNAUDIO
),
564 FORMAT_TYPE (WAVE_FORMAT_ANTEX_ADPCME
),
565 FORMAT_TYPE (WAVE_FORMAT_CONTROL_RES_VQLPC
),
566 FORMAT_TYPE (WAVE_FORMAT_DIGIREAL
),
567 FORMAT_TYPE (WAVE_FORMAT_DIGIADPCM
),
568 FORMAT_TYPE (WAVE_FORMAT_CONTROL_RES_CR10
),
569 FORMAT_TYPE (WAVE_FORMAT_NMS_VBXADPCM
),
570 FORMAT_TYPE (WAVE_FORMAT_ROLAND_RDAC
),
571 FORMAT_TYPE (WAVE_FORMAT_ECHOSC3
),
572 FORMAT_TYPE (WAVE_FORMAT_ROCKWELL_ADPCM
),
573 FORMAT_TYPE (WAVE_FORMAT_ROCKWELL_DIGITALK
),
574 FORMAT_TYPE (WAVE_FORMAT_XEBEC
),
575 FORMAT_TYPE (WAVE_FORMAT_G721_ADPCM
),
576 FORMAT_TYPE (WAVE_FORMAT_G728_CELP
),
577 FORMAT_TYPE (WAVE_FORMAT_MSG723
),
578 FORMAT_TYPE (WAVE_FORMAT_MPEG
),
579 FORMAT_TYPE (WAVE_FORMAT_RT24
),
580 FORMAT_TYPE (WAVE_FORMAT_PAC
),
581 FORMAT_TYPE (WAVE_FORMAT_MPEGLAYER3
),
582 FORMAT_TYPE (WAVE_FORMAT_LUCENT_G723
),
583 FORMAT_TYPE (WAVE_FORMAT_CIRRUS
),
584 FORMAT_TYPE (WAVE_FORMAT_ESPCM
),
585 FORMAT_TYPE (WAVE_FORMAT_VOXWARE
),
586 FORMAT_TYPE (WAVE_FORMAT_CANOPUS_ATRAC
),
587 FORMAT_TYPE (WAVE_FORMAT_G726_ADPCM
),
588 FORMAT_TYPE (WAVE_FORMAT_G722_ADPCM
),
589 FORMAT_TYPE (WAVE_FORMAT_DSAT
),
590 FORMAT_TYPE (WAVE_FORMAT_DSAT_DISPLAY
),
591 FORMAT_TYPE (WAVE_FORMAT_VOXWARE_BYTE_ALIGNED
),
592 FORMAT_TYPE (WAVE_FORMAT_VOXWARE_AC8
),
593 FORMAT_TYPE (WAVE_FORMAT_VOXWARE_AC10
),
594 FORMAT_TYPE (WAVE_FORMAT_VOXWARE_AC16
),
595 FORMAT_TYPE (WAVE_FORMAT_VOXWARE_AC20
),
596 FORMAT_TYPE (WAVE_FORMAT_VOXWARE_RT24
),
597 FORMAT_TYPE (WAVE_FORMAT_VOXWARE_RT29
),
598 FORMAT_TYPE (WAVE_FORMAT_VOXWARE_RT29HW
),
599 FORMAT_TYPE (WAVE_FORMAT_VOXWARE_VR12
),
600 FORMAT_TYPE (WAVE_FORMAT_VOXWARE_VR18
),
601 FORMAT_TYPE (WAVE_FORMAT_VOXWARE_TQ40
),
602 FORMAT_TYPE (WAVE_FORMAT_SOFTSOUND
),
603 FORMAT_TYPE (WAVE_FORMAT_VOXARE_TQ60
),
604 FORMAT_TYPE (WAVE_FORMAT_MSRT24
),
605 FORMAT_TYPE (WAVE_FORMAT_G729A
),
606 FORMAT_TYPE (WAVE_FORMAT_MVI_MV12
),
607 FORMAT_TYPE (WAVE_FORMAT_DF_G726
),
608 FORMAT_TYPE (WAVE_FORMAT_DF_GSM610
),
609 FORMAT_TYPE (WAVE_FORMAT_ONLIVE
),
610 FORMAT_TYPE (WAVE_FORMAT_SBC24
),
611 FORMAT_TYPE (WAVE_FORMAT_DOLBY_AC3_SPDIF
),
612 FORMAT_TYPE (WAVE_FORMAT_ZYXEL_ADPCM
),
613 FORMAT_TYPE (WAVE_FORMAT_PHILIPS_LPCBB
),
614 FORMAT_TYPE (WAVE_FORMAT_PACKED
),
615 FORMAT_TYPE (WAVE_FORMAT_RHETOREX_ADPCM
),
616 FORMAT_TYPE (IBM_FORMAT_MULAW
),
617 FORMAT_TYPE (IBM_FORMAT_ALAW
),
618 FORMAT_TYPE (IBM_FORMAT_ADPCM
),
619 FORMAT_TYPE (WAVE_FORMAT_VIVO_G723
),
620 FORMAT_TYPE (WAVE_FORMAT_VIVO_SIREN
),
621 FORMAT_TYPE (WAVE_FORMAT_DIGITAL_G723
),
622 FORMAT_TYPE (WAVE_FORMAT_CREATIVE_ADPCM
),
623 FORMAT_TYPE (WAVE_FORMAT_CREATIVE_FASTSPEECH8
),
624 FORMAT_TYPE (WAVE_FORMAT_CREATIVE_FASTSPEECH10
),
625 FORMAT_TYPE (WAVE_FORMAT_QUARTERDECK
),
626 FORMAT_TYPE (WAVE_FORMAT_FM_TOWNS_SND
),
627 FORMAT_TYPE (WAVE_FORMAT_BZV_DIGITAL
),
628 FORMAT_TYPE (WAVE_FORMAT_VME_VMPCM
),
629 FORMAT_TYPE (WAVE_FORMAT_OLIGSM
),
630 FORMAT_TYPE (WAVE_FORMAT_OLIADPCM
),
631 FORMAT_TYPE (WAVE_FORMAT_OLICELP
),
632 FORMAT_TYPE (WAVE_FORMAT_OLISBC
),
633 FORMAT_TYPE (WAVE_FORMAT_OLIOPR
),
634 FORMAT_TYPE (WAVE_FORMAT_LH_CODEC
),
635 FORMAT_TYPE (WAVE_FORMAT_NORRIS
),
636 FORMAT_TYPE (WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS
),
637 FORMAT_TYPE (WAVE_FORMAT_DVM
),
638 FORMAT_TYPE (WAVE_FORMAT_INTERWAV_VSC112
),
639 FORMAT_TYPE (WAVE_FORMAT_IPP_ITU_G_723_1
),
640 FORMAT_TYPE (WAVE_FORMAT_EXTENSIBLE
),
644 wav_w64_format_str (int k
)
645 { int lower
, upper
, mid
;
648 upper
= sizeof (wave_descs
) / sizeof (WAV_FORMAT_DESC
) ;
651 if ((wave_descs
[0].ID
<= k
) && (k
<= wave_descs
[upper
- 1].ID
))
653 while (lower
+ 1 < upper
)
654 { mid
= (upper
+ lower
) / 2 ;
656 if (k
== wave_descs
[mid
].ID
)
657 return wave_descs
[mid
].name
;
658 if (k
< wave_descs
[mid
].ID
)
665 return "Unknown format" ;
666 } /* wav_w64_format_str */
669 wav_w64_srate2blocksize (int srate_chan_product
)
670 { if (srate_chan_product
< 12000)
672 if (srate_chan_product
< 23000)
674 if (srate_chan_product
< 44000)
677 } /* srate2blocksize */