1 ////////////////////////////////////////////////////////////////////////////
2 // **** WAVPACK **** //
3 // Hybrid Lossless Wavefile Compressor //
4 // Copyright (c) 1998 - 2004 Conifer Software. //
5 // All Rights Reserved. //
6 // Distributed under the BSD Software License (see license.txt) //
7 ////////////////////////////////////////////////////////////////////////////
11 // This module provides a high-level interface for decoding WavPack 4.0 audio
12 // streams and files. WavPack data is read with a stream reading callback. No
13 // direct seeking is provided for, but it is possible to start decoding
14 // anywhere in a WavPack stream. In this case, WavPack will be able to provide
15 // the sample-accurate position when it synchs with the data and begins
22 static void strcpy_loc (char *dst
, char *src
) { while ((*dst
++ = *src
++) != 0); }
24 ///////////////////////////// local table storage ////////////////////////////
26 const uint32_t sample_rates
[] = { 6000, 8000, 9600, 11025, 12000, 16000, 22050,
27 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000 };
29 ///////////////////////////// executable code ////////////////////////////////
31 static uint32_t read_next_header (read_stream infile
, WavpackHeader
*wphdr
);
33 // This function reads data from the specified stream in search of a valid
34 // WavPack 4.0 audio block. If this fails in 1 megabyte (or an invalid or
35 // unsupported WavPack block is encountered) then an appropriate message is
36 // copied to "error" and NULL is returned, otherwise a pointer to a
37 // WavpackContext structure is returned (which is used to call all other
38 // functions in this module). This can be initiated at the beginning of a
39 // WavPack file, or anywhere inside a WavPack file. To determine the exact
40 // position within the file use WavpackGetSampleIndex(). For demonstration
41 // purposes this uses a single static copy of the WavpackContext structure,
42 // so obviously it cannot be used for more than one file at a time. Also,
43 // this function will not handle "correction" files, plays only the first
44 // two channels of multi-channel files, and is limited in resolution in some
45 // large integer or floating point files (but always provides at least 24 bits
48 static WavpackContext wpc IBSS_ATTR
;
50 WavpackContext
*WavpackOpenFileInput (read_stream infile
, char *error
)
52 WavpackStream
*wps
= &wpc
.stream
;
57 wpc
.total_samples
= (uint32_t) -1;
61 // open the source file for reading and store the size
63 while (!wps
->wphdr
.block_samples
) {
65 bcount
= read_next_header (wpc
.infile
, &wps
->wphdr
);
67 if (bcount
== (uint32_t) -1) {
68 strcpy_loc (error
, "invalid WavPack file!");
72 wps
->block_bytes_left
= wps
->wphdr
.ckSize
- 24;
74 if ((wps
->wphdr
.flags
& UNKNOWN_FLAGS
) || wps
->wphdr
.version
< MIN_STREAM_VERS
||
75 wps
->wphdr
.version
> MAX_STREAM_VERS
) {
76 strcpy_loc (error
, "invalid WavPack file!");
80 if (wps
->wphdr
.block_samples
&& wps
->wphdr
.total_samples
!= (uint32_t) -1)
81 wpc
.total_samples
= wps
->wphdr
.total_samples
;
83 if (!unpack_init (&wpc
)) {
84 strcpy_loc (error
, wpc
.error_message
[0] ? wpc
.error_message
:
85 "invalid WavPack file!");
91 wpc
.config
.flags
&= ~0xff;
92 wpc
.config
.flags
|= wps
->wphdr
.flags
& 0xff;
93 wpc
.config
.bytes_per_sample
= (wps
->wphdr
.flags
& BYTES_STORED
) + 1;
94 wpc
.config
.float_norm_exp
= wps
->float_norm_exp
;
96 wpc
.config
.bits_per_sample
= (wpc
.config
.bytes_per_sample
* 8) -
97 ((wps
->wphdr
.flags
& SHIFT_MASK
) >> SHIFT_LSB
);
99 if (!wpc
.config
.sample_rate
) {
100 if (!wps
|| !wps
->wphdr
.block_samples
|| (wps
->wphdr
.flags
& SRATE_MASK
) == SRATE_MASK
)
101 wpc
.config
.sample_rate
= 44100;
103 wpc
.config
.sample_rate
= sample_rates
[(wps
->wphdr
.flags
& SRATE_MASK
) >> SRATE_LSB
];
106 if (!wpc
.config
.num_channels
) {
107 wpc
.config
.num_channels
= (wps
->wphdr
.flags
& MONO_FLAG
) ? 1 : 2;
108 wpc
.config
.channel_mask
= 0x5 - wpc
.config
.num_channels
;
111 if (!(wps
->wphdr
.flags
& FINAL_BLOCK
))
112 wpc
.reduced_channels
= (wps
->wphdr
.flags
& MONO_FLAG
) ? 1 : 2;
117 // This function obtains general information about an open file and returns
118 // a mask with the following bit values:
120 // MODE_LOSSLESS: file is lossless (pure lossless only)
121 // MODE_HYBRID: file is hybrid mode (lossy part only)
122 // MODE_FLOAT: audio data is 32-bit ieee floating point
123 // MODE_HIGH: file was created in "high" mode (information only)
124 // MODE_FAST: file was created in "fast" mode (information only)
126 int WavpackGetMode (WavpackContext
*wpc
)
131 if (wpc
->config
.flags
& CONFIG_HYBRID_FLAG
)
133 else if (!(wpc
->config
.flags
& CONFIG_LOSSY_MODE
))
134 mode
|= MODE_LOSSLESS
;
136 if (wpc
->lossy_blocks
)
137 mode
&= ~MODE_LOSSLESS
;
139 if (wpc
->config
.flags
& CONFIG_FLOAT_DATA
)
142 if (wpc
->config
.flags
& CONFIG_HIGH_FLAG
)
145 if (wpc
->config
.flags
& CONFIG_FAST_FLAG
)
152 // Unpack the specified number of samples from the current file position.
153 // Note that "samples" here refers to "complete" samples, which would be
154 // 2 int32_t's for stereo files. The audio data is returned right-justified in
155 // 32-bit int32_t's in the endian mode native to the executing processor. So,
156 // if the original data was 16-bit, then the values returned would be
157 // +/-32k. Floating point data can also be returned if the source was
158 // floating point data (and this is normalized to +/-1.0). The actual number
159 // of samples unpacked is returned, which should be equal to the number
160 // requested unless the end of fle is encountered or an error occurs.
162 uint32_t WavpackUnpackSamples (WavpackContext
*wpc
, int32_t *buffer
, uint32_t samples
)
164 WavpackStream
*wps
= &wpc
->stream
;
165 uint32_t bcount
, samples_unpacked
= 0, samples_to_unpack
;
166 int num_channels
= wpc
->config
.num_channels
;
169 if (!wps
->wphdr
.block_samples
|| !(wps
->wphdr
.flags
& INITIAL_BLOCK
) ||
170 wps
->sample_index
>= wps
->wphdr
.block_index
+ wps
->wphdr
.block_samples
) {
171 bcount
= read_next_header (wpc
->infile
, &wps
->wphdr
);
173 if (bcount
== (uint32_t) -1)
176 wps
->block_bytes_left
= wps
->wphdr
.ckSize
- 24;
178 if (wps
->wphdr
.version
< MIN_STREAM_VERS
|| wps
->wphdr
.version
> MAX_STREAM_VERS
) {
179 strcpy_loc (wpc
->error_message
, "invalid WavPack file!");
183 if (!wps
->wphdr
.block_samples
|| wps
->sample_index
== wps
->wphdr
.block_index
)
184 if (!unpack_init (wpc
))
188 if (!wps
->wphdr
.block_samples
|| !(wps
->wphdr
.flags
& INITIAL_BLOCK
) ||
189 wps
->sample_index
>= wps
->wphdr
.block_index
+ wps
->wphdr
.block_samples
)
192 if (wps
->sample_index
< wps
->wphdr
.block_index
) {
193 samples_to_unpack
= wps
->wphdr
.block_index
- wps
->sample_index
;
195 if (samples_to_unpack
> samples
)
196 samples_to_unpack
= samples
;
198 wps
->sample_index
+= samples_to_unpack
;
199 samples_unpacked
+= samples_to_unpack
;
200 samples
-= samples_to_unpack
;
202 if (wpc
->reduced_channels
)
203 samples_to_unpack
*= wpc
->reduced_channels
;
205 samples_to_unpack
*= num_channels
;
207 while (samples_to_unpack
--)
213 samples_to_unpack
= wps
->wphdr
.block_index
+ wps
->wphdr
.block_samples
- wps
->sample_index
;
215 if (samples_to_unpack
> samples
)
216 samples_to_unpack
= samples
;
218 unpack_samples (wpc
, buffer
, samples_to_unpack
);
220 if (wpc
->reduced_channels
)
221 buffer
+= samples_to_unpack
* wpc
->reduced_channels
;
223 buffer
+= samples_to_unpack
* num_channels
;
225 samples_unpacked
+= samples_to_unpack
;
226 samples
-= samples_to_unpack
;
228 if (wps
->sample_index
== wps
->wphdr
.block_index
+ wps
->wphdr
.block_samples
) {
229 if (check_crc_error (wpc
))
233 if (wps
->sample_index
== wpc
->total_samples
)
237 return samples_unpacked
;
240 // Get total number of samples contained in the WavPack file, or -1 if unknown
242 uint32_t WavpackGetNumSamples (WavpackContext
*wpc
)
244 return wpc
? wpc
->total_samples
: (uint32_t) -1;
247 // Get the current sample index position, or -1 if unknown
249 uint32_t WavpackGetSampleIndex (WavpackContext
*wpc
)
252 return wpc
->stream
.sample_index
;
254 return (uint32_t) -1;
257 // Get the number of errors encountered so far
259 int WavpackGetNumErrors (WavpackContext
*wpc
)
261 return wpc
? wpc
->crc_errors
: 0;
264 // return TRUE if any uncorrected lossy blocks were actually written or read
266 int WavpackLossyBlocks (WavpackContext
*wpc
)
268 return wpc
? wpc
->lossy_blocks
: 0;
271 // Returns the sample rate of the specified WavPack file
273 uint32_t WavpackGetSampleRate (WavpackContext
*wpc
)
275 return wpc
? wpc
->config
.sample_rate
: 44100;
278 // Returns the number of channels of the specified WavPack file. Note that
279 // this is the actual number of channels contained in the file, but this
280 // version can only decode the first two.
282 int WavpackGetNumChannels (WavpackContext
*wpc
)
284 return wpc
? wpc
->config
.num_channels
: 2;
287 // Returns the actual number of valid bits per sample contained in the
288 // original file, which may or may not be a multiple of 8. Floating data
289 // always has 32 bits, integers may be from 1 to 32 bits each. When this
290 // value is not a multiple of 8, then the "extra" bits are located in the
291 // LSBs of the results. That is, values are right justified when unpacked
292 // into int32_t's, but are left justified in the number of bytes used by the
295 int WavpackGetBitsPerSample (WavpackContext
*wpc
)
297 return wpc
? wpc
->config
.bits_per_sample
: 16;
300 // Returns the number of bytes used for each sample (1 to 4) in the original
301 // file. This is required information for the user of this module because the
302 // audio data is returned in the LOWER bytes of the int32_t buffer and must be
303 // left-shifted 8, 16, or 24 bits if normalized int32_t's are required.
305 int WavpackGetBytesPerSample (WavpackContext
*wpc
)
307 return wpc
? wpc
->config
.bytes_per_sample
: 2;
310 // This function will return the actual number of channels decoded from the
311 // file (which may or may not be less than the actual number of channels, but
312 // will always be 1 or 2). Normally, this will be the front left and right
313 // channels of a multi-channel file.
315 int WavpackGetReducedChannels (WavpackContext
*wpc
)
318 return wpc
->reduced_channels
? wpc
->reduced_channels
: wpc
->config
.num_channels
;
323 // Read from current file position until a valid 32-byte WavPack 4.0 header is
324 // found and read into the specified pointer. The number of bytes skipped is
325 // returned. If no WavPack header is found within 1 meg, then a -1 is returned
326 // to indicate the error. No additional bytes are read past the header and it
327 // is returned in the processor's native endian mode. Seeking is not required.
329 static uint32_t read_next_header (read_stream infile
, WavpackHeader
*wphdr
)
331 char buffer
[sizeof (*wphdr
)], *sp
= buffer
+ sizeof (*wphdr
), *ep
= sp
;
332 uint32_t bytes_skipped
= 0;
338 memcpy (buffer
, sp
, bleft
);
343 if (infile (buffer
+ bleft
, sizeof (*wphdr
) - bleft
) != (int32_t) sizeof (*wphdr
) - bleft
)
348 if (*sp
++ == 'w' && *sp
== 'v' && *++sp
== 'p' && *++sp
== 'k' &&
349 !(*++sp
& 1) && sp
[2] < 16 && !sp
[3] && sp
[5] == 4 &&
350 sp
[4] >= (MIN_STREAM_VERS
& 0xff) && sp
[4] <= (MAX_STREAM_VERS
& 0xff)) {
351 memcpy (wphdr
, buffer
, sizeof (*wphdr
));
352 little_endian_to_native (wphdr
, WavpackHeaderFormat
);
353 return bytes_skipped
;
356 while (sp
< ep
&& *sp
!= 'w')
359 if ((bytes_skipped
+= sp
- buffer
) > 1024 * 1024)
364 // Open context for writing WavPack files. The returned context pointer is used
365 // in all following calls to the library. A return value of NULL indicates
366 // that memory could not be allocated for the context.
368 WavpackContext
*WavpackOpenFileOutput (void)
374 // Set configuration for writing WavPack files. This must be done before
375 // sending any actual samples, however it is okay to send wrapper or other
376 // metadata before calling this. The "config" structure contains the following
377 // required information:
379 // config->bytes_per_sample see WavpackGetBytesPerSample() for info
380 // config->bits_per_sample see WavpackGetBitsPerSample() for info
381 // config->num_channels self evident
382 // config->sample_rate self evident
384 // In addition, the following fields and flags may be set:
388 // o CONFIG_HYBRID_FLAG select hybrid mode (must set bitrate)
389 // o CONFIG_JOINT_STEREO select joint stereo (must set override also)
390 // o CONFIG_JOINT_OVERRIDE override default joint stereo selection
391 // o CONFIG_HYBRID_SHAPE select hybrid noise shaping (set override &
392 // shaping_weight != 0.0)
393 // o CONFIG_SHAPE_OVERRIDE override default hybrid noise shaping
394 // (set CONFIG_HYBRID_SHAPE and shaping_weight)
395 // o CONFIG_FAST_FLAG "fast" compression mode
396 // o CONFIG_HIGH_FLAG "high" compression mode
397 // o CONFIG_BITRATE_KBPS hybrid bitrate is kbps, not bits / sample
399 // config->bitrate hybrid bitrate in either bits/sample or kbps
400 // config->shaping_weight hybrid noise shaping coefficient override
401 // config->float_norm_exp select floating-point data (127 for +/-1.0)
403 // If the number of samples to be written is known then it should be passed
404 // here. If the duration is not known then pass -1. In the case that the size
405 // is not known (or the writing is terminated early) then it is suggested that
406 // the application retrieve the first block written and let the library update
407 // the total samples indication. A function is provided to do this update and
408 // it should be done to the "correction" file also. If this cannot be done
409 // (because a pipe is being used, for instance) then a valid WavPack will still
410 // be created, but when applications want to access that file they will have
411 // to seek all the way to the end to determine the actual duration. Also, if
412 // a RIFF header has been included then it should be updated as well or the
413 // WavPack file will not be directly unpackable to a valid wav file (although
414 // it will still be usable by itself). A return of FALSE indicates an error.
416 int WavpackSetConfiguration (WavpackContext
*wpc
, WavpackConfig
*config
, uint32_t total_samples
)
418 WavpackStream
*wps
= &wpc
->stream
;
419 uint32_t flags
= (config
->bytes_per_sample
- 1), shift
= 0;
420 int num_chans
= config
->num_channels
;
423 if ((wpc
->config
.flags
& CONFIG_HYBRID_FLAG
) ||
424 wpc
->config
.float_norm_exp
||
425 num_chans
< 1 || num_chans
> 2)
428 wpc
->total_samples
= total_samples
;
429 wpc
->config
.sample_rate
= config
->sample_rate
;
430 wpc
->config
.num_channels
= config
->num_channels
;
431 wpc
->config
.bits_per_sample
= config
->bits_per_sample
;
432 wpc
->config
.bytes_per_sample
= config
->bytes_per_sample
;
433 wpc
->config
.flags
= config
->flags
;
435 shift
= (config
->bytes_per_sample
* 8) - config
->bits_per_sample
;
437 for (i
= 0; i
< 15; ++i
)
438 if (wpc
->config
.sample_rate
== sample_rates
[i
])
441 flags
|= i
<< SRATE_LSB
;
442 flags
|= shift
<< SHIFT_LSB
;
443 flags
|= CROSS_DECORR
;
445 if (!(config
->flags
& CONFIG_JOINT_OVERRIDE
) || (config
->flags
& CONFIG_JOINT_STEREO
))
446 flags
|= JOINT_STEREO
;
448 flags
|= INITIAL_BLOCK
| FINAL_BLOCK
;
450 if (num_chans
== 1) {
451 flags
&= ~(JOINT_STEREO
| CROSS_DECORR
| HYBRID_BALANCE
);
456 flags
+= (1 << MAG_LSB
) * ((flags
& BYTES_STORED
) * 8 + 7);
458 memcpy (wps
->wphdr
.ckID
, "wvpk", 4);
459 wps
->wphdr
.ckSize
= sizeof (WavpackHeader
) - 8;
460 wps
->wphdr
.total_samples
= wpc
->total_samples
;
461 wps
->wphdr
.version
= CUR_STREAM_VERS
;
462 wps
->wphdr
.flags
= flags
;
468 // Add wrapper (currently RIFF only) to WavPack blocks. This should be called
469 // before sending any audio samples. If the exact contents of the RIFF header
470 // are not known because, for example, the file duration is uncertain or
471 // trailing chunks are possible, simply write a "dummy" header of the correct
472 // length. When all data has been written it will be possible to read the
473 // first block written and update the header directly. An example of this can
474 // be found in the Audition filter.
476 void WavpackAddWrapper (WavpackContext
*wpc
, void *data
, uint32_t bcount
)
478 wpc
->wrapper_data
= data
;
479 wpc
->wrapper_bytes
= bcount
;
482 // Start a WavPack block to be stored in the specified buffer. This must be
483 // called before calling WavpackPackSamples(). Note that writing CANNOT wrap
484 // in the buffer; the entire output block must fit in the buffer.
486 int WavpackStartBlock (WavpackContext
*wpc
, uchar
*begin
, uchar
*end
)
488 wpc
->stream
.blockbuff
= begin
;
489 wpc
->stream
.blockend
= end
;
490 return pack_start_block (wpc
);
493 // Pack the specified samples. Samples must be stored in int32_ts in the native
494 // endian format of the executing processor. The number of samples specified
495 // indicates composite samples (sometimes called "frames"). So, the actual
496 // number of data points would be this "sample_count" times the number of
497 // channels. The caller must decide how many samples to place in each
498 // WavPack block (1/2 second is common), but this function may be called as
499 // many times as desired to build the final block (and performs the actual
500 // compression during the call). A return of FALSE indicates an error.
502 int WavpackPackSamples (WavpackContext
*wpc
, int32_t *sample_buffer
, uint32_t sample_count
)
504 if (!sample_count
|| pack_samples (wpc
, sample_buffer
, sample_count
))
507 strcpy_loc (wpc
->error_message
, "output buffer overflowed!");
511 // Finish the WavPack block being built, returning the total size of the
512 // block in bytes. Note that the possible conversion of the WavPack header to
513 // little-endian takes place here.
515 uint32_t WavpackFinishBlock (WavpackContext
*wpc
)
517 WavpackStream
*wps
= &wpc
->stream
;
520 pack_finish_block (wpc
);
521 bcount
= ((WavpackHeader
*) wps
->blockbuff
)->ckSize
+ 8;
522 native_to_little_endian ((WavpackHeader
*) wps
->blockbuff
, WavpackHeaderFormat
);
527 // Given the pointer to the first block written (to either a .wv or .wvc file),
528 // update the block with the actual number of samples written. This should
529 // be done if WavpackSetConfiguration() was called with an incorrect number
530 // of samples (or -1). It is the responsibility of the application to read and
531 // rewrite the block. An example of this can be found in the Audition filter.
533 void WavpackUpdateNumSamples (WavpackContext
*wpc
, void *first_block
)
535 little_endian_to_native (wpc
, WavpackHeaderFormat
);
536 ((WavpackHeader
*) first_block
)->total_samples
= WavpackGetSampleIndex (wpc
);
537 native_to_little_endian (wpc
, WavpackHeaderFormat
);
540 // Given the pointer to the first block written to a WavPack file, this
541 // function returns the location of the stored RIFF header that was originally
542 // written with WavpackAddWrapper(). This would normally be used to update
543 // the wav header to indicate that a different number of samples was actually
544 // written or if additional RIFF chunks are written at the end of the file.
545 // It is the responsibility of the application to read and rewrite the block.
546 // An example of this can be found in the Audition filter.
548 void *WavpackGetWrapperLocation (void *first_block
)
550 if (((uchar
*) first_block
) [32] == ID_RIFF_HEADER
)
551 return ((uchar
*) first_block
) + 34;