1 ////////////////////////////////////////////////////////////////////////////
2 //                           **** WAVPACK ****                            //
3 //                  Hybrid Lossless Wavefile Compressor                   //
4 //                Copyright (c) 1998 - 2020 David Bryant.                 //
5 //                          All Rights Reserved.                          //
6 //      Distributed under the BSD Software License (see license.txt)      //
7 ////////////////////////////////////////////////////////////////////////////
8 
9 // wavpack.h
10 
11 #ifndef WAVPACK_H
12 #define WAVPACK_H
13 
14 // This header file contains all the definitions required to use the
15 // functions in "wputils.c" to read and write WavPack files and streams.
16 
17 #include <sys/types.h>
18 
19 #if defined(_MSC_VER) && _MSC_VER < 1600
20 typedef unsigned __int64 uint64_t;
21 typedef unsigned __int32 uint32_t;
22 typedef unsigned __int16 uint16_t;
23 typedef unsigned __int8 uint8_t;
24 typedef __int64 int64_t;
25 typedef __int32 int32_t;
26 typedef __int16 int16_t;
27 typedef __int8  int8_t;
28 #else
29 #include <stdint.h>
30 #endif
31 
32 // RIFF / wav header formats (these occur at the beginning of both wav files
33 // and pre-4.0 WavPack files that are not in the "raw" mode). Generally, an
34 // application using the library to read or write WavPack files will not be
35 // concerned with any of these.
36 
37 typedef struct {
38     char ckID [4];
39     uint32_t ckSize;
40     char formType [4];
41 } RiffChunkHeader;
42 
43 typedef struct {
44     char ckID [4];
45     uint32_t ckSize;
46 } ChunkHeader;
47 
48 #define ChunkHeaderFormat "4L"
49 
50 typedef struct {
51     uint16_t FormatTag, NumChannels;
52     uint32_t SampleRate, BytesPerSecond;
53     uint16_t BlockAlign, BitsPerSample;
54     uint16_t cbSize, ValidBitsPerSample;
55     int32_t ChannelMask;
56     uint16_t SubFormat;
57     char GUID [14];
58 } WaveHeader;
59 
60 #define WaveHeaderFormat "SSLLSSSSLS"
61 
62 // This is the ONLY structure that occurs in WavPack files (as of version
63 // 4.0), and is the preamble to every block in both the .wv and .wvc
64 // files (in little-endian format). Normally, this structure has no use
65 // to an application using the library to read or write WavPack files,
66 // but if an application needs to manually parse WavPack files then this
67 // would be used (with appropriate endian correction).
68 
69 typedef struct {
70     char ckID [4];
71     uint32_t ckSize;
72     int16_t version;
73     unsigned char block_index_u8;
74     unsigned char total_samples_u8;
75     uint32_t total_samples, block_index, block_samples, flags, crc;
76 } WavpackHeader;
77 
78 #define WavpackHeaderFormat "4LS2LLLLL"
79 
80 // Macros to access the 40-bit block_index field
81 
82 #define GET_BLOCK_INDEX(hdr) ( (int64_t) (hdr).block_index + ((int64_t) (hdr).block_index_u8 << 32) )
83 
84 #define SET_BLOCK_INDEX(hdr,value) do { \
85     int64_t tmp = (value);              \
86     (hdr).block_index = (uint32_t) tmp; \
87     (hdr).block_index_u8 =              \
88         (unsigned char) (tmp >> 32);    \
89 } while (0)
90 
91 // Macros to access the 40-bit total_samples field, which is complicated by the fact that
92 // all 1's in the lower 32 bits indicates "unknown" (regardless of upper 8 bits)
93 
94 #define GET_TOTAL_SAMPLES(hdr) ( ((hdr).total_samples == (uint32_t) -1) ? -1 : \
95     (int64_t) (hdr).total_samples + ((int64_t) (hdr).total_samples_u8 << 32) - (hdr).total_samples_u8 )
96 
97 #define SET_TOTAL_SAMPLES(hdr,value) do {       \
98     int64_t tmp = (value);                      \
99     if (tmp < 0)                                \
100         (hdr).total_samples = (uint32_t) -1;    \
101     else {                                      \
102         tmp += (tmp / 0xffffffffLL);            \
103         (hdr).total_samples = (uint32_t) tmp;   \
104         (hdr).total_samples_u8 =                \
105             (unsigned char) (tmp >> 32);        \
106     }                                           \
107 } while (0)
108 
109 // or-values for WavpackHeader.flags
110 #define BYTES_STORED    3       // 1-4 bytes/sample
111 #define MONO_FLAG       4       // not stereo
112 #define HYBRID_FLAG     8       // hybrid mode
113 #define JOINT_STEREO    0x10    // joint stereo
114 #define CROSS_DECORR    0x20    // no-delay cross decorrelation
115 #define HYBRID_SHAPE    0x40    // noise shape (hybrid mode only)
116 #define FLOAT_DATA      0x80    // ieee 32-bit floating point data
117 
118 #define INT32_DATA      0x100   // special extended int handling
119 #define HYBRID_BITRATE  0x200   // bitrate noise (hybrid mode only)
120 #define HYBRID_BALANCE  0x400   // balance noise (hybrid stereo mode only)
121 
122 #define INITIAL_BLOCK   0x800   // initial block of multichannel segment
123 #define FINAL_BLOCK     0x1000  // final block of multichannel segment
124 
125 #define SHIFT_LSB       13
126 #define SHIFT_MASK      (0x1fL << SHIFT_LSB)
127 
128 #define MAG_LSB         18
129 #define MAG_MASK        (0x1fL << MAG_LSB)
130 
131 #define SRATE_LSB       23
132 #define SRATE_MASK      (0xfL << SRATE_LSB)
133 
134 #define FALSE_STEREO    0x40000000      // block is stereo, but data is mono
135 #define NEW_SHAPING     0x20000000      // use IIR filter for negative shaping
136 
137 #define MONO_DATA (MONO_FLAG | FALSE_STEREO)
138 
139 // Introduced in WavPack 5.0:
140 #define HAS_CHECKSUM    0x10000000      // block contains a trailing checksum
141 #define DSD_FLAG        0x80000000      // block is encoded DSD (1-bit PCM)
142 
143 #define IGNORED_FLAGS   0x08000000      // reserved, but ignore if encountered
144 #define UNKNOWN_FLAGS   0x00000000      // we no longer have any of these spares
145 
146 #define MIN_STREAM_VERS     0x402       // lowest stream version we'll decode
147 #define MAX_STREAM_VERS     0x410       // highest stream version we'll decode or encode
148 
149 // These are the mask bit definitions for the metadata chunk id byte (see format.txt)
150 
151 #define ID_UNIQUE               0x3f
152 #define ID_OPTIONAL_DATA        0x20
153 #define ID_ODD_SIZE             0x40
154 #define ID_LARGE                0x80
155 
156 #define ID_DUMMY                0x0
157 #define ID_ENCODER_INFO         0x1
158 #define ID_DECORR_TERMS         0x2
159 #define ID_DECORR_WEIGHTS       0x3
160 #define ID_DECORR_SAMPLES       0x4
161 #define ID_ENTROPY_VARS         0x5
162 #define ID_HYBRID_PROFILE       0x6
163 #define ID_SHAPING_WEIGHTS      0x7
164 #define ID_FLOAT_INFO           0x8
165 #define ID_INT32_INFO           0x9
166 #define ID_WV_BITSTREAM         0xa
167 #define ID_WVC_BITSTREAM        0xb
168 #define ID_WVX_BITSTREAM        0xc
169 #define ID_CHANNEL_INFO         0xd
170 #define ID_DSD_BLOCK            0xe
171 
172 #define ID_RIFF_HEADER          (ID_OPTIONAL_DATA | 0x1)
173 #define ID_RIFF_TRAILER         (ID_OPTIONAL_DATA | 0x2)
174 #define ID_ALT_HEADER           (ID_OPTIONAL_DATA | 0x3)
175 #define ID_ALT_TRAILER          (ID_OPTIONAL_DATA | 0x4)
176 #define ID_CONFIG_BLOCK         (ID_OPTIONAL_DATA | 0x5)
177 #define ID_MD5_CHECKSUM         (ID_OPTIONAL_DATA | 0x6)
178 #define ID_SAMPLE_RATE          (ID_OPTIONAL_DATA | 0x7)
179 #define ID_ALT_EXTENSION        (ID_OPTIONAL_DATA | 0x8)
180 #define ID_ALT_MD5_CHECKSUM     (ID_OPTIONAL_DATA | 0x9)
181 #define ID_NEW_CONFIG_BLOCK     (ID_OPTIONAL_DATA | 0xa)
182 #define ID_CHANNEL_IDENTITIES   (ID_OPTIONAL_DATA | 0xb)
183 #define ID_BLOCK_CHECKSUM       (ID_OPTIONAL_DATA | 0xf)
184 
185 ///////////////////////// WavPack Configuration ///////////////////////////////
186 
187 // This external structure is used during encode to provide configuration to
188 // the encoding engine and during decoding to provide fle information back to
189 // the higher level functions. Not all fields are used in both modes.
190 
191 typedef struct {
192     float bitrate, shaping_weight;
193     int bits_per_sample, bytes_per_sample;
194     int qmode, flags, xmode, num_channels, float_norm_exp;
195     int32_t block_samples, extra_flags, sample_rate, channel_mask;
196     unsigned char md5_checksum [16], md5_read;
197     int num_tag_strings;                // this field is not used
198     char **tag_strings;                 // this field is not used
199 } WavpackConfig;
200 
201 #define CONFIG_HYBRID_FLAG      8       // hybrid mode
202 #define CONFIG_JOINT_STEREO     0x10    // joint stereo
203 #define CONFIG_CROSS_DECORR     0x20    // no-delay cross decorrelation
204 #define CONFIG_HYBRID_SHAPE     0x40    // noise shape (hybrid mode only)
205 #define CONFIG_FAST_FLAG        0x200   // fast mode
206 #define CONFIG_HIGH_FLAG        0x800   // high quality mode
207 #define CONFIG_VERY_HIGH_FLAG   0x1000  // very high
208 #define CONFIG_BITRATE_KBPS     0x2000  // bitrate is kbps, not bits / sample
209 #define CONFIG_SHAPE_OVERRIDE   0x8000  // shaping mode specified
210 #define CONFIG_JOINT_OVERRIDE   0x10000 // joint-stereo mode specified
211 #define CONFIG_DYNAMIC_SHAPING  0x20000 // dynamic noise shaping
212 #define CONFIG_CREATE_EXE       0x40000 // create executable
213 #define CONFIG_CREATE_WVC       0x80000 // create correction file
214 #define CONFIG_OPTIMIZE_WVC     0x100000 // maximize bybrid compression
215 #define CONFIG_COMPATIBLE_WRITE 0x400000 // write files for decoders < 4.3
216 #define CONFIG_CALC_NOISE       0x800000 // calc noise in hybrid mode
217 #define CONFIG_EXTRA_MODE       0x2000000 // extra processing mode
218 #define CONFIG_SKIP_WVX         0x4000000 // no wvx stream w/ floats & big ints
219 #define CONFIG_MD5_CHECKSUM     0x8000000 // store MD5 signature
220 #define CONFIG_MERGE_BLOCKS     0x10000000 // merge blocks of equal redundancy (for lossyWAV)
221 #define CONFIG_PAIR_UNDEF_CHANS 0x20000000 // encode undefined channels in stereo pairs
222 #define CONFIG_OPTIMIZE_MONO    0x80000000 // optimize for mono streams posing as stereo
223 
224 // The lower 8 bits of qmode indicate the use of new features in version 5 that (presently)
225 // only apply to Core Audio Files (CAF) and DSD files, but could apply to other things too.
226 // These flags are stored in the file and can be retrieved by a decoder that is aware of
227 // them, but the individual bits are meaningless to the library. If ANY of these bits are
228 // set then the MD5 sum is written with a new ID so that old decoders will not see it
229 // (because these features will cause the MD5 sum to be different and fail).
230 
231 #define QMODE_BIG_ENDIAN        0x1     // big-endian data format (opposite of WAV format)
232 #define QMODE_SIGNED_BYTES      0x2     // 8-bit audio data is signed (opposite of WAV format)
233 #define QMODE_UNSIGNED_WORDS    0x4     // audio data (other than 8-bit) is unsigned (opposite of WAV format)
234 #define QMODE_REORDERED_CHANS   0x8     // source channels were not Microsoft order, so they were reordered
235 #define QMODE_DSD_LSB_FIRST     0x10    // DSD bytes, LSB first (most Sony .dsf files)
236 #define QMODE_DSD_MSB_FIRST     0x20    // DSD bytes, MSB first (Philips .dff files)
237 #define QMODE_DSD_IN_BLOCKS     0x40    // DSD data is blocked by channels (Sony .dsf only)
238 #define QMODE_DSD_AUDIO         (QMODE_DSD_LSB_FIRST | QMODE_DSD_MSB_FIRST)
239 
240 // The rest of the qmode word is reserved for the private use of the command-line programs
241 // and are ignored by the library (and not stored either). They really should not be defined
242 // here, but I thought it would be a good idea to have all the definitions together.
243 
244 #define QMODE_ADOBE_MODE        0x100   // user specified Adobe mode
245 #define QMODE_NO_STORE_WRAPPER  0x200   // user specified to not store audio file wrapper (RIFF, CAFF, etc.)
246 #define QMODE_CHANS_UNASSIGNED  0x400   // user specified "..." in --channel-order option
247 #define QMODE_IGNORE_LENGTH     0x800   // user specified to ignore length in file header
248 #define QMODE_RAW_PCM           0x1000  // user specified raw PCM format (no header present)
249 
250 ////////////// Callbacks used for reading & writing WavPack streams //////////
251 
252 typedef struct {
253     int32_t (*read_bytes)(void *id, void *data, int32_t bcount);
254     uint32_t (*get_pos)(void *id);
255     int (*set_pos_abs)(void *id, uint32_t pos);
256     int (*set_pos_rel)(void *id, int32_t delta, int mode);
257     int (*push_back_byte)(void *id, int c);
258     uint32_t (*get_length)(void *id);
259     int (*can_seek)(void *id);
260 
261     // this callback is for writing edited tags only
262     int32_t (*write_bytes)(void *id, void *data, int32_t bcount);
263 } WavpackStreamReader;
264 
265 // Extended version of structure for handling large files and added
266 // functionality for truncating and closing files
267 
268 typedef struct {
269     int32_t (*read_bytes)(void *id, void *data, int32_t bcount);
270     int32_t (*write_bytes)(void *id, void *data, int32_t bcount);
271     int64_t (*get_pos)(void *id);                               // new signature for large files
272     int (*set_pos_abs)(void *id, int64_t pos);                  // new signature for large files
273     int (*set_pos_rel)(void *id, int64_t delta, int mode);      // new signature for large files
274     int (*push_back_byte)(void *id, int c);
275     int64_t (*get_length)(void *id);                            // new signature for large files
276     int (*can_seek)(void *id);
277     int (*truncate_here)(void *id);                             // new function to truncate file at current position
278     int (*close)(void *id);                                     // new function to close file
279 } WavpackStreamReader64;
280 
281 typedef int (*WavpackBlockOutput)(void *id, void *data, int32_t bcount);
282 
283 //////////////////////////// function prototypes /////////////////////////////
284 
285 typedef struct WavpackContext WavpackContext;
286 
287 #ifdef __cplusplus
288 extern "C" {
289 #endif
290 
291 #define MAX_WAVPACK_SAMPLES ((1LL << 40) - 257)
292 
293 WavpackContext *WavpackOpenRawDecoder (
294     void *main_data, int32_t main_size,
295     void *corr_data, int32_t corr_size,
296     int16_t version, char *error, int flags, int norm_offset);
297 
298 WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset);
299 WavpackContext *WavpackOpenFileInputEx (WavpackStreamReader *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset);
300 WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int flags, int norm_offset);
301 
302 #define OPEN_WVC        0x1     // open/read "correction" file
303 #define OPEN_TAGS       0x2     // read ID3v1 / APEv2 tags (seekable file)
304 #define OPEN_WRAPPER    0x4     // make audio wrapper available (i.e. RIFF)
305 #define OPEN_2CH_MAX    0x8     // open multichannel as stereo (no downmix)
306 #define OPEN_NORMALIZE  0x10    // normalize floating point data to +/- 1.0
307 #define OPEN_STREAMING  0x20    // "streaming" mode blindly unpacks blocks
308                                 // w/o regard to header file position info
309 #define OPEN_EDIT_TAGS  0x40    // allow editing of tags
310 #define OPEN_FILE_UTF8  0x80    // assume filenames are UTF-8 encoded, not ANSI (Windows only)
311 
312 // new for version 5
313 
314 #define OPEN_DSD_NATIVE 0x100   // open DSD files as bitstreams
315                                 // (returned as 8-bit "samples" stored in 32-bit words)
316 #define OPEN_DSD_AS_PCM 0x200   // open DSD files as 24-bit PCM (decimated 8x)
317 #define OPEN_ALT_TYPES  0x400   // application is aware of alternate file types & qmode
318                                 // (just affects retrieving wrappers & MD5 checksums)
319 #define OPEN_NO_CHECKSUM 0x800  // don't verify block checksums before decoding
320 
321 int WavpackGetMode (WavpackContext *wpc);
322 
323 #define MODE_WVC        0x1
324 #define MODE_LOSSLESS   0x2
325 #define MODE_HYBRID     0x4
326 #define MODE_FLOAT      0x8
327 #define MODE_VALID_TAG  0x10
328 #define MODE_HIGH       0x20
329 #define MODE_FAST       0x40
330 #define MODE_EXTRA      0x80    // extra mode used, see MODE_XMODE for possible level
331 #define MODE_APETAG     0x100
332 #define MODE_SFX        0x200
333 #define MODE_VERY_HIGH  0x400
334 #define MODE_MD5        0x800
335 #define MODE_XMODE      0x7000  // mask for extra level (1-6, 0=unknown)
336 #define MODE_DNS        0x8000
337 
338 int WavpackVerifySingleBlock (unsigned char *buffer, int verify_checksum);
339 int WavpackGetQualifyMode (WavpackContext *wpc);
340 char *WavpackGetErrorMessage (WavpackContext *wpc);
341 int WavpackGetVersion (WavpackContext *wpc);
342 char *WavpackGetFileExtension (WavpackContext *wpc);
343 unsigned char WavpackGetFileFormat (WavpackContext *wpc);
344 uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples);
345 uint32_t WavpackGetNumSamples (WavpackContext *wpc);
346 int64_t WavpackGetNumSamples64 (WavpackContext *wpc);
347 uint32_t WavpackGetNumSamplesInFrame (WavpackContext *wpc);
348 uint32_t WavpackGetSampleIndex (WavpackContext *wpc);
349 int64_t WavpackGetSampleIndex64 (WavpackContext *wpc);
350 int WavpackGetNumErrors (WavpackContext *wpc);
351 int WavpackLossyBlocks (WavpackContext *wpc);
352 int WavpackSeekSample (WavpackContext *wpc, uint32_t sample);
353 int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample);
354 WavpackContext *WavpackCloseFile (WavpackContext *wpc);
355 uint32_t WavpackGetSampleRate (WavpackContext *wpc);
356 uint32_t WavpackGetNativeSampleRate (WavpackContext *wpc);
357 int WavpackGetBitsPerSample (WavpackContext *wpc);
358 int WavpackGetBytesPerSample (WavpackContext *wpc);
359 int WavpackGetNumChannels (WavpackContext *wpc);
360 int WavpackGetChannelMask (WavpackContext *wpc);
361 int WavpackGetReducedChannels (WavpackContext *wpc);
362 int WavpackGetFloatNormExp (WavpackContext *wpc);
363 int WavpackGetMD5Sum (WavpackContext *wpc, unsigned char data [16]);
364 void WavpackGetChannelIdentities (WavpackContext *wpc, unsigned char *identities);
365 uint32_t WavpackGetChannelLayout (WavpackContext *wpc, unsigned char *reorder);
366 uint32_t WavpackGetWrapperBytes (WavpackContext *wpc);
367 unsigned char *WavpackGetWrapperData (WavpackContext *wpc);
368 void WavpackFreeWrapper (WavpackContext *wpc);
369 void WavpackSeekTrailingWrapper (WavpackContext *wpc);
370 double WavpackGetProgress (WavpackContext *wpc);
371 uint32_t WavpackGetFileSize (WavpackContext *wpc);
372 int64_t WavpackGetFileSize64 (WavpackContext *wpc);
373 double WavpackGetRatio (WavpackContext *wpc);
374 double WavpackGetAverageBitrate (WavpackContext *wpc, int count_wvc);
375 double WavpackGetInstantBitrate (WavpackContext *wpc);
376 int WavpackGetNumTagItems (WavpackContext *wpc);
377 int WavpackGetTagItem (WavpackContext *wpc, const char *item, char *value, int size);
378 int WavpackGetTagItemIndexed (WavpackContext *wpc, int index, char *item, int size);
379 int WavpackGetNumBinaryTagItems (WavpackContext *wpc);
380 int WavpackGetBinaryTagItem (WavpackContext *wpc, const char *item, char *value, int size);
381 int WavpackGetBinaryTagItemIndexed (WavpackContext *wpc, int index, char *item, int size);
382 int WavpackAppendTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize);
383 int WavpackAppendBinaryTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize);
384 int WavpackDeleteTagItem (WavpackContext *wpc, const char *item);
385 int WavpackWriteTag (WavpackContext *wpc);
386 
387 WavpackContext *WavpackOpenFileOutput (WavpackBlockOutput blockout, void *wv_id, void *wvc_id);
388 void WavpackSetFileInformation (WavpackContext *wpc, char *file_extension, unsigned char file_format);
389 
390 #define WP_FORMAT_WAV   0       // Microsoft RIFF, including BWF and RF64 varients
391 #define WP_FORMAT_W64   1       // Sony Wave64
392 #define WP_FORMAT_CAF   2       // Apple CoreAudio
393 #define WP_FORMAT_DFF   3       // Philips DSDIFF
394 #define WP_FORMAT_DSF   4       // Sony DSD Format
395 
396 int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples);
397 int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64_t total_samples, const unsigned char *chan_ids);
398 int WavpackSetChannelLayout (WavpackContext *wpc, uint32_t layout_tag, const unsigned char *reorder);
399 int WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount);
400 int WavpackStoreMD5Sum (WavpackContext *wpc, unsigned char data [16]);
401 int WavpackPackInit (WavpackContext *wpc);
402 int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count);
403 int WavpackFlushSamples (WavpackContext *wpc);
404 void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block);
405 void *WavpackGetWrapperLocation (void *first_block, uint32_t *size);
406 double WavpackGetEncodedNoise (WavpackContext *wpc, double *peak);
407 
408 void WavpackFloatNormalize (int32_t *values, int32_t num_values, int delta_exp);
409 
410 void WavpackLittleEndianToNative (void *data, char *format);
411 void WavpackNativeToLittleEndian (void *data, char *format);
412 void WavpackBigEndianToNative (void *data, char *format);
413 void WavpackNativeToBigEndian (void *data, char *format);
414 
415 uint32_t WavpackGetLibraryVersion (void);
416 const char *WavpackGetLibraryVersionString (void);
417 
418 #ifdef __cplusplus
419 }
420 #endif
421 
422 #endif
423