1
////////////////////////////////////////////////////////////////////////////
2
// **** WAVPACK **** //
3
// Hybrid Lossless Wavefile Compressor //
4
// Copyright (c) 1998 - 2006 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
///////////////////////////// local table storage ////////////////////////////
24
const uint32_t sample_rates [] = { 6000, 8000, 9600, 11025, 12000, 16000, 22050,
25
24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000 };
27
///////////////////////////// executable code ////////////////////////////////
29
static uint32_t read_next_header (read_stream infile, WavpackHeader *wphdr);
31
// This function reads data from the specified stream in search of a valid
32
// WavPack 4.0 audio block. If this fails in 1 megabyte (or an invalid or
33
// unsupported WavPack block is encountered) then an appropriate message is
34
// copied to "error" and NULL is returned, otherwise a pointer to a
35
// WavpackContext structure is returned (which is used to call all other
36
// functions in this module). This can be initiated at the beginning of a
37
// WavPack file, or anywhere inside a WavPack file. To determine the exact
38
// position within the file use WavpackGetSampleIndex(). For demonstration
39
// purposes this uses a single static copy of the WavpackContext structure,
40
// so obviously it cannot be used for more than one file at a time. Also,
41
// this function will not handle "correction" files, plays only the first
42
// two channels of multi-channel files, and is limited in resolution in some
43
// large integer or floating point files (but always provides at least 24 bits
46
static WavpackContext wpc;
48
WavpackContext *WavpackOpenFileInput (read_stream infile, char *error)
50
WavpackStream *wps = &wpc.stream;
55
wpc.total_samples = (uint32_t) -1;
59
// open the source file for reading and store the size
61
while (!wps->wphdr.block_samples) {
63
bcount = read_next_header (wpc.infile, &wps->wphdr);
65
if (bcount == (uint32_t) -1) {
66
strcpy (error, "not compatible with this version of WavPack file!");
70
if (wps->wphdr.block_samples && wps->wphdr.total_samples != (uint32_t) -1)
71
wpc.total_samples = wps->wphdr.total_samples;
73
if (!unpack_init (&wpc)) {
74
strcpy (error, wpc.error_message [0] ? wpc.error_message :
75
"not compatible with this version of WavPack file!");
81
wpc.config.flags &= ~0xff;
82
wpc.config.flags |= wps->wphdr.flags & 0xff;
83
wpc.config.bytes_per_sample = (wps->wphdr.flags & BYTES_STORED) + 1;
84
wpc.config.float_norm_exp = wps->float_norm_exp;
86
wpc.config.bits_per_sample = (wpc.config.bytes_per_sample * 8) -
87
((wps->wphdr.flags & SHIFT_MASK) >> SHIFT_LSB);
89
if (wpc.config.flags & FLOAT_DATA) {
90
wpc.config.bytes_per_sample = 3;
91
wpc.config.bits_per_sample = 24;
94
if (!wpc.config.sample_rate) {
95
if (!wps || !wps->wphdr.block_samples || (wps->wphdr.flags & SRATE_MASK) == SRATE_MASK)
96
wpc.config.sample_rate = 44100;
98
wpc.config.sample_rate = sample_rates [(wps->wphdr.flags & SRATE_MASK) >> SRATE_LSB];
101
if (!wpc.config.num_channels) {
102
wpc.config.num_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2;
103
wpc.config.channel_mask = 0x5 - wpc.config.num_channels;
106
if (!(wps->wphdr.flags & FINAL_BLOCK))
107
wpc.reduced_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2;
112
// This function obtains general information about an open file and returns
113
// a mask with the following bit values:
115
// MODE_LOSSLESS: file is lossless (pure lossless only)
116
// MODE_HYBRID: file is hybrid mode (lossy part only)
117
// MODE_FLOAT: audio data is 32-bit ieee floating point (but will provided
118
// in 24-bit integers for convenience)
119
// MODE_HIGH: file was created in "high" mode (information only)
120
// MODE_FAST: file was created in "fast" mode (information only)
122
int WavpackGetMode (WavpackContext *wpc)
127
if (wpc->config.flags & CONFIG_HYBRID_FLAG)
129
else if (!(wpc->config.flags & CONFIG_LOSSY_MODE))
130
mode |= MODE_LOSSLESS;
132
if (wpc->lossy_blocks)
133
mode &= ~MODE_LOSSLESS;
135
if (wpc->config.flags & CONFIG_FLOAT_DATA)
138
if (wpc->config.flags & CONFIG_HIGH_FLAG)
141
if (wpc->config.flags & CONFIG_FAST_FLAG)
148
// Unpack the specified number of samples from the current file position.
149
// Note that "samples" here refers to "complete" samples, which would be
150
// 2 longs for stereo files. The audio data is returned right-justified in
151
// 32-bit longs in the endian mode native to the executing processor. So,
152
// if the original data was 16-bit, then the values returned would be
153
// +/-32k. Floating point data will be returned as 24-bit integers (and may
154
// also be clipped). The actual number of samples unpacked is returned,
155
// which should be equal to the number requested unless the end of fle is
156
// encountered or an error occurs.
158
uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples)
160
WavpackStream *wps = &wpc->stream;
161
uint32_t bcount, samples_unpacked = 0, samples_to_unpack;
162
int num_channels = wpc->config.num_channels;
165
if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) ||
166
wps->sample_index >= wps->wphdr.block_index + wps->wphdr.block_samples) {
167
bcount = read_next_header (wpc->infile, &wps->wphdr);
169
if (bcount == (uint32_t) -1)
172
if (!wps->wphdr.block_samples || wps->sample_index == wps->wphdr.block_index)
173
if (!unpack_init (wpc))
177
if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) ||
178
wps->sample_index >= wps->wphdr.block_index + wps->wphdr.block_samples)
181
if (wps->sample_index < wps->wphdr.block_index) {
182
samples_to_unpack = wps->wphdr.block_index - wps->sample_index;
184
if (samples_to_unpack > samples)
185
samples_to_unpack = samples;
187
wps->sample_index += samples_to_unpack;
188
samples_unpacked += samples_to_unpack;
189
samples -= samples_to_unpack;
191
if (wpc->reduced_channels)
192
samples_to_unpack *= wpc->reduced_channels;
194
samples_to_unpack *= num_channels;
196
while (samples_to_unpack--)
202
samples_to_unpack = wps->wphdr.block_index + wps->wphdr.block_samples - wps->sample_index;
204
if (samples_to_unpack > samples)
205
samples_to_unpack = samples;
207
unpack_samples (wpc, buffer, samples_to_unpack);
209
if (wpc->reduced_channels)
210
buffer += samples_to_unpack * wpc->reduced_channels;
212
buffer += samples_to_unpack * num_channels;
214
samples_unpacked += samples_to_unpack;
215
samples -= samples_to_unpack;
217
if (wps->sample_index == wps->wphdr.block_index + wps->wphdr.block_samples) {
218
if (check_crc_error (wpc))
222
if (wps->sample_index == wpc->total_samples)
226
return samples_unpacked;
229
// Get total number of samples contained in the WavPack file, or -1 if unknown
231
uint32_t WavpackGetNumSamples (WavpackContext *wpc)
233
return wpc ? wpc->total_samples : (uint32_t) -1;
236
// Get the current sample index position, or -1 if unknown
238
uint32_t WavpackGetSampleIndex (WavpackContext *wpc)
241
return wpc->stream.sample_index;
243
return (uint32_t) -1;
246
// Get the number of errors encountered so far
248
int WavpackGetNumErrors (WavpackContext *wpc)
250
return wpc ? wpc->crc_errors : 0;
253
// return TRUE if any uncorrected lossy blocks were actually written or read
255
int WavpackLossyBlocks (WavpackContext *wpc)
257
return wpc ? wpc->lossy_blocks : 0;
260
// Returns the sample rate of the specified WavPack file
262
uint32_t WavpackGetSampleRate (WavpackContext *wpc)
264
return wpc ? wpc->config.sample_rate : 44100;
267
// Returns the number of channels of the specified WavPack file. Note that
268
// this is the actual number of channels contained in the file, but this
269
// version can only decode the first two.
271
int WavpackGetNumChannels (WavpackContext *wpc)
273
return wpc ? wpc->config.num_channels : 2;
276
// Returns the actual number of valid bits per sample contained in the
277
// original file, which may or may not be a multiple of 8. Floating data
278
// always has 32 bits, integers may be from 1 to 32 bits each. When this
279
// value is not a multiple of 8, then the "extra" bits are located in the
280
// LSBs of the results. That is, values are right justified when unpacked
281
// into longs, but are left justified in the number of bytes used by the
284
int WavpackGetBitsPerSample (WavpackContext *wpc)
286
return wpc ? wpc->config.bits_per_sample : 16;
289
// Returns the number of bytes used for each sample (1 to 4) in the original
290
// file. This is required information for the user of this module because the
291
// audio data is returned in the LOWER bytes of the long buffer and must be
292
// left-shifted 8, 16, or 24 bits if normalized longs are required.
294
int WavpackGetBytesPerSample (WavpackContext *wpc)
296
return wpc ? wpc->config.bytes_per_sample : 2;
299
// This function will return the actual number of channels decoded from the
300
// file (which may or may not be less than the actual number of channels, but
301
// will always be 1 or 2). Normally, this will be the front left and right
302
// channels of a multi-channel file.
304
int WavpackGetReducedChannels (WavpackContext *wpc)
307
return wpc->reduced_channels ? wpc->reduced_channels : wpc->config.num_channels;
312
// Read from current file position until a valid 32-byte WavPack 4.0 header is
313
// found and read into the specified pointer. The number of bytes skipped is
314
// returned. If no WavPack header is found within 1 meg, then a -1 is returned
315
// to indicate the error. No additional bytes are read past the header and it
316
// is returned in the processor's native endian mode. Seeking is not required.
318
static uint32_t read_next_header (read_stream infile, WavpackHeader *wphdr)
320
char buffer [sizeof (*wphdr)], *sp = buffer + sizeof (*wphdr), *ep = sp;
321
uint32_t bytes_skipped = 0;
327
memcpy (buffer, sp, bleft);
332
if (infile (buffer + bleft, sizeof (*wphdr) - bleft) != (int32_t) sizeof (*wphdr) - bleft)
337
if (*sp++ == 'w' && *sp == 'v' && *++sp == 'p' && *++sp == 'k' &&
338
!(*++sp & 1) && sp [2] < 16 && !sp [3] && sp [5] == 4 &&
339
sp [4] >= (MIN_STREAM_VERS & 0xff) && sp [4] <= (MAX_STREAM_VERS & 0xff)) {
340
memcpy (wphdr, buffer, sizeof (*wphdr));
341
little_endian_to_native (wphdr, WavpackHeaderFormat);
342
return bytes_skipped;
345
while (sp < ep && *sp != 'w')
348
if ((bytes_skipped += sp - buffer) > 1048576L)