diff --git a/.gitignore b/.gitignore index b5f9d79fc..febe4d97e 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,4 @@ Xcode-config/SENTRY_SETTINGS.xcconfig /ThirdParty/vorbis/lib/libvorbisfile.3.dylib /ThirdParty/vorbis/lib/libvorbis.0.dylib /ThirdParty/soxr/lib/libsoxr.0.dylib +/ThirdParty/WavPack/lib/libwavpack.a diff --git a/Frameworks/WavPack/Files/AUTHORS b/Frameworks/WavPack/Files/AUTHORS deleted file mode 100644 index 27bdd8f0d..000000000 --- a/Frameworks/WavPack/Files/AUTHORS +++ /dev/null @@ -1,11 +0,0 @@ -David Bryant -Sebastian Dröge -Joachim Henke -Joël R. Langlois -Alexis Ballier -Stephen -Phil Eichinger -Sebastian Ramacher -luxagen -Martin Koegler -nu774 diff --git a/Frameworks/WavPack/Files/ChangeLog b/Frameworks/WavPack/Files/ChangeLog deleted file mode 100644 index d68161e76..000000000 --- a/Frameworks/WavPack/Files/ChangeLog +++ /dev/null @@ -1,366 +0,0 @@ -2019-12-14 David Bryant - - * cli/wvunpack.c - -s option: add "5.1 surround side" and "7.1 surround" to reported channel configurations - -2019-12-13 David Bryant - - * cli/riff[_write].c, cli/wave64[_write].c, cli/caff[_write].c, cli/dsf[_write].c, cli/dsdiff[_write].c: - split header readers & writers so that wvunpack doesn't link libwavpack encoder - -2019-12-12 David Bryant - - * cli/riff.c, cli/wave64.c, cli/caff.c: - -i option: display warning when dropping PCM samples from end of file - -2019-12-11 David Bryant - - * cli/wavpack.c: - fix a WAV header if user specified -i (to ignore length) and we can make it valid - -2019-12-08 David Bryant - - * fuzzing/fuzzer.cc, fuzzing/fuzzer_seed_corpus.zip, etc...: - add fuzzing directory with corpus and other files for oss-fuzz - -2019-12-08 David Bryant - - * src/open_utils.c: - fix possible memory leak on opening corrupted files - -2019-12-08 David Bryant - - * src/common_utils.c, src/pack_dsd.c, src/unpack_dsd.c, src/wavpack_local.h: - - fix potential memory leak when seeking in DSD files - - simplify DSD fast mode lookup buffer allocations - -2019-12-08 David Bryant - - * src/unpack.c, src/unpack_dsd.c, src/unpack_seek.c: - seeking fixes: - - fix crash during seek to corrupted block - - check header size before malloc() - - fix overlapping memcpy() - -2019-11-30 David Bryant - - * src/pack.c: - - provide more configuration sanity checks to aid application debugging - - force max_blocksize even so bitstream buffer overflow detection works - -2019-04-09 David Bryant - - * cli/import_id3.c: - issue #69: add TPUB (Publisher) to accepted ID3v2 tag fields - -2019-03-05 David Bryant - - * cli/wave64.c: - issue #68: clear WaveHeader at start to prevent uninitialized read - -2019-03-05 David Bryant - - * cli/dsdiff.c: - issue #67: make sure sample rate is specified and non-zero in DFF files - -2019-03-04 David Bryant - - * cli/caff.c: - issue #66: make sure CAF files have a "desc" chunk - -2019-03-02 David Bryant - - * cli/dsdiff.c: - issue #65: makre sure DSDIFF files have a valid channel count - -2018-12-23 evpobr - - * include/wavpack.h src/wavpack_local.h: - remove duplication so that wavpack_local.h can include wavpack.h - -2018-12-16 evpobr - - * Makefile.am, CMakeLists.txt - add CMake project - -2018-12-09 orbea - - * cli/Makefile.am: - fix command-line builds with slibtool - -2018-12-08 Ørjan Malde - - * src/extra[12].c, src/pack.c, src/pack_x64.S, src/unpack.c, src/unpack_x64.S, src/wavpack_local.h: - x64 ASM support for midipix - -2018-11-29 David Bryant - - * src/pack_utils.c: - issue #53: error on zero sample rate - - CVE-2018-19840 - -2018-11-29 David Bryant - - * src/open_utils.c: - issue #54: fix potential out-of-bounds heap read - - CVE-2018-19841 - -2018-11-29 David Bryant - - * src/open_filename.c: - Windows only: use wvc file when verifying encode when source is stdin - -2018-09-03 Mike Tzou - - * cli/import_id3.c, cli/wvgain.c, cli/open_raw.c, cli/wvparser.c, cli/wvunpack.c, winamp/in_wv.c: - printf() format specifiers - memory leaks - -2018-08-26 David Bryant - - * cli/dsdiff.c, cli/dsf.c, cli/caff.c: - issue #41 issue #42 issue #43: sanitize input files to prevent crashes - -2018-06-02 David Bryant - - * src/unpack_armv7.S: - fix thumb interworking on ARM by adding .type for assembly functions - -2018-04-30 David Bryant - - * cli/import_id3.c, cli/wavpack.c: - allow ID3v2.3 tag import from any file type (not just DSF) - -2018-04-29 David Bryant - - * cli/import_id3.c: - handle ID3v2.3 TXXX tags using description for APEv2 item name (w/ case formatting) - -2018-04-24 David Bryant - - * cli/riff.c, cli/wave64.c: - issue #30 issue #31 issue #32: no multiple format chunks in WAV or W64 - - CVE-2018-10536 - - CVE-2018-10537 - - * cli/dsdiff.c, cli/riff.c, cli/wave64.c: - issue #33, sanitize size of unknown chunks before malloc() - - CVE-2018-10538 - - CVE-2018-10539 - - CVE-2018-10540 - -2018-04-17 David Bryant - - * cli/import_id3.c: - add a bunch more ID3v2.3 tag entries - make ImportID3v2() more robust (e.g. always set bytes_used) - -2018-04-08 David Bryant - - * src/common_utils.c: - fix memory leaks - -2018-02-11 David Bryant - - * cli/caff.c: - issue #26, fix buffer overflows and bad allocs on corrupt CAF files - - CVE-2018-7254 - -2018-02-10 David Bryant - - * cli/dsdiff.c: - issue #28, do not overwrite heap on corrupt DSDIFF file - - CVE-2018-7253 - -2018-02-04 David Bryant - - * cli/riff.c: - issue #27, do not overwrite stack on corrupt RF64 file - - CVE-2018-6767 - -2017-10-29 David Bryant - - * src/read_words.c: - issue #24, another C++ compiler fix, this time for _BitScanForward() - -2017-10-28 David Bryant - - * Makefile.am: - add README.md to extra distribution files - -2017-10-20 Joël R. Langlois - - * README, README.md: - Updated README to Markdown format. - -2017-10-12 Joël R. Langlois - - * src/decorr_utils.c, src/entropy_utils.c, src/open_legacy.c, - src/open_utils.c, src/tag_utils.c, src/tags.c, src/unpack3.c, - src/unpack3_open.c, src/unpack_dsd.c, src/unpack_seek.c, - src/unpack_utils.c: - Fixed errors when compiling using a C++ compiler. - -2017-09-30 David Bryant - - * cli/import_id3.c: - experimental fix to handle ID3v2.3 tags that [incorrectly] use synchsafe for the frame size - -2017-08-31 David Bryant - - * cli/wavpack.c - briefly describe other utilities in help displays for wavpack - -2017-07-24 David Bryant - - * cli/md5.h - do not try to use libcrypto on OS X - -2017-07-23 David Bryant - - * cli/md5.c, cli/md5.h, cli/wavpack.c, cli/wvtest.c, cli/wvunpack.c, configure.ac: - use Alexander Peslyak's MD5 implementation (or libcrypto if present) to fix - unaligned access coredump on OpenBSD/sparc64 (reported on openbsd-ports) - -2017-03-19 David Bryant - - * src/write_words.c: - improve quality of scan_word() results on very short blocks (via multiple passes) - -2017-03-01 David Bryant - - * cli/wavpack.c, cli/wvgain.c, cli/wvtag.c, cli/wvunpack.c: - add required parens to correct precedence error/warning - -2017-02-26 David Bryant - - * cli/wavpack.c, cli/wvgain.c, cli/wvtag.c, cli/wvunpack.c: - refactor debug logging mode so that we can turn on a forced arg dump - - * src/common_utils.c, src/wavpack_local.h: - provide for a "close" callback to be installed for dumping accumulated statistics - - * configure.ac, src/unpack_armv7.S: - SSAT instruction required armv6, now we should work on all ARMs using a pair of shifts instead - -2017-02-18 Alexis Ballier - - * configure.ac: - configure: Restrict arm assembly to armv7 only. - ARM assembly in wavpack is armv7 only it seems. - I have reports this causes build failures on armv5: https://bugs.gentoo.org/show_bug.cgi?id=609168 - -2017-02-16 David Bryant - - * cli/import_id3.c, cli/wvtag.c: - fix GitHub issue #19 (new dependency on wchar_t) by removing dependency - -2017-01-22 David Bryant - - * .travis.yml: - do more exhaustive testing for Travis (but should be faster) - -2017-01-22 Stephen - - * .travis.yml: - enable travis ci build and testing (#17) - Create .travis.yml - fix for running tests - limit to smaller test suite - add quotes to get spaces in arg - remove linux clang builds - move to trusty for clang - -2017-01-18 David Bryant - - * ChangeLog: - refine change log and add updated plugins - - * audition/cool_wv4.c, audition/readme.odt, audition/readme.pdf: - update Cool Edit / Audition filter to 3.1 - - * COPYING, license.txt, winamp/in_wv.c, winamp/installer/WavPackPlugin1.nsi: - update winamp to 2.8.0.3 and license dates - -2017-01-17 David Bryant - - * ChangeLog: - first pass at 5.1.0 changelog - - * cli/Makefile.am, cli/import_id3.c, cli/wavpack.c: - fix Darwin build (iconv) and ptr warnings - improve --import-id3 console messaging - -2017-01-16 David Bryant - - * wavpackdll/wavpackdll.rc, wavpackexe/wavpack.vcproj, winamp/in_wv.c: - bump DLL version and fix MSVC build - - * cli/utils.h, cli/wavpack.c, cli/wvgain.c, cli/wvtag.c, cli/wvunpack.c, - configure.ac, src/wavpack_version.h: - update version to 5.1.0 and bump some copyright dates - - * src/pack.c: - do not write data in NEW_CONFIG_BLOCK for "do not care" bits in qmode - - * src/unpack_dsd.c: - shorter DSD decimation filter with less HF rolloff and lower CPU use - -2017-01-15 David Bryant - - * doc/wavpack_doc.html: - update user manual for 5.1.0 and wvtag - -2017-01-14 David Bryant - - * cli/wvtag.c: - allow multiple files on Windows, update "help" - - * man/Makefile.am, man/wavpack.1, man/wavpack.xml, man/wvgain.1, man/wvgain.xml, - man/wvtag.1, man/wvtag.xml, man/wvunpack.1, man/wvunpack.xml: - add man page for wvtag and update the other man pages (--import-id3) - -2017-01-13 David Bryant - - * cli/Makefile.am, cli/wavpack.c: - add --import-id3 option to wavpack executable - (works with original DSF files and when transcoding) - - * cli/import_id3.c, cli/wvtag.c: - refactor ID3 import code to calculate the total number of bytes being imported - - allow total size and item count to be returned even on dry runs - - plug a memory leak in the dry run - -2017-01-11 David Bryant - - * src/pack.c, src/unpack.c: - fix issue where noise-shaping falsely triggers lossy muting - - only in very rare cases (detected with pathological testing) - - also fix (again) macro that disables lossy muting - -2017-01-08 David Bryant - - * src/pack_utils.c: - fix regression causing non-byte-aligned audio (e.g., 12-bit) - to lose the actual reduced bit-depth indication (although - there was no effect on integrity or compression ratio) - -2017-01-07 David Bryant - - * cli/import_id3.c, cli/wvtag.c, wavpack.sln, wvtagexe/wvtag.vcproj: - add wvtag to MSVC build and fix warnings (and one mistake) - - * src/open_filename.c: - fix MSVC build (broken by portability enhancements...sigh) - -2017-01-06 David Bryant - - * cli/Makefile.am, cli/import_id3.c, cli/wvtag.c: - new cli tool "wvtag" to manipulate APEv2 tags on existing WavPack files - (includes new facility to import ID3v2.3 tag items from Sony DSF files) - - * cli/wavpack.c: - add --pre-quantize-round to settings tag - - * cli/wvgain.c, cli/wvunpack.c: - copy TextToUTF8() BOM fix into other modules that use it for filename lists diff --git a/Frameworks/WavPack/Files/NEWS b/Frameworks/WavPack/Files/NEWS deleted file mode 100644 index 03523733e..000000000 --- a/Frameworks/WavPack/Files/NEWS +++ /dev/null @@ -1,717 +0,0 @@ - --------------------------------- - Release 5.2.0 - December 15, 2019 - --------------------------------- - - WavPack Library Source Code - 5.2.0 - wavpack.exe (command-line encoder) - 5.2.0 - wvunpack.exe (command-line decoder) - 5.2.0 - wvgain.exe (command-line ReplayGain scanner) - 5.2.0 - wvtag.exe (command-line tagging utility) - 5.2.0 - ---------------------------------------------------- - fixed: potential security issues including the following CVEs: - CVE-2018-19840 CVE-2018-19841 CVE-2018-10536 - CVE-2018-10537 CVE-2018-10538 CVE-2018-10539 - CVE-2018-10540 CVE-2018-7254 CVE-2018-7253 - CVE-2018-6767 - added: support for CMake, Travis CI, and Google's OSS-fuzz - fixed: use correction file for encode verify (pipe input, Windows) - fixed: correct WAV header with actual length (pipe input, -i option) - fixed: thumb interworking and not needing v6 architecture (ARM asm) - added: handle more ID3v2.3 tag items and from all file types - fixed: coredump on Sparc64 (changed MD5 implementation) - fixed: handle invalid ID3v2.3 tags from sacd-ripper - fixed: several corner-case memory leaks - - - -------------------------------- - Release 5.1.0 - January 18, 2017 - -------------------------------- - - WavPack Library Source Code - 5.1.0 - wavpack.exe (command-line encoder) - 5.1.0 - wvunpack.exe (command-line decoder) - 5.1.0 - wvgain.exe (command-line ReplayGain scanner) - 5.1.0 - wvtag.exe (command-line tagging utility) - 5.1.0 - ---------------------------------------------------- - added: all new command-line tagging utility (wvtag) - added: option to import ID3v2.3 tags from Sony DSF files - fixed: fuzz test failures from AFL reported on SourceForge - improved: DSD decimation filter (less HF rolloff & CPU use) - fixed: non-byte audio depths (12-bit, 20-bit) not showing - fixed: rare case of noise-shaping triggering a lossy mute - fixed: recognize UTF-8 BOM when reading text files - fixed: a few portability issues - - in_wv.dll (winamp plugin) - 2.8.0.3 - CoreWavPack DirectShow Filters - 1.5.1.0 - AmioWavpack.amio (Adobe Audition Plugins) - 2.1 - cool_wv4.flt (Cool Edit / Audition filter) - 3.1 - ------------------------------------------------ - updated: see 5.1.0 library changes - - - -------------------------------- - Release 5.0.0 - December 6, 2016 - -------------------------------- - - WavPack Library Source Code - 5.0.0 - wavpack.exe (command-line encoder) - 5.0.0 - wvunpack.exe (command-line decoder) - 5.0.0 - wvgain.exe (command-line ReplayGain scanner) - 5.0.0 - ---------------------------------------------------- - added: multiple input formats, including RF64, Wave64, and CAF - added: lossless DSD audio in Philips DSDIFF and Sony DSF files - fixed: seeking in > 2GB WavPack files (new stream reader) - fixed: accept > 4GB source audio files (all formats) - improved: increase maximum samples from 2^32 to 2^40 - added: block checksums for robustness to corruption - added: support for non-standard channel identities - removed: support for legacy WavPack files (< 4.0) - added: block decoder for streaming applications - fixed: many small fixes and improvements - added: all new pdf documentation - - AmioWavpack.amio (Adobe Audition Plugins) - 2.0 - ----------------------------------------------- - improved: all new dialog for WavPack settings - fixed: handle unlimited audio file size - fixed: save all Amio channel identities - added: save/restore APEv2 tags - - in_wv.dll (winamp plugin) - 2.8.0.2 - CoreWavPack DirectShow Filters - 1.5.0.0 - cool_wv4.flt (Cool Edit / Audition filter) - 3.0 - ------------------------------------------------ - updated: see 5.0.0 library changes - - - ------------------------------- - Release 4.80.0 - March 28, 2016 - ------------------------------- - - WavPack Library Source Code - 4.80.0 - wavpack.exe (command-line encoder) - 4.80.0 - wvunpack.exe (command-line decoder) - 4.80.0 - wvgain.exe (command-line ReplayGain scanner) - 4.80.0 - ----------------------------------------------------- - added: full Unicode support on Windows platform - added: new option --pre-quantize to truncate high-resolution files - to a reasonable depth (e.g., 20-bit) for better compression - fixed: Debian bug #793320 (executable stack) - fixed: LargeAddressAware problem reported on HA - fixed: several "fuzz test" failures reported on GitHub - fixed: repack blocks after possible arithmetic overflows - improved: faster assembly code for mono packing - improved: portability for various platforms - - wvtest.exe (command-line libwavpack test suite) - 4.80.0 - -------------------------------------------------------- - added: exhaustive test for WavpackSeekSample() API - - in_wv.dll (winamp plugin) - 2.8.0.1 - CoreWavPack DirectShow Filters - 1.3.0.0 - AmioWavpack.amio (Adobe Audition Plugins) - 1.5 - cool_wv4.flt (CoolEdit / Audition filter) - 2.14 - ------------------------------------------------ - updated: see 4.80.0 library changes - - - -------------------------------- - Release 4.75.2 - October 1, 2015 - -------------------------------- - - WavPack Library Source Code - 4.75.2 - ------------------------------------ - fixed: corrupt mono or multichannel files created with assembly code (rare) - fixed: building on Clang systems like Darwin and FreeBSD (req. Clang 3.5+) - fixed: explicitly sign-extend audio data (< 4-byte) to avoid corrupt files - fixed: rare decoding errors due to integer overflow (ARM assembly code) - added: assembly optimizations for "extra" mode on mono or multichannel - - wvtest.exe (command-line libwavpack test suite) - 4.75.2 - -------------------------------------------------------- - all new program to stress-test libwavpack (requires Pthreads) - - wavpack.exe (command-line encoder) - 4.75.2 - wvunpack.exe (command-line decoder) - 4.75.2 - wvgain.exe (command-line ReplayGain scanner) - 4.75.2 - ----------------------------------------------------- - fixed: corrupt mono or multichannel files created with assembly code (rare) - added: assembly optimizations for "extra" mode on mono or multichannel - improved: flush stderr after all writes - - cool_wv4.flt (CoolEdit / Audition filter) - 2.13 - AmioWavpack.amio (Adobe Audition Plugins) - 1.4 - ------------------------------------------------ - fixed: corrupt mono or multichannel files (rare) - - - ----------------------------- - Release 4.75.0 - May 25, 2015 - ----------------------------- - - WavPack Library Source Code - 4.75.0 - ------------------------------------ - improved: reorganization for modularity and to improve linking - added: assembly optimizations for encode/decode on x86 and x64 - added: assembly optimizations for decoding on ARMv7 (Linux) - improved: several minor speed optimizations using intrinsics - fixed: wavpack.pc.in not working correctly on some Linux distros - fixed: memcpy() issue causing abort() on OpenBSD - - wavpack.exe (command-line encoder) - 4.75.0 - wvunpack.exe (command-line decoder) - 4.75.0 - wvgain.exe (command-line ReplayGain scanner) - 4.75.0 - ----------------------------------------------------- - changed: writing to console title default is off (Linux only, -z1 to enable) - fixed: wvgain crashes on bad file arguments (Debian bug #716478) - - cool_wv4.flt (CoolEdit / Audition filter) - 2.12 - ------------------------------------------------ - improved: performance (from assembly optimizations) - - - ------------------------- - Update - December 7, 2013 - ------------------------- - - CoreWavPack DirectShow Filters - 1.2.0.2 - ---------------------------------------- - imported: latest filter sources from Christophe Paris and CoreCodec - updated: port to VS 2008 and add 64-bit build platform with installer - added: decode streams with full headers (tested with LAV splitter) - fixed: issues with 7.1 and non-standard channel configurations - fixed: problems with 12-bit, 20-bit, and 32-bit integer audio - fixed: crashing bug related to hybrid files with DNS - fixed: custom sampling rates being ignored - - - --------------------------------- - Release 4.70.0 - October 19, 2013 - --------------------------------- - - wavpack.exe (command-line encoder) - 4.70.0 - ------------------------------------------- - added: transcoding from existing WavPack files (with tag copy) - added: option to verify WavPack file integrity on creation (-v) - added: use temporary files for safer overwriting - added: detect UTF-16LE encoding for tag text files (mostly a Windows thing) - added: --version command to write machine-parsable value - added: option to allow up to 16 MB APEv2 tag data (--allow-huge-tags) - added: allow channel-order specification on WAV files with zeroed channel mask - added: several Windows features to Linux (clean ^C handling, console title) - added: 4GB file support on 32-bit Linux targets - - WavPack Library Source Code - 4.70.0 - ------------------------------------ - fixed: seeking to last block failure (after finishing file) - fixed: memcpy() not always used correctly (Linux targets) - fixed: unsigned char issue (ARM targets) - fixed: add binary tag functions to Windows DLL exports (forgot on 4.60) - added: read-only access to APEv2 tags that come at the beginning of files - improved: switched to Microsoft Visual Studio 2008 (win32 only) - - wvunpack.exe (command-line decoder) - 4.70.0 - -------------------------------------------- - added: use temporary files for safer overwriting - added: --version command to write machine-parsable value - added: new command (-f) for getting machine-parsable WavPack file info - added: option (-n) to suppress audio decoding (useful for extracting only tags) - - wvgain.exe (command-line ReplayGain scanner) - 4.70.0 - ----------------------------------------------------- - fixed: the -q (quiet) option would cause the -c (clean) option to fail - added: version command (-v) to write machine-parsable value - - in_wv.dll (winamp plugin) - 2.8 - ------------------------------- - fixed: settings could not be saved on newer Windows versions (7 & 8) - fixed: installation issue caused by including manifest in build - added: dialog to installer suggesting "Winamp Essentials Pack" - - AmioWavpack.amio (Adobe Audition Plugin) - 1.0 - ---------------------------------------------- - all new plugin for Audition 4.0 (CS5.5) and later (including Audition CC) - - - -------------------------- - Update - December 23, 2009 - -------------------------- - - in_wv.dll (winamp plugin) - 2.8a - -------------------------------- - fixed: crashes in winamp 5.57 when playing tracks that have "genre" tag - - - ---------------------------------- - Release 4.60.1 - November 29, 2009 - ---------------------------------- - - WavPack Library Source Code - 4.60.1 - ------------------------------------ - fixed: filename specs in tag extractions failed in batch operations - fixed: prevent creation of APEv2 tags > 1 MB (which we can't read) - fixed: crash when decoding old WavPack files (pre version 4.0) - added: man pages to build system and updated with newer options - added: versioning info to Windows DLL - improved: build compatibility (eliminated uchar, ushort types) - - wavpack.exe (command-line encoder) - 4.60.1 - ------------------------------------------- - fixed: don't allow user to attempt to place over 1 MB into APEv2 tags - - in_wv.dll (winamp plugin) - 2.7 - ------------------------------- - added: read-only support for displaying cover art (thanks Benski!) - - wvunpack.exe (command-line decoder) - 4.60.1 - wvgain.exe (command-line ReplayGain scanner) - 4.60.1 - cool_wv4.flt (CoolEdit / Audition filter) - 2.11 - ----------------------------------------------------- - (see library changes) - - - --------------------------------- - Release 4.60 - September 27, 2009 - --------------------------------- - - WavPack Library Source Code - 4.60 - ---------------------------------- - added: API for reading & writing binary fields in APEv2 tags - fixed: recognize APEv2 tags with footers but no headers - fixed: playback of files with 8 streams (15-16 channels) - fixed: playback and seeking failed on certain rare correction files - fixed: handle case where library makes RIFF header but app adds RIFF trailer - improved: channel count limit now virtually unlimited (tested to 256) - improved: move all tag functions into new module (tags.c) - - wavpack.exe (command-line encoder) - 4.60 - ----------------------------------------- - added: --write-binary-tag command for embedded cover art - added: --no-utf8-convert command to skip Unicode character conversions - added: --raw-pcm command to specify raw PCM data (samplerate, bitdepth, num chans) - added: --channel-order accepts "..." to specify unassigned channels - added: --pair-unassigned-chans command to put unassigned channels into stereo pairs - - wvunpack.exe (command-line decoder) - 4.60 - ------------------------------------------ - added: -x (and -xx) commands for extracting arbitrary tag fields to stdout (and files) - added: --no-utf8-convert command to skip Unicode character conversions - changed: -ss command no longer dumps multiline tags (use -x instead) - improved: formatting of -ss command, also shows information on binary tags - - wvgain.exe (command-line ReplayGain scanner) - 4.60 - --------------------------------------------------- - added: -n option for processing new files only (those without ReplayGain info) - improved: increase maximum gain value generated from +24 to +64 dB - - in_wv.dll (winamp plugin) - 2.6 - cool_wv4.flt (CoolEdit / Audition filter) - 2.10 - ------------------------------------------------ - (see library changes) - - - ------------------------- - Update - January 23, 2009 - ------------------------- - - in_wv.dll (winamp plugin) - 2.6b - -------------------------------- - added: "lossless" and "category" to metadata keywords that we handle in winamp plugin - added: internationalization support to facilitate inclusion in Winamp Essentials Pack - - - ----------------------------- - Release 4.50.1 - July 3, 2008 - ----------------------------- - - WavPack Library Source Code - 4.50.1 - ------------------------------------ - fixed: alignment fault when manipulating APEv2 tags (non-x86 only) - fixed: build on UNIX via elimination of non-standard strnlen() - - wavpack.exe (command-line encoder) - 4.50.1 - wvunpack.exe (command-line decoder) - 4.50.1 - -------------------------------------------- - fixed: checking return value of iconv_open() prevents core dump on Solaris - - - ---------------------------- - Release 4.50 - June 13, 2008 - ---------------------------- - - WavPack Library Source Code - 4.50 - ---------------------------------- - added: dynamic noise shaping for improved hybrid quality - added: option to merge blocks of similar redundancy - added: ability to store and retrieve extra mode level - fixed: alignment fault on some big-endian machines - fixed: compiling with enable-mmx on gcc 4.3.x (thanks Joachim) - improved: allow bitrate to be calculated for files down to 1/10 second - improved: decoding of corrupt files (prevents heap overrun crashes) - - wavpack.exe (command-line encoder) - 4.50 - ----------------------------------------- - added: dynamic noise shaping for improved hybrid quality - added: --channel-order option to reorder nonconforming multichannel files - added: --merge-blocks option to optimize storage of LossyWAV output files - added: ignore -o on Windows for compatibility with Linux version - fixed: alignment fault on some big-endian machines - improved: reformatted and expanded --help display - - wvunpack.exe (command-line decoder) - 4.50 - ------------------------------------------ - fixed: don't ignore fractions of seconds in --skip option - added: show extra level and dns status for newer files (-s command) - added: ignore -o on Windows for compatibility with Linux version - improved: decoding of corrupt files (prevents heap overrun crashes) - improved: display bitrate for files down to 1/10 second - - in_wv.dll (winamp plugin) - 2.5 - ------------------------------- - added: transcoding API (allows CD burning, format conversion, ReplayGain calc, etc.) - added: metadata writing API (for Auto-Tag, etc.) - added: full Unicode support for info box (older Winamps) and media library - added: standard Winamp metadata display & edit for newer Winamps - added: option to pass multichannel audio - added: option to pass all audio as 16-bit (for better compatibility) - added: option to output 24-bit audio when ReplayGain is active - added: genre display to info box (older Winamps) - fixed: seek bar sometimes vacillates when moved - fixed: crash when winamp is opened with files in playlist moved or deleted - improved: hi-res audio now output as 24-bit (not 32-bit) for better compatibility (EQ, etc.) - improved: performance of adding tracks to library, especially from network drives - improved: decoding of corrupt files (prevents heap overrun crashes) - - cool_wv4.flt (CoolEdit / Audition filter) - 2.9 - ----------------------------------------------- - added: about box - added: dynamic noise shaping for improved hybrid quality - improved: display bitrate for files as short as 1/10 second - improved: decoding of corrupt files (prevents heap overrun crashes) - improved: replace "extra processing" switch with a slider (0-6) - - - -------------------------- - Release 4.41 - May 6, 2007 - -------------------------- - - WavPack Library Source Code - 4.41 - ---------------------------------- - added: create wavpackdll.dll for Windows (not used yet) - fixed: corrupt floating-point audio on big-endian machines - fixed: put MSVC projects in their own subdir (fixed build problems) - fixed: limit RIFF data buffering to 16 MB to prevent out-of-memory crash - improved: attempt to mute errors when decoding corrupt legacy WavPack files - improved: overall performance enhancements of 10% to 30% (depending on mode) - added: MMX intrinsics for 24-bit (and higher) stereo encoding (thanks to - Joachim Henke) - - wavpack.exe (command-line encoder) - 4.41 - ----------------------------------------- - fixed: corrupt floating-point audio on big-endian machines - improved: refuse to encode WAV files over 4 GB or with over 16 MB RIFF data - improved: overall performance enhancements of 10% to 30% (depending on mode) - added: MMX intrinsics for 24-bit (and higher) stereo encoding (thanks to - Joachim Henke) - - wvunpack.exe (command-line decoder) - 4.41 - ------------------------------------------ - fixed: corrupt floating-point audio on big-endian machines - fixed: restore files mistakenly encoded with huge RIFF chunks - improved: attempt to mute errors when decoding corrupt legacy WavPack files - improved: overall performance enhancements of 10% to 30% (depending on mode) - added: --skip and --until commands to unpack specified range of audio data - added: MMX intrinsics for 24-bit (and higher) stereo encoding (thanks to - Joachim Henke) - - wvgain.exe (command-line ReplayGain scanner) - 4.41 - --------------------------------------------------- - improved: overall performance enhancements of 10% to 30% (depending on mode) - added: MMX intrinsics for 24-bit (and higher) stereo encoding (thanks to - Joachim Henke) - - cool_wv4.flt (CoolEdit / Audition filter) - 2.8 - ----------------------------------------------- - fixed: read all RIFF metadata from files created in other applications - improved: attempt to mute errors when decoding corrupt legacy WavPack files - improved: overall performance enhancements of 10% to 30% (depending on mode) - added: MMX intrinsics for 24-bit (and higher) stereo encoding (thanks to - Joachim Henke) - - - ------------------------------- - Release 4.40 - December 3, 2006 - ------------------------------- - - WavPack Library Source Code - 4.40 - ---------------------------------- - added: new hardware-friendly "high" mode that compresses almost as well as - old "high" mode but decodes significantly faster; old "high" mode - now available as "very high" - added: option added to improve compression of mono material in stereo files - (requires at least version 4.3 decoder) - added: function to obtain channel mapping information on decoding - added: function to get trailing wrapper info (RIFF) without decoding file - improved: "extra" mode levels 1-3 completely revamped, fast enough for use - improved: reorganized to create a standard library that should more easily - integrate into other applications; eliminated namespace issues - improved: more robust handling of corrupt files - - wavpack.exe (command-line encoder) - 4.40 - ----------------------------------------- - added: accepts long option names including --help for full usage info - added: new hardware-friendly "high" mode that compresses almost as well as - old "high" mode but decodes significantly faster; old "high" mode - now available as "very high" (-hh) - added: --optimize-mono option added to improve compression of mono material - in stereo files (requires at least version 4.3 decoder) - improved: "extra" mode levels 1-3 completely revamped, fast enough for use - improved: switched to Microsoft Visual Studio 2005 (win32 only) - removed: support for Windows 95 - - wvunpack.exe (command-line decoder) - 4.40 - ------------------------------------------ - added: cuesheet extraction (to .cue file or stdout) - added: wav header generation on decode for files with missing RIFF - information, or forced with -w option - added: more summary info (wrapper info + channel assignments) - improved: more robust handling of corrupt files - improved: separate options for raw (-r) and blind stream decoding (-b) - improved: switched to Microsoft Visual Studio 2005 (win32 only) - removed: support for Windows 95 - - wvgain.exe (command-line ReplayGain scanner) - 4.40 - --------------------------------------------------- - improved: switched to Microsoft Visual Studio 2005 (win32 only) - removed: support for Windows 95 - - wvselfx.exe (self-extraction stub) - 4.40 - ------------------------------------------ - added: automatic cuesheet extraction (if present in APEv2 tag) - - in_wv.dll (winamp plugin) - 2.4 - ------------------------------- - fixed: quietly skips deleted files in playlist - improved: more robust handling of corrupt files - improved: APEv2 tags are read even if followed by ID3v1 tag - - cool_wv4.flt (CoolEdit / Audition filter) - 2.7 - ----------------------------------------------- - added: new hardware-friendly "high" mode that compresses almost as well as - old "high" mode but decodes significantly faster; old "high" mode - now available as "v. high" - improved: more robust handling of corrupt files - - - ---------------------- - Update - April 5, 2006 - ---------------------- - - WavPack Library Source Code - 4.32 - wavpack.exe (command-line encoder) - 4.32 - ----------------------------------------- - fixed: generating RIFF headers on big-endian machines caused crash - - - -------------------------- - Update - December 10, 2005 - -------------------------- - - wavpack.exe (command-line encoder) - 4.31 - wvunpack.exe (command-line decoder) - 4.31 - ------------------------------------------ - fixed: detect debug mode in all cases (win32 only) - improved: use latest service pack and SDK for building (win32 only) - improved: better directory choice for logging file (win32 only) - improved: allow shell to expand wildcards (*nix only) - added: option (-o) to specify output directory or path (*nix only) - added: option (-t) to copy timestamp (*nix only) - - wvgain.exe (command-line ReplayGain scanner) - 4.31 - --------------------------------------------------- - new - - WavPack Library Source Code - 4.31 - ---------------------------------- - fixed: failing seek with some files that had been played to the end - fixed: small memory leak when opening hybrid lossless files - improved: signed characters no longer must be default - improved: APEv2 tags are read even if followed by ID3v1 tag - improved: limited APEv2 tag editing capability - - - ------------------------------ - Release 4.3 - November 1, 2005 - ------------------------------ - - wavpack.exe (command-line encoder) - 4.3 - ---------------------------------------- - fixed: bug causing termination error with very wide screen widths - added: command-line option (-l) to use low priority for batch operation - added: command-line option (-r) to generate a fresh RIFF header - added: debug mode (rename to wavpack_debug.exe) - added: automatically detect lower resolution data even without -x1 - added: src and dst dirs are searched also for tag source files (handy for EAC) - added: wildcard accepted for tag source files (handy for EAC) - added: handle non-standard sampling rates - improved: returns error status for any error - improved: use longer blocks in multichannel files (better "high" compression) - - wvunpack.exe (command-line decoder) - 4.3 - ----------------------------------------- - fixed: very rare decoding bug causing overflow with hi-res files - fixed: bug causing termination error with very wide screen widths - fixed: formatting error in duration display - added: command-line option (-ss) to include tags in summary dump - added: command-line option (-l) to use low priority for batch operation - added: debug mode (rename to wvunpack_debug.exe) - improved: returns error status for any error - improved: more robust decoding of damaged (or invalid) files - - in_wv.dll (winamp plugin) - 2.3 - nxWavPack.dll (Nero plugin) - 1.2 - WavPack_Apollo.dll (Apollo plugin) - 1.3 - cool_wv4.flt (CoolEdit / Audition filter) - 2.6 - ----------------------------------------------- - fixed: very rare decoding bug causing overflow with hi-res files - improved: handle ID3v1.1 tags (now includes track number) - improved: more robust decoding of damaged (or invalid) files - added: handle non-standard sampling rates - - foo_wavpack.dll (foobar plugin) - 2.3 - ----------------------------------------------- - fixed: any error during WavPack file open caused crash if wvc file present - fixed: very rare decoding bug causing overflow with hi-res files - improved: more robust decoding of damaged (or invalid) files - added: handle non-standard sampling rates - - WavPack Library Source Code - 4.3 - --------------------------------- - fixed: very rare decoding bug causing overflow with hi-res files - added: automatic generation of RIFF wav header during encoding - added: new functions to access tags by index (instead of item name) - added: automatically detect lower resolution data during encoding - added: handle non-standard sampling rates - improved: more robust decoding of damaged (or invalid) files - improved: use longer blocks in multichannel files (better "high" compression) - improved: two structures renamed to avoid namespace conflict - removed: legacy code for Borland compiler - - - -------------------------- - Update - September 1, 2005 - -------------------------- - - wavpack.exe (command-line encoder) - 4.22 - cool_wv4.flt (CoolEdit / Audition filter) - 2.5 - ----------------------------------------------- - fixed: possible corrupt files written (24 or 32-bit + "extra" mode) - - - --------------------------- - Release 4.2 - April 2, 2005 - --------------------------- - - wavpack.exe (command-line encoder) - 4.2 - ---------------------------------------- - fixed: handling of wav files larger than 2 gig - improved: stereo lossless encoding speed (including "extra" mode) - added: -i option to ignore length specified in wav header - added: -w option to write APEv2 tags directly from command line - - wvunpack.exe (command-line decoder) - 4.2 - ----------------------------------------- - improved: decoding speed - - in_wv.dll (winamp plugin) - 2.2 - ------------------------------- - added: winamp media library support - improved: decoding speed - - foo_wavpack.dll (foobar plugin) - 2.2 - ------------------------------------- - improved: decoding speed - - nxWavPack.dll (Nero plugin) - 1.1 - Cool_wv4.flt (CoolEdit / Audition filter) - 2.4 - ----------------------------------------------- - fixed: handling of wav files larger than 2 gig - improved: encoding and decoding speed - - WavPack Library Source Code - 4.2 - --------------------------------- - improved: encoding and decoding speed - fixed: works correctly with 64-bit compilers - added: mode bit to open files in "streaming" mode - - - -------------------------- - Update - December 12, 2004 - -------------------------- - - WavPack_Apollo.dll (Apollo plugin) - 1.2 - ---------------------------------------- - fixed: crash when Apollo opened and WavPack plugin can't find config file - - - -------------------------------- - Release 4.1 - September 14, 2004 - -------------------------------- - - wavpack.exe (command-line encoder) - 4.1 - ---------------------------------------- - fixed: hybrid mode + "extra" mode + very low bitrates making corrupt files - fixed: mono or multichannel files causing crash (no corruption possible) - added: third name specification for "correction" file (EAC specific) - added: -t option to preserve timestamps - added: error summary for batch mode - - wvunpack.exe (command-line decoder) - 4.1 - ----------------------------------------- - fixed: hybrid mode decoding bugs (very obscure situations) - added: -s option to dump file summary to stdout - added: -t option to preserve timestamps - added: error summary for batch mode - - wvselfx.exe (self-extraction stub) - 4.1 - ---------------------------------------- - fixed: hybrid mode decoding bugs (very obscure situations) - - in_wv.dll (winamp plugin) - 2.1 - ------------------------------- - fixed: international characters in tags display properly (UTF-8 to Ansi) - added: maximum tag data field width changed from 64 chars to 128 chars - added: new infobox items including encoder version & modes, track #, md5 - - foo_wavpack.dll (foobar plugin) - 2.1 - ------------------------------------- - added: new database items including encoder version & modes and md5 - - WavPack_Apollo.dll (Apollo plugin) - 1.1 - ---------------------------------------- - fixed: international characters in tags display properly (UTF-8 to Ansi) - - Cool_wv4.flt (CoolEdit / Audition filter) - 2.2 - ----------------------------------------------- - fixed: hybrid mode + "extra" mode + very low bitrates making corrupt files - fixed: saving mono file causing crash (no corruption possible) - fixed: hybrid mode decoding bugs (very obscure situations) - fixed: partial saves (with "Cancel") have incorrect RIFF header if unpacked - - nxWavPack.dll (Nero plugin) - 1.0 - --------------------------------- - new - - WavPack Library Source Code - 4.1 - --------------------------------- - fixed: hybrid mode + "extra" mode + very low bitrates making corrupt files - fixed: mono or multichannel files causing crash (no corruption possible) - fixed: hybrid mode decoding bugs (very obscure situations) - added: mode bits for determining additional encode info (extra, sfx) - added: function to return total compressed file length (including wvc) - added: function to return encoder version (1, 2, 3, or 4) - added: ability to obtain MD5 sum before decoding file (requires seek to end) - added: mode bit for determining tag type (for proper character translation) - added: ability to encode WavPack files without knowing length in advance - added: option for small "information only" version of library diff --git a/Frameworks/WavPack/Files/README.md b/Frameworks/WavPack/Files/README.md deleted file mode 100644 index a3742a82e..000000000 --- a/Frameworks/WavPack/Files/README.md +++ /dev/null @@ -1,136 +0,0 @@ - - -Hybrid Lossless Wavefile Compressor - -Copyright (c) 1998 - 2019 David Bryant. - -All Rights Reserved. - -Distributed under the [BSD Software License](https://github.com/dbry/WavPack/blob/master/license.txt). - ---- - -This [repository](https://github.com/dbry/WavPack) contains all of the source code required to build the WavPack library (_libwavpack_), and any associated command-line programs. - -Additional references: - -* [Official website](http://wavpack.com/) -* [Binaries](http://wavpack.com/downloads.html#binaries) -* [Other sources](http://wavpack.com/downloads.html#sources) -* [Documentation](http://wavpack.com/downloads.html#documentation) -* [Test suite](http://www.rarewares.org/wavpack/test_suite.zip) -* [Logos](http://wavpack.com/downloads.html#logos) - ---- - -## Build Status - -| Branch | Status | -|----------------|-------------------------------------------------------------------------------------------------------------------| -| `master` | [![Build Status](https://travis-ci.org/dbry/WavPack.svg?branch=master)](https://travis-ci.org/dbry/WavPack) | - -Branches [actively built](https://travis-ci.org/dbry/WavPack/branches) by TravisCI. - ---- - -## Building - -### Windows - -There are solution and project files for Visual Studio 2008, and additional source code to build the [CoolEdit/Audition](https://github.com/dbry/WavPack/tree/master/audition) plugin and the [Winamp](https://github.com/dbry/WavPack/tree/master/winamp) plugin. - -The CoolEdit/Audition plugin provides a good example for using the library to both read and write WavPack files, and the Winamp plugin makes extensive use of APEv2 tag reading and writing. - -Both 32-bit and 64-bit platforms are provided. - -Visual Studio 2008 does not support projects with x64 assembly very well. I have provided a copy of the edited `masm.rules` file that works for me, but I can't provide support if your build does not work. Please make a copy of your `masm.rules` file first. - -On my system it lives here: `C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\VCProjectDefaults` - -### Linux - -To build everything on Linux, type: - -1. `./configure` - * `--disable-asm` - * `--enable-man` - * `--enable-rpath` - * `--enable-tests` - * `--disable-apps` - * `--disable-dsd` - * `--enable-legacy` -2. `make` - * Optionally, `make install`, to install into `/usr/local/bin` - -If you are using the code directly from Git (rather than a distribution) then you will need to do a ./autogen.sh instead of the configure step. If assembly optimizations are available for your processor they will be automatically enabled, but if there is a problem with them then use the `--disable-asm` option to revert to pure C. - -For Clang-based build systems (Darwin, FreeBSD, etc.), Clang version 3.5 or higher is required. - -If you get a WARNING about unexpected _libwavpack_ version when you run the command-line programs, you might try using `--enable-rpath` to hardcode the library location in the executables, or simply force static linking with `--disable-shared`. - -There is now a CLI program to do a full suite of stress tests for _libwavpack_, and this is particularly useful for packagers to make sure that the assembly language optimizations are working correctly on various platforms. It is built with the configure option `--enable-tests` and requires Pthreads (it worked out-of-the-box on all the platforms I tried it on). There are lots of options, but the default test suite (consisting of 192 tests) is executed with `wvtest --default`. There is also a seeking test. On Windows a third-party Pthreads library is required, so I am not including this in the build for now. - ---- - -## Assembly - -Assembly language optimizations are provided for x86 and x86-64 (AMD64) processors (encoding and decoding) and ARMv7 (decoding only). - -The x86 assembly code includes a runtime check for MMX capability, so it will work on legacy i386 processors. - -## Documentation - -There are four documentation files contained in the distribution: - -| File | Description | -|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [doc/wavpack_doc.html](https://github.com/dbry/WavPack/blob/master/doc/wavpack_doc.html) | Contains user-targeted documentation for the command-line programs. | -| [doc/WavPack5PortingGuide.pdf](https://github.com/dbry/WavPack/blob/master/doc/WavPack5PortingGuide.pdf) | This document is targeted at developers who are migrating to WavPack 5, and it provides a short description of the major improvements and how to utilize them. | -| [doc/WavPack5LibraryDoc.pdf](https://github.com/dbry/WavPack/blob/master/doc/WavPack5LibraryDoc.pdf) | Contains a detailed description of the API provided by WavPack library appropriate for reading and writing WavPack files and manipulating APEv2 tags. | -| [doc/WavPack5FileFormat.pdf](https://github.com/dbry/WavPack/blob/master/doc/WavPack5FileFormat.pdf) | Contains a description of the WavPack file format, including details needed for parsing WavPack, blocks, and interpreting the block header and flags. | - -There is also a description of the WavPack algorithms in the forth edition of David Salomon's book "Data Compression: The Complete Reference". This section can be found here: www.wavpack.com/WavPack.pdf - -## Portability - -This code is designed to be easy to port to other platforms. - -It is endian-agnostic and usually uses callbacks for I/O, although there's a convenience function for reading files that accepts filename strings and automatically handles correction files. - -On Windows, there is now an option to select UTF-8 instead of ANSI. - -To maintain compatibility on various platforms, the following conventions are used: -* `char` must be 8-bits (`signed` or `unsigned`). -* `short` must be 16-bits. -* `int` and `long` must be at least 32-bits. - -## Design - -The code's modules are organized in such a way that if major chunks of the functionality are not referenced (for example, creating WavPack files) then link-time dependency resolution should provide optimum binary sizes. - -However, some functionality could not be easily excluded in this way and so there are additional macros that may be used to further reduce the size of the binary. Note that these must be defined for all modules: - -| Macros | Description | -|-----------------|------------------------------------------------------------------------------------------------------------| -| `NO_SEEKING` | To not allow seeking to a specific sample index (for applications that always read entire files). | -| `NO_TAGS` | To not read specified fields from ID3v1 and APEv2 tags, and not create or edit APEv2 tags. | -| `ENABLE_LEGACY` | Include support for Wavpack files from before version 4.0. This was eliminated by default with WavPack 5. | -| `ENABLE_DSD` | Include support for DSD audio. New for WavPack 5 and the default, but obviously not universally required. | - -Note that this has been tested on many platforms. - -## Tiny Decoder - -There are alternate versions of this library available specifically designed for resource limited CPUs, and hardware encoding and decoding. - -There is the _Tiny Decoder_ library which works with less than 32k of code and less than 4k of data, and has assembly language optimizations for the ARM and Freescale ColdFire CPUs. - -The _Tiny Decoder_ is also designed for embedded use and handles the pure lossless, lossy, and hybrid lossless modes. - -Neither of these versions use any memory allocation functions, nor do they require floating-point arithmetic support. - ---- - -Questions or comments should be directed to david@wavpack.com. - -You may also find David on GitHub as [dbry](https://github.com/dbry). diff --git a/Frameworks/WavPack/Files/common_utils.c b/Frameworks/WavPack/Files/common_utils.c deleted file mode 100644 index e7084a305..000000000 --- a/Frameworks/WavPack/Files/common_utils.c +++ /dev/null @@ -1,788 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// common_utils.c - -// This module provides a lot of the trivial WavPack API functions and several -// functions that are common to both reading and writing WavPack files (like -// WavpackCloseFile()). Functions here are restricted to those that have few -// external dependencies and this is done so that applications that statically -// link to the WavPack library (like the command-line utilities on Windows) -// do not need to include the entire library image if they only use a subset -// of it. This module will be loaded for ANY WavPack application. - -#include -#include -#include - -#include "wavpack_local.h" - -#ifndef LIBWAVPACK_VERSION_STRING -#include "wavpack_version.h" -#endif - -///////////////////////////// local table storage //////////////////////////// - -const uint32_t sample_rates [] = { 6000, 8000, 9600, 11025, 12000, 16000, 22050, - 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000 }; - -///////////////////////////// executable code //////////////////////////////// - -// This function obtains general information about an open input file and -// returns a mask with the following bit values: - -// MODE_WVC: a .wvc file has been found and will be used for lossless -// MODE_LOSSLESS: file is lossless (either pure or hybrid) -// MODE_HYBRID: file is hybrid mode (either lossy or lossless) -// MODE_FLOAT: audio data is 32-bit ieee floating point -// MODE_VALID_TAG: file contains a valid ID3v1 or APEv2 tag -// MODE_HIGH: file was created in "high" mode (information only) -// MODE_FAST: file was created in "fast" mode (information only) -// MODE_EXTRA: file was created using "extra" mode (information only) -// MODE_APETAG: file contains a valid APEv2 tag -// MODE_SFX: file was created as a "self-extracting" executable -// MODE_VERY_HIGH: file was created in the "very high" mode (or in -// the "high" mode prior to 4.4) -// MODE_MD5: file contains an MD5 checksum -// MODE_XMODE: level used for extra mode (1-6, 0=unknown) -// MODE_DNS: dynamic noise shaping - -int WavpackGetMode (WavpackContext *wpc) -{ - int mode = 0; - - if (wpc) { - if (wpc->config.flags & CONFIG_HYBRID_FLAG) - mode |= MODE_HYBRID; - else if (!(wpc->config.flags & CONFIG_LOSSY_MODE)) - mode |= MODE_LOSSLESS; - - if (wpc->wvc_flag) - mode |= (MODE_LOSSLESS | MODE_WVC); - - if (wpc->lossy_blocks) - mode &= ~MODE_LOSSLESS; - - if (wpc->config.flags & CONFIG_FLOAT_DATA) - mode |= MODE_FLOAT; - - if (wpc->config.flags & (CONFIG_HIGH_FLAG | CONFIG_VERY_HIGH_FLAG)) { - mode |= MODE_HIGH; - - if ((wpc->config.flags & CONFIG_VERY_HIGH_FLAG) || - (wpc->streams && wpc->streams [0] && wpc->streams [0]->wphdr.version < 0x405)) - mode |= MODE_VERY_HIGH; - } - - if (wpc->config.flags & CONFIG_FAST_FLAG) - mode |= MODE_FAST; - - if (wpc->config.flags & CONFIG_EXTRA_MODE) - mode |= (MODE_EXTRA | (wpc->config.xmode << 12)); - - if (wpc->config.flags & CONFIG_CREATE_EXE) - mode |= MODE_SFX; - - if (wpc->config.flags & CONFIG_MD5_CHECKSUM) - mode |= MODE_MD5; - - if ((wpc->config.flags & CONFIG_HYBRID_FLAG) && (wpc->config.flags & CONFIG_DYNAMIC_SHAPING) && - wpc->streams && wpc->streams [0] && wpc->streams [0]->wphdr.version >= 0x407) - mode |= MODE_DNS; - -#ifndef NO_TAGS - if (valid_tag (&wpc->m_tag)) { - mode |= MODE_VALID_TAG; - - if (valid_tag (&wpc->m_tag) == 'A') - mode |= MODE_APETAG; - } -#endif - - mode |= (wpc->config.qmode << 16) & 0xFF0000; - } - - return mode; -} - -// This function obtains information about specific file features that were -// added for version 5.0, specifically qualifications added to support CAF -// and DSD files. Except for indicating the presence of DSD data, these -// bits are meant to simply indicate the format of the data in the original -// source file and do NOT indicate how the library will return the data to -// the appication (which is always the same). This means that in general an -// application that simply wants to play or process the audio data need not -// be concerned about these. If the file is DSD audio, then either of the -// QMDOE_DSD_LSB_FIRST or QMODE_DSD_MSB_FIRST bits will be set (but the -// DSD audio is always returned to the caller MSB first). - -// QMODE_BIG_ENDIAN 0x1 // big-endian data format (opposite of WAV format) -// QMODE_SIGNED_BYTES 0x2 // 8-bit audio data is signed (opposite of WAV format) -// QMODE_UNSIGNED_WORDS 0x4 // audio data (other than 8-bit) is unsigned (opposite of WAV format) -// QMODE_REORDERED_CHANS 0x8 // source channels were not Microsoft order, so they were reordered -// QMODE_DSD_LSB_FIRST 0x10 // DSD bytes, LSB first (most Sony .dsf files) -// QMODE_DSD_MSB_FIRST 0x20 // DSD bytes, MSB first (Philips .dff files) -// QMODE_DSD_IN_BLOCKS 0x40 // DSD data is blocked by channels (Sony .dsf only) - -int WavpackGetQualifyMode (WavpackContext *wpc) -{ - return wpc->config.qmode & 0xFF; -} - -// This function returns a pointer to a string describing the last error -// generated by WavPack. - -char *WavpackGetErrorMessage (WavpackContext *wpc) -{ - return wpc->error_message; -} - -// Get total number of samples contained in the WavPack file, or -1 if unknown - -uint32_t WavpackGetNumSamples (WavpackContext *wpc) -{ - return (uint32_t) WavpackGetNumSamples64 (wpc); -} - -int64_t WavpackGetNumSamples64 (WavpackContext *wpc) -{ - return wpc ? wpc->total_samples : -1; -} - -// Get the current sample index position, or -1 if unknown - -uint32_t WavpackGetSampleIndex (WavpackContext *wpc) -{ - return (uint32_t) WavpackGetSampleIndex64 (wpc); -} - -int64_t WavpackGetSampleIndex64 (WavpackContext *wpc) -{ - if (wpc) { -#ifdef ENABLE_LEGACY - if (wpc->stream3) - return get_sample_index3 (wpc); - else if (wpc->streams && wpc->streams [0]) - return wpc->streams [0]->sample_index; -#else - if (wpc->streams && wpc->streams [0]) - return wpc->streams [0]->sample_index; -#endif - } - - return -1; -} - -// Get the number of errors encountered so far - -int WavpackGetNumErrors (WavpackContext *wpc) -{ - return wpc ? wpc->crc_errors : 0; -} - -// return TRUE if any uncorrected lossy blocks were actually written or read - -int WavpackLossyBlocks (WavpackContext *wpc) -{ - return wpc ? wpc->lossy_blocks : 0; -} - -// Calculate the progress through the file as a double from 0.0 (for begin) -// to 1.0 (for done). A return value of -1.0 indicates that the progress is -// unknown. - -double WavpackGetProgress (WavpackContext *wpc) -{ - if (wpc && wpc->total_samples != -1 && wpc->total_samples != 0) - return (double) WavpackGetSampleIndex64 (wpc) / wpc->total_samples; - else - return -1.0; -} - -// Return the total size of the WavPack file(s) in bytes. - -uint32_t WavpackGetFileSize (WavpackContext *wpc) -{ - return (uint32_t) (wpc ? wpc->filelen + wpc->file2len : 0); -} - -int64_t WavpackGetFileSize64 (WavpackContext *wpc) -{ - return wpc ? wpc->filelen + wpc->file2len : 0; -} - -// Calculate the ratio of the specified WavPack file size to the size of the -// original audio data as a double greater than 0.0 and (usually) smaller than -// 1.0. A value greater than 1.0 represents "negative" compression and a -// return value of 0.0 indicates that the ratio cannot be determined. - -double WavpackGetRatio (WavpackContext *wpc) -{ - if (wpc && wpc->total_samples != -1 && wpc->filelen) { - double output_size = (double) wpc->total_samples * wpc->config.num_channels * - wpc->config.bytes_per_sample; - double input_size = (double) wpc->filelen + wpc->file2len; - - if (output_size >= 1.0 && input_size >= 1.0) - return input_size / output_size; - } - - return 0.0; -} - -// Calculate the average bitrate of the WavPack file in bits per second. A -// return of 0.0 indicates that the bitrate cannot be determined. An option is -// provided to use (or not use) any attendant .wvc file. - -double WavpackGetAverageBitrate (WavpackContext *wpc, int count_wvc) -{ - if (wpc && wpc->total_samples != -1 && wpc->filelen) { - double output_time = (double) wpc->total_samples / WavpackGetSampleRate (wpc); - double input_size = (double) wpc->filelen + (count_wvc ? wpc->file2len : 0); - - if (output_time >= 0.1 && input_size >= 1.0) - return input_size * 8.0 / output_time; - } - - return 0.0; -} - -// Calculate the bitrate of the current WavPack file block in bits per second. -// This can be used for an "instant" bit display and gets updated from about -// 1 to 4 times per second. A return of 0.0 indicates that the bitrate cannot -// be determined. - -double WavpackGetInstantBitrate (WavpackContext *wpc) -{ - if (wpc && wpc->stream3) - return WavpackGetAverageBitrate (wpc, TRUE); - - if (wpc && wpc->streams && wpc->streams [0] && wpc->streams [0]->wphdr.block_samples) { - double output_time = (double) wpc->streams [0]->wphdr.block_samples / WavpackGetSampleRate (wpc); - double input_size = 0; - int si; - - for (si = 0; si < wpc->num_streams; ++si) { - if (wpc->streams [si]->blockbuff) - input_size += ((WavpackHeader *) wpc->streams [si]->blockbuff)->ckSize; - - if (wpc->streams [si]->block2buff) - input_size += ((WavpackHeader *) wpc->streams [si]->block2buff)->ckSize; - } - - if (output_time > 0.0 && input_size >= 1.0) - return input_size * 8.0 / output_time; - } - - return 0.0; -} - -// This function allows retrieving the Core Audio File channel layout, many of which do not -// conform to the Microsoft ordering standard that WavPack requires internally (at least for -// those channels present in the "channel mask"). In addition to the layout tag, this function -// returns the reordering string (if stored in the file) to allow the unpacker to reorder the -// channels back to the specified layout (if it wants to restore the CAF order). The number of -// channels in the layout is determined from the lower nybble of the layout word (and should -// probably match the number of channels in the file), and if a reorder string is requested -// then that much space must be allocated. Note that all the reordering is actually done -// outside of this library, and that if reordering is done then the appropriate qmode bit -// will be set. -// -// Note: Normally this function would not be used by an application unless it specifically -// wanted to restore a non-standard channel order (to check an MD5, for example) or obtain -// the Core Audio channel layout ID. For simple file decoding for playback, the channel_mask -// should provide all the information required unless there are non-Microsoft channels -// involved, in which case WavpackGetChannelIdentities() will provide the identities of -// the other channels (if they are known). - -uint32_t WavpackGetChannelLayout (WavpackContext *wpc, unsigned char *reorder) -{ - if ((wpc->channel_layout & 0xff) && wpc->channel_reordering && reorder) - memcpy (reorder, wpc->channel_reordering, wpc->channel_layout & 0xff); - - return wpc->channel_layout; -} - -// This function provides the identities of ALL the channels in the file, including the -// standard Microsoft channels (which come first, in order, and are numbered 1-18) and also -// any non-Microsoft channels (which can be in any order and have values from 33-254). The -// value 0x00 is invalid and 0xFF indicates an "unknown" or "unnassigned" channel. The -// string is NULL terminated so the caller must supply enough space for the number -// of channels indicated by WavpackGetNumChannels(), plus one. -// -// Note that this function returns the actual order of the channels in the Wavpack file -// (i.e., the order returned by WavpackUnpackSamples()). If the file includes a "reordering" -// string because the source file was not in Microsoft order that is NOT taken into account -// here and really only needs to be considered if doing an MD5 verification or if it's -// required to restore the original order/file (like wvunpack does). - -void WavpackGetChannelIdentities (WavpackContext *wpc, unsigned char *identities) -{ - int num_channels = wpc->config.num_channels, index = 1; - uint32_t channel_mask = wpc->config.channel_mask; - unsigned char *src = wpc->channel_identities; - - while (num_channels--) { - if (channel_mask) { - while (!(channel_mask & 1)) { - channel_mask >>= 1; - index++; - } - - *identities++ = index++; - channel_mask >>= 1; - } - else if (src && *src) - *identities++ = *src++; - else - *identities++ = 0xff; - } - - *identities = 0; -} - -// For local use only. Install a callback to be executed when WavpackCloseFile() is called, -// usually used to dump some statistics accumulated during encode or decode. - -void install_close_callback (WavpackContext *wpc, void cb_func (void *wpc)) -{ - wpc->close_callback = cb_func; -} - -// Close the specified WavPack file and release all resources used by it. -// Returns NULL. - -WavpackContext *WavpackCloseFile (WavpackContext *wpc) -{ - if (wpc->close_callback) - wpc->close_callback (wpc); - - if (wpc->streams) { - free_streams (wpc); - - if (wpc->streams [0]) - free (wpc->streams [0]); - - free (wpc->streams); - } - -#ifdef ENABLE_LEGACY - if (wpc->stream3) - free_stream3 (wpc); -#endif - - if (wpc->reader && wpc->reader->close && wpc->wv_in) - wpc->reader->close (wpc->wv_in); - - if (wpc->reader && wpc->reader->close && wpc->wvc_in) - wpc->reader->close (wpc->wvc_in); - - WavpackFreeWrapper (wpc); - - if (wpc->metadata) { - int i; - - for (i = 0; i < wpc->metacount; ++i) - if (wpc->metadata [i].data) - free (wpc->metadata [i].data); - - free (wpc->metadata); - } - - if (wpc->channel_identities) - free (wpc->channel_identities); - - if (wpc->channel_reordering) - free (wpc->channel_reordering); - -#ifndef NO_TAGS - free_tag (&wpc->m_tag); -#endif - -#ifdef ENABLE_DSD - if (wpc->decimation_context) - decimate_dsd_destroy (wpc->decimation_context); -#endif - - free (wpc); - - return NULL; -} - -// These routines are used to access (and free) header and trailer data that -// was retrieved from the Wavpack file. The header will be available before -// the samples are decoded and the trailer will be available after all samples -// have been read. - -uint32_t WavpackGetWrapperBytes (WavpackContext *wpc) -{ - return wpc ? wpc->wrapper_bytes : 0; -} - -unsigned char *WavpackGetWrapperData (WavpackContext *wpc) -{ - return wpc ? wpc->wrapper_data : NULL; -} - -void WavpackFreeWrapper (WavpackContext *wpc) -{ - if (wpc && wpc->wrapper_data) { - free (wpc->wrapper_data); - wpc->wrapper_data = NULL; - wpc->wrapper_bytes = 0; - } -} - -// Returns the sample rate of the specified WavPack file - -uint32_t WavpackGetSampleRate (WavpackContext *wpc) -{ - return wpc ? (wpc->dsd_multiplier ? wpc->config.sample_rate * wpc->dsd_multiplier : wpc->config.sample_rate) : 44100; -} - -// Returns the native sample rate of the specified WavPack file -// (provides the native rate for DSD files rather than the "byte" rate that's used for -// seeking, duration, etc. and would generally be used just for user facing reports) - -uint32_t WavpackGetNativeSampleRate (WavpackContext *wpc) -{ - return wpc ? (wpc->dsd_multiplier ? wpc->config.sample_rate * wpc->dsd_multiplier * 8 : wpc->config.sample_rate) : 44100; -} - -// Returns the number of channels of the specified WavPack file. Note that -// this is the actual number of channels contained in the file even if the -// OPEN_2CH_MAX flag was specified when the file was opened. - -int WavpackGetNumChannels (WavpackContext *wpc) -{ - return wpc ? wpc->config.num_channels : 2; -} - -// Returns the standard Microsoft channel mask for the specified WavPack -// file. A value of zero indicates that there is no speaker assignment -// information. - -int WavpackGetChannelMask (WavpackContext *wpc) -{ - return wpc ? wpc->config.channel_mask : 0; -} - -// Return the normalization value for floating point data (valid only -// if floating point data is present). A value of 127 indicates that -// the floating point range is +/- 1.0. Higher values indicate a -// larger floating point range. - -int WavpackGetFloatNormExp (WavpackContext *wpc) -{ - return wpc->config.float_norm_exp; -} - -// Returns the actual number of valid bits per sample contained in the -// original file, which may or may not be a multiple of 8. Floating data -// always has 32 bits, integers may be from 1 to 32 bits each. When this -// value is not a multiple of 8, then the "extra" bits are located in the -// LSBs of the results. That is, values are right justified when unpacked -// into ints, but are left justified in the number of bytes used by the -// original data. - -int WavpackGetBitsPerSample (WavpackContext *wpc) -{ - return wpc ? wpc->config.bits_per_sample : 16; -} - -// Returns the number of bytes used for each sample (1 to 4) in the original -// file. This is required information for the user of this module because the -// audio data is returned in the LOWER bytes of the long buffer and must be -// left-shifted 8, 16, or 24 bits if normalized longs are required. - -int WavpackGetBytesPerSample (WavpackContext *wpc) -{ - return wpc ? wpc->config.bytes_per_sample : 2; -} - -// If the OPEN_2CH_MAX flag is specified when opening the file, this function -// will return the actual number of channels decoded from the file (which may -// or may not be less than the actual number of channels, but will always be -// 1 or 2). Normally, this will be the front left and right channels of a -// multichannel file. - -int WavpackGetReducedChannels (WavpackContext *wpc) -{ - if (wpc) - return wpc->reduced_channels ? wpc->reduced_channels : wpc->config.num_channels; - else - return 2; -} - -// Free all memory allocated for raw WavPack blocks (for all allocated streams) -// and free all additional streams. This does not free the default stream ([0]) -// which is always kept around. - -void free_streams (WavpackContext *wpc) -{ - int si = wpc->num_streams; - - while (si--) { - if (wpc->streams [si]->blockbuff) { - free (wpc->streams [si]->blockbuff); - wpc->streams [si]->blockbuff = NULL; - } - - if (wpc->streams [si]->block2buff) { - free (wpc->streams [si]->block2buff); - wpc->streams [si]->block2buff = NULL; - } - - if (wpc->streams [si]->sample_buffer) { - free (wpc->streams [si]->sample_buffer); - wpc->streams [si]->sample_buffer = NULL; - } - - if (wpc->streams [si]->dc.shaping_data) { - free (wpc->streams [si]->dc.shaping_data); - wpc->streams [si]->dc.shaping_data = NULL; - } - -#ifdef ENABLE_DSD - free_dsd_tables (wpc->streams [si]); -#endif - - if (si) { - wpc->num_streams--; - free (wpc->streams [si]); - wpc->streams [si] = NULL; - } - } - - wpc->current_stream = 0; -} - -void free_dsd_tables (WavpackStream *wps) -{ - if (wps->dsd.probabilities) { - free (wps->dsd.probabilities); - wps->dsd.probabilities = NULL; - } - - if (wps->dsd.summed_probabilities) { - free (wps->dsd.summed_probabilities); - wps->dsd.summed_probabilities = NULL; - } - - if (wps->dsd.lookup_buffer) { - free (wps->dsd.lookup_buffer); - wps->dsd.lookup_buffer = NULL; - } - - if (wps->dsd.value_lookup) { - free (wps->dsd.value_lookup); - wps->dsd.value_lookup = NULL; - } - - if (wps->dsd.ptable) { - free (wps->dsd.ptable); - wps->dsd.ptable = NULL; - } -} - -void WavpackFloatNormalize (int32_t *values, int32_t num_values, int delta_exp) -{ - f32 *fvalues = (f32 *) values; - int exp; - - if (!delta_exp) - return; - - while (num_values--) { - if ((exp = get_exponent (*fvalues)) == 0 || exp + delta_exp <= 0) - *fvalues = 0; - else if (exp == 255 || (exp += delta_exp) >= 255) { - set_exponent (*fvalues, 255); - set_mantissa (*fvalues, 0); - } - else - set_exponent (*fvalues, exp); - - fvalues++; - } -} - -void WavpackLittleEndianToNative (void *data, char *format) -{ - unsigned char *cp = (unsigned char *) data; - int64_t temp; - - while (*format) { - switch (*format) { - case 'D': - temp = cp [0] + ((int64_t) cp [1] << 8) + ((int64_t) cp [2] << 16) + ((int64_t) cp [3] << 24) + - ((int64_t) cp [4] << 32) + ((int64_t) cp [5] << 40) + ((int64_t) cp [6] << 48) + ((int64_t) cp [7] << 56); - * (int64_t *) cp = temp; - cp += 8; - break; - - case 'L': - temp = cp [0] + ((int32_t) cp [1] << 8) + ((int32_t) cp [2] << 16) + ((int32_t) cp [3] << 24); - * (int32_t *) cp = (int32_t) temp; - cp += 4; - break; - - case 'S': - temp = cp [0] + (cp [1] << 8); - * (int16_t *) cp = (int16_t) temp; - cp += 2; - break; - - default: - if (isdigit (*format)) - cp += *format - '0'; - - break; - } - - format++; - } -} - -void WavpackNativeToLittleEndian (void *data, char *format) -{ - unsigned char *cp = (unsigned char *) data; - int64_t temp; - - while (*format) { - switch (*format) { - case 'D': - temp = * (int64_t *) cp; - *cp++ = (unsigned char) temp; - *cp++ = (unsigned char) (temp >> 8); - *cp++ = (unsigned char) (temp >> 16); - *cp++ = (unsigned char) (temp >> 24); - *cp++ = (unsigned char) (temp >> 32); - *cp++ = (unsigned char) (temp >> 40); - *cp++ = (unsigned char) (temp >> 48); - *cp++ = (unsigned char) (temp >> 56); - break; - - case 'L': - temp = * (int32_t *) cp; - *cp++ = (unsigned char) temp; - *cp++ = (unsigned char) (temp >> 8); - *cp++ = (unsigned char) (temp >> 16); - *cp++ = (unsigned char) (temp >> 24); - break; - - case 'S': - temp = * (int16_t *) cp; - *cp++ = (unsigned char) temp; - *cp++ = (unsigned char) (temp >> 8); - break; - - default: - if (isdigit (*format)) - cp += *format - '0'; - - break; - } - - format++; - } -} - -void WavpackBigEndianToNative (void *data, char *format) -{ - unsigned char *cp = (unsigned char *) data; - int64_t temp; - - while (*format) { - switch (*format) { - case 'D': - temp = cp [7] + ((int64_t) cp [6] << 8) + ((int64_t) cp [5] << 16) + ((int64_t) cp [4] << 24) + - ((int64_t) cp [3] << 32) + ((int64_t) cp [2] << 40) + ((int64_t) cp [1] << 48) + ((int64_t) cp [0] << 56); - * (int64_t *) cp = temp; - cp += 8; - break; - - case 'L': - temp = cp [3] + ((int32_t) cp [2] << 8) + ((int32_t) cp [1] << 16) + ((int32_t) cp [0] << 24); - * (int32_t *) cp = (int32_t) temp; - cp += 4; - break; - - case 'S': - temp = cp [1] + (cp [0] << 8); - * (int16_t *) cp = (int16_t) temp; - cp += 2; - break; - - default: - if (isdigit (*format)) - cp += *format - '0'; - - break; - } - - format++; - } -} - -void WavpackNativeToBigEndian (void *data, char *format) -{ - unsigned char *cp = (unsigned char *) data; - int64_t temp; - - while (*format) { - switch (*format) { - case 'D': - temp = * (int64_t *) cp; - *cp++ = (unsigned char) (temp >> 56); - *cp++ = (unsigned char) (temp >> 48); - *cp++ = (unsigned char) (temp >> 40); - *cp++ = (unsigned char) (temp >> 32); - *cp++ = (unsigned char) (temp >> 24); - *cp++ = (unsigned char) (temp >> 16); - *cp++ = (unsigned char) (temp >> 8); - *cp++ = (unsigned char) temp; - break; - - case 'L': - temp = * (int32_t *) cp; - *cp++ = (unsigned char) (temp >> 24); - *cp++ = (unsigned char) (temp >> 16); - *cp++ = (unsigned char) (temp >> 8); - *cp++ = (unsigned char) temp; - break; - - case 'S': - temp = * (int16_t *) cp; - *cp++ = (unsigned char) (temp >> 8); - *cp++ = (unsigned char) temp; - break; - - default: - if (isdigit (*format)) - cp += *format - '0'; - - break; - } - - format++; - } -} - -uint32_t WavpackGetLibraryVersion (void) -{ - return (LIBWAVPACK_MAJOR<<16) - |(LIBWAVPACK_MINOR<<8) - |(LIBWAVPACK_MICRO<<0); -} - -const char *WavpackGetLibraryVersionString (void) -{ - return LIBWAVPACK_VERSION_STRING; -} - diff --git a/Frameworks/WavPack/Files/decorr_tables.h b/Frameworks/WavPack/Files/decorr_tables.h deleted file mode 100644 index b47c30142..000000000 --- a/Frameworks/WavPack/Files/decorr_tables.h +++ /dev/null @@ -1,1077 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// decorr_tables.h - -// These four tables specify the characteristics of the decorrelation filters -// for the four basic compression modes (fast, normal, high, and very high). -// -// The first entry in the table represents the "default" filter for the -// corresponding mode; subsequent entries represent filters that are tried -// in the "extra" modes 1-3 ("extra" modes 4-6 create filters from scratch). -// -// The first value indicates whether the filter is applied to joint stereo -// data (0=L/R, 1=M/S) and the second value represents the "delta" value of -// the adaptive filter. The rest of the values (2-16, depending on mode) are -// the "terms" of the filter. -// -// Each term represents one layer of the sequential filter, where positive -// values indicate the relative sample involved from the same channel (1=prev), -// 17 & 18 are special functions using the previous 2 samples, and negative -// values indicate cross channel decorrelation (in stereo only). -// -// It would be ideal if this was the only source for the decorrelation tables, -// but unfortunately the defaults (first entry) are duplicated in the assembly -// code for the function pack_decorr_mono_buffer() and there is no check in -// that code to make sure the correct filter is being passed in. SO, IF A -// CHANGE IS MADE HERE TO ONE OF THE DEFAULT FILTERS, THEN THE CORRESPONDING -// ASSEMBLY CODE MUST BE CHANGED ALSO, OR VERY CORRUPT FILES WILL RESULT!! -// -// Since this include file contains that actual tables as static const data, -// it should only be included from ONE source file (currently pack.c)! - -static const WavpackDecorrSpec fast_specs [] = { - { 1, 2, {18,17} }, // 0 - { 1, 1, {17,17} }, // 1 - { 0, 2, {18,17} }, // 2 - { 0, 1, {17,17} }, // 3 - { 1, 3, { 1,18} }, // 4 - { 1, 1, {17, 1} }, // 5 - { 0, 1, { 1,17} }, // 6 - { 0, 1, {-2,17} }, // 7 - { 0, 2, {-1,17} }, // 8 - { 1, 1, {17, 2} }, // 9 - { 0, 3, {18,18} }, // 10 - { 0, 1, {17, 1} }, // 11 - { 1, 6, { 1, 2} }, // 12 - { 1, 1, {17, 3} }, // 13 - { 0, 1, {-2, 3} }, // 14 - { 0, 1, { 2,17} }, // 15 - { 0, 1, {18,-2} }, // 16 - { 0, 1, {-1,17} }, // 17 - { 0, 1, {18,17} }, // 18 - { 0, 1, {17, 2} }, // 19 - { 1, 2, {18,-2} }, // 20 - { 1, 1, { 1,17} }, // 21 - { 0, 3, {18, 2} }, // 22 - { 0, 1, {17,-2} }, // 23 - { 0, 1, {18,-2} }, // 24 - { 1, 2, {17,-3} }, // 25 - { 0, 1, {18, 3} }, // 26 - { 0, 1, {18,18} }, // 27 - { 1, 1, { 1, 3} }, // 28 - { 1, 1, {18, 3} }, // 29 - { 1, 1, { 1, 3} }, // 30 - { 0, 2, {18,17} }, // 31 - { 1, 1, { 1,17} }, // 32 - { 1, 1, {17, 3} }, // 33 - { 0, 3, {18,17} }, // 34 - { 0, 1, {18,18} }, // 35 - { 1, 1, { 1, 3} }, // 36 - { 1, 1, { 1,18} }, // 37 - { 0, 1, {18,-2} }, // 38 - { 0, 2, {18,17} }, // 39 - { 0, 1, {-1,18} }, // 40 - { 1, 1, {17, 3} }, // 41 - { 0, 1, {17, 2} }, // 42 - { 0, 1, {17, 3} }, // 43 - { 1, 1, {18, 2} }, // 44 - { 1, 1, {17,-2} }, // 45 - { 0, 1, { 1,-2} }, // 46 - { 0, 2, {18,17} }, // 47 - { 0, 1, {17,-2} }, // 48 - { 1, 1, {17,-2} }, // 49 - { 0, 1, {18, 3} }, // 50 - { 0, 1, { 2,17} }, // 51 - { 1, 2, {18,-3} }, // 52 - { 1, 2, { 1,18} }, // 53 - { 1, 2, {18, 2} }, // 54 - { 0, 1, {17,-1} }, // 55 - { 0, 1, {17,-2} }, // 56 - { 1, 1, {17,-2} }, // 57 - { 1, 1, { 1, 3} }, // 58 - { 0, 1, { 1,17} }, // 59 - { 1, 2, {18,-2} }, // 60 - { 1, 2, {17,-3} }, // 61 - { 0, 2, {18,17} }, // 62 - { 0, 2, {18,17} }, // 63 - { 1, 1, {17, 2} }, // 64 - { 1, 2, {18,18} }, // 65 - { 0, 1, {17, 2} }, // 66 - { 0, 1, {18,17} }, // 67 - { 1, 1, { 1,17} }, // 68 - { 1, 1, {17, 2} }, // 69 - { 0, 2, {18,18} }, // 70 - { 0, 2, {18,17} }, // 71 - { 1, 2, {17,-3} }, // 72 - { 1, 6, { 1, 2} }, // 73 - { 0, 3, {17,17} }, // 74 - { 0, 1, { 1,18} }, // 75 - { 0, 1, { 1,-2} }, // 76 - { 1, 1, {17, 2} }, // 77 - { 0, 2, {18,17} }, // 78 - { 0, 2, {18,17} }, // 79 - { 1, 1, {18, 3} }, // 80 - { 1, 2, {17,-3} }, // 81 - { 0, 1, {17, 2} }, // 82 - { 0, 1, {17, 3} }, // 83 - { 0, 1, {18,-2} }, // 84 - { 1, 1, {18,18} }, // 85 - { 1, 6, { 1, 2} }, // 86 - { 0, 2, {18,17} }, // 87 - { 0, 2, {18,17} }, // 88 - { 0, 1, {-1,17} }, // 89 - { 1, 1, {18, 3} }, // 90 - { 0, 1, {17,18} }, // 91 - { 1, 1, {17, 3} }, // 92 - { 0, 1, {18, 3} }, // 93 - { 0, 2, {18,17} }, // 94 - { 0, 2, {18,17} }, // 95 - { 1, 2, {18, 2} }, // 96 - { 0, 1, {-2, 3} }, // 97 - { 0, 4, {18,-1} }, // 98 - { 0, 2, {18,18} }, // 99 - { 0, 1, {-2, 3} }, // 100 - { 1, 1, {17,-2} }, // 101 - { 0, 1, {17, 3} }, // 102 - { 0, 2, {18,17} }, // 103 - { 0, 2, {-1,18} }, // 104 - { 1, 1, { 2,17} }, // 105 - { 0, 2, {17,-2} }, // 106 - { 0, 1, {17, 2} }, // 107 - { 1, 2, {18,-3} }, // 108 - { 0, 1, {17,-2} }, // 109 - { 0, 2, {18,17} }, // 110 - { 0, 2, {18,17} }, // 111 - { 1, 1, {17,-2} }, // 112 - { 1, 2, {17,-3} }, // 113 - { 1, 1, { 1, 3} }, // 114 - { 1, 1, { 2,17} }, // 115 - { 1, 2, {18, 2} }, // 116 - { 1, 1, { 2,17} }, // 117 - { 1, 1, {18, 2} }, // 118 - { 0, 2, {18,17} }, // 119 - { 0, 2, {18,17} }, // 120 - { 0, 1, {17,-2} }, // 121 - { 0, 2, {18,17} }, // 122 - { 0, 2, {17,-1} }, // 123 - { 0, 2, {18,-2} }, // 124 - { 0, 2, {18,17} }, // 125 - { 0, 2, {18,17} }, // 126 - { 0, 2, {18,17} }, // 127 - { 1, 1, { 1, 3} }, // 128 - { 0, 2, {-2,17} }, // 129 - { 0, 2, {18,-2} }, // 130 - { 0, 2, {17,-2} }, // 131 - { 1, 1, { 2,17} }, // 132 - { 1, 1, { 1, 3} }, // 133 - { 0, 1, { 2,17} }, // 134 - { 0, 2, {18,17} }, // 135 - { 0, 3, {-1,17} }, // 136 - { 1, 1, { 2,17} }, // 137 - { 0, 2, {18,18} }, // 138 - { 0, 1, {17, 2} }, // 139 - { 1, 4, {18,-3} }, // 140 - { 1, 1, {18, 1} }, // 141 - { 0, 2, {18,17} }, // 142 - { 0, 2, {18,17} }, // 143 - { 1, 2, {18,-1} }, // 144 - { 0, 1, {-1,18} }, // 145 - { 1, 6, { 1, 2} }, // 146 - { 1, 1, {17, 2} }, // 147 - { 1, 4, {18, 3} }, // 148 - { 0, 1, { 1,17} }, // 149 - { 0, 1, {18, 2} }, // 150 - { 0, 2, {18,17} }, // 151 - { 0, 2, {18,17} }, // 152 - { 1, 2, {17, 2} }, // 153 - { 0, 2, {18,-2} }, // 154 - { 0, 1, { 1,18} }, // 155 - { 1, 2, {18,-3} }, // 156 - { 0, 2, {18,17} }, // 157 - { 0, 2, {18,17} }, // 158 - { 0, 2, {18,17} }, // 159 - { 1, 2, {18,18} }, // 160 - { 1, 3, {17,17} }, // 161 - { 0, 1, {-2,17} }, // 162 - { 0, 1, {17,18} }, // 163 - { 0, 1, {-1, 3} }, // 164 - { 1, 1, { 2,17} }, // 165 - { 0, 2, {18,-1} }, // 166 - { 0, 2, {18,17} }, // 167 - { 0, 2, {18,17} }, // 168 - { 1, 1, {17,-2} }, // 169 - { 1, 2, {17, 2} }, // 170 - { 1, 1, {18, 3} }, // 171 - { 0, 1, {18, 2} }, // 172 - { 1, 2, {17,-3} }, // 173 - { 0, 2, {18,17} }, // 174 - { 0, 2, {18,17} }, // 175 - { 0, 1, {-2,17} }, // 176 - { 0, 1, {17,-1} }, // 177 - { 0, 1, {18,-1} }, // 178 - { 0, 2, {18,17} }, // 179 - { 1, 2, {17,-3} }, // 180 - { 1, 1, { 1,18} }, // 181 - { 1, 3, {18, 2} }, // 182 - { 0, 2, {18,17} }, // 183 - { 0, 2, {18,17} }, // 184 - { 0, 2, {18,17} }, // 185 - { 0, 2, {18,17} }, // 186 - { 0, 3, {18,18} }, // 187 - { 0, 1, { 1,-2} }, // 188 - { 0, 2, {18,17} }, // 189 - { 0, 2, {18,17} }, // 190 - { 0, 2, {18,17} }, // 191 - { 1, 2, {17,-3} }, // 192 - { 1, 1, {18,18} }, // 193 - { 0, 2, {18, 2} }, // 194 - { 0, 1, {17,18} }, // 195 - { 1, 2, {18, 2} }, // 196 - { 1, 1, {17,-2} }, // 197 - { 0, 2, {17,-1} }, // 198 - { 0, 2, {18,17} }, // 199 - { 0, 2, {18,17} }, // 200 - { 0, 2, {18,17} }, // 201 - { 0, 1, { 1,-2} }, // 202 - { 0, 1, {18, 1} }, // 203 - { 1, 2, {18,-2} }, // 204 - { 0, 1, {17, 2} }, // 205 - { 0, 2, {18,17} }, // 206 - { 0, 2, {18,17} }, // 207 - { 1, 1, {17, 3} }, // 208 - { 0, 1, {17,-1} }, // 209 - { 0, 1, {18, 2} }, // 210 - { 1, 1, {17, 3} }, // 211 - { 1, 1, {17,-2} }, // 212 - { 0, 1, {18,18} }, // 213 - { 0, 2, {18,17} }, // 214 - { 0, 2, {18,17} }, // 215 - { 0, 2, {18,17} }, // 216 - { 0, 2, {18,17} }, // 217 - { 0, 2, {18,17} }, // 218 - { 1, 1, {17,18} }, // 219 - { 0, 1, {-2, 3} }, // 220 - { 0, 2, {18,17} }, // 221 - { 0, 2, {18,17} }, // 222 - { 0, 2, {18,17} }, // 223 - { 1, 2, {18,-3} }, // 224 - { 0, 2, {18,17} }, // 225 - { 0, 3, {18, 2} }, // 226 - { 0, 1, { 1,18} }, // 227 - { 0, 2, {18,17} }, // 228 - { 0, 1, {17,-1} }, // 229 - { 0, 2, {18,17} }, // 230 - { 0, 2, {18,17} }, // 231 - { 0, 2, {18,17} }, // 232 - { 0, 1, {-2, 3} }, // 233 - { 0, 3, {17,17} }, // 234 - { 0, 2, {18,17} }, // 235 - { 0, 2, {18,17} }, // 236 - { 1, 1, {17, 2} }, // 237 - { 0, 2, {18,17} }, // 238 - { 0, 2, {18,17} }, // 239 - { 1, 1, {17, 2} }, // 240 - { 0, 2, {18,17} }, // 241 - { 0, 2, {18,17} }, // 242 - { 0, 2, {18,17} }, // 243 - { 0, 2, {18, 2} }, // 244 - { 0, 2, {18,17} }, // 245 - { 0, 2, {18,17} }, // 246 - { 0, 2, {18,17} }, // 247 - { 0, 2, {18,17} }, // 248 - { 0, 2, {18,17} }, // 249 - { 0, 2, {18,17} }, // 250 - { 0, 2, {18,17} }, // 251 - { 0, 2, {18,17} }, // 252 - { 0, 2, {18,17} }, // 253 - { 0, 2, {18,17} }, // 254 - { 0, 2, {18,17} }, // 255 -}; - -static const WavpackDecorrSpec default_specs [] = { - { 1, 2, {18,18, 2,17, 3} }, // 0 - { 0, 2, {18,17,-1, 3, 2} }, // 1 - { 1, 1, {17,18,18,-2, 2} }, // 2 - { 0, 2, {18,17, 3,-2,17} }, // 3 - { 1, 2, {18,17, 2,17, 3} }, // 4 - { 0, 1, {18,18,-1, 2,17} }, // 5 - { 0, 1, {17,17,-2, 2, 3} }, // 6 - { 0, 1, {18,-2,18, 2,17} }, // 7 - { 1, 2, {18,18,-1, 2, 3} }, // 8 - { 0, 2, {18,17, 3, 2, 5} }, // 9 - { 1, 1, {18,17,18, 2, 5} }, // 10 - { 0, 1, {17,17,-2, 2, 3} }, // 11 - { 0, 1, {18,-2,18, 2, 5} }, // 12 - { 0, 1, {17,-2,17, 2,-3} }, // 13 - { 1, 1, {17,-2,17, 1, 2} }, // 14 - { 0, 1, {17,17,-2, 2, 3} }, // 15 - { 1, 1, {18, 3, 1, 5, 4} }, // 16 - { 1, 4, {18,18, 2, 3,-2} }, // 17 - { 0, 1, { 1,-1,-1, 2,17} }, // 18 - { 0, 2, {18,17, 3, 2, 5} }, // 19 - { 0, 1, {18,18,18, 2,17} }, // 20 - { 0, 1, {18,17,-1, 2,18} }, // 21 - { 1, 1, {17, 3, 2, 1, 7} }, // 22 - { 0, 2, {18,-2,18, 2, 3} }, // 23 - { 1, 3, {18,-3,18, 2, 3} }, // 24 - { 0, 3, {18,17, 2, 3,17} }, // 25 - { 1, 1, {17,17, 2, 1, 4} }, // 26 - { 0, 1, {17,18,-2, 2,17} }, // 27 - { 1, 1, {18,18, 3, 5, 2} }, // 28 - { 0, 1, {17,17, 2,18, 4} }, // 29 - { 0, 1, {18,17, 1, 4, 6} }, // 30 - { 1, 1, { 3,17,18, 2,17} }, // 31 - { 1, 1, {17, 3, 2, 1, 7} }, // 32 - { 0, 1, {18,17,-1, 2, 3} }, // 33 - { 1, 1, {17,17, 2, 1, 4} }, // 34 - { 1, 2, {18,17,-1,17, 3} }, // 35 - { 1, 2, {18,17, 2, 3,-1} }, // 36 - { 0, 2, {18,18,-2, 2,17} }, // 37 - { 0, 1, {17,17, 2,18, 4} }, // 38 - { 0, 5, {-2,18,18,18, 2} }, // 39 - { 1, 1, {18,18,-1, 6, 3} }, // 40 - { 0, 1, {17,17,-2, 2, 3} }, // 41 - { 1, 1, {18,17,18, 2,17} }, // 42 - { 0, 1, {18,17, 4, 3, 1} }, // 43 - { 0, 1, {-2,18, 2, 2,18} }, // 44 - { 1, 2, {18,18,-2, 2,-1} }, // 45 - { 1, 1, {17,17, 2, 1, 4} }, // 46 - { 0, 1, {17,18,-2, 2,17} }, // 47 - { 1, 1, {17, 3, 2, 1, 7} }, // 48 - { 1, 3, {18,-3,18, 2, 3} }, // 49 - { 1, 2, {18,18,-2, 2,-1} }, // 50 - { 1, 1, {18,18, 3, 5, 2} }, // 51 - { 0, 2, {18,18,-1, 2,17} }, // 52 - { 0, 1, {18,-1,17,18, 2} }, // 53 - { 0, 1, {17,-1, 2, 3, 6} }, // 54 - { 0, 1, {18,-2,18, 2, 5} }, // 55 - { 1, 2, {18,18,-2, 2,-1} }, // 56 - { 0, 3, {18,18, 2, 3,17} }, // 57 - { 0, 1, {17,17, 2,18, 4} }, // 58 - { 1, 1, {17,-2,17, 1, 2} }, // 59 - { 0, 1, {-1, 3, 5, 4, 7} }, // 60 - { 0, 3, {18,18, 3, 2, 5} }, // 61 - { 0, 1, {17,17, 2,18, 4} }, // 62 - { 0, 1, {18,17,-2,18, 3} }, // 63 - { 0, 2, {18,18,-2, 2,17} }, // 64 - { 0, 3, {18,17,-2, 2, 3} }, // 65 - { 1, 1, {18,18,-2, 2,17} }, // 66 - { 0, 1, {18,17, 4, 3, 1} }, // 67 - { 1, 2, { 3,18,17, 2,17} }, // 68 - { 1, 2, {18,18, 2,-2,18} }, // 69 - { 1, 2, {18,18,-1,18, 2} }, // 70 - { 0, 2, {18,18,-2, 2,17} }, // 71 - { 1, 3, {18,18, 2, 3,-2} }, // 72 - { 0, 3, {18,18, 3, 2, 5} }, // 73 - { 0, 1, {18,-2,18, 2, 5} }, // 74 - { 1, 1, {17, 3, 2, 1, 7} }, // 75 - { 1, 3, {18,18,-2, 2,18} }, // 76 - { 1, 1, {17,18,18,-2, 2} }, // 77 - { 0, 1, {18,-2,18, 2, 5} }, // 78 - { 0, 2, {18,-2,18, 2, 3} }, // 79 - { 0, 1, {-1, 3, 4, 5, 7} }, // 80 - { 1, 1, {17,17, 2,-1, 7} }, // 81 - { 0, 1, {18,-1,-1, 2,-2} }, // 82 - { 0, 2, {18,17, 2, 3,17} }, // 83 - { 0, 1, {18,17, 2,18, 2} }, // 84 - { 0, 2, {18,17,-1, 2,17} }, // 85 - { 0, 1, { 1,18, 3, 2, 5} }, // 86 - { 0, 2, {18,-2, 4,18, 2} }, // 87 - { 1, 1, {18, 3, 1, 5, 4} }, // 88 - { 0, 1, {18,17,18, 2, 5} }, // 89 - { 1, 1, {18, 3, 1, 5, 4} }, // 90 - { 0, 4, {18,18,-2, 2,18} }, // 91 - { 1, 1, {18,18, 3, 2, 5} }, // 92 - { 1, 1, {17,17, 2, 1, 4} }, // 93 - { 0, 2, {18,18,-2,18, 2} }, // 94 - { 0, 2, {18,18,-2,18, 2} }, // 95 - { 1, 1, {18,18, 2, 1, 3} }, // 96 - { 1, 1, {17,17, 2, 1, 4} }, // 97 - { 1, 2, {17,17, 2,18, 3} }, // 98 - { 0, 1, {18,17, 1, 4, 6} }, // 99 - { 1, 2, {18,18,-2, 2,-1} }, // 100 - { 0, 1, {18,-2,18, 2, 5} }, // 101 - { 1, 1, {17, 2,18, 2,17} }, // 102 - { 0, 2, {18,18,-2,18, 2} }, // 103 - { 0, 1, {18,18, 3, 6,-1} }, // 104 - { 0, 1, {18,17, 2,18, 3} }, // 105 - { 0, 1, {18,17,-2, 2,17} }, // 106 - { 1, 1, { 3,17,18, 2,17} }, // 107 - { 1, 3, {18,-3,18, 2, 3} }, // 108 - { 1, 3, {18,18,-3,18, 2} }, // 109 - { 1, 1, {18, 3, 1, 5, 4} }, // 110 - { 0, 1, {17,-2,17, 2,-3} }, // 111 - { 1, 1, {18,18, 3, 5, 2} }, // 112 - { 1, 2, {18,18,-2, 2,-1} }, // 113 - { 0, 1, {18,-1,-1, 2,-2} }, // 114 - { 1, 1, {18, 3, 1, 5, 4} }, // 115 - { 0, 3, {18,17,-1, 2,17} }, // 116 - { 1, 3, {18,17, 2,18,-2} }, // 117 - { 0, 2, {18,18,-2,18, 2} }, // 118 - { 1, 2, {18,18,-2, 2,-1} }, // 119 - { 1, 1, {18, 3, 1, 5, 4} }, // 120 - { 0, 4, { 3,18,18, 2,17} }, // 121 - { 0, 2, {18,18,-2,18, 2} }, // 122 - { 1, 1, {18,17,-1,18, 2} }, // 123 - { 0, 2, {18,18,-2,18, 2} }, // 124 - { 0, 2, {18,18,-2,18, 2} }, // 125 - { 0, 2, {18,18,-2,18, 2} }, // 126 - { 0, 2, {18,18,-2,18, 2} }, // 127 - { 1, 1, {18,18,18, 3, 2} }, // 128 - { 0, 1, {17,-1, 2, 3, 6} }, // 129 - { 0, 1, {17,-1, 2, 3, 6} }, // 130 - { 0, 2, {18,17,-2, 3, 2} }, // 131 - { 1, 3, {18,17, 2,-2,18} }, // 132 - { 0, 2, {18,18, 2,17, 3} }, // 133 - { 0, 1, {18,18, 2,18,-2} }, // 134 - { 0, 2, {18,-2, 4,18, 2} }, // 135 - { 0, 1, {-2,18, 2, 2,18} }, // 136 - { 0, 2, {18,17, 3, 6, 2} }, // 137 - { 0, 1, {18,17,18, 2, 5} }, // 138 - { 0, 3, {18,18,-2, 3, 2} }, // 139 - { 1, 1, {18,18, 2,18, 5} }, // 140 - { 0, 1, {17,-1, 2, 3, 6} }, // 141 - { 1, 4, {18,18, 2, 3,-2} }, // 142 - { 0, 2, {18,17,18, 2,-2} }, // 143 - { 0, 1, { 1,18, 3, 2, 5} }, // 144 - { 1, 4, {18,-2,18, 2, 3} }, // 145 - { 1, 2, {18, 2,18, 3,-2} }, // 146 - { 0, 2, {18,18,18, 2, 4} }, // 147 - { 0, 2, { 3,17,18, 2,17} }, // 148 - { 1, 1, {18,-1,18, 2,17} }, // 149 - { 1, 2, {17,17, 2,18, 3} }, // 150 - { 0, 2, {18,17,-2, 3, 2} }, // 151 - { 0, 1, { 1,-1,-1, 2,17} }, // 152 - { 0, 3, { 3,18,18, 2,17} }, // 153 - { 0, 1, {18,-1,17,18, 2} }, // 154 - { 0, 1, {18,17, 2,18, 3} }, // 155 - { 0, 2, {18,18,-2,18, 2} }, // 156 - { 0, 1, {18,17, 2,18, 2} }, // 157 - { 0, 2, {18,18,-2,18, 2} }, // 158 - { 0, 2, {18,18,-2,18, 2} }, // 159 - { 1, 2, {17,17, 2,18, 3} }, // 160 - { 0, 1, {18,17,-2, 2, 3} }, // 161 - { 0, 1, {18,-2,18, 2, 5} }, // 162 - { 1, 4, {18,-2,18, 2, 3} }, // 163 - { 1, 3, {18,17, 2, 3, 6} }, // 164 - { 0, 2, {18,18, 2,17, 3} }, // 165 - { 0, 2, {18,17, 2,18, 2} }, // 166 - { 0, 2, {18,18,-2,18, 2} }, // 167 - { 1, 1, {18,18, 3, 5, 2} }, // 168 - { 0, 2, {18,18,-2, 2, 3} }, // 169 - { 1, 2, {18,17, 2,17, 3} }, // 170 - { 0, 1, {18,17, 2, 3,18} }, // 171 - { 0, 2, {18,18,-2,18, 2} }, // 172 - { 1, 4, {18,18, 2, 3,-2} }, // 173 - { 0, 1, {17,-2,17, 2,-3} }, // 174 - { 0, 1, {17,17, 2,18, 4} }, // 175 - { 1, 1, {18,18,18, 2, 4} }, // 176 - { 1, 2, {18, 2,18, 3,-2} }, // 177 - { 1, 1, {18,18,-2, 2,17} }, // 178 - { 0, 2, {18,18,-2,18, 2} }, // 179 - { 0, 2, {18,18, 2,17, 3} }, // 180 - { 0, 2, {18,18,18, 2, 4} }, // 181 - { 0, 2, {18,18,-2,18, 2} }, // 182 - { 0, 2, {18,17,-2, 3, 2} }, // 183 - { 0, 1, { 1,-1,-1, 2,17} }, // 184 - { 1, 4, {18,18, 2, 3,-2} }, // 185 - { 0, 2, {18,18,-2,18, 2} }, // 186 - { 0, 1, {18,-2,18, 3, 2} }, // 187 - { 0, 2, {18,18,-2,18, 2} }, // 188 - { 0, 2, {18,18,-2,18, 2} }, // 189 - { 0, 2, {18,18,-2,18, 2} }, // 190 - { 0, 2, {18,18,-2,18, 2} }, // 191 - { 0, 1, {18,18,-2, 2,17} }, // 192 - { 0, 3, {18,17, 2, 3,17} }, // 193 - { 1, 2, {18,18, 2,-2,18} }, // 194 - { 0, 1, {-1, 3, 5, 4, 7} }, // 195 - { 1, 1, {18, 3, 1, 5, 4} }, // 196 - { 1, 1, {18,18,-2,18, 3} }, // 197 - { 0, 2, {18,17,18, 2,-2} }, // 198 - { 0, 2, {18,18, 2,17, 3} }, // 199 - { 1, 2, {18, 2,18, 3,-2} }, // 200 - { 1, 4, {18,18, 2, 3,-2} }, // 201 - { 1, 3, {18,17, 2, 3, 6} }, // 202 - { 0, 2, {18,18,-2,18, 2} }, // 203 - { 1, 2, {18,17,-2,-1,17} }, // 204 - { 0, 1, {17,-1, 2, 3, 6} }, // 205 - { 0, 2, {18,18,-2,18, 2} }, // 206 - { 0, 2, {18,18,-2, 2, 3} }, // 207 - { 1, 1, {18,18,18, 2, 5} }, // 208 - { 0, 1, {17,17,-2, 2, 3} }, // 209 - { 0, 2, {18,18,-2,18, 2} }, // 210 - { 0, 2, {18,17, 3, 6, 2} }, // 211 - { 0, 2, {18,17,18, 2, 3} }, // 212 - { 0, 3, {18,17,-3,18, 2} }, // 213 - { 0, 1, {18,18,18, 2, 3} }, // 214 - { 0, 1, {18,-2,-3, 2, 6} }, // 215 - { 0, 2, {18,18,-2,18, 2} }, // 216 - { 1, 1, {18,17,18, 2, 5} }, // 217 - { 0, 2, {18,18,-2,18, 2} }, // 218 - { 0, 2, {18,18,-2,18, 2} }, // 219 - { 1, 1, {18,17,18, 2, 5} }, // 220 - { 0, 2, {18,18,-2,18, 2} }, // 221 - { 0, 2, {18,18,-2,18, 2} }, // 222 - { 0, 2, {18,18,-2,18, 2} }, // 223 - { 0, 1, {18,18,18, 2, 3} }, // 224 - { 1, 1, {17,-2,17, 1, 2} }, // 225 - { 1, 1, {17,17, 2,-1, 7} }, // 226 - { 0, 1, {18,17, 4, 3, 1} }, // 227 - { 1, 3, {18,-3,18, 2, 3} }, // 228 - { 0, 1, { 1,18, 3, 2, 5} }, // 229 - { 0, 2, {18,18,-2,18, 2} }, // 230 - { 0, 2, {18,18,-2,18, 2} }, // 231 - { 0, 1, {18,18, 3, 6, 2} }, // 232 - { 0, 1, {17,17, 2,18, 4} }, // 233 - { 0, 1, {17,17, 2,18, 4} }, // 234 - { 0, 2, {18,18,-2,18, 2} }, // 235 - { 0, 2, {18,18,-2,18, 2} }, // 236 - { 0, 2, {18,18,-2,18, 2} }, // 237 - { 1, 2, {18,-2,18, 3, 2} }, // 238 - { 1, 1, {17,-2,17, 1, 2} }, // 239 - { 1, 1, {18,18, 3, 2, 5} }, // 240 - { 0, 1, {18,18,-1, 2, 3} }, // 241 - { 0, 2, {18,18,-2,18, 2} }, // 242 - { 0, 2, {18,18,-2,18, 2} }, // 243 - { 0, 1, {18,17,18, 2, 5} }, // 244 - { 0, 2, {18,18,-2,18, 2} }, // 245 - { 0, 2, {18,18,-2,18, 2} }, // 246 - { 0, 2, {18,18,-2,18, 2} }, // 247 - { 0, 2, {18,18,-2,18, 2} }, // 248 - { 0, 1, { 3,18,18, 2,17} }, // 249 - { 0, 2, {18,18,-2,18, 2} }, // 250 - { 0, 2, {18,18,-2,18, 2} }, // 251 - { 0, 2, {18,18,-2,18, 2} }, // 252 - { 0, 2, {18,18,-2,18, 2} }, // 253 - { 0, 2, {18,18,-2,18, 2} }, // 254 - { 0, 2, {18,18,-2,18, 2} }, // 255 -}; - -static const WavpackDecorrSpec high_specs [] = { - { 1, 2, {18,18,18,-2, 2, 3, 5,-1,17, 4} }, // 0 - { 0, 1, {18,17,-2, 2,18, 3, 7, 2, 5, 4} }, // 1 - { 1, 2, { 1,18, 3, 6,-2,18, 2, 3, 4, 5} }, // 2 - { 0, 2, {18,18,-2, 2,18, 3, 6, 2,17, 4} }, // 3 - { 1, 2, {18,18, 2,18, 3, 2,-1, 4,18, 5} }, // 4 - { 1, 1, { 7, 6, 5, 3, 4, 2, 5, 4, 3, 7} }, // 5 - { 1, 1, {17, 3,18, 7, 2, 6, 1, 4, 3, 5} }, // 6 - { 1, 1, {-2,18,18,18, 3,-2, 6, 5, 2, 1} }, // 7 - { 1, 2, {18,18,-1,18, 2, 3, 6,-2,17, 5} }, // 8 - { 0, 1, {17,17,18, 3, 6, 4, 5, 2,18,-2} }, // 9 - { 1, 2, { 1,18,-2, 3, 5, 2, 4,-1, 6, 1} }, // 10 - { 0, 2, {18,18, 3, 6,18, 2, 4, 8, 5, 3} }, // 11 - { 0, 1, {-2, 1,18, 2,-2, 7,18, 2,-1, 5} }, // 12 - { 1, 1, { 4, 3, 8, 1, 5, 2, 5, 6, 2, 8} }, // 13 - { 1, 1, {17,18, 2, 6, 3, 4,-1, 1, 8, 6} }, // 14 - { 0, 1, {18,18, 3, 6, 3,-2, 2, 5,-1, 1} }, // 15 - { 0, 1, {18,18,17,-1, 2,-2,18, 3, 4, 5} }, // 16 - { 1, 2, {18,17, 2,-2,18, 3, 5, 7, 2, 4} }, // 17 - { 1, 2, {18,18, 3, 6,-2,18, 2, 5, 8, 3} }, // 18 - { 0, 1, {18,17, 2,18,18, 2, 6, 5,17, 7} }, // 19 - { 1, 2, {18,17, 2,18, 3, 2, 6,18,-1, 4} }, // 20 - { 1, 1, { 5, 3, 6, 5, 3, 4, 1, 2, 4, 7} }, // 21 - { 1, 1, { 5, 3, 6, 5, 3, 4, 1, 2, 4, 7} }, // 22 - { 0, 1, {-2,18,18,18,-2, 3, 2, 4, 6, 5} }, // 23 - { 1, 2, {18,17,-3, 3,-1,18, 2, 3, 6, 5} }, // 24 - { 0, 1, {17,18, 7, 3,-2, 7, 1, 2, 4, 5} }, // 25 - { 1, 1, { 2,18,18,-2, 2, 4,-1,18, 3, 6} }, // 26 - { 0, 3, { 1,18, 4, 3, 5, 2, 4,18, 2, 3} }, // 27 - { 0, 1, {-2,18, 2,18, 3, 7,18, 2, 6,-2} }, // 28 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 29 - { 1, 1, {18,18, 5, 4, 6, 4, 5, 1, 4, 3} }, // 30 - { 1, 1, {18, 3, 6, 5, 7, 8, 2, 3, 1,-1} }, // 31 - { 1, 1, {18,18,18, 2,-2, 3, 5,18, 2, 8} }, // 32 - { 0, 2, {18,17,-2, 2, 3,18,-3, 5, 2, 7} }, // 33 - { 1, 1, { 1, 1,-1, 8,17, 3,-2, 2, 6,17} }, // 34 - { 0, 2, {18,18,17, 2,-2, 3, 2, 4,18, 5} }, // 35 - { 1, 1, {17,18, 2,-1, 5, 7,18, 3, 4, 6} }, // 36 - { 1, 1, { 5, 4, 5,17, 3, 6, 3, 4, 7, 2} }, // 37 - { 0, 1, {17, 3, 1, 7, 4, 2, 5,-2,18, 6} }, // 38 - { 0, 1, {17,18, 2,18, 4, 3, 5, 7,-3, 6} }, // 39 - { 1, 2, {17,17,-3,-2, 2, 8,18,-1, 3, 5} }, // 40 - { 0, 1, {17,17,18, 2, 3, 6,-2, 8, 1, 7} }, // 41 - { 1, 1, { 1, 2, 6,-2,18, 2, 5,-3, 7,-2} }, // 42 - { 0, 1, {18,18, 3,18, 6, 8,-2, 2, 3, 5} }, // 43 - { 0, 1, {18,17, 2,18,-2, 3, 7, 6, 2, 4} }, // 44 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 45 - { 1, 1, {18,18, 2,-1, 3, 6, 1, 3, 4, 8} }, // 46 - { 0, 1, {18,18, 3, 6, 5, 3,-2, 2,18,-1} }, // 47 - { 0, 1, {18,17,-3,18, 2, 4,-2, 3, 6,17} }, // 48 - { 1, 3, { 1, 2,17, 3,18, 7,-1, 5, 2, 4} }, // 49 - { 1, 1, {18, 3,18, 6, 8,18,-2, 5, 7, 2} }, // 50 - { 0, 1, {17, 2,18, 6, 3, 2, 5, 4, 8, 1} }, // 51 - { 0, 1, {18,17,-1, 2, 3,18,18, 2, 3,17} }, // 52 - { 1, 1, {18, 7, 6, 5, 5, 3, 1, 4, 2, 4} }, // 53 - { 1, 1, { 6,17, 3, 8, 1, 5, 7,-1, 2, 1} }, // 54 - { 1, 1, {18,-2,18, 3,-2, 2, 7, 4, 6,18} }, // 55 - { 1, 3, {18,-3,18, 2, 3,18,-1, 7, 2, 5} }, // 56 - { 0, 2, {18,-2, 7, 1, 3, 2, 4, 6,-3, 7} }, // 57 - { 1, 1, {18,-2, 2,-3,18,-2,17,-1, 4, 2} }, // 58 - { 0, 3, {17,17, 2, 5, 3, 7,18, 6, 4, 2} }, // 59 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 60 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 61 - { 1, 1, {18,17, 4, 6, 6, 4, 5, 3, 4, 1} }, // 62 - { 0, 1, {18, 5, 3, 6, 2, 3, 8, 1, 3, 7} }, // 63 - { 1, 2, {18,17,-2, 2,18, 3, 5, 7,-1, 2} }, // 64 - { 0, 1, { 1,18,18, 3, 6,-1, 4, 8, 5, 2} }, // 65 - { 1, 1, { 1, 5, 3, 4, 1, 1, 3, 5, 7, 3} }, // 66 - { 0, 1, { 3,18,18, 2,18,18,-1, 2, 3,18} }, // 67 - { 1, 2, {18,18,-1,18, 2, 3, 4, 6,18, 5} }, // 68 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 69 - { 1, 1, {18, 3, 1, 4, 5, 2, 7, 1, 3, 6} }, // 70 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 71 - { 1, 2, {18,18,-1,18, 2, 3, 5,-2, 6, 8} }, // 72 - { 1, 1, {17,18, 4, 8, 3, 2, 5, 2, 7, 6} }, // 73 - { 1, 4, { 1, 2, 5,18,-2, 2, 3, 7,-1, 4} }, // 74 - { 0, 2, {18,17,-1, 3, 6,18, 2, 3, 7, 5} }, // 75 - { 0, 1, {-2,18, 2,-3, 6,18, 4, 3,-2, 5} }, // 76 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 77 - { 0, 1, {17,17, 6, 2, 4, 8, 3, 5,-1,17} }, // 78 - { 1, 1, {18, 3,18, 6, 8,18,-2, 5, 7, 2} }, // 79 - { 1, 2, {17,17,-3, 2,18,-2, 8, 3, 6,-1} }, // 80 - { 1, 1, {18,-2,17,18, 2, 3,-2, 6, 5, 4} }, // 81 - { 1, 2, {18,17,-1, 3,18, 2, 5, 3, 6,-3} }, // 82 - { 0, 1, {18,17, 2,18, 7,18, 2, 4, 3,17} }, // 83 - { 1, 3, {18,18, 5, 6, 4, 3, 4,18, 6, 5} }, // 84 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 85 - { 1, 1, { 7, 6, 5, 3, 4, 2, 5, 4, 3, 7} }, // 86 - { 0, 1, {-2,18,18,18, 3, 6, 4, 2, 5, 2} }, // 87 - { 0, 3, {18,17,-3,18, 3, 2, 5,-1,17, 3} }, // 88 - { 1, 1, {17,18, 7, 3, 1, 7, 4, 2, 6, 5} }, // 89 - { 1, 1, {18, 2,-2,-1,18, 5, 3,-2, 1, 2} }, // 90 - { 0, 3, {18,18,-1, 3, 2, 7, 5,18, 4, 3} }, // 91 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 92 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 93 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 94 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 95 - { 1, 1, {17,18, 2,-2, 4, 8,18, 3, 6, 5} }, // 96 - { 0, 2, {18,17, 3, 5,-2, 7, 2,18, 3,-1} }, // 97 - { 1, 1, {18, 2,-2,-1,18, 5, 3,-2, 1, 2} }, // 98 - { 0, 2, { 3,17,18,18, 2, 5, 7, 6,18, 3} }, // 99 - { 1, 1, {17,18,18, 4, 3, 2,18, 7, 8,-1} }, // 100 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 101 - { 0, 1, {17, 1, 2, 3, 5, 6, 1, 4, 8,17} }, // 102 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 103 - { 0, 2, {18,17,-1,18,-3, 2, 8, 3, 6,17} }, // 104 - { 1, 1, {17,17, 1, 2, 4, 5,-1, 2, 1, 6} }, // 105 - { 1, 1, { 1, 2, 6,-2,18, 2,-3, 3,-2, 5} }, // 106 - { 0, 1, {18, 3,18, 6,18, 5, 2, 4,-1, 8} }, // 107 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 108 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 109 - { 1, 1, {18,18,-1, 2,18, 3, 6, 4,-2, 7} }, // 110 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 111 - { 0, 2, {-1,18,18,18, 2,-2, 4, 7, 2, 3} }, // 112 - { 0, 3, { 3,17,-2, 5, 2, 7,18, 6, 4, 5} }, // 113 - { 0, 1, {17, 6,18, 3, 8, 4, 5, 3, 8,18} }, // 114 - { 0, 2, {18, 2, 6, 2,18, 3, 2, 4, 5, 8} }, // 115 - { 0, 1, { 3,18,18, 2,18,-1, 2,18, 2,17} }, // 116 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 117 - { 0, 1, { 3, 6,17,-2, 5, 1, 2, 7, 4, 8} }, // 118 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 119 - { 1, 3, { 3,18,17, 5, 6, 2, 7,-2, 8,18} }, // 120 - { 1, 1, {18,-1, 3, 1, 7, 2,-1, 4, 6,17} }, // 121 - { 1, 1, {18, 2,-2,-1,18, 5, 3,-2, 1, 2} }, // 122 - { 0, 2, {18, 1, 2,18, 3, 6, 5, 2, 4, 8} }, // 123 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 124 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 125 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 126 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 127 - { 1, 1, {17,-2, 2,18,18, 8, 5, 3, 2, 6} }, // 128 - { 0, 1, {18,17, 2,18, 3, 2, 7,-2,18, 4} }, // 129 - { 1, 2, { 1,18, 2, 3,-1, 5, 6, 4, 7,17} }, // 130 - { 0, 2, {18,17, 3, 6,-2, 2, 3, 8, 5,17} }, // 131 - { 0, 2, {18,18, 3, 2,18,-1, 2, 4, 3,17} }, // 132 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 133 - { 1, 2, {17,-1,18, 2, 3,-2, 5,18, 2, 7} }, // 134 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 135 - { 1, 2, {18,-3,18, 2, 3,-2,18, 5, 6,-3} }, // 136 - { 0, 2, {18,17, 3, 5,-2, 7, 2,18, 3,-1} }, // 137 - { 1, 1, { 1,18,-1, 2, 3, 1,-2, 8, 2, 5} }, // 138 - { 0, 1, {18,18, 3, 6,18, 2, 3, 4, 8, 5} }, // 139 - { 0, 1, {-2, 1,18, 2,-2, 5, 7,18, 2,-1} }, // 140 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 141 - { 1, 1, {17,18,-1, 2, 8, 3, 4, 5, 1, 7} }, // 142 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 143 - { 0, 2, {18,18,-1, 2,18, 3,-2, 5, 4, 2} }, // 144 - { 1, 1, {18,17, 2,18, 3, 8, 5, 2, 7,17} }, // 145 - { 0, 1, {18,18, 3,18, 6, 8,-2, 2, 3, 5} }, // 146 - { 0, 1, {18,18, 2,18, 2, 6,18, 2,17, 7} }, // 147 - { 1, 3, {18,17,18, 2, 8,18, 5,-1, 3, 6} }, // 148 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 149 - { 1, 1, {18, 7, 6, 5, 5, 3, 1, 4, 2, 4} }, // 150 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 151 - { 1, 2, {18,17,-1, 3, 6,18, 2, 5, 8, 3} }, // 152 - { 0, 1, {17,18,18, 4, 7, 2, 3,-2,18, 5} }, // 153 - { 1, 2, {18, 1, 2, 6, 2, 5,18, 2, 4, 8} }, // 154 - { 0, 4, {18, 4, 1, 2, 3, 5, 4, 1, 2, 6} }, // 155 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 156 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 157 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 158 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 159 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 160 - { 0, 2, {18,17, 2,-1,18, 3,-3, 5, 2, 4} }, // 161 - { 0, 1, {17,17, 3, 6, 3, 5,-2, 2,18,-1} }, // 162 - { 0, 2, {18,18, 3,-2,18, 2,-3, 5, 3, 6} }, // 163 - { 1, 1, {17,17, 2, 4, 1, 3, 5, 2, 6,-3} }, // 164 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 165 - { 0, 1, {17, 1, 3, 2, 7, 1, 6, 3, 4, 8} }, // 166 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 167 - { 0, 1, {17,-1,18, 2, 1, 5, 3, 8,-1,-2} }, // 168 - { 1, 1, {17,18,-1, 8, 2, 5, 3, 4, 1, 6} }, // 169 - { 1, 2, { 1,18, 3,-1, 5, 1, 2, 4, 7, 6} }, // 170 - { 0, 1, {18,18, 3, 6, 5, 3,-2, 2,18,-1} }, // 171 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 172 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 173 - { 0, 1, { 1,18,-1, 3, 8, 5, 6, 1, 2, 3} }, // 174 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 175 - { 0, 2, {18,18, 2, 3, 6,18,-1, 4, 2, 3} }, // 176 - { 1, 1, { 1, 3, 5,18, 2, 6, 7, 2, 3, 1} }, // 177 - { 1, 1, { 1, 3, 8,18, 5, 2, 7, 1, 3,-2} }, // 178 - { 0, 2, {17, 2,18, 3, 6, 2, 4, 5, 8, 3} }, // 179 - { 0, 1, {18,17, 2,18, 3, 2, 7,-2,18, 4} }, // 180 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 181 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 182 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 183 - { 1, 2, {18,-3,18,-1, 3,-2, 5, 7, 1, 2} }, // 184 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 185 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 186 - { 0, 3, {18,18, 2, 6,18, 5,18, 2, 3,17} }, // 187 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 188 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 189 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 190 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 191 - { 1, 3, { 1,-1, 1, 3,-2, 2, 5, 7,-3,18} }, // 192 - { 1, 2, {18, 7, 3,-3, 2, 8, 2, 5, 4,17} }, // 193 - { 1, 1, { 1, 4, 5, 1, 3, 4, 6, 7, 8, 3} }, // 194 - { 0, 1, {18,17, 2,18,-1, 2, 3,18, 2, 4} }, // 195 - { 0, 2, {18,18,-2,18, 2, 3, 4, 7, 5,17} }, // 196 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 197 - { 1, 1, {17,18, 2, 1, 3, 2, 5, 1, 2, 3} }, // 198 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 199 - { 0, 2, {18,18,-1, 2, 3, 5, 8, 6, 1,-2} }, // 200 - { 0, 1, {17,18, 8, 3, 4, 6, 5, 2, 8, 7} }, // 201 - { 1, 2, { 1, 3,-2,18, 2, 5, 1, 7,-1,-2} }, // 202 - { 0, 3, {18,17,-1, 3,18, 2, 3, 6, 4,17} }, // 203 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 204 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 205 - { 1, 2, {18,18, 4,18, 6, 7, 8, 3,18, 2} }, // 206 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 207 - { 0, 2, {17,-3,17, 2,-2, 8, 3,18, 4,-3} }, // 208 - { 1, 1, {18,17, 3, 5, 6, 2, 8, 1, 3, 7} }, // 209 - { 0, 1, {18,18, 3, 6, 5, 3,-2, 2,18,-1} }, // 210 - { 0, 3, {18,18, 2, 6,18, 5,18, 2, 3,17} }, // 211 - { 1, 1, {18,18, 5, 4, 6, 4, 5, 1, 4, 3} }, // 212 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 213 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 214 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 215 - { 0, 2, { 3,17,18,-3, 2, 5,18, 6,-1, 7} }, // 216 - { 1, 1, {17,18, 3, 2, 5,-1, 6, 8, 4, 7} }, // 217 - { 1, 1, {18, 1,-2, 3, 2, 1, 7, 6, 3, 4} }, // 218 - { 0, 3, { 1, 2,17, 3,18, 2, 7, 5, 4,-1} }, // 219 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 220 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 221 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 222 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 223 - { 1, 1, {17,-2, 2,18,18, 8, 5, 3, 2, 6} }, // 224 - { 0, 2, {18, 5,18, 2, 3, 7,-2, 1, 6, 8} }, // 225 - { 0, 1, { 2,-1,18,-1, 2, 4,-3, 5,18, 3} }, // 226 - { 0, 1, { 3,17,18, 5, 2,18, 7, 3, 6, 5} }, // 227 - { 1, 4, { 1, 2, 5,18,-2, 2, 3, 7,-1, 4} }, // 228 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 229 - { 0, 1, { 1,18, 2, 1, 3, 4, 1, 5, 2, 7} }, // 230 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 231 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 232 - { 0, 1, {17,17,18, 2, 4, 5,18,-2, 6, 3} }, // 233 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 234 - { 0, 2, {18,18,-1, 3, 5, 6, 8,18, 2, 3} }, // 235 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 236 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 237 - { 0, 1, {18,18, 4, 6, 8,18, 7, 3, 2, 5} }, // 238 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 239 - { 0, 2, {-1,18,18,18, 2, 4,-2, 2, 3, 6} }, // 240 - { 0, 2, {18,-2, 7, 1, 3, 2, 4, 6,-3, 7} }, // 241 - { 1, 1, {17,18, 8, 3, 4, 6,-2, 5, 3, 8} }, // 242 - { 0, 2, {18, 1, 2, 6, 2, 8, 3,18, 5, 4} }, // 243 - { 1, 1, { 3,18,18, 2,18, 2,18, 3, 2,18} }, // 244 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 245 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 246 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 247 - { 1, 1, { 3,17,18, 5, 2, 6, 7, 1, 4, 8} }, // 248 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 249 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 250 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 251 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 252 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 253 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 254 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2, 8} }, // 255 -}; - -static const WavpackDecorrSpec very_high_specs [] = { - { 1, 2, {18,18, 2, 3,-2,18, 2, 4, 7, 5, 3, 6, 8,-1,18, 2} }, // 0 - { 0, 1, {18,18,-1,18, 2, 3, 4, 6, 5, 7,18,-3, 8, 2,-1, 3} }, // 1 - { 1, 2, { 1,18,-2, 4,18, 2, 3, 6,-1, 7, 5,-2,18, 8, 2, 4} }, // 2 - { 0, 1, {17,17, 2, 3, 4,18,-1, 5, 6, 7,18, 2, 8,17, 3,-2} }, // 3 - { 1, 1, {18,18, 2,18, 3, 2,18, 4,-1, 3,18, 2, 6, 8,17, 5} }, // 4 - { 0, 2, {18,17, 2, 3,-2, 5,18,-3, 2, 4, 7, 3, 6, 8, 5,17} }, // 5 - { 1, 1, {18,-2, 2,-3,18, 5,-2,18, 2, 3, 6, 2,17, 4, 7,-1} }, // 6 - { 1, 1, {17, 8,18, 3,-2, 2, 5, 4,18, 6, 3, 8, 7, 2, 5, 4} }, // 7 - { 0, 2, {18,17,-2, 2,18, 3, 2, 5,-3, 4, 7,18, 3, 8, 6, 2} }, // 8 - { 1, 1, { 3, 6, 5, 5, 1, 3, 7, 4, 2, 6, 4,18, 3, 7, 5, 6} }, // 9 - { 1, 2, { 1,18, 3, 2,-2, 1, 5, 4, 6, 2, 7, 1, 8, 3,-1, 1} }, // 10 - { 0, 1, {18,18, 2, 3, 6, 3, 5,-2, 2, 4,18, 3,-2,-1, 6, 7} }, // 11 - { 0, 1, {-2,18, 2,18, 7, 2, 6,-2, 3, 4,18,18, 2,-3, 8, 5} }, // 12 - { 0, 2, {18,18,18, 2, 4, 3,18, 5, 3, 6,-2, 2, 4,18, 8, 7} }, // 13 - { 0, 1, {-2, 1,18, 2,-2,18,-1, 5, 7, 2, 3, 4,18, 2, 6, 2} }, // 14 - { 1, 1, {17,18, 3, 2, 1, 7,-1, 2, 4, 3, 5, 6,-2,18, 7, 8} }, // 15 - { 1, 1, {18,18, 2,18, 3, 4, 6,-2,18, 5, 8, 2, 3, 7, 4,-1} }, // 16 - { 0, 1, {18,18,18,-1, 2, 3, 4, 6, 8,18, 3, 5, 2, 6, 7, 4} }, // 17 - { 1, 1, {17,-2,18,18, 2, 5, 3, 8, 2,-1, 6, 1, 3, 4, 7, 5} }, // 18 - { 0, 1, {17,17,18, 2, 3, 6,-2, 8, 1, 7, 5, 2, 3, 1, 4, 8} }, // 19 - { 1, 1, {17,17, 3, 2, 7, 1, 4, 3, 6, 2, 5,-2, 8, 7,18, 6} }, // 20 - { 0, 1, {18,17,-2, 2,18, 3,-3, 7, 6, 5, 2, 4,-1, 8, 3,17} }, // 21 - { 1, 1, { 2,18,18,-2, 2, 4,-1, 5,18, 3, 8, 6, 2, 7,17, 4} }, // 22 - { 0, 1, {17, 3, 6, 8, 5, 4, 3, 8, 1,18, 7, 2, 4, 5, 6, 3} }, // 23 - { 1, 2, {17,18, 4, 8, 3, 2, 5, 7, 6, 8, 2, 7,-2,18, 3, 4} }, // 24 - { 1, 1, { 6, 5, 5, 3, 4, 7, 3, 2, 4, 6, 3, 7, 1, 5, 2, 4} }, // 25 - { 1, 1, { 1,18,-1, 2, 1, 3, 8,-2, 2, 5, 6, 3, 8, 7,18, 4} }, // 26 - { 0, 1, { 1,17,-1,18, 3, 2, 5, 4, 6, 7, 8, 3, 4, 2, 1,-2} }, // 27 - { 0, 1, {18, 2,18,18, 2,18, 6,-2,18, 7, 5, 4, 3, 2,18,-2} }, // 28 - { 0, 3, { 1, 4,18, 3, 2, 4, 1, 5, 2, 3, 6,18, 8, 7, 2, 4} }, // 29 - { 0, 1, {17,-2, 1,-3, 2,18, 3,-2, 4,18, 3, 6, 7,-3, 2, 8} }, // 30 - { 1, 1, {17,18,18, 4, 2, 3, 7, 6,18, 8, 5,-1, 4, 2, 3,17} }, // 31 - { 1, 2, {18,-1,17,18, 2, 3,-2,18, 5, 8, 2, 4, 3, 7, 6,-1} }, // 32 - { 1, 1, {18,18,18,-2, 4, 2, 3,18, 5, 8, 2, 4, 6, 7,-2, 3} }, // 33 - { 1, 2, {18,18,-2,18,-1, 3, 2, 5,18,-2, 7, 2, 3, 4, 6, 8} }, // 34 - { 0, 1, {17,18,-1, 2, 4,18, 8, 3, 6, 5, 7,-3, 2, 4, 3,17} }, // 35 - { 1, 1, {18,18,17, 2,-1,18, 3, 2,18, 6, 5, 4,18, 7, 2,-1} }, // 36 - { 0, 2, { 1,18,-1,18, 3, 2, 4, 6,-3, 7,-1, 5, 1, 2, 3, 8} }, // 37 - { 1, 1, { 1,17,-2, 2,-3, 6, 3, 5, 1, 2, 7, 6, 8,-2, 4, 1} }, // 38 - { 0, 1, {17,-1, 5, 1, 4, 3, 6, 2,-2,18, 3, 2, 4, 5, 8,-1} }, // 39 - { 0, 2, {18,18,17, 2, 3,-2, 5,18, 2, 4, 7, 8, 6,17, 3, 5} }, // 40 - { 1, 1, { 1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8} }, // 41 - { 1, 2, { 1,-1, 3, 2,18, 7,-2, 5, 2, 6, 4, 3,-1,18, 8, 7} }, // 42 - { 0, 2, {18,17, 3,18, 2, 5, 4, 3, 6, 2, 7, 8,18, 3, 4, 5} }, // 43 - { 1, 1, { 3, 6,17, 8, 7, 5,18,-1, 1, 2, 3, 4, 2, 6, 8, 1} }, // 44 - { 0, 2, {18,18, 3,-3,18, 2, 6, 5, 3, 7,18, 4,-2, 8, 2, 3} }, // 45 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 46 - { 1, 1, {17, 1, 7, 2, 3,18,-2, 3, 6, 4, 2, 7, 8, 5, 3,17} }, // 47 - { 1, 1, { 3, 6, 5, 5, 1, 3, 7, 4, 2, 6, 4,18, 3, 7, 5, 6} }, // 48 - { 0, 1, {18,18,18, 2, 4,-1,18, 8,-1, 2, 3, 4, 6,-2, 1, 7} }, // 49 - { 1, 1, {18,-2,17,18, 2, 6, 3,-2, 5, 4, 7, 1,-3, 8, 2, 6} }, // 50 - { 0, 1, {17,18,18, 4, 2, 7, 3, 6,-2,18, 8, 4, 5, 2, 7,17} }, // 51 - { 1, 1, {18,18, 5, 4, 6, 4, 1, 5, 4, 3, 2, 5, 6, 1, 4, 5} }, // 52 - { 0, 1, {18,18,-2,18, 2,-3, 3, 8, 5,18, 6, 4, 3,-1, 7, 2} }, // 53 - { 1, 1, {18, 2,-2,-3,18, 5, 2, 3,-2, 4, 6, 1,-3, 2, 7, 8} }, // 54 - { 0, 1, {18, 3, 5, 8, 2, 6, 7, 3, 1, 5, 2,-1, 8, 6, 7, 4} }, // 55 - { 1, 1, { 4, 3, 8, 1, 5, 6, 2, 5, 8,-2, 2, 7, 3,18, 5, 4} }, // 56 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 57 - { 1, 1, {17, 3,18,18, 7, 2, 4,18, 6, 2, 3,-1, 8, 5,18,-3} }, // 58 - { 0, 1, { 3,17,18, 2,18, 6, 7,-3,18, 2, 5, 6, 3, 8, 7,-1} }, // 59 - { 1, 1, {18,18, 2,18,18, 2,-1, 7, 3,18, 5, 2, 6, 4,-1,18} }, // 60 - { 0, 3, {18, 3, 4, 1, 5, 2,18, 4, 2, 3,18, 7, 6, 1, 2, 4} }, // 61 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 62 - { 1, 1, {17, 1,18, 2, 3, 6, 4, 5, 7,18, 3, 8, 2, 4,-2,17} }, // 63 - { 1, 2, {18,17, 2, 3, 5,18, 6,-2, 7, 3, 2, 4,18, 8,-1, 5} }, // 64 - { 0, 2, { 1,18,-1,18, 3, 2, 4, 6,-3, 7,-1, 5, 1, 2, 3, 8} }, // 65 - { 1, 1, { 1,18,-1, 8, 2, 6, 3,-2, 1, 2, 5, 4,-3, 8, 6, 3} }, // 66 - { 0, 1, {18,18, 2,18, 2,18, 7, 6,18, 2,-2, 3, 5, 4,18, 8} }, // 67 - { 1, 2, {18,17, 2, 3,18,-1, 2, 3, 6,18, 5, 4, 3, 7, 2, 8} }, // 68 - { 1, 2, {18,18, 3,-2, 4,18, 5, 7, 6, 2, 4,-3, 8, 5,18, 3} }, // 69 - { 1, 1, {17,-2,18,18, 2, 5, 3, 8, 2,-1, 6, 1, 3, 4, 7, 5} }, // 70 - { 1, 1, { 3,17,18, 5, 7, 2, 4, 6, 1, 8,-1, 3, 7, 4, 1, 2} }, // 71 - { 0, 2, { 1,-2, 2,18, 3, 5, 2, 4, 7,-1, 2, 3, 5,18,-2, 4} }, // 72 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 73 - { 1, 1, { 1, 2,-2, 6,18,-3, 2, 7, 3,-2, 5, 6, 1, 8, 2, 4} }, // 74 - { 0, 1, {18,18,18, 3,-2, 6,18, 2, 4, 3, 5, 8, 7, 6, 2,-2} }, // 75 - { 1, 1, { 1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8} }, // 76 - { 0, 1, { 3,17,18, 2, 5,18, 6, 7, 5,-2, 2, 4,18, 3, 6, 8} }, // 77 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 78 - { 0, 2, {17,-1,18, 2, 4,-1, 8, 3,18, 7,-3, 4, 5, 1, 2,-2} }, // 79 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 8, 6, 4, 5, 7,-1} }, // 80 - { 1, 1, {18,18, 3, 6, 4, 8,-2, 2, 5, 3, 7,18, 6, 8, 4, 2} }, // 81 - { 1, 1, {17,18,18,-2, 5, 2, 3, 1, 4,-1, 8, 6, 5, 3, 2,18} }, // 82 - { 1, 1, {17,17, 1, 2, 4, 5, 2, 6,-1, 3, 1, 1,-2, 4, 2, 7} }, // 83 - { 1, 1, {17, 1, 7, 2, 3,18,-2, 3, 6, 4, 2, 7, 8, 5, 3,17} }, // 84 - { 0, 1, {18,17,-2,-3, 1, 2, 3, 2, 5, 4, 7,-3, 6,-2, 2, 1} }, // 85 - { 1, 1, { 1, 3, 5,18, 1, 2, 7, 3, 6, 2, 5, 8,-1, 1, 4, 7} }, // 86 - { 1, 1, {17, 3, 6, 8, 1, 4, 5, 3,-2, 7, 2, 8, 5, 6,18, 3} }, // 87 - { 1, 1, {17,18, 2, 4, 8,-2, 3, 1, 5, 6, 7, 1, 2, 3, 4, 7} }, // 88 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 89 - { 1, 1, { 3, 1, 8,18, 5, 2, 3,18, 6, 7,-2, 4, 3, 2, 8,18} }, // 90 - { 0, 1, {18,17, 2,18, 3, 4,-1,18, 7, 6, 2, 8, 4,18,18, 5} }, // 91 - { 0, 1, {18,18, 2,18,18, 2, 7,-2, 6, 5, 4, 3,18, 3, 2,17} }, // 92 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 93 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 94 - { 1, 1, {17, 8,18, 3, 2, 1, 5, 4, 6,-1, 3,-3, 8,18, 7, 2} }, // 95 - { 1, 2, {18,17,18, 2, 3, 5,-2,18, 6,-1, 2, 3, 7, 4, 8,17} }, // 96 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 8, 6, 4, 5, 7,-1} }, // 97 - { 1, 2, {18,18,-2,17, 2,18, 3, 4,18, 8, 7,-1, 2, 4, 5,17} }, // 98 - { 0, 2, {17,-3,17, 3, 2,-2,18, 8, 4,-3, 2,18, 5, 3,-2, 6} }, // 99 - { 0, 1, {18,18, 2,18,18, 2, 7,-2, 6, 5, 4, 3,18, 3, 2,17} }, // 100 - { 0, 2, { 1,18,-1, 3, 5, 2,-3,18, 7, 3,-1, 6, 4, 2,17, 5} }, // 101 - { 1, 1, {17,-2,17, 2,-3, 1, 5,-1, 4, 6, 3, 2, 8, 7,-2, 5} }, // 102 - { 1, 1, { 1,18, 1, 3, 5, 8, 6, 2, 3,-1, 7, 1, 4, 8, 5,-3} }, // 103 - { 0, 2, { 3,18,18, 2,18,-2, 6, 5, 7, 2, 4,18, 3, 6,-3, 5} }, // 104 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 105 - { 1, 1, { 3, 6,17, 8, 7, 5,18,-1, 1, 2, 3, 4, 2, 6, 8, 1} }, // 106 - { 0, 4, {18, 2,17, 3,18,-2, 2, 6,18, 2, 7, 3, 5, 4, 8,18} }, // 107 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 108 - { 0, 1, {18,18, 2, 3, 6, 3, 5,-2, 2, 4,18, 3,-2,-1, 6, 7} }, // 109 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 110 - { 1, 1, {17, 1, 2, 5, 3,-2, 1, 4, 3, 7, 6,-3, 2, 1, 1, 2} }, // 111 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 112 - { 1, 1, {18,18,-2,18,-2, 2, 3, 6,18, 4,-1, 2, 3, 8, 1, 4} }, // 113 - { 1, 1, {17,-2,17, 2,-3, 1, 5,-1, 4, 6, 3, 2, 8, 7,-2, 5} }, // 114 - { 0, 1, {17,17,18, 3, 2,18,18, 6, 8, 2,-2, 3, 5, 4,17,18} }, // 115 - { 1, 1, { 1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8} }, // 116 - { 1, 1, { 1, 3,-3,18,18, 6, 5,18, 2,-1, 3, 8, 7,-3, 4,17} }, // 117 - { 1, 1, {18, 1, 2, 1, 3, 8, 7, 4, 1, 5, 2,-1,-3,18, 6, 2} }, // 118 - { 0, 1, {18, 3, 5, 2, 6, 8,18, 5, 7, 2, 3,-1, 6, 7, 8, 5} }, // 119 - { 0, 2, {18, 3,-2, 7, 8, 2, 5, 4,-3, 8, 3, 2,18, 5, 4, 6} }, // 120 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 121 - { 1, 3, { 1, 1, 2, 5, 2, 7, 4, 3,-1,18,-2, 8, 2, 1, 6, 7} }, // 122 - { 0, 1, { 3,17,18, 5, 2, 6, 7,18, 4, 5, 3, 6,18, 2, 7, 8} }, // 123 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 124 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 125 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 126 - { 0, 1, { 1,18, 1, 2, 3, 5, 1, 2, 6, 7, 4, 3, 8, 1,17, 5} }, // 127 - { 1, 2, {17,-1,18,-2, 2, 3, 5,18, 2, 4, 6, 7, 3,-1, 5, 8} }, // 128 - { 1, 1, {18,18,-3,18,-2, 2, 3,-2,18, 6, 4, 5, 8, 3,17,-3} }, // 129 - { 1, 1, {18, 7, 6, 5, 5, 3, 1, 4, 2, 7, 3, 4,-3, 6,18, 8} }, // 130 - { 0, 2, {18,18, 2, 3, 5,18, 2, 4, 3, 6,18, 7, 8,-1, 5, 2} }, // 131 - { 0, 1, {18,17,-1, 2,18, 3, 2,18, 4, 3,18, 2, 6, 5, 8,17} }, // 132 - { 0, 2, {18,17, 2, 3,18, 5,-1, 6, 7, 8, 2, 3, 4, 5,18, 6} }, // 133 - { 1, 2, {18,-3,18, 2, 3,-2,-3, 5,18, 7, 6, 2, 4, 3, 8,-2} }, // 134 - { 1, 1, {17,18,18,-2, 2, 3, 5, 4, 8,18,-1, 5, 3, 6,-2, 7} }, // 135 - { 1, 2, {18,17, 2,-2,18, 3,-1, 4,18, 2, 7, 5, 3, 8, 6, 4} }, // 136 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 137 - { 1, 1, { 1, 5, 1, 3, 4, 3, 7, 5, 1, 3, 6, 1, 2, 4, 3, 8} }, // 138 - { 0, 2, {18,18, 3, 3,-2, 2, 5,18, 6, 3,-1, 4, 7,-1, 1, 2} }, // 139 - { 0, 1, {-2, 1,18, 2,-2, 5, 7,18, 3, 2, 6, 2,-1, 4,-2,17} }, // 140 - { 0, 2, {18,18,18, 2, 3,-2,18, 5, 4, 2, 6, 8, 3,-2, 4,18} }, // 141 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 142 - { 1, 1, {17,18,-1, 3, 2, 5, 1, 3, 2, 8, 4, 7, 6, 2,-1, 5} }, // 143 - { 1, 1, {17,18,18, 4, 2, 3, 7, 6,18, 8, 5,-1, 4, 2, 3,17} }, // 144 - { 0, 1, {18,18,-2,18, 2, 3, 4, 5, 6,18, 8, 2, 3, 7,-2, 4} }, // 145 - { 0, 1, {18,-2,18,18,-3,-2, 2, 3, 5, 8, 1, 2, 6, 4, 7,-1} }, // 146 - { 0, 1, {18,17, 2,18, 3,-2, 2, 7, 6, 4,18, 3, 8, 7, 4, 2} }, // 147 - { 1, 1, {17,18,18, 4, 2, 3, 7, 6,18, 8, 5,-1, 4, 2, 3,17} }, // 148 - { 1, 1, {18,17,18, 2, 5, 3,-2,18, 6, 2, 3, 4, 8, 7, 5,-1} }, // 149 - { 0, 1, { 2,-1,18,-1, 2, 4,-3,18, 5, 3, 6,18, 2, 4, 7, 8} }, // 150 - { 1, 1, {17,18, 8, 3, 6, 4,-1, 5, 2, 7, 3, 8, 6, 5,18, 4} }, // 151 - { 0, 2, {18, 3,-2, 7, 8, 2, 5, 4,-3, 8, 3, 2,18, 5, 4, 6} }, // 152 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 153 - { 1, 1, { 1,18,-1, 8, 2, 6, 3,-2, 1, 2, 5, 4,-3, 8, 6, 3} }, // 154 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 155 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 156 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 157 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 158 - { 0, 1, {17,18,18, 4, 2, 7, 3, 6,-2,18, 8, 4, 5, 2, 7,17} }, // 159 - { 1, 2, {18,-1,18, 3,-2,18, 2, 5, 3, 6, 7, 2,-1,18, 8, 4} }, // 160 - { 1, 2, { 1,18,-2, 4,18, 2, 3, 6,-1, 7, 5,-2,18, 8, 2, 4} }, // 161 - { 1, 2, { 1,18,-3, 2, 3,18,-1, 5, 6, 2, 8, 3, 4, 1,-2, 7} }, // 162 - { 0, 1, { 1,17,-1,18, 3, 2, 5, 4, 6, 7, 8, 3, 4, 2, 1,-2} }, // 163 - { 1, 1, {18,17,18, 4, 3, 5, 1, 2, 6, 3, 4, 7, 1, 8, 5, 2} }, // 164 - { 0, 1, {18,-2, 7, 1, 3, 2,-3, 4, 6,-2, 7, 8, 1, 5, 4, 3} }, // 165 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 166 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 167 - { 0, 2, {18,18,18,-2, 2, 5, 3, 7,18, 2, 4,-3, 5, 6, 3, 8} }, // 168 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 169 - { 0, 3, { 3,18,-1, 5, 2, 7,18, 6, 5, 2, 4, 3,-1, 7,18, 6} }, // 170 - { 0, 2, {18,18,18, 4, 3, 2, 6, 4, 8,18, 5, 3, 2, 7,-2, 6} }, // 171 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 172 - { 0, 2, {18,18,18, 2, 3,-2,18, 5, 4, 2, 6, 8, 3,-2, 4,18} }, // 173 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 174 - { 1, 1, {17, 8,18, 3, 2, 1, 5, 4, 6,-1, 3,-3, 8,18, 7, 2} }, // 175 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 176 - { 0, 1, {-1,18,18,18, 2, 4, 6,-2, 2, 8, 3, 4,18, 7,-1, 6} }, // 177 - { 0, 1, {18, 1,-2, 2, 4, 1, 3,-1, 2, 5, 7, 1, 6, 8,-2,17} }, // 178 - { 0, 1, {17,17,18, 2, 5, 4,18, 3, 8, 7, 4, 6, 8, 1, 5, 2} }, // 179 - { 1, 2, {18,18, 5, 4, 6, 3, 4,18, 8, 4,-1, 7, 5, 3, 6, 2} }, // 180 - { 0, 1, {18,18,-3,18, 3, 6, 2, 5, 7,18, 3, 8,-1, 4, 5, 2} }, // 181 - { 1, 1, {18, 2,-2,-3,18, 5, 2,-2, 4, 3, 6,18, 8,-1, 2, 7} }, // 182 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 183 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 184 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 185 - { 1, 1, {17, 1, 7, 2, 3,18,-2, 3, 6, 4, 2, 7, 8, 5, 3,17} }, // 186 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 187 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 188 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 189 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 190 - { 0, 1, {17,18, 3,18, 2, 5, 4, 7,-3, 6, 3, 2,18, 4, 7, 3} }, // 191 - { 1, 1, { 1, 7, 4, 5, 3, 4, 5, 1, 3, 6, 3, 2, 4, 8,-2, 7} }, // 192 - { 0, 1, { 1,18,-1,-2,18, 3, 2,-1, 6, 7, 4, 5, 3,18, 2,-3} }, // 193 - { 1, 1, {18,18,-1, 3, 6,18, 5, 4, 8, 2, 3, 6,18, 7, 4,-2} }, // 194 - { 0, 2, {18,18, 2, 6,18, 2,18, 5, 3,18, 2, 4, 7, 8, 3,18} }, // 195 - { 1, 1, { 3,18,18, 5,18, 6, 2, 4, 7,-2,18, 5, 8, 6, 3, 2} }, // 196 - { 0, 1, {18,-2, 7, 1, 3, 2,-3, 4, 6,-2, 7, 8, 1, 5, 4, 3} }, // 197 - { 1, 1, {18,-2,18, 2, 5,18, 3,-2, 4, 7, 2,-1, 8, 6, 5, 1} }, // 198 - { 1, 1, {17,17, 5,18, 4, 1, 2, 8, 6, 4,-2, 3, 5,-1, 1, 8} }, // 199 - { 0, 2, { 1, 2,17, 3, 7,18, 2,-1, 4, 5,18, 2, 7, 3, 6, 8} }, // 200 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 201 - { 1, 1, { 3, 6,17, 8, 7, 5,18,-1, 1, 2, 3, 4, 2, 6, 8, 1} }, // 202 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 203 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 204 - { 0, 2, {18,18,18, 2,-2, 3, 6, 4, 8,18, 2, 5, 7, 4, 3, 6} }, // 205 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 206 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 207 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 208 - { 1, 1, {18, 1, 8, 3, 5, 6, 4,-1, 8, 3, 7,18, 2, 5, 8, 4} }, // 209 - { 1, 1, {17,18, 5, 2, 4, 3, 1, 6,-2, 1, 3, 2, 4, 5,-1,17} }, // 210 - { 1, 1, {18,17, 2,18, 3,-3, 7, 2, 6, 4, 3, 5,18, 8, 2,-2} }, // 211 - { 1, 1, {18,17,18, 4, 3, 5,-1,18, 2, 7, 8, 4, 6, 3,18, 5} }, // 212 - { 0, 1, {18,17,18,-2, 2,-3, 3, 4, 8, 5, 2,18, 6, 3, 7,-2} }, // 213 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 214 - { 1, 1, {17,18, 8, 3, 4, 6,18, 5,-2, 3, 8, 5, 2, 4, 7, 6} }, // 215 - { 0, 1, {18,-2, 3, 5, 1, 7, 3, 2, 6,-3, 4, 1, 5, 8, 3,-2} }, // 216 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 217 - { 1, 1, { 3,17,18, 5,-1,18, 2, 6, 7,18, 5, 3,-3,-1, 6, 2} }, // 218 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 219 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 220 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 221 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 222 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 223 - { 1, 3, {18,17,-2, 3,-1,18, 2, 5, 3, 7, 6, 2, 4, 8,18, 5} }, // 224 - { 0, 1, {18,-1,18, 2,18, 3, 5,18, 2, 8,18, 5, 4,-1, 6, 2} }, // 225 - { 1, 2, {18,-2,18,18, 2, 3, 4,-3, 2, 5,18, 7, 4, 3, 8, 6} }, // 226 - { 0, 2, {17,-1,18, 2,-1, 1, 7, 3, 8, 5,-2, 4, 1, 2,-3, 6} }, // 227 - { 0, 1, {18,17, 2,18, 2,18, 6, 7, 4, 3,18, 5, 2,-2,17, 8} }, // 228 - { 0, 3, {18,17, 2, 3,-3,-1,18, 2, 4, 5,18, 7, 3, 2,-3, 6} }, // 229 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 230 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 231 - { 0, 2, { 3,18,18,18, 2, 6, 5,18, 7, 2, 4, 6,18, 5, 3, 8} }, // 232 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 233 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 234 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 235 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 236 - { 0, 1, {18,18, 3, 6, 3,-2, 2,18, 5,-1, 7, 3, 4,-2, 2, 6} }, // 237 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 238 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 239 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 240 - { 1, 1, {18,17,18,18,-2, 2, 3,-3,18, 6, 4, 2,-2, 8, 3, 7} }, // 241 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 242 - { 0, 1, {18,18,18, 4, 2, 7, 8,18, 3, 2,-2, 4, 7, 6,17, 5} }, // 243 - { 1, 1, {18,18,-1,-2, 8, 3,18, 6, 3, 5, 8, 2, 4, 7, 1, 6} }, // 244 - { 1, 1, { 1,-3, 3,18,18, 2,-1, 3, 6, 5,18, 4, 7,-2, 8, 3} }, // 245 - { 1, 1, { 1,18, 4, 2, 5,18, 1, 3,-1, 6, 1, 4, 8, 2, 5, 1} }, // 246 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 247 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 248 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 249 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 250 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 251 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 252 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 253 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 254 - { 0, 1, {-1,18,18, 2,18, 3, 5,18, 2,18, 6, 8, 4, 5, 7,-1} }, // 255 -}; - -#define NUM_FAST_SPECS (sizeof (fast_specs) / sizeof (fast_specs [0])) -#define NUM_DEFAULT_SPECS (sizeof (default_specs) / sizeof (default_specs [0])) -#define NUM_HIGH_SPECS (sizeof (high_specs) / sizeof (high_specs [0])) -#define NUM_VERY_HIGH_SPECS (sizeof (very_high_specs) / sizeof (very_high_specs [0])) diff --git a/Frameworks/WavPack/Files/decorr_utils.c b/Frameworks/WavPack/Files/decorr_utils.c deleted file mode 100644 index a76b14ccf..000000000 --- a/Frameworks/WavPack/Files/decorr_utils.c +++ /dev/null @@ -1,204 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// decorr_utils.c - -// This module contains the functions that process metadata blocks that are -// specific to the decorrelator. These would be called any time a WavPack -// block was parsed. These are in a module separate from the actual unpack -// decorrelation code (unpack.c) so that if an application just wants to get -// information from WavPack files (rather than actually decoding audio) then -// less code needs to be linked. - -#include -#include - -#include "wavpack_local.h" - -///////////////////////////// executable code //////////////////////////////// - -// Read decorrelation terms from specified metadata block into the -// decorr_passes array. The terms range from -3 to 8, plus 17 & 18; -// other values are reserved and generate errors for now. The delta -// ranges from 0 to 7 with all values valid. Note that the terms are -// stored in the opposite order in the decorr_passes array compared -// to packing. - -int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd) -{ - int termcnt = wpmd->byte_length; - unsigned char *byteptr = (unsigned char *)wpmd->data; - struct decorr_pass *dpp; - - if (termcnt > MAX_NTERMS) - return FALSE; - - wps->num_terms = termcnt; - - for (dpp = wps->decorr_passes + termcnt - 1; termcnt--; dpp--) { - dpp->term = (int)(*byteptr & 0x1f) - 5; - dpp->delta = (*byteptr++ >> 5) & 0x7; - - if (!dpp->term || dpp->term < -3 || (dpp->term > MAX_TERM && dpp->term < 17) || dpp->term > 18 || - ((wps->wphdr.flags & MONO_DATA) && dpp->term < 0)) - return FALSE; - } - - return TRUE; -} - -// Read decorrelation weights from specified metadata block into the -// decorr_passes array. The weights range +/-1024, but are rounded and -// truncated to fit in signed chars for metadata storage. Weights are -// separate for the two channels and are specified from the "last" term -// (first during encode). Unspecified weights are set to zero. - -int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd) -{ - int termcnt = wpmd->byte_length, tcount; - char *byteptr = (char *)wpmd->data; - struct decorr_pass *dpp; - - if (!(wps->wphdr.flags & MONO_DATA)) - termcnt /= 2; - - if (termcnt > wps->num_terms) - return FALSE; - - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) - dpp->weight_A = dpp->weight_B = 0; - - while (--dpp >= wps->decorr_passes && termcnt--) { - dpp->weight_A = restore_weight (*byteptr++); - - if (!(wps->wphdr.flags & MONO_DATA)) - dpp->weight_B = restore_weight (*byteptr++); - } - - return TRUE; -} - -// Read decorrelation samples from specified metadata block into the -// decorr_passes array. The samples are signed 32-bit values, but are -// converted to signed log2 values for storage in metadata. Values are -// stored for both channels and are specified from the "last" term -// (first during encode) with unspecified samples set to zero. The -// number of samples stored varies with the actual term value, so -// those must obviously come first in the metadata. - -int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd) -{ - unsigned char *byteptr = (unsigned char *)wpmd->data; - unsigned char *endptr = byteptr + wpmd->byte_length; - struct decorr_pass *dpp; - int tcount; - - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - CLEAR (dpp->samples_A); - CLEAR (dpp->samples_B); - } - - if (wps->wphdr.version == 0x402 && (wps->wphdr.flags & HYBRID_FLAG)) { - if (byteptr + (wps->wphdr.flags & MONO_DATA ? 2 : 4) > endptr) - return FALSE; - - wps->dc.error [0] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - byteptr += 2; - - if (!(wps->wphdr.flags & MONO_DATA)) { - wps->dc.error [1] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - byteptr += 2; - } - } - - while (dpp-- > wps->decorr_passes && byteptr < endptr) - if (dpp->term > MAX_TERM) { - if (byteptr + (wps->wphdr.flags & MONO_DATA ? 4 : 8) > endptr) - return FALSE; - - dpp->samples_A [0] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - dpp->samples_A [1] = wp_exp2s ((int16_t)(byteptr [2] + (byteptr [3] << 8))); - byteptr += 4; - - if (!(wps->wphdr.flags & MONO_DATA)) { - dpp->samples_B [0] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - dpp->samples_B [1] = wp_exp2s ((int16_t)(byteptr [2] + (byteptr [3] << 8))); - byteptr += 4; - } - } - else if (dpp->term < 0) { - if (byteptr + 4 > endptr) - return FALSE; - - dpp->samples_A [0] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - dpp->samples_B [0] = wp_exp2s ((int16_t)(byteptr [2] + (byteptr [3] << 8))); - byteptr += 4; - } - else { - int m = 0, cnt = dpp->term; - - while (cnt--) { - if (byteptr + (wps->wphdr.flags & MONO_DATA ? 2 : 4) > endptr) - return FALSE; - - dpp->samples_A [m] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - byteptr += 2; - - if (!(wps->wphdr.flags & MONO_DATA)) { - dpp->samples_B [m] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - byteptr += 2; - } - - m++; - } - } - - return byteptr == endptr; -} - -// Read the shaping weights from specified metadata block into the -// WavpackStream structure. Note that there must be two values (even -// for mono streams) and that the values are stored in the same -// manner as decorrelation weights. These would normally be read from -// the "correction" file and are used for lossless reconstruction of -// hybrid data. - -int read_shaping_info (WavpackStream *wps, WavpackMetadata *wpmd) -{ - if (wpmd->byte_length == 2) { - char *byteptr = (char *)wpmd->data; - - wps->dc.shaping_acc [0] = (int32_t) restore_weight (*byteptr++) << 16; - wps->dc.shaping_acc [1] = (int32_t) restore_weight (*byteptr++) << 16; - return TRUE; - } - else if (wpmd->byte_length >= (wps->wphdr.flags & MONO_DATA ? 4 : 8)) { - unsigned char *byteptr = (unsigned char *)wpmd->data; - - wps->dc.error [0] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - wps->dc.shaping_acc [0] = wp_exp2s ((int16_t)(byteptr [2] + (byteptr [3] << 8))); - byteptr += 4; - - if (!(wps->wphdr.flags & MONO_DATA)) { - wps->dc.error [1] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - wps->dc.shaping_acc [1] = wp_exp2s ((int16_t)(byteptr [2] + (byteptr [3] << 8))); - byteptr += 4; - } - - if (wpmd->byte_length == (wps->wphdr.flags & MONO_DATA ? 6 : 12)) { - wps->dc.shaping_delta [0] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - - if (!(wps->wphdr.flags & MONO_DATA)) - wps->dc.shaping_delta [1] = wp_exp2s ((int16_t)(byteptr [2] + (byteptr [3] << 8))); - } - - return TRUE; - } - - return FALSE; -} diff --git a/Frameworks/WavPack/Files/entropy_utils.c b/Frameworks/WavPack/Files/entropy_utils.c deleted file mode 100644 index 3ce91d410..000000000 --- a/Frameworks/WavPack/Files/entropy_utils.c +++ /dev/null @@ -1,378 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// entropy_utils.c - -// This module contains the functions that process metadata blocks that are -// specific to the entropy decoder; these would be called any time a WavPack -// block was parsed. Additionally, it contains tables and functions that are -// common to both entropy coding and decoding. These are in a module separate -// from the actual entropy encoder (write_words.c) and decoder (read_words.c) -// so that if applications that just do a subset of the full WavPack reading -// and writing can link with a subset of the library. - -#include -#include - -#include "wavpack_local.h" - -///////////////////////////// local table storage //////////////////////////// - -const uint32_t bitset [] = { - 1L << 0, 1L << 1, 1L << 2, 1L << 3, - 1L << 4, 1L << 5, 1L << 6, 1L << 7, - 1L << 8, 1L << 9, 1L << 10, 1L << 11, - 1L << 12, 1L << 13, 1L << 14, 1L << 15, - 1L << 16, 1L << 17, 1L << 18, 1L << 19, - 1L << 20, 1L << 21, 1L << 22, 1L << 23, - 1L << 24, 1L << 25, 1L << 26, 1L << 27, - 1L << 28, 1L << 29, 1L << 30, 1L << 31 -}; - -const uint32_t bitmask [] = { - (1L << 0) - 1, (1L << 1) - 1, (1L << 2) - 1, (1L << 3) - 1, - (1L << 4) - 1, (1L << 5) - 1, (1L << 6) - 1, (1L << 7) - 1, - (1L << 8) - 1, (1L << 9) - 1, (1L << 10) - 1, (1L << 11) - 1, - (1L << 12) - 1, (1L << 13) - 1, (1L << 14) - 1, (1L << 15) - 1, - (1L << 16) - 1, (1L << 17) - 1, (1L << 18) - 1, (1L << 19) - 1, - (1L << 20) - 1, (1L << 21) - 1, (1L << 22) - 1, (1L << 23) - 1, - (1L << 24) - 1, (1L << 25) - 1, (1L << 26) - 1, (1L << 27) - 1, - (1L << 28) - 1, (1L << 29) - 1, (1L << 30) - 1, 0x7fffffff -}; - -const char nbits_table [] = { - 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, // 0 - 15 - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, // 16 - 31 - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 32 - 47 - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 48 - 63 - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 64 - 79 - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 80 - 95 - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 96 - 111 - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 112 - 127 - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 128 - 143 - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 144 - 159 - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 160 - 175 - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 176 - 191 - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 192 - 207 - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 208 - 223 - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, // 224 - 239 - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 // 240 - 255 -}; - -static const unsigned char log2_table [] = { - 0x00, 0x01, 0x03, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, 0x15, - 0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, - 0x2c, 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e, - 0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x51, - 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, - 0x64, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x75, - 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, - 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, - 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, - 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb2, - 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc0, - 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcb, 0xcc, 0xcd, 0xce, - 0xcf, 0xd0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd8, 0xd9, 0xda, 0xdb, - 0xdc, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe4, 0xe5, 0xe6, 0xe7, 0xe7, - 0xe8, 0xe9, 0xea, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xee, 0xef, 0xf0, 0xf1, 0xf1, 0xf2, 0xf3, 0xf4, - 0xf4, 0xf5, 0xf6, 0xf7, 0xf7, 0xf8, 0xf9, 0xf9, 0xfa, 0xfb, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff -}; - -static const unsigned char exp2_table [] = { - 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b, - 0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16, - 0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d, - 0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b, - 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, - 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, - 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, - 0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, - 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, - 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4, - 0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9, - 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff -}; - -///////////////////////////// executable code //////////////////////////////// - -// Read the median log2 values from the specified metadata structure, convert -// them back to 32-bit unsigned values and store them. If length is not -// exactly correct then we flag and return an error. - -int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd) -{ - unsigned char *byteptr = (unsigned char *)wpmd->data; - - if (wpmd->byte_length != ((wps->wphdr.flags & MONO_DATA) ? 6 : 12)) - return FALSE; - - wps->w.c [0].median [0] = wp_exp2s (byteptr [0] + (byteptr [1] << 8)); - wps->w.c [0].median [1] = wp_exp2s (byteptr [2] + (byteptr [3] << 8)); - wps->w.c [0].median [2] = wp_exp2s (byteptr [4] + (byteptr [5] << 8)); - - if (!(wps->wphdr.flags & MONO_DATA)) { - wps->w.c [1].median [0] = wp_exp2s (byteptr [6] + (byteptr [7] << 8)); - wps->w.c [1].median [1] = wp_exp2s (byteptr [8] + (byteptr [9] << 8)); - wps->w.c [1].median [2] = wp_exp2s (byteptr [10] + (byteptr [11] << 8)); - } - - return TRUE; -} - -// Read the hybrid related values from the specified metadata structure, convert -// them back to their internal formats and store them. The extended profile -// stuff is not implemented yet, so return an error if we get more data than -// we know what to do with. - -int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd) -{ - unsigned char *byteptr = (unsigned char *)wpmd->data; - unsigned char *endptr = byteptr + wpmd->byte_length; - - if (wps->wphdr.flags & HYBRID_BITRATE) { - if (byteptr + (wps->wphdr.flags & MONO_DATA ? 2 : 4) > endptr) - return FALSE; - - wps->w.c [0].slow_level = wp_exp2s (byteptr [0] + (byteptr [1] << 8)); - byteptr += 2; - - if (!(wps->wphdr.flags & MONO_DATA)) { - wps->w.c [1].slow_level = wp_exp2s (byteptr [0] + (byteptr [1] << 8)); - byteptr += 2; - } - } - - if (byteptr + (wps->wphdr.flags & MONO_DATA ? 2 : 4) > endptr) - return FALSE; - - wps->w.bitrate_acc [0] = (int32_t)(byteptr [0] + (byteptr [1] << 8)) << 16; - byteptr += 2; - - if (!(wps->wphdr.flags & MONO_DATA)) { - wps->w.bitrate_acc [1] = (int32_t)(byteptr [0] + (byteptr [1] << 8)) << 16; - byteptr += 2; - } - - if (byteptr < endptr) { - if (byteptr + (wps->wphdr.flags & MONO_DATA ? 2 : 4) > endptr) - return FALSE; - - wps->w.bitrate_delta [0] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - byteptr += 2; - - if (!(wps->wphdr.flags & MONO_DATA)) { - wps->w.bitrate_delta [1] = wp_exp2s ((int16_t)(byteptr [0] + (byteptr [1] << 8))); - byteptr += 2; - } - - if (byteptr < endptr) - return FALSE; - } - else - wps->w.bitrate_delta [0] = wps->w.bitrate_delta [1] = 0; - - return TRUE; -} - -// This function is called during both encoding and decoding of hybrid data to -// update the "error_limit" variable which determines the maximum sample error -// allowed in the main bitstream. In the HYBRID_BITRATE mode (which is the only -// currently implemented) this is calculated from the slow_level values and the -// bitrate accumulators. Note that the bitrate accumulators can be changing. - -void update_error_limit (WavpackStream *wps) -{ - int bitrate_0 = (wps->w.bitrate_acc [0] += wps->w.bitrate_delta [0]) >> 16; - - if (wps->wphdr.flags & MONO_DATA) { - if (wps->wphdr.flags & HYBRID_BITRATE) { - int slow_log_0 = (wps->w.c [0].slow_level + SLO) >> SLS; - - if (slow_log_0 - bitrate_0 > -0x100) - wps->w.c [0].error_limit = wp_exp2s (slow_log_0 - bitrate_0 + 0x100); - else - wps->w.c [0].error_limit = 0; - } - else - wps->w.c [0].error_limit = wp_exp2s (bitrate_0); - } - else { - int bitrate_1 = (wps->w.bitrate_acc [1] += wps->w.bitrate_delta [1]) >> 16; - - if (wps->wphdr.flags & HYBRID_BITRATE) { - int slow_log_0 = (wps->w.c [0].slow_level + SLO) >> SLS; - int slow_log_1 = (wps->w.c [1].slow_level + SLO) >> SLS; - - if (wps->wphdr.flags & HYBRID_BALANCE) { - int balance = (slow_log_1 - slow_log_0 + bitrate_1 + 1) >> 1; - - if (balance > bitrate_0) { - bitrate_1 = bitrate_0 * 2; - bitrate_0 = 0; - } - else if (-balance > bitrate_0) { - bitrate_0 = bitrate_0 * 2; - bitrate_1 = 0; - } - else { - bitrate_1 = bitrate_0 + balance; - bitrate_0 = bitrate_0 - balance; - } - } - - if (slow_log_0 - bitrate_0 > -0x100) - wps->w.c [0].error_limit = wp_exp2s (slow_log_0 - bitrate_0 + 0x100); - else - wps->w.c [0].error_limit = 0; - - if (slow_log_1 - bitrate_1 > -0x100) - wps->w.c [1].error_limit = wp_exp2s (slow_log_1 - bitrate_1 + 0x100); - else - wps->w.c [1].error_limit = 0; - } - else { - wps->w.c [0].error_limit = wp_exp2s (bitrate_0); - wps->w.c [1].error_limit = wp_exp2s (bitrate_1); - } - } -} - -// The concept of a base 2 logarithm is used in many parts of WavPack. It is -// a way of sufficiently accurately representing 32-bit signed and unsigned -// values storing only 16 bits (actually fewer). It is also used in the hybrid -// mode for quickly comparing the relative magnitude of large values (i.e. -// division) and providing smooth exponentials using only addition. - -// These are not strict logarithms in that they become linear around zero and -// can therefore represent both zero and negative values. They have 8 bits -// of precision and in "roundtrip" conversions the total error never exceeds 1 -// part in 225 except for the cases of +/-115 and +/-195 (which error by 1). - - -// This function returns the log2 for the specified 32-bit unsigned value. -// The maximum value allowed is about 0xff800000 and returns 8447. - -int FASTCALL wp_log2 (uint32_t avalue) -{ - int dbits; - - if ((avalue += avalue >> 9) < (1 << 8)) { - dbits = nbits_table [avalue]; - return (dbits << 8) + log2_table [(avalue << (9 - dbits)) & 0xff]; - } - else { - if (avalue < (1L << 16)) - dbits = nbits_table [avalue >> 8] + 8; - else if (avalue < (1L << 24)) - dbits = nbits_table [avalue >> 16] + 16; - else - dbits = nbits_table [avalue >> 24] + 24; - - return (dbits << 8) + log2_table [(avalue >> (dbits - 9)) & 0xff]; - } -} - -// This function scans a buffer of longs and accumulates the total log2 value -// of all the samples. This is useful for determining maximum compression -// because the bitstream storage required for entropy coding is proportional -// to the base 2 log of the samples. On some platforms there is an assembly -// version of this. - -#if !defined(OPT_ASM_X86) && !defined(OPT_ASM_X64) - -uint32_t log2buffer (int32_t *samples, uint32_t num_samples, int limit) -{ - uint32_t result = 0, avalue; - int dbits; - - while (num_samples--) { - avalue = abs (*samples++); - - if ((avalue += avalue >> 9) < (1 << 8)) { - dbits = nbits_table [avalue]; - result += (dbits << 8) + log2_table [(avalue << (9 - dbits)) & 0xff]; - } - else { - if (avalue < (1L << 16)) - dbits = nbits_table [avalue >> 8] + 8; - else if (avalue < (1L << 24)) - dbits = nbits_table [avalue >> 16] + 16; - else - dbits = nbits_table [avalue >> 24] + 24; - - result += dbits = (dbits << 8) + log2_table [(avalue >> (dbits - 9)) & 0xff]; - - if (limit && dbits >= limit) - return (uint32_t) -1; - } - } - - return result; -} - -#endif - -// This function returns the log2 for the specified 32-bit signed value. -// All input values are valid and the return values are in the range of -// +/- 8192. - -int wp_log2s (int32_t value) -{ - return (value < 0) ? -wp_log2 (-value) : wp_log2 (value); -} - -// This function returns the original integer represented by the supplied -// logarithm (at least within the provided accuracy). The log is signed, -// but since a full 32-bit value is returned this can be used for unsigned -// conversions as well (i.e. the input range is -8192 to +8447). - -int32_t wp_exp2s (int log) -{ - uint32_t value; - - if (log < 0) - return -wp_exp2s (-log); - - value = exp2_table [log & 0xff] | 0x100; - - if ((log >>= 8) <= 9) - return value >> (9 - log); - else - return value << (log - 9); -} - -// These two functions convert internal weights (which are normally +/-1024) -// to and from an 8-bit signed character version for storage in metadata. The -// weights are clipped here in the case that they are outside that range. - -signed char store_weight (int weight) -{ - if (weight > 1024) - weight = 1024; - else if (weight < -1024) - weight = -1024; - - if (weight > 0) - weight -= (weight + 64) >> 7; - - return (weight + 4) >> 3; -} - -int restore_weight (signed char weight) -{ - int result; - - if ((result = (int) weight << 3) > 0) - result += (result + 64) >> 7; - - return result; -} diff --git a/Frameworks/WavPack/Files/extra1.c b/Frameworks/WavPack/Files/extra1.c deleted file mode 100644 index 39e61d5c2..000000000 --- a/Frameworks/WavPack/Files/extra1.c +++ /dev/null @@ -1,704 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// extra1.c - -// This module handles the "extra" mode for mono files. - -#include -#include -#include -#include - -#include "wavpack_local.h" - -// This flag causes this module to take into account the size of the header -// (which grows with more decorrelation passes) when making decisions about -// adding additional passes (as opposed to just considering the resulting -// magnitude of the residuals). With really long blocks it seems to actually -// hurt compression (for reasons I cannot explain), but with short blocks it -// works okay, so we're enabling it for now. - -#define USE_OVERHEAD - -// If the log2 value of any sample in a buffer being scanned exceeds this value, -// we abandon that configuration. This prevents us from going down paths that -// are wildly unstable. - -#define LOG_LIMIT 6912 - -//#define EXTRA_DUMP // dump generated filter data error_line() - -#ifdef OPT_ASM_X86 - #define PACK_DECORR_MONO_PASS_CONT pack_decorr_mono_pass_cont_x86 -#elif defined(OPT_ASM_X64) && (defined (_WIN64) || defined(__CYGWIN__) || defined(__MINGW64__) || defined(__midipix__)) - #define PACK_DECORR_MONO_PASS_CONT pack_decorr_mono_pass_cont_x64win -#elif defined(OPT_ASM_X64) - #define PACK_DECORR_MONO_PASS_CONT pack_decorr_mono_pass_cont_x64 -#endif - -#ifdef PACK_DECORR_MONO_PASS_CONT - void PACK_DECORR_MONO_PASS_CONT (int32_t *out_buffer, int32_t *in_buffer, struct decorr_pass *dpp, int32_t sample_count); -#endif - -typedef struct { - int32_t *sampleptrs [MAX_NTERMS+2]; - struct decorr_pass dps [MAX_NTERMS]; - int nterms, log_limit; - uint32_t best_bits; -} WavpackExtraInfo; - -static void decorr_mono_pass (int32_t *in_samples, int32_t *out_samples, uint32_t num_samples, struct decorr_pass *dpp, int dir) -{ - int32_t cont_samples = 0; - int m = 0, i; - -#ifdef PACK_DECORR_MONO_PASS_CONT - if (num_samples > 16 && dir > 0) { - int32_t pre_samples = (dpp->term > MAX_TERM) ? 2 : dpp->term; - cont_samples = num_samples - pre_samples; - num_samples = pre_samples; - } -#endif - - dpp->sum_A = 0; - - if (dir < 0) { - out_samples += (num_samples + cont_samples - 1); - in_samples += (num_samples + cont_samples - 1); - dir = -1; - } - else - dir = 1; - - dpp->weight_A = restore_weight (store_weight (dpp->weight_A)); - - for (i = 0; i < 8; ++i) - dpp->samples_A [i] = wp_exp2s (wp_log2s (dpp->samples_A [i])); - - if (dpp->term > MAX_TERM) { - while (num_samples--) { - int32_t left, sam_A; - - if (dpp->term & 1) - sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - else - sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - - dpp->samples_A [1] = dpp->samples_A [0]; - dpp->samples_A [0] = left = in_samples [0]; - - left -= apply_weight (dpp->weight_A, sam_A); - update_weight (dpp->weight_A, dpp->delta, sam_A, left); - dpp->sum_A += dpp->weight_A; - out_samples [0] = left; - in_samples += dir; - out_samples += dir; - } - } - else if (dpp->term > 0) { - while (num_samples--) { - int k = (m + dpp->term) & (MAX_TERM - 1); - int32_t left, sam_A; - - sam_A = dpp->samples_A [m]; - dpp->samples_A [k] = left = in_samples [0]; - m = (m + 1) & (MAX_TERM - 1); - - left -= apply_weight (dpp->weight_A, sam_A); - update_weight (dpp->weight_A, dpp->delta, sam_A, left); - dpp->sum_A += dpp->weight_A; - out_samples [0] = left; - in_samples += dir; - out_samples += dir; - } - } - - if (m && dpp->term > 0 && dpp->term <= MAX_TERM) { - int32_t temp_A [MAX_TERM]; - int k; - - memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A)); - - for (k = 0; k < MAX_TERM; k++) { - dpp->samples_A [k] = temp_A [m]; - m = (m + 1) & (MAX_TERM - 1); - } - } - -#ifdef PACK_DECORR_MONO_PASS_CONT - if (cont_samples) - PACK_DECORR_MONO_PASS_CONT (out_samples, in_samples, dpp, cont_samples); -#endif -} - -static void reverse_mono_decorr (struct decorr_pass *dpp) -{ - if (dpp->term > MAX_TERM) { - int32_t sam_A; - - if (dpp->term & 1) - sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - else - sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - - dpp->samples_A [1] = dpp->samples_A [0]; - dpp->samples_A [0] = sam_A; - - if (dpp->term & 1) - sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - else - sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - - dpp->samples_A [1] = sam_A; - } - else if (dpp->term > 1) { - int i = 0, j = dpp->term - 1, cnt = dpp->term / 2; - - while (cnt--) { - i &= (MAX_TERM - 1); - j &= (MAX_TERM - 1); - dpp->samples_A [i] ^= dpp->samples_A [j]; - dpp->samples_A [j] ^= dpp->samples_A [i]; - dpp->samples_A [i++] ^= dpp->samples_A [j--]; - } - -// CLEAR (dpp->samples_A); - } -} - -static void decorr_mono_buffer (int32_t *samples, int32_t *outsamples, uint32_t num_samples, struct decorr_pass *dpp, int tindex) -{ - struct decorr_pass dp, *dppi = dpp + tindex; - int delta = dppi->delta, pre_delta, term = dppi->term; - - if (delta == 7) - pre_delta = 7; - else if (delta < 2) - pre_delta = 3; - else - pre_delta = delta + 1; - - CLEAR (dp); - dp.term = term; - dp.delta = pre_delta; - decorr_mono_pass (samples, outsamples, num_samples > 2048 ? 2048 : num_samples, &dp, -1); - dp.delta = delta; - - if (tindex == 0) - reverse_mono_decorr (&dp); - else - CLEAR (dp.samples_A); - - memcpy (dppi->samples_A, dp.samples_A, sizeof (dp.samples_A)); - dppi->weight_A = dp.weight_A; - - if (delta == 0) { - dp.delta = 1; - decorr_mono_pass (samples, outsamples, num_samples, &dp, 1); - dp.delta = 0; - memcpy (dp.samples_A, dppi->samples_A, sizeof (dp.samples_A)); - dppi->weight_A = dp.weight_A = dp.sum_A / num_samples; - } - -// if (memcmp (dppi, &dp, sizeof (dp))) -// error_line ("decorr_passes don't match, delta = %d", delta); - - decorr_mono_pass (samples, outsamples, num_samples, &dp, 1); -} - -static int log2overhead (int first_term, int num_terms) -{ -#ifdef USE_OVERHEAD - if (first_term > MAX_TERM) - return (4 + num_terms * 2) << 11; - else - return (2 + num_terms * 2) << 11; -#else - return 0; -#endif -} - -static void recurse_mono (WavpackContext *wpc, WavpackExtraInfo *info, int depth, int delta, uint32_t input_bits) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int term, branches = ((wpc->config.extra_flags & EXTRA_BRANCHES) >> 6) - depth; - int32_t *samples, *outsamples; - uint32_t term_bits [22], bits; - - if (branches < 1 || depth + 1 == info->nterms) - branches = 1; - - CLEAR (term_bits); - samples = info->sampleptrs [depth]; - outsamples = info->sampleptrs [depth + 1]; - - for (term = 1; term <= 18; ++term) { - if (term == 17 && branches == 1 && depth + 1 < info->nterms) - continue; - - if (term > 8 && term < 17) - continue; - - if ((wpc->config.flags & CONFIG_FAST_FLAG) && (term > 4 && term < 17)) - continue; - - info->dps [depth].term = term; - info->dps [depth].delta = delta; - decorr_mono_buffer (samples, outsamples, wps->wphdr.block_samples, info->dps, depth); - bits = LOG2BUFFER (outsamples, wps->wphdr.block_samples, info->log_limit); - - if (bits != (uint32_t) -1) - bits += log2overhead (info->dps [0].term, depth + 1); - - if (bits < info->best_bits) { - info->best_bits = bits; - CLEAR (wps->decorr_passes); - memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * (depth + 1)); - memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [depth + 1], wps->wphdr.block_samples * 4); - } - - term_bits [term + 3] = bits; - } - - while (depth + 1 < info->nterms && branches--) { - uint32_t local_best_bits = input_bits; - int best_term = 0, i; - - for (i = 0; i < 22; ++i) - if (term_bits [i] && term_bits [i] < local_best_bits) { - local_best_bits = term_bits [i]; -// term_bits [i] = 0; - best_term = i - 3; - } - - if (!best_term) - break; - - term_bits [best_term + 3] = 0; - - info->dps [depth].term = best_term; - info->dps [depth].delta = delta; - decorr_mono_buffer (samples, outsamples, wps->wphdr.block_samples, info->dps, depth); - -// if (log2buffer (outsamples, wps->wphdr.block_samples * 2, 0) != local_best_bits) -// error_line ("data doesn't match!"); - - recurse_mono (wpc, info, depth + 1, delta, local_best_bits); - } -} - -static void delta_mono (WavpackContext *wpc, WavpackExtraInfo *info) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int lower = FALSE, delta, d; - uint32_t bits; - - if (wps->decorr_passes [0].term) - delta = wps->decorr_passes [0].delta; - else - return; - - for (d = delta - 1; d >= 0; --d) { - int i; - - if (!d && (wps->wphdr.flags & HYBRID_FLAG)) - break; - - for (i = 0; i < info->nterms && wps->decorr_passes [i].term; ++i) { - info->dps [i].term = wps->decorr_passes [i].term; - info->dps [i].delta = d; - decorr_mono_buffer (info->sampleptrs [i], info->sampleptrs [i+1], wps->wphdr.block_samples, info->dps, i); - } - - bits = LOG2BUFFER (info->sampleptrs [i], wps->wphdr.block_samples, info->log_limit); - - if (bits != (uint32_t) -1) - bits += log2overhead (wps->decorr_passes [0].term, i); - - if (bits < info->best_bits) { - lower = TRUE; - info->best_bits = bits; - CLEAR (wps->decorr_passes); - memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * i); - memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [i], wps->wphdr.block_samples * 4); - } - else - break; - } - - for (d = delta + 1; !lower && d <= 7; ++d) { - int i; - - for (i = 0; i < info->nterms && wps->decorr_passes [i].term; ++i) { - info->dps [i].term = wps->decorr_passes [i].term; - info->dps [i].delta = d; - decorr_mono_buffer (info->sampleptrs [i], info->sampleptrs [i+1], wps->wphdr.block_samples, info->dps, i); - } - - bits = LOG2BUFFER (info->sampleptrs [i], wps->wphdr.block_samples, info->log_limit); - - if (bits != (uint32_t) -1) - bits += log2overhead (wps->decorr_passes [0].term, i); - - if (bits < info->best_bits) { - info->best_bits = bits; - CLEAR (wps->decorr_passes); - memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * i); - memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [i], wps->wphdr.block_samples * 4); - } - else - break; - } -} - -static void sort_mono (WavpackContext *wpc, WavpackExtraInfo *info) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int reversed = TRUE; - uint32_t bits; - - while (reversed) { - int ri, i; - - memcpy (info->dps, wps->decorr_passes, sizeof (wps->decorr_passes)); - reversed = FALSE; - - for (ri = 0; ri < info->nterms && wps->decorr_passes [ri].term; ++ri) { - - if (ri + 1 >= info->nterms || !wps->decorr_passes [ri+1].term) - break; - - if (wps->decorr_passes [ri].term == wps->decorr_passes [ri+1].term) { - decorr_mono_buffer (info->sampleptrs [ri], info->sampleptrs [ri+1], wps->wphdr.block_samples, info->dps, ri); - continue; - } - - info->dps [ri] = wps->decorr_passes [ri+1]; - info->dps [ri+1] = wps->decorr_passes [ri]; - - for (i = ri; i < info->nterms && wps->decorr_passes [i].term; ++i) - decorr_mono_buffer (info->sampleptrs [i], info->sampleptrs [i+1], wps->wphdr.block_samples, info->dps, i); - - bits = LOG2BUFFER (info->sampleptrs [i], wps->wphdr.block_samples, info->log_limit); - - if (bits != (uint32_t) -1) - bits += log2overhead (wps->decorr_passes [0].term, i); - - if (bits < info->best_bits) { - reversed = TRUE; - info->best_bits = bits; - CLEAR (wps->decorr_passes); - memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * i); - memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [i], wps->wphdr.block_samples * 4); - } - else { - info->dps [ri] = wps->decorr_passes [ri]; - info->dps [ri+1] = wps->decorr_passes [ri+1]; - decorr_mono_buffer (info->sampleptrs [ri], info->sampleptrs [ri+1], wps->wphdr.block_samples, info->dps, ri); - } - } - } -} - -static const uint32_t xtable [] = { 91, 123, 187, 251 }; - -static void analyze_mono (WavpackContext *wpc, int32_t *samples, int do_samples) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - WavpackExtraInfo info; - int i; - -#ifdef LOG_LIMIT - info.log_limit = (((wps->wphdr.flags & MAG_MASK) >> MAG_LSB) + 4) * 256; - - if (info.log_limit > LOG_LIMIT) - info.log_limit = LOG_LIMIT; -#else - info.log_limit = 0; -#endif - - if (wpc->config.flags & (CONFIG_HIGH_FLAG | CONFIG_VERY_HIGH_FLAG)) - wpc->config.extra_flags = xtable [wpc->config.xmode - 4]; - else - wpc->config.extra_flags = xtable [wpc->config.xmode - 3]; - - info.nterms = wps->num_terms; - - for (i = 0; i < info.nterms + 2; ++i) - info.sampleptrs [i] = malloc (wps->wphdr.block_samples * 4); - - memcpy (info.dps, wps->decorr_passes, sizeof (info.dps)); - memcpy (info.sampleptrs [0], samples, wps->wphdr.block_samples * 4); - - for (i = 0; i < info.nterms && info.dps [i].term; ++i) - decorr_mono_pass (info.sampleptrs [i], info.sampleptrs [i + 1], wps->wphdr.block_samples, info.dps + i, 1); - - info.best_bits = LOG2BUFFER (info.sampleptrs [info.nterms], wps->wphdr.block_samples, 0) * 1; - info.best_bits += log2overhead (info.dps [0].term, i); - memcpy (info.sampleptrs [info.nterms + 1], info.sampleptrs [i], wps->wphdr.block_samples * 4); - - if (wpc->config.extra_flags & EXTRA_BRANCHES) - recurse_mono (wpc, &info, 0, (int) floor (wps->delta_decay + 0.5), - LOG2BUFFER (info.sampleptrs [0], wps->wphdr.block_samples, 0)); - - if (wpc->config.extra_flags & EXTRA_SORT_FIRST) - sort_mono (wpc, &info); - - if (wpc->config.extra_flags & EXTRA_TRY_DELTAS) { - delta_mono (wpc, &info); - - if ((wpc->config.extra_flags & EXTRA_ADJUST_DELTAS) && wps->decorr_passes [0].term) - wps->delta_decay = (float)((wps->delta_decay * 2.0 + wps->decorr_passes [0].delta) / 3.0); - else - wps->delta_decay = 2.0; - } - - if (wpc->config.extra_flags & EXTRA_SORT_LAST) - sort_mono (wpc, &info); - - if (do_samples) - memcpy (samples, info.sampleptrs [info.nterms + 1], wps->wphdr.block_samples * 4); - - for (i = 0; i < info.nterms; ++i) - if (!wps->decorr_passes [i].term) - break; - - wps->num_terms = i; - - for (i = 0; i < info.nterms + 2; ++i) - free (info.sampleptrs [i]); -} - -static void mono_add_noise (WavpackStream *wps, int32_t *lptr, int32_t *rptr) -{ - int shaping_weight, new = wps->wphdr.flags & NEW_SHAPING; - short *shaping_array = wps->dc.shaping_array; - int32_t error = 0, temp, cnt; - - scan_word (wps, rptr, wps->wphdr.block_samples, -1); - cnt = wps->wphdr.block_samples; - - if (wps->wphdr.flags & HYBRID_SHAPE) { - while (cnt--) { - if (shaping_array) - shaping_weight = *shaping_array++; - else - shaping_weight = (wps->dc.shaping_acc [0] += wps->dc.shaping_delta [0]) >> 16; - - temp = -apply_weight (shaping_weight, error); - - if (new && shaping_weight < 0 && temp) { - if (temp == error) - temp = (temp < 0) ? temp + 1 : temp - 1; - - lptr [0] += (error = nosend_word (wps, rptr [0], 0) - rptr [0] + temp); - } - else - lptr [0] += (error = nosend_word (wps, rptr [0], 0) - rptr [0]) + temp; - - lptr++; - rptr++; - } - - if (!shaping_array) - wps->dc.shaping_acc [0] -= wps->dc.shaping_delta [0] * wps->wphdr.block_samples; - } - else - while (cnt--) { - lptr [0] += nosend_word (wps, rptr [0], 0) - rptr [0]; - lptr++; - rptr++; - } -} - -void execute_mono (WavpackContext *wpc, int32_t *samples, int no_history, int do_samples) -{ - int32_t *temp_buffer [2], *best_buffer, *noisy_buffer = NULL; - struct decorr_pass temp_decorr_pass, save_decorr_passes [MAX_NTERMS]; - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int32_t num_samples = wps->wphdr.block_samples; - int32_t buf_size = sizeof (int32_t) * num_samples; - uint32_t best_size = (uint32_t) -1, size; - int log_limit, pi, i; - -#ifdef SKIP_DECORRELATION - CLEAR (wps->decorr_passes); - wps->num_terms = 0; - return; -#endif - - for (i = 0; i < num_samples; ++i) - if (samples [i]) - break; - - if (i == num_samples) { - CLEAR (wps->decorr_passes); - wps->num_terms = 0; - init_words (wps); - return; - } - -#ifdef LOG_LIMIT - log_limit = (((wps->wphdr.flags & MAG_MASK) >> MAG_LSB) + 4) * 256; - - if (log_limit > LOG_LIMIT) - log_limit = LOG_LIMIT; -#else - log_limit = 0; -#endif - - CLEAR (save_decorr_passes); - temp_buffer [0] = malloc (buf_size); - temp_buffer [1] = malloc (buf_size); - best_buffer = malloc (buf_size); - - if (wps->num_passes > 1 && (wps->wphdr.flags & HYBRID_FLAG)) { - CLEAR (temp_decorr_pass); - temp_decorr_pass.delta = 2; - temp_decorr_pass.term = 18; - - decorr_mono_pass (samples, temp_buffer [0], - num_samples > 2048 ? 2048 : num_samples, &temp_decorr_pass, -1); - - reverse_mono_decorr (&temp_decorr_pass); - decorr_mono_pass (samples, temp_buffer [0], num_samples, &temp_decorr_pass, 1); - CLEAR (temp_decorr_pass); - temp_decorr_pass.delta = 2; - temp_decorr_pass.term = 17; - - decorr_mono_pass (temp_buffer [0], temp_buffer [1], - num_samples > 2048 ? 2048 : num_samples, &temp_decorr_pass, -1); - - decorr_mono_pass (temp_buffer [0], temp_buffer [1], num_samples, &temp_decorr_pass, 1); - noisy_buffer = malloc (buf_size); - memcpy (noisy_buffer, samples, buf_size); - mono_add_noise (wps, noisy_buffer, temp_buffer [1]); - no_history = 1; - } - - if (no_history || wps->num_passes >= 7) - wps->best_decorr = wps->mask_decorr = 0; - - for (pi = 0; pi < wps->num_passes;) { - const WavpackDecorrSpec *wpds; - int nterms, c, j; - - if (!pi) - c = wps->best_decorr; - else { - if (wps->mask_decorr == 0) - c = 0; - else - c = (wps->best_decorr & (wps->mask_decorr - 1)) | wps->mask_decorr; - - if (c == wps->best_decorr) { - wps->mask_decorr = wps->mask_decorr ? ((wps->mask_decorr << 1) & (wps->num_decorrs - 1)) : 1; - continue; - } - } - - wpds = &wps->decorr_specs [c]; - nterms = (int) strlen ((char *) wpds->terms); - - while (1) { - memcpy (temp_buffer [0], noisy_buffer ? noisy_buffer : samples, buf_size); - CLEAR (save_decorr_passes); - - for (j = 0; j < nterms; ++j) { - CLEAR (temp_decorr_pass); - temp_decorr_pass.delta = wpds->delta; - temp_decorr_pass.term = wpds->terms [j]; - - if (temp_decorr_pass.term < 0) - temp_decorr_pass.term = 1; - - decorr_mono_pass (temp_buffer [j&1], temp_buffer [~j&1], - num_samples > 2048 ? 2048 : num_samples, &temp_decorr_pass, -1); - - if (j) { - CLEAR (temp_decorr_pass.samples_A); - } - else - reverse_mono_decorr (&temp_decorr_pass); - - memcpy (save_decorr_passes + j, &temp_decorr_pass, sizeof (struct decorr_pass)); - decorr_mono_pass (temp_buffer [j&1], temp_buffer [~j&1], num_samples, &temp_decorr_pass, 1); - } - - size = LOG2BUFFER (temp_buffer [j&1], num_samples, log_limit); - - if (size == (uint32_t) -1 && nterms) - nterms >>= 1; - else - break; - } - - size += log2overhead (wpds->terms [0], nterms); - - if (size < best_size) { - memcpy (best_buffer, temp_buffer [j&1], buf_size); - memcpy (wps->decorr_passes, save_decorr_passes, sizeof (struct decorr_pass) * MAX_NTERMS); - wps->num_terms = nterms; - wps->best_decorr = c; - best_size = size; - } - - if (pi++) - wps->mask_decorr = wps->mask_decorr ? ((wps->mask_decorr << 1) & (wps->num_decorrs - 1)) : 1; - } - - if (wpc->config.xmode > 3) { - if (noisy_buffer) { - analyze_mono (wpc, noisy_buffer, do_samples); - - if (do_samples) - memcpy (samples, noisy_buffer, buf_size); - } - else - analyze_mono (wpc, samples, do_samples); - } - else if (do_samples) - memcpy (samples, best_buffer, buf_size); - - if (no_history || wpc->config.xmode > 3) - scan_word (wps, best_buffer, num_samples, -1); - - if (noisy_buffer) - free (noisy_buffer); - - free (temp_buffer [1]); - free (temp_buffer [0]); - free (best_buffer); - -#ifdef EXTRA_DUMP - if (1) { - char string [256], substring [20]; - int i; - - sprintf (string, "M: terms ="); - - for (i = 0; i < wps->num_terms; ++i) { - if (wps->decorr_passes [i].term) { - if (i && wps->decorr_passes [i-1].delta == wps->decorr_passes [i].delta) - sprintf (substring, " %d", wps->decorr_passes [i].term); - else - sprintf (substring, " %d->%d", wps->decorr_passes [i].term, - wps->decorr_passes [i].delta); - } - else - sprintf (substring, " *"); - - strcat (string, substring); - } - - error_line (string); - } -#endif -} - diff --git a/Frameworks/WavPack/Files/extra2.c b/Frameworks/WavPack/Files/extra2.c deleted file mode 100644 index a2d49bf9c..000000000 --- a/Frameworks/WavPack/Files/extra2.c +++ /dev/null @@ -1,929 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// MMX optimizations (c) 2006 Joachim Henke // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// extra2.c - -// This module handles the "extra" mode for stereo files. - -#include -#include -#include -#include - -#include "wavpack_local.h" - -// This flag causes this module to take into account the size of the header -// (which grows with more decorrelation passes) when making decisions about -// adding additional passes (as opposed to just considering the resulting -// magnitude of the residuals). With really long blocks it seems to actually -// hurt compression (for reasons I cannot explain), but with short blocks it -// works okay, so we're enabling it for now. - -#define USE_OVERHEAD - -// If the log2 value of any sample in a buffer being scanned exceeds this value, -// we abandon that configuration. This prevents us from going down paths that -// are wildly unstable. - -#define LOG_LIMIT 6912 - -//#define EXTRA_DUMP // dump generated filter data to error_line() - -#ifdef OPT_ASM_X86 - #define PACK_DECORR_STEREO_PASS_CONT pack_decorr_stereo_pass_cont_x86 - #define PACK_DECORR_STEREO_PASS_CONT_REV pack_decorr_stereo_pass_cont_rev_x86 - #define PACK_DECORR_STEREO_PASS_CONT_AVAILABLE pack_cpu_has_feature_x86(CPU_FEATURE_MMX) -#elif defined(OPT_ASM_X64) && (defined (_WIN64) || defined(__CYGWIN__) || defined(__MINGW64__) || defined(__midipix__)) - #define PACK_DECORR_STEREO_PASS_CONT pack_decorr_stereo_pass_cont_x64win - #define PACK_DECORR_STEREO_PASS_CONT_REV pack_decorr_stereo_pass_cont_rev_x64win - #define PACK_DECORR_STEREO_PASS_CONT_AVAILABLE 1 -#elif defined(OPT_ASM_X64) - #define PACK_DECORR_STEREO_PASS_CONT pack_decorr_stereo_pass_cont_x64 - #define PACK_DECORR_STEREO_PASS_CONT_REV pack_decorr_stereo_pass_cont_rev_x64 - #define PACK_DECORR_STEREO_PASS_CONT_AVAILABLE 1 -#endif - -#ifdef PACK_DECORR_STEREO_PASS_CONT - void PACK_DECORR_STEREO_PASS_CONT (struct decorr_pass *dpp, int32_t *in_buffer, int32_t *out_buffer, int32_t sample_count); - void PACK_DECORR_STEREO_PASS_CONT_REV (struct decorr_pass *dpp, int32_t *in_buffer, int32_t *out_buffer, int32_t sample_count); -#endif - -typedef struct { - int32_t *sampleptrs [MAX_NTERMS+2]; - struct decorr_pass dps [MAX_NTERMS]; - int nterms, log_limit; - uint32_t best_bits; -} WavpackExtraInfo; - -static void decorr_stereo_pass (int32_t *in_samples, int32_t *out_samples, int32_t num_samples, struct decorr_pass *dpp, int dir) -{ - int32_t cont_samples = 0; - int m = 0, i; - -#ifdef PACK_DECORR_STEREO_PASS_CONT - if (num_samples > 16 && PACK_DECORR_STEREO_PASS_CONT_AVAILABLE) { - int32_t pre_samples = (dpp->term < 0 || dpp->term > MAX_TERM) ? 2 : dpp->term; - cont_samples = num_samples - pre_samples; - num_samples = pre_samples; - } -#endif - - dpp->sum_A = dpp->sum_B = 0; - - if (dir < 0) { - out_samples += (num_samples + cont_samples - 1) * 2; - in_samples += (num_samples + cont_samples - 1) * 2; - dir = -2; - } - else - dir = 2; - - dpp->weight_A = restore_weight (store_weight (dpp->weight_A)); - dpp->weight_B = restore_weight (store_weight (dpp->weight_B)); - - for (i = 0; i < 8; ++i) { - dpp->samples_A [i] = wp_exp2s (wp_log2s (dpp->samples_A [i])); - dpp->samples_B [i] = wp_exp2s (wp_log2s (dpp->samples_B [i])); - } - - switch (dpp->term) { - - case 2: - while (num_samples--) { - int32_t sam, tmp; - - sam = dpp->samples_A [0]; - dpp->samples_A [0] = dpp->samples_A [1]; - out_samples [0] = tmp = (dpp->samples_A [1] = in_samples [0]) - apply_weight (dpp->weight_A, sam); - update_weight (dpp->weight_A, dpp->delta, sam, tmp); - dpp->sum_A += dpp->weight_A; - - sam = dpp->samples_B [0]; - dpp->samples_B [0] = dpp->samples_B [1]; - out_samples [1] = tmp = (dpp->samples_B [1] = in_samples [1]) - apply_weight (dpp->weight_B, sam); - update_weight (dpp->weight_B, dpp->delta, sam, tmp); - dpp->sum_B += dpp->weight_B; - - in_samples += dir; - out_samples += dir; - } - - break; - - case 17: - while (num_samples--) { - int32_t sam, tmp; - - sam = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - dpp->samples_A [1] = dpp->samples_A [0]; - out_samples [0] = tmp = (dpp->samples_A [0] = in_samples [0]) - apply_weight (dpp->weight_A, sam); - update_weight (dpp->weight_A, dpp->delta, sam, tmp); - dpp->sum_A += dpp->weight_A; - - sam = 2 * dpp->samples_B [0] - dpp->samples_B [1]; - dpp->samples_B [1] = dpp->samples_B [0]; - out_samples [1] = tmp = (dpp->samples_B [0] = in_samples [1]) - apply_weight (dpp->weight_B, sam); - update_weight (dpp->weight_B, dpp->delta, sam, tmp); - dpp->sum_B += dpp->weight_B; - - in_samples += dir; - out_samples += dir; - } - - break; - - case 18: - while (num_samples--) { - int32_t sam, tmp; - - sam = dpp->samples_A [0] + ((dpp->samples_A [0] - dpp->samples_A [1]) >> 1); - dpp->samples_A [1] = dpp->samples_A [0]; - out_samples [0] = tmp = (dpp->samples_A [0] = in_samples [0]) - apply_weight (dpp->weight_A, sam); - update_weight (dpp->weight_A, dpp->delta, sam, tmp); - dpp->sum_A += dpp->weight_A; - - sam = dpp->samples_B [0] + ((dpp->samples_B [0] - dpp->samples_B [1]) >> 1); - dpp->samples_B [1] = dpp->samples_B [0]; - out_samples [1] = tmp = (dpp->samples_B [0] = in_samples [1]) - apply_weight (dpp->weight_B, sam); - update_weight (dpp->weight_B, dpp->delta, sam, tmp); - dpp->sum_B += dpp->weight_B; - - in_samples += dir; - out_samples += dir; - } - - break; - - default: { - int k = dpp->term & (MAX_TERM - 1); - - while (num_samples--) { - int32_t sam, tmp; - - sam = dpp->samples_A [m]; - out_samples [0] = tmp = (dpp->samples_A [k] = in_samples [0]) - apply_weight (dpp->weight_A, sam); - update_weight (dpp->weight_A, dpp->delta, sam, tmp); - dpp->sum_A += dpp->weight_A; - - sam = dpp->samples_B [m]; - out_samples [1] = tmp = (dpp->samples_B [k] = in_samples [1]) - apply_weight (dpp->weight_B, sam); - update_weight (dpp->weight_B, dpp->delta, sam, tmp); - dpp->sum_B += dpp->weight_B; - - in_samples += dir; - out_samples += dir; - m = (m + 1) & (MAX_TERM - 1); - k = (k + 1) & (MAX_TERM - 1); - } - - if (m) { - int32_t temp_A [MAX_TERM], temp_B [MAX_TERM]; - int k; - - memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A)); - memcpy (temp_B, dpp->samples_B, sizeof (dpp->samples_B)); - - for (k = 0; k < MAX_TERM; k++) { - dpp->samples_A [k] = temp_A [m]; - dpp->samples_B [k] = temp_B [m]; - m = (m + 1) & (MAX_TERM - 1); - } - } - - break; - } - - case -1: - while (num_samples--) { - int32_t sam_A, sam_B, tmp; - - sam_A = dpp->samples_A [0]; - out_samples [0] = tmp = (sam_B = in_samples [0]) - apply_weight (dpp->weight_A, sam_A); - update_weight_clip (dpp->weight_A, dpp->delta, sam_A, tmp); - dpp->sum_A += dpp->weight_A; - - out_samples [1] = tmp = (dpp->samples_A [0] = in_samples [1]) - apply_weight (dpp->weight_B, sam_B); - update_weight_clip (dpp->weight_B, dpp->delta, sam_B, tmp); - dpp->sum_B += dpp->weight_B; - - in_samples += dir; - out_samples += dir; - } - - break; - - case -2: - while (num_samples--) { - int32_t sam_A, sam_B, tmp; - - sam_B = dpp->samples_B [0]; - out_samples [1] = tmp = (sam_A = in_samples [1]) - apply_weight (dpp->weight_B, sam_B); - update_weight_clip (dpp->weight_B, dpp->delta, sam_B, tmp); - dpp->sum_B += dpp->weight_B; - - out_samples [0] = tmp = (dpp->samples_B [0] = in_samples [0]) - apply_weight (dpp->weight_A, sam_A); - update_weight_clip (dpp->weight_A, dpp->delta, sam_A, tmp); - dpp->sum_A += dpp->weight_A; - - in_samples += dir; - out_samples += dir; - } - - break; - - case -3: - while (num_samples--) { - int32_t sam_A, sam_B, tmp; - - sam_A = dpp->samples_A [0]; - sam_B = dpp->samples_B [0]; - - dpp->samples_A [0] = tmp = in_samples [1]; - out_samples [1] = tmp -= apply_weight (dpp->weight_B, sam_B); - update_weight_clip (dpp->weight_B, dpp->delta, sam_B, tmp); - dpp->sum_B += dpp->weight_B; - - dpp->samples_B [0] = tmp = in_samples [0]; - out_samples [0] = tmp -= apply_weight (dpp->weight_A, sam_A); - update_weight_clip (dpp->weight_A, dpp->delta, sam_A, tmp); - dpp->sum_A += dpp->weight_A; - - in_samples += dir; - out_samples += dir; - } - - break; - } - -#ifdef PACK_DECORR_STEREO_PASS_CONT - if (cont_samples) { - if (dir < 0) - PACK_DECORR_STEREO_PASS_CONT_REV (dpp, in_samples, out_samples, cont_samples); - else - PACK_DECORR_STEREO_PASS_CONT (dpp, in_samples, out_samples, cont_samples); - } -#endif -} - -static void reverse_decorr (struct decorr_pass *dpp) -{ - if (dpp->term > MAX_TERM) { - int32_t sam_A, sam_B; - - if (dpp->term & 1) { - sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - sam_B = 2 * dpp->samples_B [0] - dpp->samples_B [1]; - } - else { - sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - sam_B = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1; - } - - dpp->samples_A [1] = dpp->samples_A [0]; - dpp->samples_B [1] = dpp->samples_B [0]; - dpp->samples_A [0] = sam_A; - dpp->samples_B [0] = sam_B; - - if (dpp->term & 1) { - sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - sam_B = 2 * dpp->samples_B [0] - dpp->samples_B [1]; - } - else { - sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - sam_B = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1; - } - - dpp->samples_A [1] = sam_A; - dpp->samples_B [1] = sam_B; - } - else if (dpp->term > 1) { - int i = 0, j = dpp->term - 1, cnt = dpp->term / 2; - - while (cnt--) { - i &= (MAX_TERM - 1); - j &= (MAX_TERM - 1); - dpp->samples_A [i] ^= dpp->samples_A [j]; - dpp->samples_A [j] ^= dpp->samples_A [i]; - dpp->samples_A [i] ^= dpp->samples_A [j]; - dpp->samples_B [i] ^= dpp->samples_B [j]; - dpp->samples_B [j] ^= dpp->samples_B [i]; - dpp->samples_B [i++] ^= dpp->samples_B [j--]; - } - } - else if (dpp->term == -1) { - } - else if (dpp->term == -2) { - } - else if (dpp->term == -3) { - } -} - -static void decorr_stereo_buffer (WavpackExtraInfo *info, int32_t *samples, int32_t *outsamples, int32_t num_samples, int tindex) -{ - struct decorr_pass dp, *dppi = info->dps + tindex; - int delta = dppi->delta, pre_delta; - int term = dppi->term; - - if (delta == 7) - pre_delta = 7; - else if (delta < 2) - pre_delta = 3; - else - pre_delta = delta + 1; - - CLEAR (dp); - dp.term = term; - dp.delta = pre_delta; - decorr_stereo_pass (samples, outsamples, num_samples > 2048 ? 2048 : num_samples, &dp, -1); - dp.delta = delta; - - if (tindex == 0) - reverse_decorr (&dp); - else { - CLEAR (dp.samples_A); - CLEAR (dp.samples_B); - } - - memcpy (dppi->samples_A, dp.samples_A, sizeof (dp.samples_A)); - memcpy (dppi->samples_B, dp.samples_B, sizeof (dp.samples_B)); - dppi->weight_A = dp.weight_A; - dppi->weight_B = dp.weight_B; - - if (delta == 0) { - dp.delta = 1; - decorr_stereo_pass (samples, outsamples, num_samples, &dp, 1); - dp.delta = 0; - memcpy (dp.samples_A, dppi->samples_A, sizeof (dp.samples_A)); - memcpy (dp.samples_B, dppi->samples_B, sizeof (dp.samples_B)); - dppi->weight_A = dp.weight_A = dp.sum_A / num_samples; - dppi->weight_B = dp.weight_B = dp.sum_B / num_samples; - } - -// if (memcmp (dppi, &dp, sizeof (dp))) -// error_line ("decorr_passes don't match, delta = %d", delta); - - decorr_stereo_pass (samples, outsamples, num_samples, &dp, 1); -} - -static int log2overhead (int first_term, int num_terms) -{ -#ifdef USE_OVERHEAD - if (first_term > MAX_TERM) - return (8 + num_terms * 3) << 11; - else - return (4 + num_terms * 3) << 11; -#else - return 0; -#endif -} - -static void recurse_stereo (WavpackContext *wpc, WavpackExtraInfo *info, int depth, int delta, uint32_t input_bits) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int term, branches = ((wpc->config.extra_flags & EXTRA_BRANCHES) >> 6) - depth; - int32_t *samples, *outsamples; - uint32_t term_bits [22], bits; - - if (branches < 1 || depth + 1 == info->nterms) - branches = 1; - - CLEAR (term_bits); - samples = info->sampleptrs [depth]; - outsamples = info->sampleptrs [depth + 1]; - - for (term = -3; term <= 18; ++term) { - if (!term || (term > 8 && term < 17)) - continue; - - if (term == 17 && branches == 1 && depth + 1 < info->nterms) - continue; - - if (term == -1 || term == -2) - if (!(wps->wphdr.flags & CROSS_DECORR)) - continue; - - if ((wpc->config.flags & CONFIG_FAST_FLAG) && (term > 4 && term < 17)) - continue; - - info->dps [depth].term = term; - info->dps [depth].delta = delta; - decorr_stereo_buffer (info, samples, outsamples, wps->wphdr.block_samples, depth); - bits = LOG2BUFFER (outsamples, wps->wphdr.block_samples * 2, info->log_limit); - - if (bits != (uint32_t) -1) - bits += log2overhead (info->dps [0].term, depth + 1); - - if (bits < info->best_bits) { - info->best_bits = bits; - CLEAR (wps->decorr_passes); - memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * (depth + 1)); - memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [depth + 1], wps->wphdr.block_samples * 8); - } - - term_bits [term + 3] = bits; - } - - while (depth + 1 < info->nterms && branches--) { - uint32_t local_best_bits = input_bits; - int best_term = 0, i; - - for (i = 0; i < 22; ++i) - if (term_bits [i] && term_bits [i] < local_best_bits) { - local_best_bits = term_bits [i]; -// term_bits [i] = 0; - best_term = i - 3; - } - - if (!best_term) - break; - - term_bits [best_term + 3] = 0; - - info->dps [depth].term = best_term; - info->dps [depth].delta = delta; - decorr_stereo_buffer (info, samples, outsamples, wps->wphdr.block_samples, depth); - -// if (log2buffer (outsamples, wps->wphdr.block_samples * 2, 0) != local_best_bits) -// error_line ("data doesn't match!"); - - recurse_stereo (wpc, info, depth + 1, delta, local_best_bits); - } -} - -static void delta_stereo (WavpackContext *wpc, WavpackExtraInfo *info) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int lower = FALSE; - int delta, d; - uint32_t bits; - - if (wps->decorr_passes [0].term) - delta = wps->decorr_passes [0].delta; - else - return; - - for (d = delta - 1; d >= 0; --d) { - int i; - - if (!d && (wps->wphdr.flags & HYBRID_FLAG)) - break; - - for (i = 0; i < info->nterms && wps->decorr_passes [i].term; ++i) { - info->dps [i].term = wps->decorr_passes [i].term; - info->dps [i].delta = d; - decorr_stereo_buffer (info, info->sampleptrs [i], info->sampleptrs [i+1], wps->wphdr.block_samples, i); - } - - bits = LOG2BUFFER (info->sampleptrs [i], wps->wphdr.block_samples * 2, info->log_limit); - - if (bits != (uint32_t) -1) - bits += log2overhead (wps->decorr_passes [0].term, i); - - if (bits < info->best_bits) { - lower = TRUE; - info->best_bits = bits; - CLEAR (wps->decorr_passes); - memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * i); - memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [i], wps->wphdr.block_samples * 8); - } - else - break; - } - - for (d = delta + 1; !lower && d <= 7; ++d) { - int i; - - for (i = 0; i < info->nterms && wps->decorr_passes [i].term; ++i) { - info->dps [i].term = wps->decorr_passes [i].term; - info->dps [i].delta = d; - decorr_stereo_buffer (info, info->sampleptrs [i], info->sampleptrs [i+1], wps->wphdr.block_samples, i); - } - - bits = LOG2BUFFER (info->sampleptrs [i], wps->wphdr.block_samples * 2, info->log_limit); - - if (bits != (uint32_t) -1) - bits += log2overhead (wps->decorr_passes [0].term, i); - - if (bits < info->best_bits) { - info->best_bits = bits; - CLEAR (wps->decorr_passes); - memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * i); - memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [i], wps->wphdr.block_samples * 8); - } - else - break; - } -} - -static void sort_stereo (WavpackContext *wpc, WavpackExtraInfo *info) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int reversed = TRUE; - uint32_t bits; - - while (reversed) { - int ri, i; - - memcpy (info->dps, wps->decorr_passes, sizeof (wps->decorr_passes)); - reversed = FALSE; - - for (ri = 0; ri < info->nterms && wps->decorr_passes [ri].term; ++ri) { - - if (ri + 1 >= info->nterms || !wps->decorr_passes [ri+1].term) - break; - - if (wps->decorr_passes [ri].term == wps->decorr_passes [ri+1].term) { - decorr_stereo_buffer (info, info->sampleptrs [ri], info->sampleptrs [ri+1], wps->wphdr.block_samples, ri); - continue; - } - - info->dps [ri] = wps->decorr_passes [ri+1]; - info->dps [ri+1] = wps->decorr_passes [ri]; - - for (i = ri; i < info->nterms && wps->decorr_passes [i].term; ++i) - decorr_stereo_buffer (info, info->sampleptrs [i], info->sampleptrs [i+1], wps->wphdr.block_samples, i); - - bits = LOG2BUFFER (info->sampleptrs [i], wps->wphdr.block_samples * 2, info->log_limit); - - if (bits != (uint32_t) -1) - bits += log2overhead (wps->decorr_passes [0].term, i); - - if (bits < info->best_bits) { - reversed = TRUE; - info->best_bits = bits; - CLEAR (wps->decorr_passes); - memcpy (wps->decorr_passes, info->dps, sizeof (info->dps [0]) * i); - memcpy (info->sampleptrs [info->nterms + 1], info->sampleptrs [i], wps->wphdr.block_samples * 8); - } - else { - info->dps [ri] = wps->decorr_passes [ri]; - info->dps [ri+1] = wps->decorr_passes [ri+1]; - decorr_stereo_buffer (info, info->sampleptrs [ri], info->sampleptrs [ri+1], wps->wphdr.block_samples, ri); - } - } - } -} - -static const uint32_t xtable [] = { 91, 123, 187, 251 }; - -static void analyze_stereo (WavpackContext *wpc, int32_t *samples, int do_samples) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - WavpackExtraInfo info; - int i; - -#ifdef LOG_LIMIT - info.log_limit = (((wps->wphdr.flags & MAG_MASK) >> MAG_LSB) + 4) * 256; - - if (info.log_limit > LOG_LIMIT) - info.log_limit = LOG_LIMIT; -#else - info.log_limit = 0; -#endif - - if (wpc->config.flags & (CONFIG_HIGH_FLAG | CONFIG_VERY_HIGH_FLAG)) - wpc->config.extra_flags = xtable [wpc->config.xmode - 4]; - else - wpc->config.extra_flags = xtable [wpc->config.xmode - 3]; - - info.nterms = wps->num_terms; - - for (i = 0; i < info.nterms + 2; ++i) - info.sampleptrs [i] = malloc (wps->wphdr.block_samples * 8); - - memcpy (info.dps, wps->decorr_passes, sizeof (info.dps)); - memcpy (info.sampleptrs [0], samples, wps->wphdr.block_samples * 8); - - for (i = 0; i < info.nterms && info.dps [i].term; ++i) - decorr_stereo_pass (info.sampleptrs [i], info.sampleptrs [i + 1], wps->wphdr.block_samples, info.dps + i, 1); - - info.best_bits = LOG2BUFFER (info.sampleptrs [info.nterms], wps->wphdr.block_samples * 2, 0) * 1; - info.best_bits += log2overhead (info.dps [0].term, i); - memcpy (info.sampleptrs [info.nterms + 1], info.sampleptrs [i], wps->wphdr.block_samples * 8); - - if (wpc->config.extra_flags & EXTRA_BRANCHES) - recurse_stereo (wpc, &info, 0, (int) floor (wps->delta_decay + 0.5), - LOG2BUFFER (info.sampleptrs [0], wps->wphdr.block_samples * 2, 0)); - - if (wpc->config.extra_flags & EXTRA_SORT_FIRST) - sort_stereo (wpc, &info); - - if (wpc->config.extra_flags & EXTRA_TRY_DELTAS) { - delta_stereo (wpc, &info); - - if ((wpc->config.extra_flags & EXTRA_ADJUST_DELTAS) && wps->decorr_passes [0].term) - wps->delta_decay = (float)((wps->delta_decay * 2.0 + wps->decorr_passes [0].delta) / 3.0); - else - wps->delta_decay = 2.0; - } - - if (wpc->config.extra_flags & EXTRA_SORT_LAST) - sort_stereo (wpc, &info); - - if (do_samples) - memcpy (samples, info.sampleptrs [info.nterms + 1], wps->wphdr.block_samples * 8); - - for (i = 0; i < info.nterms; ++i) - if (!wps->decorr_passes [i].term) - break; - - wps->num_terms = i; - - for (i = 0; i < info.nterms + 2; ++i) - free (info.sampleptrs [i]); -} - -static void stereo_add_noise (WavpackStream *wps, int32_t *lptr, int32_t *rptr) -{ - int shaping_weight, new = wps->wphdr.flags & NEW_SHAPING; - short *shaping_array = wps->dc.shaping_array; - int32_t error [2], temp, cnt; - - scan_word (wps, rptr, wps->wphdr.block_samples, -1); - cnt = wps->wphdr.block_samples; - CLEAR (error); - - if (wps->wphdr.flags & HYBRID_SHAPE) { - while (cnt--) { - if (shaping_array) - shaping_weight = *shaping_array++; - else - shaping_weight = (wps->dc.shaping_acc [0] += wps->dc.shaping_delta [0]) >> 16; - - temp = -apply_weight (shaping_weight, error [0]); - - if (new && shaping_weight < 0 && temp) { - if (temp == error [0]) - temp = (temp < 0) ? temp + 1 : temp - 1; - - lptr [0] += (error [0] = nosend_word (wps, rptr [0], 0) - rptr [0] + temp); - } - else - lptr [0] += (error [0] = nosend_word (wps, rptr [0], 0) - rptr [0]) + temp; - - if (!shaping_array) - shaping_weight = (wps->dc.shaping_acc [1] += wps->dc.shaping_delta [1]) >> 16; - - temp = -apply_weight (shaping_weight, error [1]); - - if (new && shaping_weight < 0 && temp) { - if (temp == error [1]) - temp = (temp < 0) ? temp + 1 : temp - 1; - - lptr [1] += (error [1] = nosend_word (wps, rptr [1], 1) - rptr [1] + temp); - } - else - lptr [1] += (error [1] = nosend_word (wps, rptr [1], 1) - rptr [1]) + temp; - - lptr += 2; - rptr += 2; - } - - if (!shaping_array) { - wps->dc.shaping_acc [0] -= wps->dc.shaping_delta [0] * wps->wphdr.block_samples; - wps->dc.shaping_acc [1] -= wps->dc.shaping_delta [1] * wps->wphdr.block_samples; - } - } - else - while (cnt--) { - lptr [0] += nosend_word (wps, rptr [0], 0) - rptr [0]; - lptr [1] += nosend_word (wps, rptr [1], 1) - rptr [1]; - lptr += 2; - rptr += 2; - } -} - -void execute_stereo (WavpackContext *wpc, int32_t *samples, int no_history, int do_samples) -{ - int32_t *temp_buffer [2], *best_buffer, *noisy_buffer = NULL, *js_buffer = NULL; - struct decorr_pass temp_decorr_pass, save_decorr_passes [MAX_NTERMS]; - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int32_t num_samples = wps->wphdr.block_samples; - int32_t buf_size = sizeof (int32_t) * num_samples * 2; - uint32_t best_size = (uint32_t) -1, size; - int log_limit, force_js = 0, force_ts = 0, pi, i; - -#ifdef SKIP_DECORRELATION - CLEAR (wps->decorr_passes); - wps->num_terms = 0; - return; -#endif - - for (i = 0; i < num_samples * 2; ++i) - if (samples [i]) - break; - - if (i == num_samples * 2) { - wps->wphdr.flags &= ~((uint32_t) JOINT_STEREO); - CLEAR (wps->decorr_passes); - wps->num_terms = 0; - init_words (wps); - return; - } - -#ifdef LOG_LIMIT - log_limit = (((wps->wphdr.flags & MAG_MASK) >> MAG_LSB) + 4) * 256; - - if (log_limit > LOG_LIMIT) - log_limit = LOG_LIMIT; -#else - log_limit = 0; -#endif - - if (wpc->config.flags & CONFIG_JOINT_OVERRIDE) { - if (wps->wphdr.flags & JOINT_STEREO) - force_js = 1; - else - force_ts = 1; - } - - CLEAR (save_decorr_passes); - temp_buffer [0] = malloc (buf_size); - temp_buffer [1] = malloc (buf_size); - best_buffer = malloc (buf_size); - - if (wps->num_passes > 1 && (wps->wphdr.flags & HYBRID_FLAG)) { - CLEAR (temp_decorr_pass); - temp_decorr_pass.delta = 2; - temp_decorr_pass.term = 18; - - decorr_stereo_pass (samples, temp_buffer [0], - num_samples > 2048 ? 2048 : num_samples, &temp_decorr_pass, -1); - - reverse_decorr (&temp_decorr_pass); - decorr_stereo_pass (samples, temp_buffer [0], num_samples, &temp_decorr_pass, 1); - CLEAR (temp_decorr_pass); - temp_decorr_pass.delta = 2; - temp_decorr_pass.term = 17; - - decorr_stereo_pass (temp_buffer [0], temp_buffer [1], - num_samples > 2048 ? 2048 : num_samples, &temp_decorr_pass, -1); - - decorr_stereo_pass (temp_buffer [0], temp_buffer [1], num_samples, &temp_decorr_pass, 1); - noisy_buffer = malloc (buf_size); - memcpy (noisy_buffer, samples, buf_size); - stereo_add_noise (wps, noisy_buffer, temp_buffer [1]); - no_history = 1; - } - - if (no_history || wps->num_passes >= 7) - wps->best_decorr = wps->mask_decorr = 0; - - for (pi = 0; pi < wps->num_passes;) { - const WavpackDecorrSpec *wpds; - int nterms, c, j; - - if (!pi) - c = wps->best_decorr; - else { - if (wps->mask_decorr == 0) - c = 0; - else - c = (wps->best_decorr & (wps->mask_decorr - 1)) | wps->mask_decorr; - - if (c == wps->best_decorr) { - wps->mask_decorr = wps->mask_decorr ? ((wps->mask_decorr << 1) & (wps->num_decorrs - 1)) : 1; - continue; - } - } - - wpds = &wps->decorr_specs [c]; - nterms = (int) strlen ((char *) wpds->terms); - - while (1) { - if (force_js || (wpds->joint_stereo && !force_ts)) { - if (!js_buffer) { - int32_t *lptr, cnt = num_samples; - - lptr = js_buffer = malloc (buf_size); - memcpy (js_buffer, noisy_buffer ? noisy_buffer : samples, buf_size); - - while (cnt--) { - lptr [1] += ((lptr [0] -= lptr [1]) >> 1); - lptr += 2; - } - } - - memcpy (temp_buffer [0], js_buffer, buf_size); - } - else - memcpy (temp_buffer [0], noisy_buffer ? noisy_buffer : samples, buf_size); - - CLEAR (save_decorr_passes); - - for (j = 0; j < nterms; ++j) { - CLEAR (temp_decorr_pass); - temp_decorr_pass.delta = wpds->delta; - temp_decorr_pass.term = wpds->terms [j]; - - if (temp_decorr_pass.term < 0 && !(wps->wphdr.flags & CROSS_DECORR)) - temp_decorr_pass.term = -3; - - decorr_stereo_pass (temp_buffer [j&1], temp_buffer [~j&1], - num_samples > 2048 ? 2048 : num_samples, &temp_decorr_pass, -1); - - if (j) { - CLEAR (temp_decorr_pass.samples_A); - CLEAR (temp_decorr_pass.samples_B); - } - else - reverse_decorr (&temp_decorr_pass); - - memcpy (save_decorr_passes + j, &temp_decorr_pass, sizeof (struct decorr_pass)); - decorr_stereo_pass (temp_buffer [j&1], temp_buffer [~j&1], num_samples, &temp_decorr_pass, 1); - } - - size = LOG2BUFFER (temp_buffer [j&1], num_samples * 2, log_limit); - - if (size == (uint32_t) -1 && nterms) - nterms >>= 1; - else - break; - } - - size += log2overhead (wpds->terms [0], nterms); - - if (size < best_size) { - memcpy (best_buffer, temp_buffer [j&1], buf_size); - memcpy (wps->decorr_passes, save_decorr_passes, sizeof (struct decorr_pass) * MAX_NTERMS); - wps->num_terms = nterms; - wps->best_decorr = c; - best_size = size; - } - - if (pi++) - wps->mask_decorr = wps->mask_decorr ? ((wps->mask_decorr << 1) & (wps->num_decorrs - 1)) : 1; - } - - if (force_js || (wps->decorr_specs [wps->best_decorr].joint_stereo && !force_ts)) - wps->wphdr.flags |= JOINT_STEREO; - else - wps->wphdr.flags &= ~((uint32_t) JOINT_STEREO); - - if (wpc->config.xmode > 3) { - if (wps->wphdr.flags & JOINT_STEREO) { - analyze_stereo (wpc, js_buffer, do_samples); - - if (do_samples) - memcpy (samples, js_buffer, buf_size); - } - else if (noisy_buffer) { - analyze_stereo (wpc, noisy_buffer, do_samples); - - if (do_samples) - memcpy (samples, noisy_buffer, buf_size); - } - else - analyze_stereo (wpc, samples, do_samples); - } - else if (do_samples) - memcpy (samples, best_buffer, buf_size); - - if (wpc->config.xmode > 3 || no_history || wps->joint_stereo != wps->decorr_specs [wps->best_decorr].joint_stereo) { - wps->joint_stereo = wps->decorr_specs [wps->best_decorr].joint_stereo; - scan_word (wps, best_buffer, num_samples, -1); - } - - if (noisy_buffer) - free (noisy_buffer); - - if (js_buffer) - free (js_buffer); - - free (temp_buffer [1]); - free (temp_buffer [0]); - free (best_buffer); - -#ifdef EXTRA_DUMP - if (1) { - char string [256], substring [20]; - int i; - - sprintf (string, "%s: terms =", - (wps->wphdr.flags & JOINT_STEREO) ? "JS" : "TS"); - - for (i = 0; i < wps->num_terms; ++i) { - if (wps->decorr_passes [i].term) { - if (i && wps->decorr_passes [i-1].delta == wps->decorr_passes [i].delta) - sprintf (substring, " %d", wps->decorr_passes [i].term); - else - sprintf (substring, " %d->%d", wps->decorr_passes [i].term, - wps->decorr_passes [i].delta); - } - else - sprintf (substring, " *"); - - strcat (string, substring); - } - - error_line (string); - } -#endif -} - diff --git a/Frameworks/WavPack/Files/md5.c b/Frameworks/WavPack/Files/md5.c deleted file mode 100644 index 8d3240b0c..000000000 --- a/Frameworks/WavPack/Files/md5.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD5 Message-Digest Algorithm (RFC 1321). - * - * Homepage: - * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 - * - * Author: - * Alexander Peslyak, better known as Solar Designer - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. - * In case this attempt to disclaim copyright and place the software in the - * public domain is deemed null and void, then the software is - * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the - * general public under the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There's ABSOLUTELY NO WARRANTY, express or implied. - * - * (This is a heavily cut-down "BSD license".) - * - * This differs from Colin Plumb's older public domain implementation in that - * no exactly 32-bit integer data type is required (any 32-bit or wider - * unsigned integer data type will do), there's no compile-time endianness - * configuration, and the function prototypes match OpenSSL's. No code from - * Colin Plumb's implementation has been reused; this comment merely compares - * the properties of the two independent implementations. - * - * The primary goals of this implementation are portability and ease of use. - * It is meant to be fast, but not as fast as possible. Some known - * optimizations are not included to reduce source code size and avoid - * compile-time configuration. - */ - -#ifndef HAVE_LIBCRYPTO - -#include - -#include "md5.h" - -/* - * The basic MD5 functions. - * - * F and G are optimized compared to their RFC 1321 definitions for - * architectures that lack an AND-NOT instruction, just like in Colin Plumb's - * implementation. - */ -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) -#define H(x, y, z) (((x) ^ (y)) ^ (z)) -#define H2(x, y, z) ((x) ^ ((y) ^ (z))) -#define I(x, y, z) ((y) ^ ((x) | ~(z))) - -/* - * The MD5 transformation for all four rounds. - */ -#define STEP(f, a, b, c, d, x, t, s) \ - (a) += f((b), (c), (d)) + (x) + (t); \ - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ - (a) += (b); - -/* - * SET reads 4 input bytes in little-endian byte order and stores them in a - * properly aligned word in host byte order. - * - * The check for little-endian architectures that tolerate unaligned memory - * accesses is just an optimization. Nothing will break if it fails to detect - * a suitable architecture. - * - * Unfortunately, this optimization may be a C strict aliasing rules violation - * if the caller's data buffer has effective type that cannot be aliased by - * MD5_u32plus. In practice, this problem may occur if these MD5 routines are - * inlined into a calling function, or with future and dangerously advanced - * link-time optimizations. For the time being, keeping these MD5 routines in - * their own translation unit avoids the problem. - */ -#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) -#define SET(n) \ - (*(MD5_u32plus *)&ptr[(n) * 4]) -#define GET(n) \ - SET(n) -#else -#define SET(n) \ - (ctx->block[(n)] = \ - (MD5_u32plus)ptr[(n) * 4] | \ - ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ - ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ - ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) -#define GET(n) \ - (ctx->block[(n)]) -#endif - -/* - * This processes one or more 64-byte data blocks, but does NOT update the bit - * counters. There are no alignment requirements. - */ -static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) -{ - const unsigned char *ptr; - MD5_u32plus a, b, c, d; - MD5_u32plus saved_a, saved_b, saved_c, saved_d; - - ptr = (const unsigned char *)data; - - a = ctx->a; - b = ctx->b; - c = ctx->c; - d = ctx->d; - - do { - saved_a = a; - saved_b = b; - saved_c = c; - saved_d = d; - -/* Round 1 */ - STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) - STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) - STEP(F, c, d, a, b, SET(2), 0x242070db, 17) - STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) - STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) - STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) - STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) - STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) - STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) - STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) - STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) - STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) - STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) - STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) - STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) - STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) - -/* Round 2 */ - STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) - STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) - STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) - STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) - STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) - STEP(G, d, a, b, c, GET(10), 0x02441453, 9) - STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) - STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) - STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) - STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) - STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) - STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) - STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) - STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) - STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) - STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) - -/* Round 3 */ - STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) - STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) - STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) - STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23) - STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) - STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11) - STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) - STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23) - STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) - STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11) - STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) - STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23) - STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) - STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) - STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) - STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) - -/* Round 4 */ - STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) - STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) - STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) - STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) - STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) - STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) - STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) - STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) - STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) - STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) - STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) - STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) - STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) - STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) - STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) - STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) - - a += saved_a; - b += saved_b; - c += saved_c; - d += saved_d; - - ptr += 64; - } while (size -= 64); - - ctx->a = a; - ctx->b = b; - ctx->c = c; - ctx->d = d; - - return ptr; -} - -void MD5_Init(MD5_CTX *ctx) -{ - ctx->a = 0x67452301; - ctx->b = 0xefcdab89; - ctx->c = 0x98badcfe; - ctx->d = 0x10325476; - - ctx->lo = 0; - ctx->hi = 0; -} - -void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) -{ - MD5_u32plus saved_lo; - unsigned long used, available; - - saved_lo = ctx->lo; - if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) - ctx->hi++; - ctx->hi += size >> 29; - - used = saved_lo & 0x3f; - - if (used) { - available = 64 - used; - - if (size < available) { - memcpy(&ctx->buffer[used], data, size); - return; - } - - memcpy(&ctx->buffer[used], data, available); - data = (const unsigned char *)data + available; - size -= available; - body(ctx, ctx->buffer, 64); - } - - if (size >= 64) { - data = body(ctx, data, size & ~(unsigned long)0x3f); - size &= 0x3f; - } - - memcpy(ctx->buffer, data, size); -} - -#define OUT(dst, src) \ - (dst)[0] = (unsigned char)(src); \ - (dst)[1] = (unsigned char)((src) >> 8); \ - (dst)[2] = (unsigned char)((src) >> 16); \ - (dst)[3] = (unsigned char)((src) >> 24); - -void MD5_Final(unsigned char *result, MD5_CTX *ctx) -{ - unsigned long used, available; - - used = ctx->lo & 0x3f; - - ctx->buffer[used++] = 0x80; - - available = 64 - used; - - if (available < 8) { - memset(&ctx->buffer[used], 0, available); - body(ctx, ctx->buffer, 64); - used = 0; - available = 64; - } - - memset(&ctx->buffer[used], 0, available - 8); - - ctx->lo <<= 3; - OUT(&ctx->buffer[56], ctx->lo) - OUT(&ctx->buffer[60], ctx->hi) - - body(ctx, ctx->buffer, 64); - - OUT(&result[0], ctx->a) - OUT(&result[4], ctx->b) - OUT(&result[8], ctx->c) - OUT(&result[12], ctx->d) - - memset(ctx, 0, sizeof(*ctx)); -} - -#endif diff --git a/Frameworks/WavPack/Files/md5.h b/Frameworks/WavPack/Files/md5.h deleted file mode 100644 index d81083043..000000000 --- a/Frameworks/WavPack/Files/md5.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. - * MD5 Message-Digest Algorithm (RFC 1321). - * - * Homepage: - * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 - * - * Author: - * Alexander Peslyak, better known as Solar Designer - * - * This software was written by Alexander Peslyak in 2001. No copyright is - * claimed, and the software is hereby placed in the public domain. - * In case this attempt to disclaim copyright and place the software in the - * public domain is deemed null and void, then the software is - * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the - * general public under the following terms: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted. - * - * There's ABSOLUTELY NO WARRANTY, express or implied. - * - * See md5.c for more information. - */ - -#ifdef HAVE_LIBCRYPTO -#include -#elif !defined(_MD5_H) -#define _MD5_H - -/* Any 32-bit or wider unsigned integer data type will do */ -typedef unsigned int MD5_u32plus; - -typedef struct { - MD5_u32plus lo, hi; - MD5_u32plus a, b, c, d; - unsigned char buffer[64]; - MD5_u32plus block[16]; -} MD5_CTX; - -extern void MD5_Init(MD5_CTX *ctx); -extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); -extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); - -#endif diff --git a/Frameworks/WavPack/Files/open_filename.c b/Frameworks/WavPack/Files/open_filename.c deleted file mode 100644 index cea13e3b9..000000000 --- a/Frameworks/WavPack/Files/open_filename.c +++ /dev/null @@ -1,304 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// open_filename.c - -// This module provides all the code required to open an existing WavPack -// file, by filename, for reading. It does not contain the actual code to -// unpack audio data and this was done so that programs that just want to -// query WavPack files for information (like, for example, taggers) don't -// need to link in a lot of unnecessary code. -// -// To allow opening files by filename, this code provides an interface -// between the reader callback mechanism that WavPack uses internally and -// the standard fstream C library. Note that in applications that do not -// require opening files by filename, this module can be omitted (which -// might make building easier). -// -// For Unicode support on Windows, a flag has been added (OPEN_FILE_UTF8) -// that forces the filename string to be assumed UTF-8 and converted to -// a widechar string suitable for _wfopen(). Without this flag we revert -// to the previous behavior of simply calling fopen() and hoping that the -// local character set works. This is ignored on non-Windows platforms -// (which is okay because they are probably UTF-8 anyway). - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -#endif - -#include -#include - -#include "wavpack_local.h" - -#include -#include - -#if (defined(__GNUC__) || defined(__sun)) && !defined(_WIN32) -#include -#endif - -#ifdef __OS2__ -#include -#endif - -#ifdef _WIN32 -#define fileno _fileno -static FILE *fopen_utf8 (const char *filename_utf8, const char *mode_utf8); -#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif -#endif - -#ifdef HAVE_FSEEKO -#define fseek fseeko -#define ftell ftello -#endif - -static int32_t read_bytes (void *id, void *data, int32_t bcount) -{ - return (int32_t) fread (data, 1, bcount, (FILE*) id); -} - -static int64_t get_pos (void *id) -{ -#ifdef _WIN32 - return _ftelli64 ((FILE*) id); -#else - return ftell ((FILE*) id); -#endif -} - -static int set_pos_abs (void *id, int64_t pos) -{ -#ifdef _WIN32 - return _fseeki64 (id, pos, SEEK_SET); -#else - return fseek (id, pos, SEEK_SET); -#endif -} - -static int set_pos_rel (void *id, int64_t delta, int mode) -{ -#ifdef _WIN32 - return _fseeki64 (id, delta, mode); -#else - return fseek (id, delta, mode); -#endif -} - -static int push_back_byte (void *id, int c) -{ - return ungetc (c, id); -} - -#ifdef _WIN32 - -static int64_t get_length (void *id) -{ - LARGE_INTEGER Size; - HANDLE fHandle; - - if (id == NULL) - return 0; - - fHandle = (HANDLE)_get_osfhandle(_fileno((FILE*) id)); - if (fHandle == INVALID_HANDLE_VALUE) - return 0; - - Size.u.LowPart = GetFileSize(fHandle, &Size.u.HighPart); - - if (Size.u.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) - return 0; - - return (int64_t)Size.QuadPart; -} - -#else - -static int64_t get_length (void *id) -{ - FILE *file = id; - struct stat statbuf; - - if (!file || fstat (fileno (file), &statbuf) || !S_ISREG(statbuf.st_mode)) - return 0; - - return statbuf.st_size; -} - -#endif - -static int can_seek (void *id) -{ - FILE *file = id; - struct stat statbuf; - - return file && !fstat (fileno (file), &statbuf) && S_ISREG(statbuf.st_mode); -} - -static int32_t write_bytes (void *id, void *data, int32_t bcount) -{ - return (int32_t) fwrite (data, 1, bcount, (FILE*) id); -} - -#ifdef _WIN32 - -static int truncate_here (void *id) -{ - FILE *file = id; - int64_t curr_pos = _ftelli64 (file); - - return _chsize_s (fileno (file), curr_pos); -} - -#else - -static int truncate_here (void *id) -{ - FILE *file = id; - off_t curr_pos = ftell (file); - - return ftruncate (fileno (file), curr_pos); -} - -#endif - -static int close_stream (void *id) -{ - return fclose ((FILE*) id); -} - -// int32_t (*read_bytes)(void *id, void *data, int32_t bcount); -// int32_t (*write_bytes)(void *id, void *data, int32_t bcount); -// int64_t (*get_pos)(void *id); // new signature for large files -// int (*set_pos_abs)(void *id, int64_t pos); // new signature for large files -// int (*set_pos_rel)(void *id, int64_t delta, int mode); // new signature for large files -// int (*push_back_byte)(void *id, int c); -// int64_t (*get_length)(void *id); // new signature for large files -// int (*can_seek)(void *id); -// int (*truncate_here)(void *id); // new function to truncate file at current position -// int (*close)(void *id); // new function to close file - -static WavpackStreamReader64 freader = { - read_bytes, write_bytes, get_pos, set_pos_abs, set_pos_rel, - push_back_byte, get_length, can_seek, truncate_here, close_stream -}; - -// This function attempts to open the specified WavPack file for reading. If -// this fails for any reason then an appropriate message is copied to "error" -// (which must accept 80 characters) and NULL is returned, otherwise a -// pointer to a WavpackContext structure is returned (which is used to call -// all other functions in this module). A filename beginning with "-" is -// assumed to be stdin. The "flags" argument has the following bit mask -// values to specify details of the open operation: - -// OPEN_WVC: attempt to open/read "correction" file -// OPEN_TAGS: attempt to read ID3v1 / APEv2 tags (requires seekable file) -// OPEN_WRAPPER: make audio wrapper available (i.e. RIFF) to caller -// OPEN_2CH_MAX: open only first stream of multichannel file (usually L/R) -// OPEN_NORMALIZE: normalize floating point data to +/- 1.0 (w/ offset exp) -// OPEN_STREAMING: blindly unpacks blocks w/o regard to header file position -// OPEN_EDIT_TAGS: allow editing of tags (file must be writable) -// OPEN_FILE_UTF8: assume infilename is UTF-8 encoded (Windows only) - -// Version 4.2 of the WavPack library adds the OPEN_STREAMING flag. This is -// essentially a "raw" mode where the library will simply decode any blocks -// fed it through the reader callback, regardless of where those blocks came -// from in a stream. The only requirement is that complete WavPack blocks are -// fed to the decoder (and this may require multiple blocks in multichannel -// mode) and that complete blocks are decoded (even if all samples are not -// actually required). All the blocks must contain the same number of channels -// and bit resolution, and the correction data must be either present or not. -// All other parameters may change from block to block (like lossy/lossless). -// Obviously, in this mode any seeking must be performed by the application -// (and again, decoding must start at the beginning of the block containing -// the seek sample). - -WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int flags, int norm_offset) -{ - char *file_mode = (flags & OPEN_EDIT_TAGS) ? "r+b" : "rb"; - FILE *(*fopen_func)(const char *, const char *) = fopen; - FILE *wv_id, *wvc_id; - -#ifdef _WIN32 - if (flags & OPEN_FILE_UTF8) - fopen_func = fopen_utf8; -#endif - - if (*infilename == '-') { - wv_id = stdin; -#if defined(_WIN32) - _setmode (fileno (stdin), O_BINARY); -#endif -#if defined(__OS2__) - setmode (fileno (stdin), O_BINARY); -#endif - } - else if ((wv_id = fopen_func (infilename, file_mode)) == NULL) { - if (error) strcpy (error, (flags & OPEN_EDIT_TAGS) ? "can't open file for editing" : "can't open file"); - return NULL; - } - - if (*infilename != '-' && (flags & OPEN_WVC)) { - char *in2filename = malloc (strlen (infilename) + 10); - - strcpy (in2filename, infilename); - strcat (in2filename, "c"); - wvc_id = fopen_func (in2filename, "rb"); - free (in2filename); - } - else - wvc_id = NULL; - - return WavpackOpenFileInputEx64 (&freader, wv_id, wvc_id, error, flags, norm_offset); -} - -#ifdef _WIN32 - -// The following code Copyright (c) 2004-2012 LoRd_MuldeR -// (see cli/win32_unicode_support.c for full license) - -static wchar_t *utf8_to_utf16(const char *input) -{ - wchar_t *Buffer; - int BuffSize = 0, Result = 0; - - BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0); - Buffer = (wchar_t*) malloc(sizeof(wchar_t) * BuffSize); - if(Buffer) - { - Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize); - } - - return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL; -} - - -static FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8) -{ - FILE *ret = NULL; - wchar_t *filename_utf16 = utf8_to_utf16(filename_utf8); - wchar_t *mode_utf16 = utf8_to_utf16(mode_utf8); - - if(filename_utf16 && mode_utf16) - { - ret = _wfopen(filename_utf16, mode_utf16); - } - - if(filename_utf16) free(filename_utf16); - if(mode_utf16) free(mode_utf16); - - return ret; -} - -#endif - - diff --git a/Frameworks/WavPack/Files/open_legacy.c b/Frameworks/WavPack/Files/open_legacy.c deleted file mode 100644 index 1b505d836..000000000 --- a/Frameworks/WavPack/Files/open_legacy.c +++ /dev/null @@ -1,114 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2019 David Bryant. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// open_legacy.c - -// This code provides an interface between the new reader callback mechanism that -// WavPack uses internally and the old reader callback functions that did not -// provide large file support. - -#include -#include - -#include "wavpack_local.h" - -typedef struct { - WavpackStreamReader *reader; - void *id; -} WavpackReaderTranslator; - -static int32_t trans_read_bytes (void *id, void *data, int32_t bcount) -{ - WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id; - return trans->reader->read_bytes (trans->id, data, bcount); -} - -static int32_t trans_write_bytes (void *id, void *data, int32_t bcount) -{ - WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id; - return trans->reader->write_bytes (trans->id, data, bcount); -} - -static int64_t trans_get_pos (void *id) -{ - WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id; - return trans->reader->get_pos (trans->id); -} - -static int trans_set_pos_abs (void *id, int64_t pos) -{ - WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id; - return trans->reader->set_pos_abs (trans->id, (uint32_t) pos); -} - -static int trans_set_pos_rel (void *id, int64_t delta, int mode) -{ - WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id; - return trans->reader->set_pos_rel (trans->id, (int32_t) delta, mode); -} - -static int trans_push_back_byte (void *id, int c) -{ - WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id; - return trans->reader->push_back_byte (trans->id, c); -} - -static int64_t trans_get_length (void *id) -{ - WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id; - return trans->reader->get_length (trans->id); -} - -static int trans_can_seek (void *id) -{ - WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id; - return trans->reader->can_seek (trans->id); -} - -static int trans_close_stream (void *id) -{ - free (id); - return 0; -} - -static WavpackStreamReader64 trans_reader = { - trans_read_bytes, trans_write_bytes, trans_get_pos, trans_set_pos_abs, trans_set_pos_rel, - trans_push_back_byte, trans_get_length, trans_can_seek, NULL, trans_close_stream -}; - -// This function is identical to WavpackOpenFileInput64() except that instead -// of providing the new 64-bit reader callbacks, the old reader callbacks are -// utilized and a translation layer is employed. It is provided as a compatibility -// function for existing applications. To ensure that streaming applications using -// this function continue to work, the OPEN_NO_CHECKSUM flag is forced on when -// the OPEN_STREAMING flag is set. - -WavpackContext *WavpackOpenFileInputEx (WavpackStreamReader *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset) -{ - WavpackReaderTranslator *trans_wv = NULL, *trans_wvc = NULL; - - // this prevents existing streaming applications from failing if they try to pass - // in blocks that have been modified from the original (e.g., Matroska blocks) - - if (flags & OPEN_STREAMING) - flags |= OPEN_NO_CHECKSUM; - - if (wv_id) { - trans_wv = (WavpackReaderTranslator *)malloc (sizeof (WavpackReaderTranslator)); - trans_wv->reader = reader; - trans_wv->id = wv_id; - } - - if (wvc_id) { - trans_wvc = (WavpackReaderTranslator *)malloc (sizeof (WavpackReaderTranslator)); - trans_wvc->reader = reader; - trans_wvc->id = wvc_id; - } - - return WavpackOpenFileInputEx64 (&trans_reader, trans_wv, trans_wvc, error, flags, norm_offset); -} diff --git a/Frameworks/WavPack/Files/open_raw.c b/Frameworks/WavPack/Files/open_raw.c deleted file mode 100644 index 69dc8f396..000000000 --- a/Frameworks/WavPack/Files/open_raw.c +++ /dev/null @@ -1,315 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2019 David Bryant. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// open_raw.c - -// This code provides the ability to decode WavPack frames directly from -// memory for use in a streaming application. It can handle full blocks -// or the headerless block data provided by Matroska and the DirectShow -// WavPack splitter. For information about how Matroska stores WavPack, -// see: https://www.matroska.org/technical/specs/codecid/wavpack.html - -#include -#include - -#include "wavpack_local.h" - -typedef struct { - unsigned char *sptr, *dptr, *eptr, free_required; -} RawSegment; - -typedef struct { - RawSegment *segments; - int num_segments, curr_segment; - unsigned char ungetc_char, ungetc_flag; -} WavpackRawContext; - -static int32_t raw_read_bytes (void *id, void *data, int32_t bcount) -{ - WavpackRawContext *rcxt = id; - unsigned char *outptr = data; - - while (bcount) { - if (rcxt->ungetc_flag) { - *outptr++ = rcxt->ungetc_char; - rcxt->ungetc_flag = 0; - bcount--; - } - else if (rcxt->curr_segment < rcxt->num_segments) { - RawSegment *segptr = rcxt->segments + rcxt->curr_segment; - int bytes_to_copy = (int)(segptr->eptr - segptr->dptr); - - if (bytes_to_copy > bcount) - bytes_to_copy = bcount; - - memcpy (outptr, segptr->dptr, bytes_to_copy); - outptr += bytes_to_copy; - bcount -= bytes_to_copy; - - if ((segptr->dptr += bytes_to_copy) == segptr->eptr) - rcxt->curr_segment++; - } - else - break; - } - - return (int32_t)(outptr - (unsigned char *) data); -} - -static int32_t raw_write_bytes (void *id, void *data, int32_t bcount) -{ - return 0; -} - -static int64_t raw_get_pos (void *id) -{ - return 0; -} - -static int raw_set_pos_abs (void *id, int64_t pos) -{ - return 0; -} - -static int raw_set_pos_rel (void *id, int64_t delta, int mode) -{ - return 0; -} - -static int raw_push_back_byte (void *id, int c) -{ - WavpackRawContext *rcxt = id; - rcxt->ungetc_char = c; - rcxt->ungetc_flag = 1; - return c; -} - -static int64_t raw_get_length (void *id) -{ - return 0; -} - -static int raw_can_seek (void *id) -{ - return 0; -} - -static int raw_close_stream (void *id) -{ - WavpackRawContext *rcxt = id; - int i; - - if (rcxt) { - for (i = 0; i < rcxt->num_segments; ++i) - if (rcxt->segments [i].sptr && rcxt->segments [i].free_required) - free (rcxt->segments [i].sptr); - - if (rcxt->segments) free (rcxt->segments); - free (rcxt); - } - - return 0; -} - -static WavpackStreamReader64 raw_reader = { - raw_read_bytes, raw_write_bytes, raw_get_pos, raw_set_pos_abs, raw_set_pos_rel, - raw_push_back_byte, raw_get_length, raw_can_seek, NULL, raw_close_stream -}; - -// This function is similar to WavpackOpenFileInput() except that instead of -// providing a filename to open, the caller provides pointers to buffered -// WavPack frames (both standard and, optionally, correction data). It -// decodes only a single frame. Note that in this context, a "frame" is a -// collection of WavPack blocks that represent all the channels present. In -// the case of mono or [most] stereo streams, this is the same thing, but -// for multichannel streams each frame consists of several WavPack blocks -// (which can contain only 1 or 2 channels). - -WavpackContext *WavpackOpenRawDecoder ( - void *main_data, int32_t main_size, - void *corr_data, int32_t corr_size, - int16_t version, char *error, int flags, int norm_offset) -{ - WavpackRawContext *raw_wv = NULL, *raw_wvc = NULL; - - // if the WavPack data does not contain headers we assume Matroska-style storage - // and recreate the missing headers - - if (strncmp (main_data, "wvpk", 4)) { - uint32_t multiple_blocks = 0, block_size, block_samples = 0, wphdr_flags, crc; - uint32_t main_bytes = main_size, corr_bytes = corr_size; - unsigned char *mcp = main_data; - unsigned char *ccp = corr_data; - int msi = 0, csi = 0; - - raw_wv = malloc (sizeof (WavpackRawContext)); - memset (raw_wv, 0, sizeof (WavpackRawContext)); - - if (corr_data && corr_size) { - raw_wvc = malloc (sizeof (WavpackRawContext)); - memset (raw_wvc, 0, sizeof (WavpackRawContext)); - } - - while (main_bytes >= 12) { - if (!msi) { - block_samples = *mcp++; - block_samples += *mcp++ << 8; - block_samples += *mcp++ << 16; - block_samples += *mcp++ << 24; - main_bytes -= 4; - } - - wphdr_flags = *mcp++; - wphdr_flags += *mcp++ << 8; - wphdr_flags += *mcp++ << 16; - wphdr_flags += *mcp++ << 24; - main_bytes -= 4; - - // if the first block does not have the FINAL_BLOCK flag set, - // then there are multiple blocks - - if (!msi && !(wphdr_flags & FINAL_BLOCK)) - multiple_blocks = 1; - - crc = *mcp++; - crc += *mcp++ << 8; - crc += *mcp++ << 16; - crc += *mcp++ << 24; - main_bytes -= 4; - - if (multiple_blocks) { - block_size = *mcp++; - block_size += *mcp++ << 8; - block_size += *mcp++ << 16; - block_size += *mcp++ << 24; - main_bytes -= 4; - } - else - block_size = main_bytes; - - if (block_size > main_bytes) { - if (error) strcpy (error, "main block overran available data!"); - raw_close_stream (raw_wv); - raw_close_stream (raw_wvc); - return NULL; - } - else { - WavpackHeader *wphdr = malloc (sizeof (WavpackHeader)); - memset (wphdr, 0, sizeof (WavpackHeader)); - memcpy (wphdr->ckID, "wvpk", 4); - wphdr->ckSize = sizeof (WavpackHeader) - 8 + block_size; - SET_TOTAL_SAMPLES (*wphdr, block_samples); - wphdr->block_samples = block_samples; - wphdr->version = version; - wphdr->flags = wphdr_flags; - wphdr->crc = crc; - WavpackLittleEndianToNative (wphdr, WavpackHeaderFormat); - - raw_wv->num_segments += 2; - raw_wv->segments = realloc (raw_wv->segments, sizeof (RawSegment) * raw_wv->num_segments); - raw_wv->segments [msi].dptr = raw_wv->segments [msi].sptr = (unsigned char *) wphdr; - raw_wv->segments [msi].eptr = raw_wv->segments [msi].dptr + sizeof (WavpackHeader); - raw_wv->segments [msi++].free_required = 1; - raw_wv->segments [msi].dptr = raw_wv->segments [msi].sptr = mcp; - raw_wv->segments [msi].eptr = raw_wv->segments [msi].dptr + block_size; - raw_wv->segments [msi++].free_required = 0; - main_bytes -= block_size; - mcp += block_size; - } - - if (corr_data && corr_bytes >= 4) { - crc = *ccp++; - crc += *ccp++ << 8; - crc += *ccp++ << 16; - crc += *ccp++ << 24; - corr_bytes -= 4; - - if (multiple_blocks) { - block_size = *ccp++; - block_size += *ccp++ << 8; - block_size += *ccp++ << 16; - block_size += *ccp++ << 24; - corr_bytes -= 4; - } - else - block_size = corr_bytes; - - if (block_size > corr_bytes) { - if (error) strcpy (error, "correction block overran available data!"); - raw_close_stream (raw_wv); - raw_close_stream (raw_wvc); - return NULL; - } - else { - WavpackHeader *wphdr = malloc (sizeof (WavpackHeader)); - memset (wphdr, 0, sizeof (WavpackHeader)); - memcpy (wphdr->ckID, "wvpk", 4); - wphdr->ckSize = sizeof (WavpackHeader) - 8 + block_size; - SET_TOTAL_SAMPLES (*wphdr, block_samples); - wphdr->block_samples = block_samples; - wphdr->version = version; - wphdr->flags = wphdr_flags; - wphdr->crc = crc; - WavpackLittleEndianToNative (wphdr, WavpackHeaderFormat); - - raw_wvc->num_segments += 2; - raw_wvc->segments = realloc (raw_wvc->segments, sizeof (RawSegment) * raw_wvc->num_segments); - raw_wvc->segments [csi].dptr = raw_wvc->segments [csi].sptr = (unsigned char *) wphdr; - raw_wvc->segments [csi].eptr = raw_wvc->segments [csi].dptr + sizeof (WavpackHeader); - raw_wvc->segments [csi++].free_required = 1; - raw_wvc->segments [csi].dptr = raw_wvc->segments [csi].sptr = ccp; - raw_wvc->segments [csi].eptr = raw_wvc->segments [csi].dptr + block_size; - raw_wvc->segments [csi++].free_required = 0; - corr_bytes -= block_size; - ccp += block_size; - } - } - } - - if (main_bytes || (corr_data && corr_bytes)) { - if (error) strcpy (error, "leftover multiblock data!"); - raw_close_stream (raw_wv); - raw_close_stream (raw_wvc); - return NULL; - } - } - else { // the case of WavPack blocks with headers is much easier... - if (main_data) { - raw_wv = malloc (sizeof (WavpackRawContext)); - memset (raw_wv, 0, sizeof (WavpackRawContext)); - raw_wv->num_segments = 1; - raw_wv->segments = malloc (sizeof (RawSegment) * raw_wv->num_segments); - raw_wv->segments [0].dptr = raw_wv->segments [0].sptr = main_data; - raw_wv->segments [0].eptr = raw_wv->segments [0].dptr + main_size; - raw_wv->segments [0].free_required = 0; - } - - if (corr_data && corr_size) { - raw_wvc = malloc (sizeof (WavpackRawContext)); - memset (raw_wvc, 0, sizeof (WavpackRawContext)); - raw_wvc->num_segments = 1; - raw_wvc->segments = malloc (sizeof (RawSegment) * raw_wvc->num_segments); - raw_wvc->segments [0].dptr = raw_wvc->segments [0].sptr = corr_data; - raw_wvc->segments [0].eptr = raw_wvc->segments [0].dptr + corr_size; - raw_wvc->segments [0].free_required = 0; - } - } - - return WavpackOpenFileInputEx64 (&raw_reader, raw_wv, raw_wvc, error, flags | OPEN_STREAMING | OPEN_NO_CHECKSUM, norm_offset); -} - -// Return the number of samples represented by the current (and in the raw case, only) frame. - -uint32_t WavpackGetNumSamplesInFrame (WavpackContext *wpc) -{ - if (wpc && wpc->streams && wpc->streams [0]) - return wpc->streams [0]->wphdr.block_samples; - else - return -1; -} - diff --git a/Frameworks/WavPack/Files/open_utils.c b/Frameworks/WavPack/Files/open_utils.c deleted file mode 100644 index dfb7cf632..000000000 --- a/Frameworks/WavPack/Files/open_utils.c +++ /dev/null @@ -1,1284 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2019 David Bryant. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// open_utils.c - -// This module provides all the code required to open an existing WavPack file -// for reading by using a reader callback mechanism (NOT a filename). This -// includes the code required to find and parse WavPack blocks, process any -// included metadata, and queue up the bitstreams containing the encoded audio -// data. It does not the actual code to unpack audio data and this was done so -// that programs that just want to query WavPack files for information (like, -// for example, taggers) don't need to link in a lot of unnecessary code. - -#include -#include - -#include "wavpack_local.h" - -// This function is identical to WavpackOpenFileInput() except that instead -// of providing a filename to open, the caller provides a pointer to a set of -// reader callbacks and instances of up to two streams. The first of these -// streams is required and contains the regular WavPack data stream; the second -// contains the "correction" file if desired. Unlike the standard open -// function which handles the correction file transparently, in this case it -// is the responsibility of the caller to be aware of correction files. - -static int seek_eof_information (WavpackContext *wpc, int64_t *final_index, int get_wrapper); - -WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset) -{ - WavpackContext *wpc = (WavpackContext *)malloc (sizeof (WavpackContext)); - WavpackStream *wps; - int num_blocks = 0; - unsigned char first_byte; - uint32_t bcount; - - if (!wpc) { - if (error) strcpy (error, "can't allocate memory"); - return NULL; - } - - CLEAR (*wpc); - wpc->wv_in = wv_id; - wpc->wvc_in = wvc_id; - wpc->reader = reader; - wpc->total_samples = -1; - wpc->norm_offset = norm_offset; - wpc->max_streams = OLD_MAX_STREAMS; // use this until overwritten with actual number - wpc->open_flags = flags; - - wpc->filelen = wpc->reader->get_length (wpc->wv_in); - -#ifndef NO_TAGS - if ((flags & (OPEN_TAGS | OPEN_EDIT_TAGS)) && wpc->reader->can_seek (wpc->wv_in)) { - load_tag (wpc); - wpc->reader->set_pos_abs (wpc->wv_in, 0); - - if ((flags & OPEN_EDIT_TAGS) && !editable_tag (&wpc->m_tag)) { - if (error) strcpy (error, "can't edit tags located at the beginning of files!"); - return WavpackCloseFile (wpc); - } - } -#endif - - if (wpc->reader->read_bytes (wpc->wv_in, &first_byte, 1) != 1) { - if (error) strcpy (error, "can't read all of WavPack file!"); - return WavpackCloseFile (wpc); - } - - wpc->reader->push_back_byte (wpc->wv_in, first_byte); - - if (first_byte == 'R') { -#ifdef ENABLE_LEGACY - return open_file3 (wpc, error); -#else - if (error) strcpy (error, "this legacy WavPack file is deprecated, use version 4.80.0 to transcode"); - return WavpackCloseFile (wpc); -#endif - } - - wpc->streams = (WavpackStream **)(malloc ((wpc->num_streams = 1) * sizeof (wpc->streams [0]))); - if (!wpc->streams) { - if (error) strcpy (error, "can't allocate memory"); - return WavpackCloseFile (wpc); - } - - wpc->streams [0] = wps = (WavpackStream *)malloc (sizeof (WavpackStream)); - if (!wps) { - if (error) strcpy (error, "can't allocate memory"); - return WavpackCloseFile (wpc); - } - CLEAR (*wps); - - while (!wps->wphdr.block_samples) { - - wpc->filepos = wpc->reader->get_pos (wpc->wv_in); - bcount = read_next_header (wpc->reader, wpc->wv_in, &wps->wphdr); - - if (bcount == (uint32_t) -1 || - (!wps->wphdr.block_samples && num_blocks++ > 16)) { - if (error) strcpy (error, "not compatible with this version of WavPack file!"); - return WavpackCloseFile (wpc); - } - - wpc->filepos += bcount; - wps->blockbuff = (unsigned char *)malloc (wps->wphdr.ckSize + 8); - if (!wps->blockbuff) { - if (error) strcpy (error, "can't allocate memory"); - return WavpackCloseFile (wpc); - } - memcpy (wps->blockbuff, &wps->wphdr, 32); - - if (wpc->reader->read_bytes (wpc->wv_in, wps->blockbuff + 32, wps->wphdr.ckSize - 24) != wps->wphdr.ckSize - 24) { - if (error) strcpy (error, "can't read all of WavPack file!"); - return WavpackCloseFile (wpc); - } - - // if block does not verify, flag error, free buffer, and continue - if (!WavpackVerifySingleBlock (wps->blockbuff, !(flags & OPEN_NO_CHECKSUM))) { - wps->wphdr.block_samples = 0; - free (wps->blockbuff); - wps->blockbuff = NULL; - wpc->crc_errors++; - continue; - } - - wps->init_done = FALSE; - - if (wps->wphdr.block_samples) { - if (flags & OPEN_STREAMING) - SET_BLOCK_INDEX (wps->wphdr, 0); - else if (wpc->total_samples == -1) { - if (GET_BLOCK_INDEX (wps->wphdr) || GET_TOTAL_SAMPLES (wps->wphdr) == -1) { - wpc->initial_index = GET_BLOCK_INDEX (wps->wphdr); - SET_BLOCK_INDEX (wps->wphdr, 0); - - if (wpc->reader->can_seek (wpc->wv_in)) { - int64_t final_index = -1; - - seek_eof_information (wpc, &final_index, FALSE); - - if (final_index != -1) - wpc->total_samples = final_index - wpc->initial_index; - } - } - else - wpc->total_samples = GET_TOTAL_SAMPLES (wps->wphdr); - } - } - else if (wpc->total_samples == -1 && !GET_BLOCK_INDEX (wps->wphdr) && GET_TOTAL_SAMPLES (wps->wphdr)) - wpc->total_samples = GET_TOTAL_SAMPLES (wps->wphdr); - - if (wpc->wvc_in && wps->wphdr.block_samples && (wps->wphdr.flags & HYBRID_FLAG)) { - unsigned char ch; - - if (wpc->reader->read_bytes (wpc->wvc_in, &ch, 1) == 1) { - wpc->reader->push_back_byte (wpc->wvc_in, ch); - wpc->file2len = wpc->reader->get_length (wpc->wvc_in); - wpc->wvc_flag = TRUE; - } - } - - if (wpc->wvc_flag && !read_wvc_block (wpc)) { - if (error) strcpy (error, "not compatible with this version of correction file!"); - return WavpackCloseFile (wpc); - } - - if (!wps->init_done && !unpack_init (wpc)) { - if (error) strcpy (error, wpc->error_message [0] ? wpc->error_message : - "not compatible with this version of WavPack file!"); - - return WavpackCloseFile (wpc); - } - - if (!wps->wphdr.block_samples) { // free blockbuff if we're going to loop again - free (wps->blockbuff); - wps->blockbuff = NULL; - } - - wps->init_done = TRUE; - } - - wpc->config.flags &= ~0xff; - wpc->config.flags |= wps->wphdr.flags & 0xff; - - if (!wpc->config.num_channels) { - wpc->config.num_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2; - wpc->config.channel_mask = 0x5 - wpc->config.num_channels; - } - - if ((flags & OPEN_2CH_MAX) && !(wps->wphdr.flags & FINAL_BLOCK)) - wpc->reduced_channels = (wps->wphdr.flags & MONO_FLAG) ? 1 : 2; - - if (wps->wphdr.flags & DSD_FLAG) { -#ifdef ENABLE_DSD - if (flags & OPEN_DSD_NATIVE) { - wpc->config.bytes_per_sample = 1; - wpc->config.bits_per_sample = 8; - } - else if (flags & OPEN_DSD_AS_PCM) { - wpc->decimation_context = decimate_dsd_init (wpc->reduced_channels ? - wpc->reduced_channels : wpc->config.num_channels); - - wpc->config.bytes_per_sample = 3; - wpc->config.bits_per_sample = 24; - } - else { - if (error) strcpy (error, "not configured to handle DSD WavPack files!"); - return WavpackCloseFile (wpc); - } -#else - if (error) strcpy (error, "not configured to handle DSD WavPack files!"); - return WavpackCloseFile (wpc); -#endif - } - else { - wpc->config.bytes_per_sample = (wps->wphdr.flags & BYTES_STORED) + 1; - wpc->config.float_norm_exp = wps->float_norm_exp; - - wpc->config.bits_per_sample = (wpc->config.bytes_per_sample * 8) - - ((wps->wphdr.flags & SHIFT_MASK) >> SHIFT_LSB); - } - - if (!wpc->config.sample_rate) { - if (!wps->wphdr.block_samples || (wps->wphdr.flags & SRATE_MASK) == SRATE_MASK) - wpc->config.sample_rate = 44100; - else - wpc->config.sample_rate = sample_rates [(wps->wphdr.flags & SRATE_MASK) >> SRATE_LSB]; - } - - return wpc; -} - -// This function returns the major version number of the WavPack program -// (or library) that created the open file. Currently, this can be 1 to 5. -// Minor versions are not recorded in WavPack files. - -int WavpackGetVersion (WavpackContext *wpc) -{ - if (wpc) { -#ifdef ENABLE_LEGACY - if (wpc->stream3) - return get_version3 (wpc); -#endif - return wpc->version_five ? 5 : 4; - } - - return 0; -} - -// Return the file format specified in the call to WavpackSetFileInformation() -// when the file was created. For all files created prior to WavPack 5.0 this -// will 0 (WP_FORMAT_WAV). - -unsigned char WavpackGetFileFormat (WavpackContext *wpc) -{ - return wpc->file_format; -} - -// Return a string representing the recommended file extension for the open -// WavPack file. For all files created prior to WavPack 5.0 this will be "wav", -// even for raw files with no RIFF into. This string is specified in the -// call to WavpackSetFileInformation() when the file was created. - -char *WavpackGetFileExtension (WavpackContext *wpc) -{ - if (wpc && wpc->file_extension [0]) - return wpc->file_extension; - else - return "wav"; -} - -// This function initializes everything required to unpack a WavPack block -// and must be called before unpack_samples() is called to obtain audio data. -// It is assumed that the WavpackHeader has been read into the wps->wphdr -// (in the current WavpackStream) and that the entire block has been read at -// wps->blockbuff. If a correction file is available (wpc->wvc_flag = TRUE) -// then the corresponding correction block must be read into wps->block2buff -// and its WavpackHeader has overwritten the header at wps->wphdr. This is -// where all the metadata blocks are scanned including those that contain -// bitstream data. - -static int read_metadata_buff (WavpackMetadata *wpmd, unsigned char *blockbuff, unsigned char **buffptr); -static int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd); -static void bs_open_read (Bitstream *bs, void *buffer_start, void *buffer_end); - -int unpack_init (WavpackContext *wpc) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - unsigned char *blockptr, *block2ptr; - WavpackMetadata wpmd; - - wps->num_terms = 0; - wps->mute_error = FALSE; - wps->crc = wps->crc_x = 0xffffffff; - wps->dsd.ready = 0; - CLEAR (wps->wvbits); - CLEAR (wps->wvcbits); - CLEAR (wps->wvxbits); - CLEAR (wps->decorr_passes); - CLEAR (wps->dc); - CLEAR (wps->w); - - if (!(wps->wphdr.flags & MONO_FLAG) && wpc->config.num_channels && wps->wphdr.block_samples && - (wpc->reduced_channels == 1 || wpc->config.num_channels == 1)) { - wps->mute_error = TRUE; - return FALSE; - } - - if ((wps->wphdr.flags & UNKNOWN_FLAGS) || (wps->wphdr.flags & MONO_DATA) == MONO_DATA) { - wps->mute_error = TRUE; - return FALSE; - } - - blockptr = wps->blockbuff + sizeof (WavpackHeader); - - while (read_metadata_buff (&wpmd, wps->blockbuff, &blockptr)) - if (!process_metadata (wpc, &wpmd)) { - wps->mute_error = TRUE; - return FALSE; - } - - if (wps->wphdr.block_samples && wpc->wvc_flag && wps->block2buff) { - block2ptr = wps->block2buff + sizeof (WavpackHeader); - - while (read_metadata_buff (&wpmd, wps->block2buff, &block2ptr)) - if (!process_metadata (wpc, &wpmd)) { - wps->mute_error = TRUE; - return FALSE; - } - } - - if (wps->wphdr.block_samples && ((wps->wphdr.flags & DSD_FLAG) ? !wps->dsd.ready : !bs_is_open (&wps->wvbits))) { - if (bs_is_open (&wps->wvcbits)) - strcpy (wpc->error_message, "can't unpack correction files alone!"); - - wps->mute_error = TRUE; - return FALSE; - } - - if (wps->wphdr.block_samples && !bs_is_open (&wps->wvxbits)) { - if ((wps->wphdr.flags & INT32_DATA) && wps->int32_sent_bits) - wpc->lossy_blocks = TRUE; - - if ((wps->wphdr.flags & FLOAT_DATA) && - wps->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT | FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME)) - wpc->lossy_blocks = TRUE; - } - - if (wps->wphdr.block_samples) - wps->sample_index = GET_BLOCK_INDEX (wps->wphdr); - - return TRUE; -} - -//////////////////////////////// matadata handlers /////////////////////////////// - -// These functions handle specific metadata types and are called directly -// during WavPack block parsing by process_metadata() at the bottom. - -// This function initializes the main bitstream for audio samples, which must -// be in the "wv" file. - -static int init_wv_bitstream (WavpackStream *wps, WavpackMetadata *wpmd) -{ - if (!wpmd->byte_length || (wpmd->byte_length & 1)) - return FALSE; - - bs_open_read (&wps->wvbits, wpmd->data, (unsigned char *) wpmd->data + wpmd->byte_length); - return TRUE; -} - -// This function initializes the "correction" bitstream for audio samples, -// which currently must be in the "wvc" file. - -static int init_wvc_bitstream (WavpackStream *wps, WavpackMetadata *wpmd) -{ - if (!wpmd->byte_length || (wpmd->byte_length & 1)) - return FALSE; - - bs_open_read (&wps->wvcbits, wpmd->data, (unsigned char *) wpmd->data + wpmd->byte_length); - return TRUE; -} - -// This function initializes the "extra" bitstream for audio samples which -// contains the information required to losslessly decompress 32-bit float data -// or integer data that exceeds 24 bits. This bitstream is in the "wv" file -// for pure lossless data or the "wvc" file for hybrid lossless. This data -// would not be used for hybrid lossy mode. There is also a 32-bit CRC stored -// in the first 4 bytes of these blocks. - -static int init_wvx_bitstream (WavpackStream *wps, WavpackMetadata *wpmd) -{ - unsigned char *cp = (unsigned char *)wpmd->data; - - if (wpmd->byte_length <= 4 || (wpmd->byte_length & 1)) - return FALSE; - - wps->crc_wvx = *cp++; - wps->crc_wvx |= (int32_t) *cp++ << 8; - wps->crc_wvx |= (int32_t) *cp++ << 16; - wps->crc_wvx |= (int32_t) *cp++ << 24; - - bs_open_read (&wps->wvxbits, cp, (unsigned char *) wpmd->data + wpmd->byte_length); - return TRUE; -} - -// Read the int32 data from the specified metadata into the specified stream. -// This data is used for integer data that has more than 24 bits of magnitude -// or, in some cases, used to eliminate redundant bits from any audio stream. - -static int read_int32_info (WavpackStream *wps, WavpackMetadata *wpmd) -{ - int bytecnt = wpmd->byte_length; - char *byteptr = (char *)wpmd->data; - - if (bytecnt != 4) - return FALSE; - - wps->int32_sent_bits = *byteptr++; - wps->int32_zeros = *byteptr++; - wps->int32_ones = *byteptr++; - wps->int32_dups = *byteptr; - - return TRUE; -} - -static int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd) -{ - int bytecnt = wpmd->byte_length; - char *byteptr = (char *)wpmd->data; - - if (bytecnt != 4) - return FALSE; - - wps->float_flags = *byteptr++; - wps->float_shift = *byteptr++; - wps->float_max_exp = *byteptr++; - wps->float_norm_exp = *byteptr; - return TRUE; -} - -// Read multichannel information from metadata. The first byte is the total -// number of channels and the following bytes represent the channel_mask -// as described for Microsoft WAVEFORMATEX. - -static int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - int bytecnt = wpmd->byte_length, shift = 0, mask_bits; - unsigned char *byteptr = (unsigned char *)wpmd->data; - uint32_t mask = 0; - - if (!bytecnt || bytecnt > 7) - return FALSE; - - if (!wpc->config.num_channels) { - - // if bytecnt is 6 or 7 we are using new configuration with "unlimited" streams - - if (bytecnt >= 6) { - wpc->config.num_channels = (byteptr [0] | ((byteptr [2] & 0xf) << 8)) + 1; - wpc->max_streams = (byteptr [1] | ((byteptr [2] & 0xf0) << 4)) + 1; - - if (wpc->config.num_channels < wpc->max_streams) - return FALSE; - - byteptr += 3; - mask = *byteptr++; - mask |= (uint32_t) *byteptr++ << 8; - mask |= (uint32_t) *byteptr++ << 16; - - if (bytecnt == 7) // this was introduced in 5.0 - mask |= (uint32_t) *byteptr << 24; - } - else { - wpc->config.num_channels = *byteptr++; - - while (--bytecnt) { - mask |= (uint32_t) *byteptr++ << shift; - shift += 8; - } - } - - if (wpc->config.num_channels > wpc->max_streams * 2) - return FALSE; - - wpc->config.channel_mask = mask; - - for (mask_bits = 0; mask; mask >>= 1) - if ((mask & 1) && ++mask_bits > wpc->config.num_channels) - return FALSE; - } - - return TRUE; -} - -// Read multichannel identity information from metadata. Data is an array of -// unsigned characters representing any channels in the file that DO NOT -// match one the 18 Microsoft standard channels (and are represented in the -// channel mask). A value of 0 is not allowed and 0xff means an unknown or -// undefined channel identity. - -static int read_channel_identities (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - if (!wpc->channel_identities) { - wpc->channel_identities = (unsigned char *)malloc (wpmd->byte_length + 1); - memcpy (wpc->channel_identities, wpmd->data, wpmd->byte_length); - wpc->channel_identities [wpmd->byte_length] = 0; - } - - return TRUE; -} - -// Read configuration information from metadata. - -static int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - int bytecnt = wpmd->byte_length; - unsigned char *byteptr = (unsigned char *)wpmd->data; - - if (bytecnt >= 3) { - wpc->config.flags &= 0xff; - wpc->config.flags |= (int32_t) *byteptr++ << 8; - wpc->config.flags |= (int32_t) *byteptr++ << 16; - wpc->config.flags |= (int32_t) *byteptr++ << 24; - bytecnt -= 3; - - if (bytecnt && (wpc->config.flags & CONFIG_EXTRA_MODE)) { - wpc->config.xmode = *byteptr++; - bytecnt--; - } - - // we used an extra config byte here for the 5.0.0 alpha, so still - // honor it now (but this has been replaced with NEW_CONFIG) - - if (bytecnt) { - wpc->config.qmode = (wpc->config.qmode & ~0xff) | *byteptr; - wpc->version_five = 1; - } - } - - return TRUE; -} - -// Read "new" configuration information from metadata. - -static int read_new_config_info (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - int bytecnt = wpmd->byte_length; - unsigned char *byteptr = (unsigned char *)wpmd->data; - - wpc->version_five = 1; // just having this block signals version 5.0 - - wpc->file_format = wpc->config.qmode = wpc->channel_layout = 0; - - if (wpc->channel_reordering) { - free (wpc->channel_reordering); - wpc->channel_reordering = NULL; - } - - // if there's any data, the first two bytes are file_format and qmode flags - - if (bytecnt >= 2) { - wpc->file_format = *byteptr++; - wpc->config.qmode = (wpc->config.qmode & ~0xff) | *byteptr++; - bytecnt -= 2; - - // another byte indicates a channel layout - - if (bytecnt) { - int nchans, i; - - wpc->channel_layout = (int32_t) *byteptr++ << 16; - bytecnt--; - - // another byte means we have a channel count for the layout and maybe a reordering - - if (bytecnt) { - wpc->channel_layout += nchans = *byteptr++; - bytecnt--; - - // any more means there's a reordering string - - if (bytecnt) { - if (bytecnt > nchans) - return FALSE; - - wpc->channel_reordering = (unsigned char *)malloc (nchans); - - // note that redundant reordering info is not stored, so we fill in the rest - - if (wpc->channel_reordering) { - for (i = 0; i < nchans; ++i) - if (bytecnt) { - wpc->channel_reordering [i] = *byteptr++; - - if (wpc->channel_reordering [i] >= nchans) // make sure index is in range - wpc->channel_reordering [i] = 0; - - bytecnt--; - } - else - wpc->channel_reordering [i] = i; - } - } - } - else - wpc->channel_layout += wpc->config.num_channels; - } - } - - return TRUE; -} - -// Read non-standard sampling rate from metadata. - -static int read_sample_rate (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - int bytecnt = wpmd->byte_length; - unsigned char *byteptr = (unsigned char *)wpmd->data; - - if (bytecnt == 3 || bytecnt == 4) { - wpc->config.sample_rate = (int32_t) *byteptr++; - wpc->config.sample_rate |= (int32_t) *byteptr++ << 8; - wpc->config.sample_rate |= (int32_t) *byteptr++ << 16; - - // for sampling rates > 16777215 (non-audio probably, or ...) - - if (bytecnt == 4) - wpc->config.sample_rate |= (int32_t) (*byteptr & 0x7f) << 24; - } - - return TRUE; -} - -// Read wrapper data from metadata. Currently, this consists of the RIFF -// header and trailer that wav files contain around the audio data but could -// be used for other formats as well. Because WavPack files contain all the -// information required for decoding and playback, this data can probably -// be ignored except when an exact wavefile restoration is needed. - -static int read_wrapper_data (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - if ((wpc->open_flags & OPEN_WRAPPER) && wpc->wrapper_bytes < MAX_WRAPPER_BYTES && wpmd->byte_length) { - wpc->wrapper_data = (unsigned char *)realloc (wpc->wrapper_data, wpc->wrapper_bytes + wpmd->byte_length); - if (!wpc->wrapper_data) - return FALSE; - memcpy (wpc->wrapper_data + wpc->wrapper_bytes, wpmd->data, wpmd->byte_length); - wpc->wrapper_bytes += wpmd->byte_length; - } - - return TRUE; -} - -static int read_metadata_buff (WavpackMetadata *wpmd, unsigned char *blockbuff, unsigned char **buffptr) -{ - WavpackHeader *wphdr = (WavpackHeader *) blockbuff; - unsigned char *buffend = blockbuff + wphdr->ckSize + 8; - - if (buffend - *buffptr < 2) - return FALSE; - - wpmd->id = *(*buffptr)++; - wpmd->byte_length = *(*buffptr)++ << 1; - - if (wpmd->id & ID_LARGE) { - wpmd->id &= ~ID_LARGE; - - if (buffend - *buffptr < 2) - return FALSE; - - wpmd->byte_length += *(*buffptr)++ << 9; - wpmd->byte_length += *(*buffptr)++ << 17; - } - - if (wpmd->id & ID_ODD_SIZE) { - if (!wpmd->byte_length) // odd size and zero length makes no sense - return FALSE; - wpmd->id &= ~ID_ODD_SIZE; - wpmd->byte_length--; - } - - if (wpmd->byte_length) { - if (buffend - *buffptr < wpmd->byte_length + (wpmd->byte_length & 1)) { - wpmd->data = NULL; - return FALSE; - } - - wpmd->data = *buffptr; - (*buffptr) += wpmd->byte_length + (wpmd->byte_length & 1); - } - else - wpmd->data = NULL; - - return TRUE; -} - -static int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - - switch (wpmd->id) { - case ID_DUMMY: - return TRUE; - - case ID_DECORR_TERMS: - return read_decorr_terms (wps, wpmd); - - case ID_DECORR_WEIGHTS: - return read_decorr_weights (wps, wpmd); - - case ID_DECORR_SAMPLES: - return read_decorr_samples (wps, wpmd); - - case ID_ENTROPY_VARS: - return read_entropy_vars (wps, wpmd); - - case ID_HYBRID_PROFILE: - return read_hybrid_profile (wps, wpmd); - - case ID_SHAPING_WEIGHTS: - return read_shaping_info (wps, wpmd); - - case ID_FLOAT_INFO: - return read_float_info (wps, wpmd); - - case ID_INT32_INFO: - return read_int32_info (wps, wpmd); - - case ID_CHANNEL_INFO: - return read_channel_info (wpc, wpmd); - - case ID_CHANNEL_IDENTITIES: - return read_channel_identities (wpc, wpmd); - - case ID_CONFIG_BLOCK: - return read_config_info (wpc, wpmd); - - case ID_NEW_CONFIG_BLOCK: - return read_new_config_info (wpc, wpmd); - - case ID_SAMPLE_RATE: - return read_sample_rate (wpc, wpmd); - - case ID_WV_BITSTREAM: - return init_wv_bitstream (wps, wpmd); - - case ID_WVC_BITSTREAM: - return init_wvc_bitstream (wps, wpmd); - - case ID_WVX_BITSTREAM: - return init_wvx_bitstream (wps, wpmd); - - case ID_DSD_BLOCK: -#ifdef ENABLE_DSD - return init_dsd_block (wpc, wpmd); -#else - strcpy (wpc->error_message, "not configured to handle DSD WavPack files!"); - return FALSE; -#endif - - case ID_ALT_HEADER: case ID_ALT_TRAILER: - if (!(wpc->open_flags & OPEN_ALT_TYPES)) - return TRUE; - - case ID_RIFF_HEADER: case ID_RIFF_TRAILER: - return read_wrapper_data (wpc, wpmd); - - case ID_ALT_MD5_CHECKSUM: - if (!(wpc->open_flags & OPEN_ALT_TYPES)) - return TRUE; - - case ID_MD5_CHECKSUM: - if (wpmd->byte_length == 16) { - memcpy (wpc->config.md5_checksum, wpmd->data, 16); - wpc->config.flags |= CONFIG_MD5_CHECKSUM; - wpc->config.md5_read = 1; - } - - return TRUE; - - case ID_ALT_EXTENSION: - if (wpmd->byte_length && wpmd->byte_length < sizeof (wpc->file_extension)) { - memcpy (wpc->file_extension, wpmd->data, wpmd->byte_length); - wpc->file_extension [wpmd->byte_length] = 0; - } - - return TRUE; - - // we don't actually verify the checksum here (it's done right after the - // block is read), but it's a good indicator of version 5 files - - case ID_BLOCK_CHECKSUM: - wpc->version_five = 1; - return TRUE; - - default: - return (wpmd->id & ID_OPTIONAL_DATA) ? TRUE : FALSE; - } -} - -//////////////////////////////// bitstream management /////////////////////////////// - -// Open the specified BitStream and associate with the specified buffer. - -static void bs_read (Bitstream *bs); - -static void bs_open_read (Bitstream *bs, void *buffer_start, void *buffer_end) -{ - bs->error = bs->sr = bs->bc = 0; - bs->ptr = (bs->buf = buffer_start) - 1; - bs->end = buffer_end; - bs->wrap = bs_read; -} - -// This function is only called from the getbit() and getbits() macros when -// the BitStream has been exhausted and more data is required. Sinve these -// bistreams no longer access files, this function simple sets an error and -// resets the buffer. - -static void bs_read (Bitstream *bs) -{ - bs->ptr = bs->buf; - bs->error = 1; -} - -// This function is called to close the bitstream. It returns the number of -// full bytes actually read as bits. - -uint32_t bs_close_read (Bitstream *bs) -{ - uint32_t bytes_read; - - if (bs->bc < sizeof (*(bs->ptr)) * 8) - bs->ptr++; - - bytes_read = (uint32_t)(bs->ptr - bs->buf) * sizeof (*(bs->ptr)); - - if (!(bytes_read & 1)) - ++bytes_read; - - CLEAR (*bs); - return bytes_read; -} - -// Normally the trailing wrapper will not be available when a WavPack file is first -// opened for reading because it is stored in the final block of the file. This -// function forces a seek to the end of the file to pick up any trailing wrapper -// stored there (then use WavPackGetWrapper**() to obtain). This can obviously only -// be used for seekable files (not pipes) and is not available for pre-4.0 WavPack -// files. - -void WavpackSeekTrailingWrapper (WavpackContext *wpc) -{ - if ((wpc->open_flags & OPEN_WRAPPER) && - wpc->reader->can_seek (wpc->wv_in) && !wpc->stream3) - seek_eof_information (wpc, NULL, TRUE); -} - -// Get any MD5 checksum stored in the metadata (should be called after reading -// last sample or an extra seek will occur). A return value of FALSE indicates -// that no MD5 checksum was stored. - -int WavpackGetMD5Sum (WavpackContext *wpc, unsigned char data [16]) -{ - if (wpc->config.flags & CONFIG_MD5_CHECKSUM) { - if (!wpc->config.md5_read && wpc->reader->can_seek (wpc->wv_in)) - seek_eof_information (wpc, NULL, FALSE); - - if (wpc->config.md5_read) { - memcpy (data, wpc->config.md5_checksum, 16); - return TRUE; - } - } - - return FALSE; -} - -// Read from current file position until a valid 32-byte WavPack 4.0 header is -// found and read into the specified pointer. The number of bytes skipped is -// returned. If no WavPack header is found within 1 meg, then a -1 is returned -// to indicate the error. No additional bytes are read past the header and it -// is returned in the processor's native endian mode. Seeking is not required. - -uint32_t read_next_header (WavpackStreamReader64 *reader, void *id, WavpackHeader *wphdr) -{ - unsigned char buffer [sizeof (*wphdr)], *sp = buffer + sizeof (*wphdr), *ep = sp; - uint32_t bytes_skipped = 0; - int bleft; - - while (1) { - if (sp < ep) { - bleft = (int)(ep - sp); - memmove (buffer, sp, bleft); - } - else - bleft = 0; - - if (reader->read_bytes (id, buffer + bleft, sizeof (*wphdr) - bleft) != sizeof (*wphdr) - bleft) - return -1; - - sp = buffer; - - if (*sp++ == 'w' && *sp == 'v' && *++sp == 'p' && *++sp == 'k' && - !(*++sp & 1) && sp [2] < 16 && !sp [3] && (sp [2] || sp [1] || *sp >= 24) && sp [5] == 4 && - sp [4] >= (MIN_STREAM_VERS & 0xff) && sp [4] <= (MAX_STREAM_VERS & 0xff) && sp [18] < 3 && !sp [19]) { - memcpy (wphdr, buffer, sizeof (*wphdr)); - WavpackLittleEndianToNative (wphdr, WavpackHeaderFormat); - return bytes_skipped; - } - - while (sp < ep && *sp != 'w') - sp++; - - if ((bytes_skipped += (uint32_t)(sp - buffer)) > 1024 * 1024) - return -1; - } -} - -// Compare the regular wv file block header to a potential matching wvc -// file block header and return action code based on analysis: -// -// 0 = use wvc block (assuming rest of block is readable) -// 1 = bad match; try to read next wvc block -// -1 = bad match; ignore wvc file for this block and backup fp (if -// possible) and try to use this block next time - -static int match_wvc_header (WavpackHeader *wv_hdr, WavpackHeader *wvc_hdr) -{ - if (GET_BLOCK_INDEX (*wv_hdr) == GET_BLOCK_INDEX (*wvc_hdr) && - wv_hdr->block_samples == wvc_hdr->block_samples) { - int wvi = 0, wvci = 0; - - if (wv_hdr->flags == wvc_hdr->flags) - return 0; - - if (wv_hdr->flags & INITIAL_BLOCK) - wvi -= 1; - - if (wv_hdr->flags & FINAL_BLOCK) - wvi += 1; - - if (wvc_hdr->flags & INITIAL_BLOCK) - wvci -= 1; - - if (wvc_hdr->flags & FINAL_BLOCK) - wvci += 1; - - return (wvci - wvi < 0) ? 1 : -1; - } - - if (((GET_BLOCK_INDEX (*wvc_hdr) - GET_BLOCK_INDEX (*wv_hdr)) << 24) < 0) - return 1; - else - return -1; -} - -// Read the wvc block that matches the regular wv block that has been -// read for the current stream. If an exact match is not found then -// we either keep reading or back up and (possibly) use the block -// later. The skip_wvc flag is set if not matching wvc block is found -// so that we can still decode using only the lossy version (although -// we flag this as an error). A return of FALSE indicates a serious -// error (not just that we missed one wvc block). - -int read_wvc_block (WavpackContext *wpc) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int64_t bcount, file2pos; - WavpackHeader orig_wphdr; - WavpackHeader wphdr; - int compare_result; - - while (1) { - file2pos = wpc->reader->get_pos (wpc->wvc_in); - bcount = read_next_header (wpc->reader, wpc->wvc_in, &wphdr); - - if (bcount == (uint32_t) -1) { - wps->wvc_skip = TRUE; - wpc->crc_errors++; - return FALSE; - } - - memcpy (&orig_wphdr, &wphdr, 32); // save original header for verify step - - if (wpc->open_flags & OPEN_STREAMING) - SET_BLOCK_INDEX (wphdr, wps->sample_index = 0); - else - SET_BLOCK_INDEX (wphdr, GET_BLOCK_INDEX (wphdr) - wpc->initial_index); - - if (wphdr.flags & INITIAL_BLOCK) - wpc->file2pos = file2pos + bcount; - - compare_result = match_wvc_header (&wps->wphdr, &wphdr); - - if (!compare_result) { - wps->block2buff = (unsigned char *)malloc (wphdr.ckSize + 8); - if (!wps->block2buff) - return FALSE; - - if (wpc->reader->read_bytes (wpc->wvc_in, wps->block2buff + 32, wphdr.ckSize - 24) != - wphdr.ckSize - 24) { - free (wps->block2buff); - wps->block2buff = NULL; - wps->wvc_skip = TRUE; - wpc->crc_errors++; - return FALSE; - } - - memcpy (wps->block2buff, &orig_wphdr, 32); - - // don't use corrupt blocks - if (!WavpackVerifySingleBlock (wps->block2buff, !(wpc->open_flags & OPEN_NO_CHECKSUM))) { - free (wps->block2buff); - wps->block2buff = NULL; - wps->wvc_skip = TRUE; - wpc->crc_errors++; - return TRUE; - } - - wps->wvc_skip = FALSE; - memcpy (wps->block2buff, &wphdr, 32); - memcpy (&wps->wphdr, &wphdr, 32); - return TRUE; - } - else if (compare_result == -1) { - wps->wvc_skip = TRUE; - wpc->reader->set_pos_rel (wpc->wvc_in, -32, SEEK_CUR); - wpc->crc_errors++; - return TRUE; - } - } -} - -// This function is used to seek to end of a file to obtain certain information -// that is stored there at the file creation time because it is not known at -// the start. This includes the MD5 sum and and trailing part of the file -// wrapper, and in some rare cases may include the total number of samples in -// the file (although we usually try to back up and write that at the front of -// the file). Note this function restores the file position to its original -// location (and obviously requires a seekable file). The normal return value -// is TRUE indicating no errors, although this does not actually mean that any -// information was retrieved. An error return of FALSE usually means the file -// terminated unexpectedly. Note that this could be used to get all three -// types of information in one go, but it's not actually used that way now. - -static int seek_eof_information (WavpackContext *wpc, int64_t *final_index, int get_wrapper) -{ - int64_t restore_pos, last_pos = -1; - WavpackStreamReader64 *reader = wpc->reader; - int alt_types = wpc->open_flags & OPEN_ALT_TYPES; - uint32_t blocks = 0, audio_blocks = 0; - void *id = wpc->wv_in; - WavpackHeader wphdr; - - restore_pos = reader->get_pos (id); // we restore file position when done - - // start 1MB from the end-of-file, or from the start if the file is not that big - - if (reader->get_length (id) > (int64_t) 1048576) - reader->set_pos_rel (id, -1048576, SEEK_END); - else - reader->set_pos_abs (id, 0); - - // Note that we go backward (without parsing inside blocks) until we find a block - // with audio (careful to not get stuck in a loop). Only then do we go forward - // parsing all blocks in their entirety. - - while (1) { - uint32_t bcount = read_next_header (reader, id, &wphdr); - int64_t current_pos = reader->get_pos (id); - - // if we just got to the same place as last time, we're stuck and need to give up - - if (current_pos == last_pos) { - reader->set_pos_abs (id, restore_pos); - return FALSE; - } - - last_pos = current_pos; - - // We enter here if we just read 1 MB without seeing any WavPack block headers. - // Since WavPack blocks are < 1 MB, that means we're in a big APE tag, or we got - // to the end-of-file. - - if (bcount == (uint32_t) -1) { - - // if we have not seen any blocks at all yet, back up almost 2 MB (or to the - // beginning of the file) and try again - - if (!blocks) { - if (current_pos > (int64_t) 2000000) - reader->set_pos_rel (id, -2000000, SEEK_CUR); - else - reader->set_pos_abs (id, 0); - - continue; - } - - // if we have seen WavPack blocks, then this means we've done all we can do here - - reader->set_pos_abs (id, restore_pos); - return TRUE; - } - - blocks++; - - // If the block has audio samples, calculate a final index, although this is not - // final since this may not be the last block with audio. On the other hand, if - // this block does not have audio, and we haven't seen one with audio, we have - // to go back some more. - - if (wphdr.block_samples) { - if (final_index) - *final_index = GET_BLOCK_INDEX (wphdr) + wphdr.block_samples; - - audio_blocks++; - } - else if (!audio_blocks) { - if (current_pos > (int64_t) 1048576) - reader->set_pos_rel (id, -1048576, SEEK_CUR); - else - reader->set_pos_abs (id, 0); - - continue; - } - - // at this point we have seen at least one block with audio, so we parse the - // entire block looking for MD5 metadata or (conditionally) trailing wrappers - - bcount = wphdr.ckSize - sizeof (WavpackHeader) + 8; - - while (bcount >= 2) { - unsigned char meta_id, c1, c2; - uint32_t meta_bc, meta_size; - - if (reader->read_bytes (id, &meta_id, 1) != 1 || - reader->read_bytes (id, &c1, 1) != 1) { - reader->set_pos_abs (id, restore_pos); - return FALSE; - } - - meta_bc = c1 << 1; - bcount -= 2; - - if (meta_id & ID_LARGE) { - if (bcount < 2 || reader->read_bytes (id, &c1, 1) != 1 || - reader->read_bytes (id, &c2, 1) != 1) { - reader->set_pos_abs (id, restore_pos); - return FALSE; - } - - meta_bc += ((uint32_t) c1 << 9) + ((uint32_t) c2 << 17); - bcount -= 2; - } - - meta_size = (meta_id & ID_ODD_SIZE) ? meta_bc - 1 : meta_bc; - meta_id &= ID_UNIQUE; - - if (get_wrapper && (meta_id == ID_RIFF_TRAILER || (alt_types && meta_id == ID_ALT_TRAILER)) && meta_bc) { - wpc->wrapper_data = (unsigned char *)realloc (wpc->wrapper_data, wpc->wrapper_bytes + meta_bc); - - if (!wpc->wrapper_data) { - reader->set_pos_abs (id, restore_pos); - return FALSE; - } - - if (reader->read_bytes (id, wpc->wrapper_data + wpc->wrapper_bytes, meta_bc) == meta_bc) - wpc->wrapper_bytes += meta_size; - else { - reader->set_pos_abs (id, restore_pos); - return FALSE; - } - } - else if (meta_id == ID_MD5_CHECKSUM || (alt_types && meta_id == ID_ALT_MD5_CHECKSUM)) { - if (meta_bc == 16 && bcount >= 16) { - if (reader->read_bytes (id, wpc->config.md5_checksum, 16) == 16) - wpc->config.md5_read = TRUE; - else { - reader->set_pos_abs (id, restore_pos); - return FALSE; - } - } - else - reader->set_pos_rel (id, meta_bc, SEEK_CUR); - } - else - reader->set_pos_rel (id, meta_bc, SEEK_CUR); - - bcount -= meta_bc; - } - } -} - -// Quickly verify the referenced block. It is assumed that the WavPack header has been converted -// to native endian format. If a block checksum is performed, that is done in little-endian -// (file) format. It is also assumed that the caller has made sure that the block length -// indicated in the header is correct (we won't overflow the buffer). If a checksum is present, -// then it is checked, otherwise we just check that all the metadata blocks are formatted -// correctly (without looking at their contents). Returns FALSE for bad block. - -int WavpackVerifySingleBlock (unsigned char *buffer, int verify_checksum) -{ - WavpackHeader *wphdr = (WavpackHeader *) buffer; - uint32_t checksum_passed = 0, bcount, meta_bc; - unsigned char *dp, meta_id, c1, c2; - - if (strncmp (wphdr->ckID, "wvpk", 4) || wphdr->ckSize + 8 < sizeof (WavpackHeader)) - return FALSE; - - bcount = wphdr->ckSize - sizeof (WavpackHeader) + 8; - dp = (unsigned char *)(wphdr + 1); - - while (bcount >= 2) { - meta_id = *dp++; - c1 = *dp++; - - meta_bc = c1 << 1; - bcount -= 2; - - if (meta_id & ID_LARGE) { - if (bcount < 2) - return FALSE; - - c1 = *dp++; - c2 = *dp++; - meta_bc += ((uint32_t) c1 << 9) + ((uint32_t) c2 << 17); - bcount -= 2; - } - - if (bcount < meta_bc) - return FALSE; - - if (verify_checksum && (meta_id & ID_UNIQUE) == ID_BLOCK_CHECKSUM) { -#ifdef BITSTREAM_SHORTS - uint16_t *csptr = (uint16_t*) buffer; -#else - unsigned char *csptr = buffer; -#endif - int wcount = (int)(dp - 2 - buffer) >> 1; - uint32_t csum = (uint32_t) -1; - - if ((meta_id & ID_ODD_SIZE) || meta_bc < 2 || meta_bc > 4) - return FALSE; - -#ifdef BITSTREAM_SHORTS - while (wcount--) - csum = (csum * 3) + *csptr++; -#else - WavpackNativeToLittleEndian ((WavpackHeader *) buffer, WavpackHeaderFormat); - - while (wcount--) { - csum = (csum * 3) + csptr [0] + (csptr [1] << 8); - csptr += 2; - } - - WavpackLittleEndianToNative ((WavpackHeader *) buffer, WavpackHeaderFormat); -#endif - - if (meta_bc == 4) { - if (*dp != (csum & 0xff) || dp[1] != ((csum >> 8) & 0xff) || dp[2] != ((csum >> 16) & 0xff) || dp[3] != ((csum >> 24) & 0xff)) - return FALSE; - } - else { - csum ^= csum >> 16; - - if (*dp != (csum & 0xff) || dp[1] != ((csum >> 8) & 0xff)) - return FALSE; - } - - checksum_passed++; - } - - bcount -= meta_bc; - dp += meta_bc; - } - - return (bcount == 0) && (!verify_checksum || !(wphdr->flags & HAS_CHECKSUM) || checksum_passed); -} diff --git a/Frameworks/WavPack/Files/pack.c b/Frameworks/WavPack/Files/pack.c deleted file mode 100644 index c9257f5f5..000000000 --- a/Frameworks/WavPack/Files/pack.c +++ /dev/null @@ -1,1726 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// MMX optimizations (c) 2006 Joachim Henke // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// pack.c - -// This module actually handles the compression of the audio data, except for -// the entropy encoding which is handled by the write_words.c module. For better -// efficiency, the conversion is isolated to tight loops that handle an entire -// buffer. - -#include -#include -#include - -#include "wavpack_local.h" -#include "decorr_tables.h" // contains data, only include from this module! - -///////////////////////////// executable code //////////////////////////////// - -// This function initializes everything required to pack WavPack bitstreams -// and must be called BEFORE any other function in this module. - -void pack_init (WavpackContext *wpc) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - - wps->sample_index = 0; - wps->delta_decay = 2.0; - CLEAR (wps->decorr_passes); - CLEAR (wps->dc); - -#ifdef SKIP_DECORRELATION - wpc->config.xmode = 0; -#endif - - /* although we set the term and delta values here for clarity, they're - * actually hardcoded in the analysis function for speed - */ - - CLEAR (wps->analysis_pass); - wps->analysis_pass.term = 18; - wps->analysis_pass.delta = 2; - - if (wpc->config.flags & CONFIG_AUTO_SHAPING) { - if (wpc->config.flags & CONFIG_OPTIMIZE_WVC) - wps->dc.shaping_acc [0] = wps->dc.shaping_acc [1] = -(512L << 16); - else if (wpc->config.sample_rate >= 64000) - wps->dc.shaping_acc [0] = wps->dc.shaping_acc [1] = 1024L << 16; - else - wpc->config.flags |= CONFIG_DYNAMIC_SHAPING; - } - else { - int32_t weight = (int32_t) floor (wpc->config.shaping_weight * 1024.0 + 0.5); - - if (weight <= -1000) - weight = -1000; - - wps->dc.shaping_acc [0] = wps->dc.shaping_acc [1] = weight << 16; - } - - if (wpc->config.flags & CONFIG_DYNAMIC_SHAPING) - wps->dc.shaping_data = malloc (wpc->max_samples * sizeof (*wps->dc.shaping_data)); - - if (!wpc->config.xmode) - wps->num_passes = 0; - else if (wpc->config.xmode == 1) - wps->num_passes = 2; - else if (wpc->config.xmode == 2) - wps->num_passes = 4; - else - wps->num_passes = 9; - - if (wpc->config.flags & CONFIG_VERY_HIGH_FLAG) { - wps->num_decorrs = NUM_VERY_HIGH_SPECS; - wps->decorr_specs = very_high_specs; - } - else if (wpc->config.flags & CONFIG_HIGH_FLAG) { - wps->num_decorrs = NUM_HIGH_SPECS; - wps->decorr_specs = high_specs; - } - else if (wpc->config.flags & CONFIG_FAST_FLAG) { - wps->num_decorrs = NUM_FAST_SPECS; - wps->decorr_specs = fast_specs; - } - else { - wps->num_decorrs = NUM_DEFAULT_SPECS; - wps->decorr_specs = default_specs; - } - - init_words (wps); -} - -// Allocate room for and copy the decorrelation terms from the decorr_passes -// array into the specified metadata structure. Both the actual term id and -// the delta are packed into single characters. - -static void write_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd) -{ - int tcount = wps->num_terms; - struct decorr_pass *dpp; - char *byteptr; - - byteptr = wpmd->data = malloc (tcount + 1); - wpmd->id = ID_DECORR_TERMS; - - for (dpp = wps->decorr_passes; tcount--; ++dpp) - *byteptr++ = ((dpp->term + 5) & 0x1f) | ((dpp->delta << 5) & 0xe0); - - wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); -} - -// Allocate room for and copy the decorrelation term weights from the -// decorr_passes array into the specified metadata structure. The weights -// range +/-1024, but are rounded and truncated to fit in signed chars for -// metadata storage. Weights are separate for the two channels - -static void write_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd) -{ - struct decorr_pass *dpp = wps->decorr_passes; - int tcount = wps->num_terms, i; - char *byteptr; - - byteptr = wpmd->data = malloc ((tcount * 2) + 1); - wpmd->id = ID_DECORR_WEIGHTS; - - for (i = wps->num_terms - 1; i >= 0; --i) - if (store_weight (dpp [i].weight_A) || - (!(wps->wphdr.flags & MONO_DATA) && store_weight (dpp [i].weight_B))) - break; - - tcount = i + 1; - - for (i = 0; i < wps->num_terms; ++i) { - if (i < tcount) { - dpp [i].weight_A = restore_weight (*byteptr++ = store_weight (dpp [i].weight_A)); - - if (!(wps->wphdr.flags & MONO_DATA)) - dpp [i].weight_B = restore_weight (*byteptr++ = store_weight (dpp [i].weight_B)); - } - else - dpp [i].weight_A = dpp [i].weight_B = 0; - } - - wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); -} - -// Allocate room for and copy the decorrelation samples from the decorr_passes -// array into the specified metadata structure. The samples are signed 32-bit -// values, but are converted to signed log2 values for storage in metadata. -// Values are stored for both channels and are specified from the first term -// with unspecified samples set to zero. The number of samples stored varies -// with the actual term value, so those must obviously be specified before -// these in the metadata list. Any number of terms can have their samples -// specified from no terms to all the terms, however I have found that -// sending more than the first term's samples is a waste. The "wcount" -// variable can be set to the number of terms to have their samples stored. - -static void write_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd) -{ - int tcount = wps->num_terms, wcount = 1, temp; - struct decorr_pass *dpp; - unsigned char *byteptr; - - byteptr = wpmd->data = malloc (256); - wpmd->id = ID_DECORR_SAMPLES; - - for (dpp = wps->decorr_passes; tcount--; ++dpp) - if (wcount) { - if (dpp->term > MAX_TERM) { - dpp->samples_A [0] = wp_exp2s (temp = wp_log2s (dpp->samples_A [0])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - dpp->samples_A [1] = wp_exp2s (temp = wp_log2s (dpp->samples_A [1])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - - if (!(wps->wphdr.flags & MONO_DATA)) { - dpp->samples_B [0] = wp_exp2s (temp = wp_log2s (dpp->samples_B [0])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - dpp->samples_B [1] = wp_exp2s (temp = wp_log2s (dpp->samples_B [1])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - } - } - else if (dpp->term < 0) { - dpp->samples_A [0] = wp_exp2s (temp = wp_log2s (dpp->samples_A [0])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - dpp->samples_B [0] = wp_exp2s (temp = wp_log2s (dpp->samples_B [0])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - } - else { - int m = 0, cnt = dpp->term; - - while (cnt--) { - dpp->samples_A [m] = wp_exp2s (temp = wp_log2s (dpp->samples_A [m])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - - if (!(wps->wphdr.flags & MONO_DATA)) { - dpp->samples_B [m] = wp_exp2s (temp = wp_log2s (dpp->samples_B [m])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - } - - m++; - } - } - - wcount--; - } - else { - CLEAR (dpp->samples_A); - CLEAR (dpp->samples_B); - } - - wpmd->byte_length = (int32_t)(byteptr - (unsigned char *) wpmd->data); -} - -// Allocate room for and copy the noise shaping info into the specified -// metadata structure. These would normally be written to the -// "correction" file and are used for lossless reconstruction of -// hybrid data. The "delta" parameter is not yet used in encoding as it -// will be part of the "quality" mode. - -static void write_shaping_info (WavpackStream *wps, WavpackMetadata *wpmd) -{ - char *byteptr; - int temp; - - byteptr = wpmd->data = malloc (12); - wpmd->id = ID_SHAPING_WEIGHTS; - - wps->dc.error [0] = wp_exp2s (temp = wp_log2s (wps->dc.error [0])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - wps->dc.shaping_acc [0] = wp_exp2s (temp = wp_log2s (wps->dc.shaping_acc [0])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - - if (!(wps->wphdr.flags & MONO_DATA)) { - wps->dc.error [1] = wp_exp2s (temp = wp_log2s (wps->dc.error [1])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - wps->dc.shaping_acc [1] = wp_exp2s (temp = wp_log2s (wps->dc.shaping_acc [1])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - } - - if (wps->dc.shaping_delta [0] | wps->dc.shaping_delta [1]) { - wps->dc.shaping_delta [0] = wp_exp2s (temp = wp_log2s (wps->dc.shaping_delta [0])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - - if (!(wps->wphdr.flags & MONO_DATA)) { - wps->dc.shaping_delta [1] = wp_exp2s (temp = wp_log2s (wps->dc.shaping_delta [1])); - *byteptr++ = temp; - *byteptr++ = temp >> 8; - } - } - - wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); -} - -// Allocate room for and copy the int32 data values into the specified -// metadata structure. This data is used for integer data that has more -// than 24 bits of magnitude or, in some cases, it's used to eliminate -// redundant bits from any audio stream. - -static void write_int32_info (WavpackStream *wps, WavpackMetadata *wpmd) -{ - char *byteptr; - - byteptr = wpmd->data = malloc (4); - wpmd->id = ID_INT32_INFO; - *byteptr++ = wps->int32_sent_bits; - *byteptr++ = wps->int32_zeros; - *byteptr++ = wps->int32_ones; - *byteptr++ = wps->int32_dups; - wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); -} - -static void write_float_info (WavpackStream *wps, WavpackMetadata *wpmd) -{ - char *byteptr; - - byteptr = wpmd->data = malloc (4); - wpmd->id = ID_FLOAT_INFO; - *byteptr++ = wps->float_flags; - *byteptr++ = wps->float_shift; - *byteptr++ = wps->float_max_exp; - *byteptr++ = wps->float_norm_exp; - wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); -} - -// Allocate room for and copy the multichannel information into the specified -// metadata structure. The first byte is the total number of channels and the -// following bytes represent the channel_mask as described for Microsoft -// WAVEFORMATEX. - -static void write_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - uint32_t mask = wpc->config.channel_mask; - char *byteptr = wpmd->data = malloc (8); - - wpmd->id = ID_CHANNEL_INFO; - - if (wpc->num_streams > OLD_MAX_STREAMS) { // if > 8 streams, use 6 or 7 bytes (breaks old decoders - *byteptr++ = wpc->config.num_channels - 1; // that could only handle 8 streams) and allow (in theory) - *byteptr++ = wpc->num_streams - 1; // up to 4096 channels - *byteptr++ = (((wpc->num_streams - 1) >> 4) & 0xf0) | (((wpc->config.num_channels - 1) >> 8) & 0xf); - *byteptr++ = mask; - *byteptr++ = (mask >> 8); - *byteptr++ = (mask >> 16); - - if (mask & 0xff000000) // this will break versions < 5.0, but is RF64-specific - *byteptr++ = (mask >> 24); - } - else { // otherwise use only 1 to 5 bytes - *byteptr++ = wpc->config.num_channels; - - while (mask) { - *byteptr++ = mask; - mask >>= 8; - } - } - - wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); -} - -// Allocate room for and copy the multichannel identities into the specified -// metadata structure. Data is an array of unsigned characters representing -// any channels in the file that DO NOT match one the 18 Microsoft standard -// channels (and are represented in the channel mask). A value of 0 is not -// allowed and 0xff means an unknown or undefined channel identity. - -static void write_channel_identities_info (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - wpmd->byte_length = (int) strlen ((char *) wpc->channel_identities); - wpmd->data = strdup ((char *) wpc->channel_identities); - wpmd->id = ID_CHANNEL_IDENTITIES; -} - -// Allocate room for and copy the configuration information into the specified -// metadata structure. Currently, we just store the upper 3 bytes of -// config.flags and only in the first block of audio data. Note that this is -// for informational purposes not required for playback or decoding (like -// whether high or fast mode was specified). - -static void write_config_info (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - char *byteptr; - - byteptr = wpmd->data = malloc (8); - wpmd->id = ID_CONFIG_BLOCK; - *byteptr++ = (char) (wpc->config.flags >> 8); - *byteptr++ = (char) (wpc->config.flags >> 16); - *byteptr++ = (char) (wpc->config.flags >> 24); - - if (wpc->config.flags & CONFIG_EXTRA_MODE) - *byteptr++ = (char) wpc->config.xmode; - - // for the 5.0.0 alpha, we wrote the qmode flags here, but this - // has been replaced with the new_config block - // *byteptr++ = (char) wpc->config.qmode; - - wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); -} - -// Allocate room for and copy the "new" configuration information into the -// specified metadata structure. This is all the stuff introduced with version -// 5.0 and includes the qmode flags (big-endian, etc.) and CAF extended -// channel layouts (including optional reordering). Even if there is no new -// configuration, we still send the empty metadata block to signal a 5.0 file. - -static void write_new_config_info (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - char *byteptr = wpmd->data = malloc (260); - - wpmd->id = ID_NEW_CONFIG_BLOCK; - - if (wpc->file_format || (wpc->config.qmode & 0xff) || wpc->channel_layout) { - *byteptr++ = (char) wpc->file_format; - *byteptr++ = (char) wpc->config.qmode; - - if (wpc->channel_layout) { - int nchans = wpc->channel_layout & 0xff; - - *byteptr++ = (char) ((wpc->channel_layout & 0xff0000) >> 16); - - if (wpc->channel_reordering || nchans != wpc->config.num_channels) - *byteptr++ = (char) nchans; - - if (wpc->channel_reordering) { - int i, num_to_send = 0; - - // to save space, don't send redundant reorder string bytes - - for (i = 0; i < nchans; ++i) - if (wpc->channel_reordering [i] != i) - num_to_send = i + 1; - - if (num_to_send) { - memcpy (byteptr, wpc->channel_reordering, num_to_send); - byteptr += num_to_send; - } - } - } - } - - wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); -} - -// Allocate room for and copy the non-standard sampling rate into the specified -// metadata structure. We normally store the lower 3 bytes of the sampling rate, -// unless 4 bytes are required (introduced in version 5). Note that this would -// only be used when the sampling rate was not included in the table of 15 -// "standard" values. - -static void write_sample_rate (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - char *byteptr; - - byteptr = wpmd->data = malloc (4); - wpmd->id = ID_SAMPLE_RATE; - *byteptr++ = (char) (wpc->config.sample_rate); - *byteptr++ = (char) (wpc->config.sample_rate >> 8); - *byteptr++ = (char) (wpc->config.sample_rate >> 16); - - // handle 4-byte sampling rates for scientific applications, etc. - - if (wpc->config.sample_rate & 0x7f000000) - *byteptr++ = (char) (wpc->config.sample_rate >> 24) & 0x7f; - - wpmd->byte_length = (int32_t)(byteptr - (char *) wpmd->data); -} - -// Pack an entire block of samples (either mono or stereo) into a completed -// WavPack block. This function is actually a shell for pack_samples() and -// performs tasks like handling any shift required by the format, preprocessing -// of floating point data or integer data over 24 bits wide, and implementing -// the "extra" mode (via the extra?.c modules). It is assumed that there is -// sufficient space for the completed block at "wps->blockbuff" and that -// "wps->blockend" points to the end of the available space. A return value of -// FALSE indicates an error. - -static int scan_int32_data (WavpackStream *wps, int32_t *values, int32_t num_values); -static void scan_int32_quick (WavpackStream *wps, int32_t *values, int32_t num_values); -static void send_int32_data (WavpackStream *wps, int32_t *values, int32_t num_values); -static int scan_redundancy (int32_t *values, int32_t num_values); -static int pack_samples (WavpackContext *wpc, int32_t *buffer); -static void bs_open_write (Bitstream *bs, void *buffer_start, void *buffer_end); -static uint32_t bs_close_write (Bitstream *bs); - -int pack_block (WavpackContext *wpc, int32_t *buffer) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - uint32_t flags = wps->wphdr.flags, sflags = wps->wphdr.flags; - int32_t sample_count = wps->wphdr.block_samples, *orig_data = NULL; - int dynamic_shaping_done = FALSE; - - // This is done first because this code can potentially change the size of the block about to - // be encoded. This can happen because the dynamic noise shaping algorithm wants to send a - // shorter block because the desired noise-shaping profile is changing quickly. It can also - // be that the --merge-blocks feature wants to create a longer block because it combines areas - // with equal redundancy. These are not applicable for anything besides the first stream of - // the file and they are not applicable with float data or >24-bit data. - - if (!wpc->current_stream && !(flags & FLOAT_DATA) && (flags & MAG_MASK) >> MAG_LSB < 24) { - if ((wpc->config.flags & CONFIG_DYNAMIC_SHAPING) && !wpc->config.block_samples) { - dynamic_noise_shaping (wpc, buffer, TRUE); - sample_count = wps->wphdr.block_samples; - dynamic_shaping_done = TRUE; - } - else if (wpc->block_boundary && sample_count >= (int32_t) wpc->block_boundary * 2) { - int bc = sample_count / wpc->block_boundary, chans = (flags & MONO_DATA) ? 1 : 2; - int res = scan_redundancy (buffer, wpc->block_boundary * chans), i; - - for (i = 1; i < bc; ++i) - if (res != scan_redundancy (buffer + (i * wpc->block_boundary * chans), - wpc->block_boundary * chans)) { - sample_count = wps->wphdr.block_samples = wpc->block_boundary * i; - break; - } - } - } - - // This code scans stereo data to check whether it can be stored as mono data - // (i.e., all L/R samples identical). Only available with MAX_STREAM_VERS. - - if (!(flags & MONO_FLAG) && wpc->stream_version == MAX_STREAM_VERS) { - int32_t lor = 0, diff = 0; - int32_t *sptr, *dptr, i; - - for (sptr = buffer, i = 0; i < (int32_t) sample_count; sptr += 2, i++) { - lor |= sptr [0] | sptr [1]; - diff |= sptr [0] - sptr [1]; - - if (lor && diff) - break; - } - - if (i == sample_count && lor && !diff) { - flags &= ~(JOINT_STEREO | CROSS_DECORR | HYBRID_BALANCE); - wps->wphdr.flags = flags |= FALSE_STEREO; - dptr = buffer; - sptr = buffer; - - for (i = sample_count; i--; sptr++) - *dptr++ = *sptr++; - - if (!wps->false_stereo) { - wps->false_stereo = 1; - wps->num_terms = 0; - init_words (wps); - } - } - else if (wps->false_stereo) { - wps->false_stereo = 0; - wps->num_terms = 0; - init_words (wps); - } - } - - // This is where we handle any fixed shift which occurs when the integer size does not evenly fit - // in bytes (like 12-bit or 20-bit) and is the same for the entire file (not based on scanning) - - if (flags & SHIFT_MASK) { - int shift = (flags & SHIFT_MASK) >> SHIFT_LSB; - int mag = (flags & MAG_MASK) >> MAG_LSB; - uint32_t cnt = sample_count; - int32_t *ptr = buffer; - - if (flags & MONO_DATA) - while (cnt--) - *ptr++ >>= shift; - else - while (cnt--) { - *ptr++ >>= shift; - *ptr++ >>= shift; - } - - if ((mag -= shift) < 0) - flags &= ~MAG_MASK; - else - flags -= (1 << MAG_LSB) * shift; - - wps->wphdr.flags = flags; - } - - // The regular WavPack decorrelation and entropy encoding can handle up to 24-bit integer data. If - // we have float data or integers larger than 24-bit, then we have to potentially do extra processing. - // For lossy encoding, we can simply convert this data in-place to 24-bit data and encode and sent - // that, along with some metadata about how to restore the original format (even if the restoration - // is not exact). However, for lossless operation we must make a copy of the original data that will - // be used to create a "extension stream" that will allow verbatim restoration of the original data. - // In the hybrid mode that extension goes in the correction file, otherwise it goes in the mail file. - - if ((flags & FLOAT_DATA) || (flags & MAG_MASK) >> MAG_LSB >= 24) { // if float data or >24-bit integers... - - // if lossless we have to copy the data to use later... - - if ((!(flags & HYBRID_FLAG) || wpc->wvc_flag) && !(wpc->config.flags & CONFIG_SKIP_WVX)) { - orig_data = malloc (sizeof (f32) * ((flags & MONO_DATA) ? sample_count : sample_count * 2)); - memcpy (orig_data, buffer, sizeof (f32) * ((flags & MONO_DATA) ? sample_count : sample_count * 2)); - - if (flags & FLOAT_DATA) { // if lossless float data come here - wps->float_norm_exp = wpc->config.float_norm_exp; - - if (!scan_float_data (wps, (f32 *) buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2)) { - free (orig_data); - orig_data = NULL; - } - } - else { // otherwise lossless > 24-bit integers - if (!scan_int32_data (wps, buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2)) { - free (orig_data); - orig_data = NULL; - } - } - } - else { // otherwise, we're lossy, so no copy - if (flags & FLOAT_DATA) { - wps->float_norm_exp = wpc->config.float_norm_exp; - - if (scan_float_data (wps, (f32 *) buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2)) - wpc->lossy_blocks = TRUE; - } - else if (scan_int32_data (wps, buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2)) - wpc->lossy_blocks = TRUE; - } - - // if there's any chance of magnitude change, clear the noise-shaping error term - // and also reset the entropy encoder (which this does) - - wps->dc.error [0] = wps->dc.error [1] = 0; - wps->num_terms = 0; - } - // if 24-bit integers or less we do a "quick" scan which just scans for redundancy and does NOT set the flag's "magnitude" value - else { - scan_int32_quick (wps, buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2); - - if (wps->shift != wps->int32_zeros + wps->int32_ones + wps->int32_dups) { // detect a change in any redundancy shifting here - wps->shift = wps->int32_zeros + wps->int32_ones + wps->int32_dups; - wps->dc.error [0] = wps->dc.error [1] = 0; // on a change, clear the noise-shaping error term and - wps->num_terms = 0; // also reset the entropy encoder (which this does) - } - } - - if ((wpc->config.flags & CONFIG_DYNAMIC_SHAPING) && !dynamic_shaping_done) // calculate dynamic noise profile - dynamic_noise_shaping (wpc, buffer, FALSE); - - // In some cases we need to start the decorrelation and entropy encoding from scratch. This - // could be because we switched from stereo to mono encoding or because the magnitude of - // the data changed, or just because this is the first block. - - if (!wps->num_passes && !wps->num_terms) { - wps->num_passes = 1; - - if (flags & MONO_DATA) - execute_mono (wpc, buffer, 1, 0); - else - execute_stereo (wpc, buffer, 1, 0); - - wps->num_passes = 0; - } - - // actually pack the block here and return on an error (which pretty much can only be a block buffer overrun) - - if (!pack_samples (wpc, buffer)) { - wps->wphdr.flags = sflags; - - if (orig_data) - free (orig_data); - - return FALSE; - } - else - wps->wphdr.flags = sflags; - - // potentially move any unused dynamic noise shaping profile data to use next time - - if (wps->dc.shaping_data) { - if (wps->dc.shaping_samples != sample_count) - memmove (wps->dc.shaping_data, wps->dc.shaping_data + sample_count, - (wps->dc.shaping_samples - sample_count) * sizeof (*wps->dc.shaping_data)); - - wps->dc.shaping_samples -= sample_count; - } - - // finally, if we're doing lossless float data or lossless >24-bit integers, this is where we take the - // original data that we saved earlier and create the "extension" stream containing the information - // required to refine the "lossy" 24-bit data into the lossless original - - if (orig_data) { - uint32_t data_count; - unsigned char *cptr; - - if (wpc->wvc_flag) - cptr = wps->block2buff + ((WavpackHeader *) wps->block2buff)->ckSize + 8; - else - cptr = wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 8; - - bs_open_write (&wps->wvxbits, cptr + 8, wpc->wvc_flag ? wps->block2end : wps->blockend); - - if (flags & FLOAT_DATA) - send_float_data (wps, (f32*) orig_data, (flags & MONO_DATA) ? sample_count : sample_count * 2); - else - send_int32_data (wps, orig_data, (flags & MONO_DATA) ? sample_count : sample_count * 2); - - data_count = bs_close_write (&wps->wvxbits); - free (orig_data); - - if (data_count) { - if (data_count != (uint32_t) -1) { - *cptr++ = ID_WVX_BITSTREAM | ID_LARGE; - *cptr++ = (data_count += 4) >> 1; - *cptr++ = data_count >> 9; - *cptr++ = data_count >> 17; - *cptr++ = wps->crc_x; - *cptr++ = wps->crc_x >> 8; - *cptr++ = wps->crc_x >> 16; - *cptr = wps->crc_x >> 24; - - if (wpc->wvc_flag) - ((WavpackHeader *) wps->block2buff)->ckSize += data_count + 4; - else - ((WavpackHeader *) wps->blockbuff)->ckSize += data_count + 4; - } - else - return FALSE; - } - } - - return TRUE; -} - -// Quickly scan a buffer of long integer data and determine whether any -// redundancy in the LSBs can be used to reduce the data's magnitude. If yes, -// then the INT32_DATA flag is set and the int32 parameters are set. This -// version is designed to terminate as soon as it figures out that no -// redundancy is available so that it can be used for all files. - -static void scan_int32_quick (WavpackStream *wps, int32_t *values, int32_t num_values) -{ - uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0; - int total_shift = 0; - int32_t *dp, count; - - wps->int32_sent_bits = wps->int32_zeros = wps->int32_ones = wps->int32_dups = 0; - - for (dp = values, count = num_values; count--; dp++) { - magdata |= (*dp < 0) ? ~*dp : *dp; - xordata |= *dp ^ -(*dp & 1); - anddata &= *dp; - ordata |= *dp; - - if ((ordata & 1) && !(anddata & 1) && (xordata & 2)) - return; - } - - wps->wphdr.flags &= ~MAG_MASK; - - while (magdata) { - wps->wphdr.flags += 1 << MAG_LSB; - magdata >>= 1; - } - - if (!(wps->wphdr.flags & MAG_MASK)) - return; - - if (!(ordata & 1)) - while (!(ordata & 1)) { - wps->wphdr.flags -= 1 << MAG_LSB; - wps->int32_zeros++; - total_shift++; - ordata >>= 1; - } - else if (anddata & 1) - while (anddata & 1) { - wps->wphdr.flags -= 1 << MAG_LSB; - wps->int32_ones++; - total_shift++; - anddata >>= 1; - } - else if (!(xordata & 2)) - while (!(xordata & 2)) { - wps->wphdr.flags -= 1 << MAG_LSB; - wps->int32_dups++; - total_shift++; - xordata >>= 1; - } - - if (total_shift) { - wps->wphdr.flags |= INT32_DATA; - - for (dp = values, count = num_values; count--; dp++) - *dp >>= total_shift; - } -} - -static int scan_redundancy (int32_t *values, int32_t num_values) -{ - uint32_t ordata = 0, xordata = 0, anddata = ~0; - int redundant_bits = 0; - int32_t *dp, count; - - for (dp = values, count = num_values; count--; dp++) { - xordata |= *dp ^ -(*dp & 1); - anddata &= *dp; - ordata |= *dp; - - if ((ordata & 1) && !(anddata & 1) && (xordata & 2)) - return 0; - } - - if (!ordata || anddata == ~0 || !xordata) - return 0; - - if (!(ordata & 1)) - while (!(ordata & 1)) { - redundant_bits++; - ordata >>= 1; - } - else if (anddata & 1) - while (anddata & 1) { - redundant_bits = (redundant_bits + 1) | 0x40; - anddata >>= 1; - } - else if (!(xordata & 2)) - while (!(xordata & 2)) { - redundant_bits = (redundant_bits + 1) | 0x80; - redundant_bits++; - xordata >>= 1; - } - - return redundant_bits; -} - -// Scan a buffer of long integer data and determine whether any redundancy in -// the LSBs can be used to reduce the data's magnitude. If yes, then the -// INT32_DATA flag is set and the int32 parameters are set. If bits must still -// be transmitted literally to get down to 24 bits (which is all the integer -// compression code can handle) then we return TRUE to indicate that a wvx -// stream must be created in either lossless mode. - -static int scan_int32_data (WavpackStream *wps, int32_t *values, int32_t num_values) -{ - uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0; - uint32_t crc = 0xffffffff; - int total_shift = 0; - int32_t *dp, count; - - wps->int32_sent_bits = wps->int32_zeros = wps->int32_ones = wps->int32_dups = 0; - - for (dp = values, count = num_values; count--; dp++) { - crc = crc * 9 + (*dp & 0xffff) * 3 + ((*dp >> 16) & 0xffff); - magdata |= (*dp < 0) ? ~*dp : *dp; - xordata |= *dp ^ -(*dp & 1); - anddata &= *dp; - ordata |= *dp; - } - - wps->crc_x = crc; - wps->wphdr.flags &= ~MAG_MASK; - - while (magdata) { - wps->wphdr.flags += 1 << MAG_LSB; - magdata >>= 1; - } - - if (!((wps->wphdr.flags & MAG_MASK) >> MAG_LSB)) { - wps->wphdr.flags &= ~INT32_DATA; - return FALSE; - } - - if (!(ordata & 1)) - while (!(ordata & 1)) { - wps->wphdr.flags -= 1 << MAG_LSB; - wps->int32_zeros++; - total_shift++; - ordata >>= 1; - } - else if (anddata & 1) - while (anddata & 1) { - wps->wphdr.flags -= 1 << MAG_LSB; - wps->int32_ones++; - total_shift++; - anddata >>= 1; - } - else if (!(xordata & 2)) - while (!(xordata & 2)) { - wps->wphdr.flags -= 1 << MAG_LSB; - wps->int32_dups++; - total_shift++; - xordata >>= 1; - } - - if (((wps->wphdr.flags & MAG_MASK) >> MAG_LSB) > 23) { - wps->int32_sent_bits = (unsigned char)(((wps->wphdr.flags & MAG_MASK) >> MAG_LSB) - 23); - total_shift += wps->int32_sent_bits; - wps->wphdr.flags &= ~MAG_MASK; - wps->wphdr.flags += 23 << MAG_LSB; - } - - if (total_shift) { - wps->wphdr.flags |= INT32_DATA; - - for (dp = values, count = num_values; count--; dp++) - *dp >>= total_shift; - } - - return wps->int32_sent_bits; -} - -// For the specified buffer values and the int32 parameters stored in "wps", -// send the literal bits required to the "wvxbits" bitstream. - -static void send_int32_data (WavpackStream *wps, int32_t *values, int32_t num_values) -{ - int sent_bits = wps->int32_sent_bits, pre_shift; - int32_t mask = (1 << sent_bits) - 1; - int32_t count, value, *dp; - - pre_shift = wps->int32_zeros + wps->int32_ones + wps->int32_dups; - - if (sent_bits) - for (dp = values, count = num_values; count--; dp++) { - value = (*dp >> pre_shift) & mask; - putbits (value, sent_bits, &wps->wvxbits); - } -} - -void send_general_metadata (WavpackContext *wpc) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - uint32_t flags = wps->wphdr.flags; - WavpackMetadata wpmd; - - if ((flags & SRATE_MASK) == SRATE_MASK && wpc->config.sample_rate != 44100) { - write_sample_rate (wpc, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - } - - if ((flags & INITIAL_BLOCK) && - (wpc->config.num_channels > 2 || - wpc->config.channel_mask != 0x5 - wpc->config.num_channels)) { - write_channel_info (wpc, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - - if (wpc->channel_identities) { - write_channel_identities_info (wpc, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - } - } - - if ((flags & INITIAL_BLOCK) && !wps->sample_index) { - write_config_info (wpc, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - } - - if (flags & INITIAL_BLOCK) { - write_new_config_info (wpc, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - } -} - -// Pack an entire block of samples (either mono or stereo) into a completed -// WavPack block. It is assumed that there is sufficient space for the -// completed block at "wps->blockbuff" and that "wps->blockend" points to the -// end of the available space. A return value of FALSE indicates an error. -// Any unsent metadata is transmitted first, then required metadata for this -// block is sent, and finally the compressed integer data is sent. If a "wpx" -// stream is required for floating point data or large integer data, then this -// must be handled outside this function. To find out how much data was written -// the caller must look at the ckSize field of the written WavpackHeader, NOT -// the one in the WavpackStream. - -#ifdef OPT_ASM_X86 - #define DECORR_STEREO_PASS(a,b,c) do { \ - if (pack_cpu_has_feature_x86 (CPU_FEATURE_MMX)) \ - pack_decorr_stereo_pass_x86 (a, b, c); \ - else decorr_stereo_pass (a, b, c); } while (0) - #define DECORR_MONO_BUFFER pack_decorr_mono_buffer_x86 - #define SCAN_MAX_MAGNITUDE(a,b) \ - (pack_cpu_has_feature_x86 (CPU_FEATURE_MMX) ? \ - scan_max_magnitude_x86 (a, b) : \ - scan_max_magnitude (a, b)) -#elif defined(OPT_ASM_X64) && (defined (_WIN64) || defined(__CYGWIN__) || defined(__MINGW64__) || defined(__midipix__)) - #define DECORR_STEREO_PASS pack_decorr_stereo_pass_x64win - #define DECORR_MONO_BUFFER pack_decorr_mono_buffer_x64win - #define SCAN_MAX_MAGNITUDE scan_max_magnitude_x64win -#elif defined(OPT_ASM_X64) - #define DECORR_STEREO_PASS pack_decorr_stereo_pass_x64 - #define DECORR_MONO_BUFFER pack_decorr_mono_buffer_x64 - #define SCAN_MAX_MAGNITUDE scan_max_magnitude_x64 -#else - #define DECORR_STEREO_PASS decorr_stereo_pass - #define DECORR_MONO_BUFFER decorr_mono_buffer - #define SCAN_MAX_MAGNITUDE scan_max_magnitude -#endif - -uint32_t DECORR_MONO_BUFFER (int32_t *buffer, struct decorr_pass *decorr_passes, int32_t num_terms, int32_t sample_count); - -#ifdef OPT_ASM_X86 -void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count); -void pack_decorr_stereo_pass_x86 (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count); -uint32_t scan_max_magnitude (int32_t *values, int32_t num_values); -uint32_t scan_max_magnitude_x86 (int32_t *values, int32_t num_values); -#else -void DECORR_STEREO_PASS (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count); -uint32_t SCAN_MAX_MAGNITUDE (int32_t *values, int32_t num_values); -#endif - -// This macro controls the "repack" function where a block of samples will be repacked with -// fewer terms if a single residual exceeds the specified magnitude threshold. - -#define REPACK_SAFE_NUM_TERMS 5 // 5 terms is always okay (and we truncate to this) - -static int pack_samples (WavpackContext *wpc, int32_t *buffer) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream], saved_stream; - uint32_t flags = wps->wphdr.flags, repack_possible, data_count, crc, crc2, i; - uint32_t sample_count = wps->wphdr.block_samples, repack_mask; - int32_t *bptr, *saved_buffer = NULL; - struct decorr_pass *dpp; - WavpackMetadata wpmd; - - crc = crc2 = 0xffffffff; - - if (!(flags & HYBRID_FLAG) && (flags & MONO_DATA)) { - int32_t *eptr = buffer + sample_count; - - for (bptr = buffer; bptr < eptr;) - crc += (crc << 1) + *bptr++; - - if (wps->num_passes) - execute_mono (wpc, buffer, !wps->num_terms, 1); - } - else if (!(flags & HYBRID_FLAG) && !(flags & MONO_DATA)) { - int32_t *eptr = buffer + (sample_count * 2); - - for (bptr = buffer; bptr < eptr; bptr += 2) - crc += (crc << 3) + (bptr [0] << 1) + bptr [0] + bptr [1]; - - if (wps->num_passes) { - execute_stereo (wpc, buffer, !wps->num_terms, 1); - flags = wps->wphdr.flags; - } - } - else if ((flags & HYBRID_FLAG) && (flags & MONO_DATA)) { - if (wps->num_passes) - execute_mono (wpc, buffer, !wps->num_terms, 0); - } - else if ((flags & HYBRID_FLAG) && !(flags & MONO_DATA)) { - if (wps->num_passes) { - execute_stereo (wpc, buffer, !wps->num_terms, 0); - flags = wps->wphdr.flags; - } - } - - wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; - memcpy (wps->blockbuff, &wps->wphdr, sizeof (WavpackHeader)); - - if (wpc->metacount) { - WavpackMetadata *wpmdp = wpc->metadata; - - while (wpc->metacount) { - copy_metadata (wpmdp, wps->blockbuff, wps->blockend); - wpc->metabytes -= wpmdp->byte_length; - free_metadata (wpmdp++); - wpc->metacount--; - } - - free (wpc->metadata); - wpc->metadata = NULL; - } - - if (!sample_count) - return TRUE; - - memcpy (&wps->wphdr, wps->blockbuff, sizeof (WavpackHeader)); - repack_possible = !wps->num_passes && wps->num_terms > REPACK_SAFE_NUM_TERMS; - repack_mask = (flags & MAG_MASK) >> MAG_LSB >= 16 ? 0xF0000000 : 0xFFF00000; - saved_stream = *wps; - - if (repack_possible && !(flags & HYBRID_FLAG)) { - saved_buffer = malloc (sample_count * sizeof (int32_t) * (flags & MONO_DATA ? 1 : 2)); - memcpy (saved_buffer, buffer, sample_count * sizeof (int32_t) * (flags & MONO_DATA ? 1 : 2)); - } - - // This code is written as a loop, but in the overwhelming majority of cases it executes only once. - // If one of the higher modes is being used and a residual exceeds a certain threshold, then the - // block will be repacked using fewer decorrelation terms. Note that this has only been triggered - // by pathological audio samples designed to trigger it...in practice this might never happen. Note - // that this only applies to the "high" and "very high" modes and only when packing directly - // (i.e. without the "extra" modes that will have already checked magnitude). - - do { - short *shaping_array = wps->dc.shaping_array; - int tcount, lossy = FALSE, m = 0; - double noise_acc = 0.0, noise; - uint32_t max_magnitude = 0; - - write_decorr_terms (wps, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - - write_decorr_weights (wps, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - - write_decorr_samples (wps, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - - write_entropy_vars (wps, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - - if (flags & HYBRID_FLAG) { - write_hybrid_profile (wps, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - } - - if (flags & FLOAT_DATA) { - write_float_info (wps, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - } - - if (flags & INT32_DATA) { - write_int32_info (wps, &wpmd); - copy_metadata (&wpmd, wps->blockbuff, wps->blockend); - free_metadata (&wpmd); - } - - send_general_metadata (wpc); - bs_open_write (&wps->wvbits, wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 12, wps->blockend); - - if (wpc->wvc_flag) { - wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; - memcpy (wps->block2buff, &wps->wphdr, sizeof (WavpackHeader)); - - if (flags & HYBRID_SHAPE) { - write_shaping_info (wps, &wpmd); - copy_metadata (&wpmd, wps->block2buff, wps->block2end); - free_metadata (&wpmd); - } - - bs_open_write (&wps->wvcbits, wps->block2buff + ((WavpackHeader *) wps->block2buff)->ckSize + 12, wps->block2end); - } - - /////////////////////// handle lossless mono mode ///////////////////////// - - if (!(flags & HYBRID_FLAG) && (flags & MONO_DATA)) { - if (!wps->num_passes) { - max_magnitude = DECORR_MONO_BUFFER (buffer, wps->decorr_passes, wps->num_terms, sample_count); - m = sample_count & (MAX_TERM - 1); - } - - send_words_lossless (wps, buffer, sample_count); - } - - //////////////////// handle the lossless stereo mode ////////////////////// - - else if (!(flags & HYBRID_FLAG) && !(flags & MONO_DATA)) { - if (!wps->num_passes) { - if (flags & JOINT_STEREO) { - int32_t *eptr = buffer + (sample_count * 2); - - for (bptr = buffer; bptr < eptr; bptr += 2) - bptr [1] += ((bptr [0] -= bptr [1]) >> 1); - } - - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount-- ; dpp++) - DECORR_STEREO_PASS (dpp, buffer, sample_count); - - m = sample_count & (MAX_TERM - 1); - - if (repack_possible) - max_magnitude = SCAN_MAX_MAGNITUDE (buffer, sample_count * 2); - } - - send_words_lossless (wps, buffer, sample_count); - } - - /////////////////// handle the lossy/hybrid mono mode ///////////////////// - - else if ((flags & HYBRID_FLAG) && (flags & MONO_DATA)) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t code, temp; - int shaping_weight; - - crc2 += (crc2 << 1) + (code = *bptr++); - - if (flags & HYBRID_SHAPE) { - if (shaping_array) - shaping_weight = *shaping_array++; - else - shaping_weight = (wps->dc.shaping_acc [0] += wps->dc.shaping_delta [0]) >> 16; - - temp = -apply_weight (shaping_weight, wps->dc.error [0]); - - if ((flags & NEW_SHAPING) && shaping_weight < 0 && temp) { - if (temp == wps->dc.error [0]) - temp = (temp < 0) ? temp + 1 : temp - 1; - - wps->dc.error [0] = -code; - code += temp; - } - else - wps->dc.error [0] = -(code += temp); - } - - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount-- ; dpp++) - if (dpp->term > MAX_TERM) { - if (dpp->term & 1) - dpp->samples_A [2] = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - else - dpp->samples_A [2] = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - - code -= (dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [2])); - } - else - code -= (dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [m])); - - max_magnitude |= (code < 0 ? ~code : code); - code = send_word (wps, code, 0); - - while (--dpp >= wps->decorr_passes) { - if (dpp->term > MAX_TERM) { - update_weight (dpp->weight_A, dpp->delta, dpp->samples_A [2], code); - dpp->samples_A [1] = dpp->samples_A [0]; - dpp->samples_A [0] = (code += dpp->aweight_A); - } - else { - int32_t sam = dpp->samples_A [m]; - - update_weight (dpp->weight_A, dpp->delta, sam, code); - dpp->samples_A [(m + dpp->term) & (MAX_TERM - 1)] = (code += dpp->aweight_A); - } - } - - wps->dc.error [0] += code; - m = (m + 1) & (MAX_TERM - 1); - - if ((crc += (crc << 1) + code) != crc2) - lossy = TRUE; - - if (wpc->config.flags & CONFIG_CALC_NOISE) { - noise = code - bptr [-1]; - - noise_acc += noise *= noise; - wps->dc.noise_ave = (wps->dc.noise_ave * 0.99) + (noise * 0.01); - - if (wps->dc.noise_ave > wps->dc.noise_max) - wps->dc.noise_max = wps->dc.noise_ave; - } - } - - /////////////////// handle the lossy/hybrid stereo mode /////////////////// - - else if ((flags & HYBRID_FLAG) && !(flags & MONO_DATA)) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t left, right, temp; - int shaping_weight; - - left = *bptr++; - crc2 += (crc2 << 3) + (left << 1) + left + (right = *bptr++); - - if (flags & HYBRID_SHAPE) { - if (shaping_array) - shaping_weight = *shaping_array++; - else - shaping_weight = (wps->dc.shaping_acc [0] += wps->dc.shaping_delta [0]) >> 16; - - temp = -apply_weight (shaping_weight, wps->dc.error [0]); - - if ((flags & NEW_SHAPING) && shaping_weight < 0 && temp) { - if (temp == wps->dc.error [0]) - temp = (temp < 0) ? temp + 1 : temp - 1; - - wps->dc.error [0] = -left; - left += temp; - } - else - wps->dc.error [0] = -(left += temp); - - if (!shaping_array) - shaping_weight = (wps->dc.shaping_acc [1] += wps->dc.shaping_delta [1]) >> 16; - - temp = -apply_weight (shaping_weight, wps->dc.error [1]); - - if ((flags & NEW_SHAPING) && shaping_weight < 0 && temp) { - if (temp == wps->dc.error [1]) - temp = (temp < 0) ? temp + 1 : temp - 1; - - wps->dc.error [1] = -right; - right += temp; - } - else - wps->dc.error [1] = -(right += temp); - } - - if (flags & JOINT_STEREO) - right += ((left -= right) >> 1); - - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount-- ; dpp++) - if (dpp->term > MAX_TERM) { - if (dpp->term & 1) { - dpp->samples_A [2] = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - dpp->samples_B [2] = 2 * dpp->samples_B [0] - dpp->samples_B [1]; - } - else { - dpp->samples_A [2] = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - dpp->samples_B [2] = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1; - } - - left -= (dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [2])); - right -= (dpp->aweight_B = apply_weight (dpp->weight_B, dpp->samples_B [2])); - } - else if (dpp->term > 0) { - left -= (dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [m])); - right -= (dpp->aweight_B = apply_weight (dpp->weight_B, dpp->samples_B [m])); - } - else { - if (dpp->term == -1) - dpp->samples_B [0] = left; - else if (dpp->term == -2) - dpp->samples_A [0] = right; - - left -= (dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [0])); - right -= (dpp->aweight_B = apply_weight (dpp->weight_B, dpp->samples_B [0])); - } - - max_magnitude |= (left < 0 ? ~left : left) | (right < 0 ? ~right : right); - left = send_word (wps, left, 0); - right = send_word (wps, right, 1); - - while (--dpp >= wps->decorr_passes) - if (dpp->term > MAX_TERM) { - update_weight (dpp->weight_A, dpp->delta, dpp->samples_A [2], left); - update_weight (dpp->weight_B, dpp->delta, dpp->samples_B [2], right); - - dpp->samples_A [1] = dpp->samples_A [0]; - dpp->samples_B [1] = dpp->samples_B [0]; - - dpp->samples_A [0] = (left += dpp->aweight_A); - dpp->samples_B [0] = (right += dpp->aweight_B); - } - else if (dpp->term > 0) { - int k = (m + dpp->term) & (MAX_TERM - 1); - - update_weight (dpp->weight_A, dpp->delta, dpp->samples_A [m], left); - dpp->samples_A [k] = (left += dpp->aweight_A); - - update_weight (dpp->weight_B, dpp->delta, dpp->samples_B [m], right); - dpp->samples_B [k] = (right += dpp->aweight_B); - } - else { - if (dpp->term == -1) { - dpp->samples_B [0] = left + dpp->aweight_A; - dpp->aweight_B = apply_weight (dpp->weight_B, dpp->samples_B [0]); - } - else if (dpp->term == -2) { - dpp->samples_A [0] = right + dpp->aweight_B; - dpp->aweight_A = apply_weight (dpp->weight_A, dpp->samples_A [0]); - } - - update_weight_clip (dpp->weight_A, dpp->delta, dpp->samples_A [0], left); - update_weight_clip (dpp->weight_B, dpp->delta, dpp->samples_B [0], right); - dpp->samples_B [0] = (left += dpp->aweight_A); - dpp->samples_A [0] = (right += dpp->aweight_B); - } - - if (flags & JOINT_STEREO) - left += (right -= (left >> 1)); - - wps->dc.error [0] += left; - wps->dc.error [1] += right; - m = (m + 1) & (MAX_TERM - 1); - - if ((crc += (crc << 3) + (left << 1) + left + right) != crc2) - lossy = TRUE; - - if (wpc->config.flags & CONFIG_CALC_NOISE) { - noise = (double)(left - bptr [-2]) * (left - bptr [-2]); - noise += (double)(right - bptr [-1]) * (right - bptr [-1]); - - noise_acc += noise /= 2.0; - wps->dc.noise_ave = (wps->dc.noise_ave * 0.99) + (noise * 0.01); - - if (wps->dc.noise_ave > wps->dc.noise_max) - wps->dc.noise_max = wps->dc.noise_ave; - } - } - - if (m) - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) - if (dpp->term > 0 && dpp->term <= MAX_TERM) { - int32_t temp_A [MAX_TERM], temp_B [MAX_TERM]; - int k; - - memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A)); - memcpy (temp_B, dpp->samples_B, sizeof (dpp->samples_B)); - - for (k = 0; k < MAX_TERM; k++) { - dpp->samples_A [k] = temp_A [m]; - dpp->samples_B [k] = temp_B [m]; - m = (m + 1) & (MAX_TERM - 1); - } - } - - if (wpc->config.flags & CONFIG_CALC_NOISE) - wps->dc.noise_sum += noise_acc; - - flush_word (wps); - data_count = bs_close_write (&wps->wvbits); - - if (data_count) { - if (data_count != (uint32_t) -1) { - unsigned char *cptr = wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 8; - - *cptr++ = ID_WV_BITSTREAM | ID_LARGE; - *cptr++ = data_count >> 1; - *cptr++ = data_count >> 9; - *cptr++ = data_count >> 17; - ((WavpackHeader *) wps->blockbuff)->ckSize += data_count + 4; - } - else - return FALSE; - } - - ((WavpackHeader *) wps->blockbuff)->crc = crc; - - if (wpc->wvc_flag) { - data_count = bs_close_write (&wps->wvcbits); - - if (data_count && lossy) { - if (data_count != (uint32_t) -1) { - unsigned char *cptr = wps->block2buff + ((WavpackHeader *) wps->block2buff)->ckSize + 8; - - *cptr++ = ID_WVC_BITSTREAM | ID_LARGE; - *cptr++ = data_count >> 1; - *cptr++ = data_count >> 9; - *cptr++ = data_count >> 17; - ((WavpackHeader *) wps->block2buff)->ckSize += data_count + 4; - } - else - return FALSE; - } - - ((WavpackHeader *) wps->block2buff)->crc = crc2; - } - else if (lossy) - wpc->lossy_blocks = TRUE; - - // we're done with the entire block, so now we check if our threshold for a "repack" was hit - - if (repack_possible && wps->num_terms > REPACK_SAFE_NUM_TERMS && (max_magnitude & repack_mask)) { - *wps = saved_stream; - wps->num_terms = REPACK_SAFE_NUM_TERMS; - memcpy (wps->blockbuff, &wps->wphdr, sizeof (WavpackHeader)); - - if (saved_buffer) - memcpy (buffer, saved_buffer, sample_count * sizeof (int32_t) * (flags & MONO_DATA ? 1 : 2)); - - if (flags & HYBRID_FLAG) - crc = crc2 = 0xffffffff; - } - else { - // if we actually did repack the block with fewer terms, we detect that here - // and clean up so that we return to the original term count...otherwise we just - // free the saved_buffer (if allocated) and break out of the loop - if (wps->num_terms != saved_stream.num_terms) { - int ti; - - for (ti = wps->num_terms; ti < saved_stream.num_terms; ++ti) { - wps->decorr_passes [ti].weight_A = wps->decorr_passes [ti].weight_B = 0; - CLEAR (wps->decorr_passes [ti].samples_A); - CLEAR (wps->decorr_passes [ti].samples_B); - } - - wps->num_terms = saved_stream.num_terms; - } - - if (saved_buffer) - free (saved_buffer); - - break; - } - - } while (1); - - wps->sample_index += sample_count; - return TRUE; -} - -#if !defined(OPT_ASM_X64) - -// This is the "C" version of the stereo decorrelation pass function. There -// are assembly optimized versions of this that can be used if available. -// It performs a single pass of stereo decorrelation, in place, as specified -// by the decorr_pass structure. Note that this function does NOT return the -// dpp->samples_X[] values in the "normalized" positions for terms 1-8, so if -// the number of samples is not a multiple of MAX_TERM, these must be moved if -// they are to be used somewhere else. - -void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count) -{ - int32_t *bptr, *eptr = buffer + (sample_count * 2); - int m, k; - - switch (dpp->term) { - case 17: - for (bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam, tmp; - - sam = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - dpp->samples_A [1] = dpp->samples_A [0]; - bptr [0] = tmp = (dpp->samples_A [0] = bptr [0]) - apply_weight (dpp->weight_A, sam); - update_weight (dpp->weight_A, dpp->delta, sam, tmp); - - sam = 2 * dpp->samples_B [0] - dpp->samples_B [1]; - dpp->samples_B [1] = dpp->samples_B [0]; - bptr [1] = tmp = (dpp->samples_B [0] = bptr [1]) - apply_weight (dpp->weight_B, sam); - update_weight (dpp->weight_B, dpp->delta, sam, tmp); - } - - break; - - case 18: - for (bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam, tmp; - - sam = dpp->samples_A [0] + ((dpp->samples_A [0] - dpp->samples_A [1]) >> 1); - dpp->samples_A [1] = dpp->samples_A [0]; - bptr [0] = tmp = (dpp->samples_A [0] = bptr [0]) - apply_weight (dpp->weight_A, sam); - update_weight (dpp->weight_A, dpp->delta, sam, tmp); - - sam = dpp->samples_B [0] + ((dpp->samples_B [0] - dpp->samples_B [1]) >> 1); - dpp->samples_B [1] = dpp->samples_B [0]; - bptr [1] = tmp = (dpp->samples_B [0] = bptr [1]) - apply_weight (dpp->weight_B, sam); - update_weight (dpp->weight_B, dpp->delta, sam, tmp); - } - - break; - - default: - for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam, tmp; - - sam = dpp->samples_A [m]; - bptr [0] = tmp = (dpp->samples_A [k] = bptr [0]) - apply_weight (dpp->weight_A, sam); - update_weight (dpp->weight_A, dpp->delta, sam, tmp); - - sam = dpp->samples_B [m]; - bptr [1] = tmp = (dpp->samples_B [k] = bptr [1]) - apply_weight (dpp->weight_B, sam); - update_weight (dpp->weight_B, dpp->delta, sam, tmp); - - m = (m + 1) & (MAX_TERM - 1); - k = (k + 1) & (MAX_TERM - 1); - } - - break; - - case -1: - for (bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam_A, sam_B, tmp; - - sam_A = dpp->samples_A [0]; - bptr [0] = tmp = (sam_B = bptr [0]) - apply_weight (dpp->weight_A, sam_A); - update_weight_clip (dpp->weight_A, dpp->delta, sam_A, tmp); - - bptr [1] = tmp = (dpp->samples_A [0] = bptr [1]) - apply_weight (dpp->weight_B, sam_B); - update_weight_clip (dpp->weight_B, dpp->delta, sam_B, tmp); - } - - break; - - case -2: - for (bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam_A, sam_B, tmp; - - sam_B = dpp->samples_B [0]; - bptr [1] = tmp = (sam_A = bptr [1]) - apply_weight (dpp->weight_B, sam_B); - update_weight_clip (dpp->weight_B, dpp->delta, sam_B, tmp); - - bptr [0] = tmp = (dpp->samples_B [0] = bptr [0]) - apply_weight (dpp->weight_A, sam_A); - update_weight_clip (dpp->weight_A, dpp->delta, sam_A, tmp); - } - - break; - - case -3: - for (bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam_A, sam_B, tmp; - - sam_A = dpp->samples_A [0]; - sam_B = dpp->samples_B [0]; - - dpp->samples_A [0] = tmp = bptr [1]; - bptr [1] = tmp -= apply_weight (dpp->weight_B, sam_B); - update_weight_clip (dpp->weight_B, dpp->delta, sam_B, tmp); - - dpp->samples_B [0] = tmp = bptr [0]; - bptr [0] = tmp -= apply_weight (dpp->weight_A, sam_A); - update_weight_clip (dpp->weight_A, dpp->delta, sam_A, tmp); - } - - break; - } -} - -// This is the "C" version of the magnitude scanning function. There are -// assembly optimized versions of this that can be used if available. This -// function scans a buffer of signed 32-bit ints and returns the magnitude -// of the largest sample, with a power-of-two resolution. It might be more -// useful to return the actual maximum absolute value (and this function -// could do that without breaking anything), but that implementation would -// likely be slower. Instead, this simply returns the "or" of all the -// values "xor"d with their own sign. - -uint32_t scan_max_magnitude (int32_t *values, int32_t num_values) -{ - uint32_t magnitude = 0; - - while (num_values--) - magnitude |= (*values < 0) ? ~*values++ : *values++; - - return magnitude; -} - -#endif - -#if !defined(OPT_ASM_X86) && !defined(OPT_ASM_X64) - -// This is the "C" version of the mono decorrelation pass function. There -// are assembly optimized versions of this that are be used if available. -// It decorrelates a buffer of mono samples, in place, as specified by the array -// of decorr_pass structures. Note that this function does NOT return the -// dpp->samples_X[] values in the "normalized" positions for terms 1-8, so if -// the number of samples is not a multiple of MAX_TERM, these must be moved if -// they are to be used somewhere else. The magnitude of the output samples is -// accumulated and returned (see scan_max_magnitude() for more details). - -uint32_t decorr_mono_buffer (int32_t *buffer, struct decorr_pass *decorr_passes, int32_t num_terms, int32_t sample_count) -{ - uint32_t max_magnitude = 0; - struct decorr_pass *dpp; - int tcount, i; - - for (i = 0; i < sample_count; ++i) { - int32_t code = *buffer; - - for (tcount = num_terms, dpp = decorr_passes; tcount--; dpp++) { - int32_t sam; - - if (dpp->term > MAX_TERM) { - if (dpp->term & 1) - sam = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - else - sam = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - - dpp->samples_A [1] = dpp->samples_A [0]; - dpp->samples_A [0] = code; - } - else { - sam = dpp->samples_A [i & (MAX_TERM - 1)]; - dpp->samples_A [(i + dpp->term) & (MAX_TERM - 1)] = code; - } - - code -= apply_weight (dpp->weight_A, sam); - update_weight (dpp->weight_A, dpp->delta, sam, code); - } - - *buffer++ = code; - max_magnitude |= (code < 0) ? ~code : code; - } - - return max_magnitude; -} - -#endif - -////////////////////////////////////////////////////////////////////////////// -// This function returns the accumulated RMS noise as a double if the // -// CALC_NOISE bit was set in the WavPack header. The peak noise can also be // -// returned if desired. See wavpack.c for the calculations required to // -// convert this into decibels of noise below full scale. // -////////////////////////////////////////////////////////////////////////////// - -double WavpackGetEncodedNoise (WavpackContext *wpc, double *peak) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - - if (peak) - *peak = wps->dc.noise_max; - - return wps->dc.noise_sum; -} - -// Open the specified BitStream using the specified buffer pointers. It is -// assumed that enough buffer space has been allocated for all data that will -// be written, otherwise an error will be generated. - -static void bs_write (Bitstream *bs); - -static void bs_open_write (Bitstream *bs, void *buffer_start, void *buffer_end) -{ - bs->error = bs->sr = bs->bc = 0; - bs->ptr = bs->buf = buffer_start; - bs->end = buffer_end; - bs->wrap = bs_write; -} - -// This function is only called from the putbit() and putbits() macros when -// the buffer is full, which is now flagged as an error. - -static void bs_write (Bitstream *bs) -{ - bs->ptr = bs->buf; - bs->error = 1; -} - -// This function forces a flushing write of the specified BitStream, and -// returns the total number of bytes written into the buffer. - -static uint32_t bs_close_write (Bitstream *bs) -{ - uint32_t bytes_written; - - if (bs->error) - return (uint32_t) -1; - - while (1) { - while (bs->bc) - putbit_1 (bs); - - bytes_written = (uint32_t)(bs->ptr - bs->buf) * sizeof (*(bs->ptr)); - - if (bytes_written & 1) { - putbit_1 (bs); - } - else - break; - }; - - CLEAR (*bs); - return bytes_written; -} diff --git a/Frameworks/WavPack/Files/pack_dns.c b/Frameworks/WavPack/Files/pack_dns.c deleted file mode 100644 index 2c6f3c8f1..000000000 --- a/Frameworks/WavPack/Files/pack_dns.c +++ /dev/null @@ -1,191 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// pack_dns.c - -// This module handles the implementation of "dynamic noise shaping" which is -// designed to move the spectrum of the quantization noise introduced by lossy -// compression up or down in frequency so that it is more likely to be masked -// by the source material. - -#include -#include -#include - -#include "wavpack_local.h" - -static void best_floating_line (short *values, int num_values, double *initial_y, double *final_y, short *max_error); - -void dynamic_noise_shaping (WavpackContext *wpc, int32_t *buffer, int shortening_allowed) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int32_t sample_count = wps->wphdr.block_samples; - struct decorr_pass *ap = &wps->analysis_pass; - uint32_t flags = wps->wphdr.flags; - int32_t *bptr, temp, sam; - short *swptr; - int sc; - - if (!wps->num_terms && sample_count > 8) { - if (flags & MONO_DATA) - for (bptr = buffer + sample_count - 3, sc = sample_count - 2; sc--;) { - sam = (3 * bptr [1] - bptr [2]) >> 1; - temp = *bptr-- - apply_weight (ap->weight_A, sam); - update_weight (ap->weight_A, 2, sam, temp); - } - else - for (bptr = buffer + (sample_count - 3) * 2 + 1, sc = sample_count - 2; sc--;) { - sam = (3 * bptr [2] - bptr [4]) >> 1; - temp = *bptr-- - apply_weight (ap->weight_B, sam); - update_weight (ap->weight_B, 2, sam, temp); - sam = (3 * bptr [2] - bptr [4]) >> 1; - temp = *bptr-- - apply_weight (ap->weight_A, sam); - update_weight (ap->weight_A, 2, sam, temp); - } - } - - if (sample_count > wps->dc.shaping_samples) { - sc = sample_count - wps->dc.shaping_samples; - swptr = wps->dc.shaping_data + wps->dc.shaping_samples; - bptr = buffer + wps->dc.shaping_samples * ((flags & MONO_DATA) ? 1 : 2); - - if (flags & MONO_DATA) - while (sc--) { - sam = (3 * ap->samples_A [0] - ap->samples_A [1]) >> 1; - temp = *bptr - apply_weight (ap->weight_A, sam); - update_weight (ap->weight_A, 2, sam, temp); - ap->samples_A [1] = ap->samples_A [0]; - ap->samples_A [0] = *bptr++; - *swptr++ = (ap->weight_A < 256) ? 1024 : 1536 - ap->weight_A * 2; - } - else - while (sc--) { - sam = (3 * ap->samples_A [0] - ap->samples_A [1]) >> 1; - temp = *bptr - apply_weight (ap->weight_A, sam); - update_weight (ap->weight_A, 2, sam, temp); - ap->samples_A [1] = ap->samples_A [0]; - ap->samples_A [0] = *bptr++; - - sam = (3 * ap->samples_B [0] - ap->samples_B [1]) >> 1; - temp = *bptr - apply_weight (ap->weight_B, sam); - update_weight (ap->weight_B, 2, sam, temp); - ap->samples_B [1] = ap->samples_B [0]; - ap->samples_B [0] = *bptr++; - - *swptr++ = (ap->weight_A + ap->weight_B < 512) ? 1024 : 1536 - ap->weight_A - ap->weight_B; - } - - wps->dc.shaping_samples = sample_count; - } - - if (wpc->wvc_flag) { - int max_allowed_error = 1000000 / wpc->ave_block_samples; - short max_error, trial_max_error; - double initial_y, final_y; - - if (max_allowed_error < 128) - max_allowed_error = 128; - - best_floating_line (wps->dc.shaping_data, sample_count, &initial_y, &final_y, &max_error); - - if (shortening_allowed && max_error > max_allowed_error) { - int min_samples = 0, max_samples = sample_count, trial_count; - double trial_initial_y, trial_final_y; - - while (1) { - trial_count = (min_samples + max_samples) / 2; - - best_floating_line (wps->dc.shaping_data, trial_count, &trial_initial_y, - &trial_final_y, &trial_max_error); - - if (trial_max_error < max_allowed_error) { - max_error = trial_max_error; - min_samples = trial_count; - initial_y = trial_initial_y; - final_y = trial_final_y; - } - else - max_samples = trial_count; - - if (min_samples > 10000 || max_samples - min_samples < 2) - break; - } - - sample_count = min_samples; - } - - if (initial_y < -512) initial_y = -512; - else if (initial_y > 1024) initial_y = 1024; - - if (final_y < -512) final_y = -512; - else if (final_y > 1024) final_y = 1024; -#if 0 - error_line ("%.2f sec, sample count = %5d, max error = %3d, range = %5d, %5d, actual = %5d, %5d", - (double) wps->sample_index / wpc->config.sample_rate, sample_count, max_error, - (int) floor (initial_y), (int) floor (final_y), - wps->dc.shaping_data [0], wps->dc.shaping_data [sample_count-1]); -#endif - if (sample_count != wps->wphdr.block_samples) - wps->wphdr.block_samples = sample_count; - - if (wpc->wvc_flag) { - wps->dc.shaping_acc [0] = wps->dc.shaping_acc [1] = (int32_t) floor (initial_y * 65536.0 + 0.5); - - wps->dc.shaping_delta [0] = wps->dc.shaping_delta [1] = - (int32_t) floor ((final_y - initial_y) / (sample_count - 1) * 65536.0 + 0.5); - - wps->dc.shaping_array = NULL; - } - else - wps->dc.shaping_array = wps->dc.shaping_data; - } - else - wps->dc.shaping_array = wps->dc.shaping_data; -} - -// Given an array of integer data (in shorts), find the linear function that most closely -// represents it (based on minimum sum of absolute errors). This is returned as the double -// precision initial & final Y values of the best-fit line. The function can also optionally -// compute and return a maximum error value (as a short). Note that the ends of the resulting -// line may fall way outside the range of input values, so some sort of clipping may be -// needed. - -static void best_floating_line (short *values, int num_values, double *initial_y, double *final_y, short *max_error) -{ - double left_sum = 0.0, right_sum = 0.0, center_x = (num_values - 1) / 2.0, center_y, m; - int i; - - for (i = 0; i < num_values >> 1; ++i) { - right_sum += values [num_values - i - 1]; - left_sum += values [i]; - } - - if (num_values & 1) { - right_sum += values [num_values >> 1] * 0.5; - left_sum += values [num_values >> 1] * 0.5; - } - - center_y = (right_sum + left_sum) / num_values; - m = (right_sum - left_sum) / ((double) num_values * num_values) * 4.0; - - if (initial_y) - *initial_y = center_y - m * center_x; - - if (final_y) - *final_y = center_y + m * center_x; - - if (max_error) { - double max = 0.0; - - for (i = 0; i < num_values; ++i) - if (fabs (values [i] - (center_y + (i - center_x) * m)) > max) - max = fabs (values [i] - (center_y + (i - center_x) * m)); - - *max_error = (short) floor (max + 0.5); - } -} diff --git a/Frameworks/WavPack/Files/pack_dsd.c b/Frameworks/WavPack/Files/pack_dsd.c deleted file mode 100644 index 2ffa2855f..000000000 --- a/Frameworks/WavPack/Files/pack_dsd.c +++ /dev/null @@ -1,668 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** DSDPACK **** // -// Lossless DSD (Direct Stream Digital) Audio Compressor // -// Copyright (c) 2013 - 2016 David Bryant. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// pack_dsd.c - -// This module actually handles the compression of the DSD audio data. - -#ifdef ENABLE_DSD - -#include -#include -#include - -#include "wavpack_local.h" - -///////////////////////////// executable code //////////////////////////////// - -// This function initializes everything required to pack WavPack DSD bitstreams -// and must be called BEFORE any other function in this module. - -void pack_dsd_init (WavpackContext *wpc) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - - wps->sample_index = 0; -} - -// Pack an entire block of samples (either mono or stereo) into a completed -// WavPack block. This function is actually a shell for pack_samples() and -// performs tasks like handling any shift required by the format, preprocessing -// of floating point data or integer data over 24 bits wide, and implementing -// the "extra" mode (via the extra?.c modules). It is assumed that there is -// sufficient space for the completed block at "wps->blockbuff" and that -// "wps->blockend" points to the end of the available space. A return value of -// FALSE indicates an error. - -// Pack an entire block of samples (either mono or stereo) into a completed -// WavPack block. It is assumed that there is sufficient space for the -// completed block at "wps->blockbuff" and that "wps->blockend" points to the -// end of the available space. A return value of FALSE indicates an error. -// Any unsent metadata is transmitted first, then required metadata for this -// block is sent, and finally the compressed integer data is sent. If a "wpx" -// stream is required for floating point data or large integer data, then this -// must be handled outside this function. To find out how much data was written -// the caller must look at the ckSize field of the written WavpackHeader, NOT -// the one in the WavpackStream. - -static int encode_buffer_high (WavpackStream *wps, int32_t *buffer, int num_samples, unsigned char *destination); -static int encode_buffer_fast (WavpackStream *wps, int32_t *buffer, int num_samples, unsigned char *destination); - -int pack_dsd_block (WavpackContext *wpc, int32_t *buffer) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - uint32_t flags = wps->wphdr.flags, mult = wpc->dsd_multiplier, data_count; - uint32_t sample_count = wps->wphdr.block_samples; - unsigned char *dsd_encoding, dsd_power = 0; - int32_t res; - - // This code scans stereo data to check whether it can be stored as mono data - // (i.e., all L/R samples identical). - - if (!(flags & MONO_FLAG)) { - int32_t *sptr, *dptr, i; - - for (sptr = buffer, i = 0; i < (int32_t) sample_count; sptr += 2, i++) - if ((sptr [0] ^ sptr [1]) & 0xff) - break; - - if (i == sample_count) { - wps->wphdr.flags = flags |= FALSE_STEREO; - dptr = buffer; - sptr = buffer; - - for (i = sample_count; i--; sptr++) - *dptr++ = *sptr++; - } - else - wps->wphdr.flags = flags &= ~FALSE_STEREO; - } - - wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; - memcpy (wps->blockbuff, &wps->wphdr, sizeof (WavpackHeader)); - - if (wpc->metacount) { - WavpackMetadata *wpmdp = wpc->metadata; - - while (wpc->metacount) { - copy_metadata (wpmdp, wps->blockbuff, wps->blockend); - wpc->metabytes -= wpmdp->byte_length; - free_metadata (wpmdp++); - wpc->metacount--; - } - - free (wpc->metadata); - wpc->metadata = NULL; - } - - if (!sample_count) - return TRUE; - - send_general_metadata (wpc); - memcpy (&wps->wphdr, wps->blockbuff, sizeof (WavpackHeader)); - - dsd_encoding = wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 12; - - while (mult >>= 1) - dsd_power++; - - *dsd_encoding++ = dsd_power; - - if (wpc->config.flags & CONFIG_HIGH_FLAG) { - int fast_res = encode_buffer_fast (wps, buffer, sample_count, dsd_encoding); - - res = encode_buffer_high (wps, buffer, sample_count, dsd_encoding); - - if ((fast_res != -1) && (res == -1 || res > fast_res)) - res = encode_buffer_fast (wps, buffer, sample_count, dsd_encoding); - } - else - res = encode_buffer_fast (wps, buffer, sample_count, dsd_encoding); - - if (res == -1) { - int num_samples = sample_count * ((flags & MONO_DATA) ? 1 : 2); - uint32_t crc = 0xffffffff; - - *dsd_encoding++ = 0; - - data_count = num_samples + 2; - - while (num_samples--) - crc += (crc << 1) + (*dsd_encoding++ = *buffer++); - - ((WavpackHeader *) wps->blockbuff)->crc = crc; - } - else - data_count = res + 1; - - if (data_count) { - unsigned char *cptr = wps->blockbuff + ((WavpackHeader *) wps->blockbuff)->ckSize + 8; - - if (data_count & 1) { - cptr [data_count + 4] = 0; - *cptr++ = ID_DSD_BLOCK | ID_LARGE | ID_ODD_SIZE; - data_count++; - } - else - *cptr++ = ID_DSD_BLOCK | ID_LARGE; - - *cptr++ = data_count >> 1; - *cptr++ = data_count >> 9; - *cptr++ = data_count >> 17; - ((WavpackHeader *) wps->blockbuff)->ckSize += data_count + 4; - } - - wps->sample_index += sample_count; - return TRUE; -} - -/*------------------------------------------------------------------------------------------------------------------------*/ - -// #define DSD_BYTE_READY(low,high) (((low) >> 24) == ((high) >> 24)) -// #define DSD_BYTE_READY(low,high) (!(((low) ^ (high)) >> 24)) -#define DSD_BYTE_READY(low,high) (!(((low) ^ (high)) & 0xff000000)) - -#define MAX_PROBABILITY 0xa0 // set to 0xff to disable RLE encoding for probabilities table - -#if (MAX_PROBABILITY < 0xff) - -static int rle_encode (unsigned char *src, int bcount, unsigned char *destination) -{ - int max_rle_zeros = 0xff - MAX_PROBABILITY; - unsigned char *dp = destination; - int zcount = 0; - - while (bcount--) { - if (*src) { - while (zcount) { - *dp++ = MAX_PROBABILITY + (zcount > max_rle_zeros ? max_rle_zeros : zcount); - zcount -= (zcount > max_rle_zeros ? max_rle_zeros : zcount); - } - - *dp++ = *src++; - } - else { - zcount++; - src++; - } - } - - while (zcount) { - *dp++ = MAX_PROBABILITY + (zcount > max_rle_zeros ? max_rle_zeros : zcount); - zcount -= (zcount > max_rle_zeros ? max_rle_zeros : zcount); - } - - *dp++ = 0; - - return (int)(dp - destination); -} - -#endif - -static void calculate_probabilities (int hist [256], unsigned char probs [256], unsigned short prob_sums [256]) -{ - int divisor, min_value, max_value, sum_values; - int min_hits = 0x7fffffff, max_hits = 0, i; - - for (i = 0; i < 256; ++i) { - if (hist [i] < min_hits) min_hits = hist [i]; - if (hist [i] > max_hits) max_hits = hist [i]; - } - - if (max_hits == 0) { - memset (probs, 0, sizeof (*probs) * 256); - memset (prob_sums, 0, sizeof (*prob_sums) * 256); - return; - } - -// fprintf (stderr, "process_histogram(): hits = %d to %d\n", min_hits, max_hits); - - if (max_hits > MAX_PROBABILITY) - divisor = ((max_hits << 8) + (MAX_PROBABILITY >> 1)) / MAX_PROBABILITY; - else - divisor = 0; - - while (1) { - min_value = 0x7fffffff; max_value = 0; sum_values = 0; - - for (i = 0; i < 256; ++i) { - int value; - - if (hist [i]) { - if (divisor) { - if (!(value = ((hist [i] << 8) + (divisor >> 1)) / divisor)) - value = 1; - } - else - value = hist [i]; - - if (value < min_value) min_value = value; - if (value > max_value) max_value = value; - } - else - value = 0; - - prob_sums [i] = sum_values += value; - probs [i] = value; - } - - if (max_value > MAX_PROBABILITY) { - divisor++; - continue; - } - -#if 0 // this code reduces probability values when they are completely redundant (i.e., common divisor), but - // this doesn't really happen often enough to make it worthwhile - - if (min_value > 1) { - for (i = 0; i < 256; ++i) - if (probs [i] % min_value) - break; - - if (i == 256) { - for (i = 0; i < 256; ++i) { - prob_sums [i] /= min_value; - probs [i] /= min_value; - } - - // fprintf (stderr, "fixed min_value = %d, divisor = %d, probs_sum = %d\n", min_value, divisor, prob_sums [255]); - } - } -#endif - - break; - } -} - -static int encode_buffer_fast (WavpackStream *wps, int32_t *buffer, int num_samples, unsigned char *destination) -{ - uint32_t flags = wps->wphdr.flags, crc = 0xffffffff; - unsigned int low = 0, high = 0xffffffff, mult; - unsigned short (*summed_probabilities) [256]; - unsigned char (*probabilities) [256]; - unsigned char *dp = destination, *ep; - int history_bins, bc, p0 = 0, p1 = 0; - int total_summed_probabilities = 0; - int (*histogram) [256]; - int32_t *bp = buffer; - char history_bits; - - if (!(flags & MONO_DATA)) - num_samples *= 2; - - if (num_samples < 280) - return -1; - else if (num_samples < 560) - history_bits = 0; - else if (num_samples < 1725) - history_bits = 1; - else if (num_samples < 5000) - history_bits = 2; - else if (num_samples < 14000) - history_bits = 3; - else if (num_samples < 28000) - history_bits = 4; - else if (num_samples < 76000) - history_bits = 5; - else if (num_samples < 130000) - history_bits = 6; - else if (num_samples < 300000) - history_bits = 7; - else - history_bits = 8; - - if (history_bits > MAX_HISTORY_BITS) - history_bits = MAX_HISTORY_BITS; - - history_bins = 1 << history_bits; - histogram = malloc (sizeof (*histogram) * history_bins); - memset (histogram, 0, sizeof (*histogram) * history_bins); - probabilities = malloc (sizeof (*probabilities) * history_bins); - summed_probabilities = malloc (sizeof (*summed_probabilities) * history_bins); - - bc = num_samples; - - if (flags & MONO_DATA) - while (bc--) { - crc += (crc << 1) + (*bp & 0xff); - histogram [p0] [*bp & 0xff]++; - p0 = *bp++ & (history_bins-1); - } - else - while (bc--) { - crc += (crc << 1) + (*bp & 0xff); - histogram [p0] [*bp & 0xff]++; - p0 = p1; - p1 = *bp++ & (history_bins-1); - } - - for (p0 = 0; p0 < history_bins; p0++) { - calculate_probabilities (histogram [p0], probabilities [p0], summed_probabilities [p0]); - total_summed_probabilities += summed_probabilities [p0] [255]; - } - - ((WavpackHeader *) wps->blockbuff)->crc = crc; - - // This code detects the case where the required value lookup tables grow silly big and cuts them back down. This would - // normally only happen with large blocks or poorly compressible data. The target is to guarantee that the total memory - // required for all three decode tables will be 2K bytes per history bin. - - while (total_summed_probabilities > history_bins * MAX_BYTES_PER_BIN) { - int max_sum = 0, sum_values = 0, largest_bin = 0; - - for (p0 = 0; p0 < history_bins; ++p0) - if (summed_probabilities [p0] [255] > max_sum) { - max_sum = summed_probabilities [p0] [255]; - largest_bin = p0; - } - - total_summed_probabilities -= max_sum; - p0 = largest_bin; - - for (p1 = 0; p1 < 256; ++p1) - summed_probabilities [p0] [p1] = sum_values += probabilities [p0] [p1] = (probabilities [p0] [p1] + 1) >> 1; - - total_summed_probabilities += summed_probabilities [p0] [255]; - // fprintf (stderr, "processed bin 0x%02x, bin: %d --> %d, new sum = %d\n", - // p0, max_sum, summed_probabilities [p0] [255], total_summed_probabilities); - } - - free (histogram); - bp = buffer; - bc = num_samples; - *dp++ = 1; - *dp++ = history_bits; - *dp++ = MAX_PROBABILITY; - ep = destination + num_samples - 10; - -#if (MAX_PROBABILITY < 0xff) - dp += rle_encode ((unsigned char *) probabilities, sizeof (*probabilities) * history_bins, dp); -#else - memcpy (dp, probabilities, sizeof (*probabilities) * history_bins); - dp += sizeof (*probabilities) * history_bins; -#endif - - p0 = p1 = 0; - - while (dp < ep && bc--) { - - mult = (high - low) / summed_probabilities [p0] [255]; - - if (!mult) { - high = low; - - while (DSD_BYTE_READY (high, low)) { - *dp++ = high >> 24; - high = (high << 8) | 0xff; - low <<= 8; - } - - mult = (high - low) / summed_probabilities [p0] [255]; - } - - if (*bp & 0xff) - low += summed_probabilities [p0] [(*bp & 0xff)-1] * mult; - - high = low + probabilities [p0] [*bp & 0xff] * mult - 1; - - while (DSD_BYTE_READY (high, low)) { - *dp++ = high >> 24; - high = (high << 8) | 0xff; - low <<= 8; - } - - if (flags & MONO_DATA) - p0 = *bp++ & (history_bins-1); - else { - p0 = p1; - p1 = *bp++ & (history_bins-1); - } - } - - high = low; - - while (DSD_BYTE_READY (high, low)) { - *dp++ = high >> 24; - high = (high << 8) | 0xff; - low <<= 8; - } - - free (summed_probabilities); - free (probabilities); - - if (dp < ep) - return (int)(dp - destination); - else - return -1; -} - -/*------------------------------------------------------------------------------------------------------------------------*/ - -#define PTABLE_BITS 8 -#define PTABLE_BINS (1<> 8; c--;) - value += (DOWN - value) >> DECAY; - - for (i = 0; i < PTABLE_BINS/2; ++i) { - table [i] = value; - table [PTABLE_BINS-1-i] = 0x100ffff - value; - - if (value > 0x010000) { - rate += (rate * rate_s + 128) >> 8; - - for (c = (rate + 64) >> 7; c--;) - value += (DOWN - value) >> DECAY; - } - } -} - -static int normalize_ptable (int *ptable) -{ - int rate = 0, min_error, error_sum, i; - int ntable [PTABLE_BINS]; - - init_ptable (ntable, rate, RATE_S); - - for (min_error = i = 0; i < PTABLE_BINS; ++i) - min_error += abs (ptable [i] - ntable [i]) >> 8; - - while (1) { - init_ptable (ntable, ++rate, RATE_S); - - for (error_sum = i = 0; i < PTABLE_BINS; ++i) - error_sum += abs (ptable [i] - ntable [i]) >> 8; - - if (error_sum < min_error) - min_error = error_sum; - else - break; - } - - return rate - 1; -} - -static int encode_buffer_high (WavpackStream *wps, int32_t *buffer, int num_samples, unsigned char *destination) -{ - int channel, stereo = (wps->wphdr.flags & MONO_DATA) ? 0 : 1; - uint32_t crc = 0xffffffff, high = 0xffffffff, low = 0; - unsigned char *dp = destination, *ep; - DSDfilters *sp; - - if (num_samples * (stereo + 1) < 280) - return -1; - - *dp++ = 3; - ep = destination + num_samples * (stereo + 1) - 10; - - if (!wps->sample_index) { - if (!wps->dsd.ptable) - wps->dsd.ptable = malloc (PTABLE_BINS * sizeof (*wps->dsd.ptable)); - - init_ptable (wps->dsd.ptable, INITIAL_TERM, RATE_S); - - for (channel = 0; channel < 2; ++channel) { - sp = wps->dsd.filters + channel; - - sp->filter1 = sp->filter2 = sp->filter3 = sp->filter4 = sp->filter5 = VALUE_ONE / 2; - sp->filter6 = sp->factor = 0; - } - - *dp++ = INITIAL_TERM; - *dp++ = RATE_S; - } - else { - int rate = normalize_ptable (wps->dsd.ptable); - init_ptable (wps->dsd.ptable, rate, RATE_S); - *dp++ = rate; - *dp++ = RATE_S; - } - - for (channel = 0; channel <= stereo; ++channel) { - sp = wps->dsd.filters + channel; - - *dp = sp->filter1 >> (PRECISION - 8); - sp->filter1 = *dp++ << (PRECISION - 8); - - *dp = sp->filter2 >> (PRECISION - 8); - sp->filter2 = *dp++ << (PRECISION - 8); - - *dp = sp->filter3 >> (PRECISION - 8); - sp->filter3 = *dp++ << (PRECISION - 8); - - *dp = sp->filter4 >> (PRECISION - 8); - sp->filter4 = *dp++ << (PRECISION - 8); - - *dp = sp->filter5 >> (PRECISION - 8); - sp->filter5 = *dp++ << (PRECISION - 8); - - *dp++ = sp->factor; - *dp++ = sp->factor >> 8; - sp->filter6 = 0; - sp->factor = (sp->factor << 16) >> 16; - } - - sp = wps->dsd.filters; - - while (dp < ep && num_samples--) { - int bitcount = 8; - - crc += (crc << 1) + (sp->byte = *buffer++ & 0xff); - sp [0].value = sp [0].filter1 - sp [0].filter5 + ((sp [0].filter6 * sp [0].factor) >> 2); - - if (stereo) { - crc += (crc << 1) + (sp [1].byte = *buffer++ & 0xff); - sp [1].value = sp [1].filter1 - sp [1].filter5 + ((sp [1].filter6 * sp [1].factor) >> 2); - } - - while (bitcount--) { - int32_t *pp = wps->dsd.ptable + ((sp [0].value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK); - - if (sp [0].byte & 0x80) { - high = low + ((high - low) >> 8) * (*pp >> 16); - *pp += (UP - *pp) >> DECAY; - sp [0].filter0 = -1; - } - else { - low += 1 + ((high - low) >> 8) * (*pp >> 16); - *pp += (DOWN - *pp) >> DECAY; - sp [0].filter0 = 0; - } - - while (DSD_BYTE_READY (high, low)) { - *dp++ = high >> 24; - high = (high << 8) | 0xff; - low <<= 8; - } - - sp [0].value += sp [0].filter6 << 3; - sp [0].factor += (((sp [0].value ^ sp [0].filter0) >> 31) | 1) & ((sp [0].value ^ (sp [0].value - (sp [0].filter6 << 4))) >> 31); - sp [0].filter1 += ((sp [0].filter0 & VALUE_ONE) - sp [0].filter1) >> 6; - sp [0].filter2 += ((sp [0].filter0 & VALUE_ONE) - sp [0].filter2) >> 4; - sp [0].filter3 += (sp [0].filter2 - sp [0].filter3) >> 4; - sp [0].filter4 += (sp [0].filter3 - sp [0].filter4) >> 4; - sp [0].value = (sp [0].filter4 - sp [0].filter5) >> 4; - sp [0].filter5 += sp [0].value; - sp [0].filter6 += (sp [0].value - sp [0].filter6) >> 3; - sp [0].value = sp [0].filter1 - sp [0].filter5 + ((sp [0].filter6 * sp [0].factor) >> 2); - sp [0].byte <<= 1; - - if (!stereo) - continue; - - pp = wps->dsd.ptable + ((sp [1].value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK); - - if (sp [1].byte & 0x80) { - high = low + ((high - low) >> 8) * (*pp >> 16); - *pp += (UP - *pp) >> DECAY; - sp [1].filter0 = -1; - } - else { - low += 1 + ((high - low) >> 8) * (*pp >> 16); - *pp += (DOWN - *pp) >> DECAY; - sp [1].filter0 = 0; - } - - while (DSD_BYTE_READY (high, low)) { - *dp++ = high >> 24; - high = (high << 8) | 0xff; - low <<= 8; - } - - sp [1].value += sp [1].filter6 << 3; - sp [1].factor += (((sp [1].value ^ sp [1].filter0) >> 31) | 1) & ((sp [1].value ^ (sp [1].value - (sp [1].filter6 << 4))) >> 31); - sp [1].filter1 += ((sp [1].filter0 & VALUE_ONE) - sp [1].filter1) >> 6; - sp [1].filter2 += ((sp [1].filter0 & VALUE_ONE) - sp [1].filter2) >> 4; - sp [1].filter3 += (sp [1].filter2 - sp [1].filter3) >> 4; - sp [1].filter4 += (sp [1].filter3 - sp [1].filter4) >> 4; - sp [1].value = (sp [1].filter4 - sp [1].filter5) >> 4; - sp [1].filter5 += sp [1].value; - sp [1].filter6 += (sp [1].value - sp [1].filter6) >> 3; - sp [1].value = sp [1].filter1 - sp [1].filter5 + ((sp [1].filter6 * sp [1].factor) >> 2); - sp [1].byte <<= 1; - } - - sp [0].factor -= (sp->factor + 512) >> 10; - - if (stereo) - sp [1].factor -= (sp [1].factor + 512) >> 10; - } - - ((WavpackHeader *) wps->blockbuff)->crc = crc; - high = low; - - while (DSD_BYTE_READY (high, low)) { - *dp++ = high >> 24; - high = (high << 8) | 0xff; - low <<= 8; - } - - if (dp < ep) - return (int)(dp - destination); - else - return -1; -} - -#endif // ENABLE_DSD diff --git a/Frameworks/WavPack/Files/pack_floats.c b/Frameworks/WavPack/Files/pack_floats.c deleted file mode 100644 index eca1dbc6b..000000000 --- a/Frameworks/WavPack/Files/pack_floats.c +++ /dev/null @@ -1,270 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// pack_floats.c - -// This module deals with the compression of floating-point data. Note that no -// floating point math is involved here...the values are only processed with -// the macros that directly access the mantissa, exponent, and sign fields. -// That's why we use the f32 type instead of the built-in float type. - -#include - -#include "wavpack_local.h" - -//#define DISPLAY_DIAGNOSTICS - -// Scan the provided buffer of floating-point values and (1) convert the -// significant portion of the data to integers for compression using the -// regular WavPack algorithms (which only operate on integers) and (2) -// determine whether the data requires a second stream for lossless -// storage (which will usually be the case except when the floating-point -// data was originally integer data). The converted integers are returned -// "in-place" and a return value of TRUE indicates that a second stream -// is required. - -int scan_float_data (WavpackStream *wps, f32 *values, int32_t num_values) -{ - int32_t shifted_ones = 0, shifted_zeros = 0, shifted_both = 0; - int32_t false_zeros = 0, neg_zeros = 0; -#ifdef DISPLAY_DIAGNOSTICS - int32_t true_zeros = 0, denormals = 0, exceptions = 0; -#endif - uint32_t ordata = 0, crc = 0xffffffff; - int32_t count, value, shift_count; - int max_mag = 0, max_exp = 0; - f32 *dp; - - wps->float_shift = wps->float_flags = 0; - - // First loop goes through all the data and (1) calculates the CRC and (2) finds the - // max magnitude that does not have an exponent of 255 (reserved for +/-inf and NaN). - for (dp = values, count = num_values; count--; dp++) { - crc = crc * 27 + get_mantissa (*dp) * 9 + get_exponent (*dp) * 3 + get_sign (*dp); - - if (get_exponent (*dp) < 255 && get_magnitude (*dp) > max_mag) - max_mag = get_magnitude (*dp); - } - - wps->crc_x = crc; - - // round up the magnitude so that when we convert the floating-point values to integers, - // they will be (at most) just over 24-bits signed precision - if (get_exponent (max_mag)) - max_exp = get_exponent (max_mag + 0x7F0000); - - for (dp = values, count = num_values; count--; dp++) { - // Exponent of 255 is reserved for +/-inf (mantissa = 0) or NaN (mantissa != 0). - // we use a value one greater than 24-bits unsigned for this. - if (get_exponent (*dp) == 255) { -#ifdef DISPLAY_DIAGNOSTICS - exceptions++; -#endif - wps->float_flags |= FLOAT_EXCEPTIONS; - value = 0x1000000; - shift_count = 0; - } - // This is the regular case. We generate a 24-bit unsigned value with the implied - // '1' MSB set and calculate a shift that will make it line up with the biggest - // samples in this block (although that shift would obviously shift out real data). - else if (get_exponent (*dp)) { - shift_count = max_exp - get_exponent (*dp); - value = 0x800000 + get_mantissa (*dp); - } - // Zero exponent means either +/- zero (mantissa = 0) or denormals (mantissa != 0). - // shift_count is set so that denormals (without an implied '1') will line up with - // regular values (with their implied '1' added at bit 23). Trust me. We don't care - // about the shift with zero. - else { - shift_count = max_exp ? max_exp - 1 : 0; - value = get_mantissa (*dp); - -#ifdef DISPLAY_DIAGNOSTICS - if (get_mantissa (*dp)) - denormals++; -#endif - } - - if (shift_count < 25) - value >>= shift_count; // perform the shift if there could be anything left - else - value = 0; // else just zero the value - - // If we are going to encode an integer zero, then this might be a "false zero" which - // means that there are significant bits but they're completely shifted out, or a - // "negative zero" which is simply a floating point value that we have to encode - // (and converting it to a positive zero would be an error). - if (!value) { - if (get_exponent (*dp) || get_mantissa (*dp)) - ++false_zeros; - else if (get_sign (*dp)) - ++neg_zeros; -#ifdef DISPLAY_DIAGNOSTICS - else - ++true_zeros; -#endif - } - // If we are going to shift something (but not everything) out of our integer before - // encoding, then we generate a mask corresponding to the bits that will be shifted - // out and increment the counter for the 3 possible cases of (1) all zeros, (2) all - // ones, and (3) a mix of ones and zeros. - else if (shift_count) { - int32_t mask = (1 << shift_count) - 1; - - if (!(get_mantissa (*dp) & mask)) - shifted_zeros++; - else if ((get_mantissa (*dp) & mask) == mask) - shifted_ones++; - else - shifted_both++; - } - - // "or" all the integer values together, and store the final integer with applied sign - - ordata |= value; - * (int32_t *) dp = (get_sign (*dp)) ? -value : value; - } - - wps->float_max_exp = max_exp; // on decode, we use this to calculate actual exponent - - // Now, based on our various counts, we determine the scheme required to encode the bits - // shifted out. Usually these will simply have to be sent literally, but in some rare cases - // we can get away with always assuming ones shifted out, or assuming all the bits shifted - // out in each value are the same (which means we only have to send a single bit). - if (shifted_both) - wps->float_flags |= FLOAT_SHIFT_SENT; - else if (shifted_ones && !shifted_zeros) - wps->float_flags |= FLOAT_SHIFT_ONES; - else if (shifted_ones && shifted_zeros) - wps->float_flags |= FLOAT_SHIFT_SAME; - // Another case is that we only shift out zeros (or maybe nothing), and in that case we - // check to see if our data actually has less than 24 or 25 bits of resolution, which means - // that we reduce can the magnitude of the integers we are encoding (which saves all those - // bits). The number of bits of reduced resolution is stored in float_shift. - else if (ordata && !(ordata & 1)) { - while (!(ordata & 1)) { - wps->float_shift++; - ordata >>= 1; - } - - // here we shift out all those zeros in the integer data we will encode - for (dp = values, count = num_values; count--; dp++) - * (int32_t *) dp >>= wps->float_shift; - } - - // Here we calculate the actual magnitude used by our integer data, although this is just - // used for informational purposes during encode/decode to possibly use faster math. - - wps->wphdr.flags &= ~MAG_MASK; - - while (ordata) { - wps->wphdr.flags += 1 << MAG_LSB; - ordata >>= 1; - } - - // Finally, we have to set some flags that guide how we encode various types of "zeros". - // If none of these are set (which is the most common situation), then every integer - // zero in the decoded data will simply become a floating-point zero. - - if (false_zeros || neg_zeros) - wps->float_flags |= FLOAT_ZEROS_SENT; - - if (neg_zeros) - wps->float_flags |= FLOAT_NEG_ZEROS; - -#ifdef DISPLAY_DIAGNOSTICS - { - int32_t *ip, min = 0x7fffffff, max = 0x80000000; - for (ip = (int32_t *) values, count = num_values; count--; ip++) { - if (*ip < min) min = *ip; - if (*ip > max) max = *ip; - } - - fprintf (stderr, "integer range = %d to %d\n", min, max); - } - - fprintf (stderr, "samples = %d, max exp = %d, pre-shift = %d, denormals = %d, exceptions = %d, max_mag = %x\n", - num_values, max_exp, wps->float_shift, denormals, exceptions, max_mag); - fprintf (stderr, "shifted ones/zeros/both = %d/%d/%d, true/neg/false zeros = %d/%d/%d\n", - shifted_ones, shifted_zeros, shifted_both, true_zeros, neg_zeros, false_zeros); -#endif - - return wps->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT | FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME); -} - -// Given a buffer of float data, convert the data to integers (which is what the WavPack compression -// algorithms require) and write the other data required for lossless compression (which includes -// significant bits shifted out of the integers, plus information about +/- zeros and exceptions -// like NaN and +/- infinities) into the wvxbits stream (which is assumed to be opened). Note that -// for this work correctly, scan_float_data() must have been called on the original data to set -// the appropriate flags in float_flags and max_exp. - -void send_float_data (WavpackStream *wps, f32 *values, int32_t num_values) -{ - int max_exp = wps->float_max_exp; - int32_t count, value, shift_count; - f32 *dp; - - for (dp = values, count = num_values; count--; dp++) { - if (get_exponent (*dp) == 255) { - if (get_mantissa (*dp)) { - putbit_1 (&wps->wvxbits); - putbits (get_mantissa (*dp), 23, &wps->wvxbits); - } - else { - putbit_0 (&wps->wvxbits); - } - - value = 0x1000000; - shift_count = 0; - } - else if (get_exponent (*dp)) { - shift_count = max_exp - get_exponent (*dp); - value = 0x800000 + get_mantissa (*dp); - } - else { - shift_count = max_exp ? max_exp - 1 : 0; - value = get_mantissa (*dp); - } - - if (shift_count < 25) - value >>= shift_count; - else - value = 0; - - if (!value) { - if (wps->float_flags & FLOAT_ZEROS_SENT) { - if (get_exponent (*dp) || get_mantissa (*dp)) { - putbit_1 (&wps->wvxbits); - putbits (get_mantissa (*dp), 23, &wps->wvxbits); - - if (max_exp >= 25) { - putbits (get_exponent (*dp), 8, &wps->wvxbits); - } - - putbit (get_sign (*dp), &wps->wvxbits); - } - else { - putbit_0 (&wps->wvxbits); - - if (wps->float_flags & FLOAT_NEG_ZEROS) - putbit (get_sign (*dp), &wps->wvxbits); - } - } - } - else if (shift_count) { - if (wps->float_flags & FLOAT_SHIFT_SENT) { - int32_t data = get_mantissa (*dp) & ((1 << shift_count) - 1); - putbits (data, shift_count, &wps->wvxbits); - } - else if (wps->float_flags & FLOAT_SHIFT_SAME) { - putbit (get_mantissa (*dp) & 1, &wps->wvxbits); - } - } - } -} diff --git a/Frameworks/WavPack/Files/pack_utils.c b/Frameworks/WavPack/Files/pack_utils.c deleted file mode 100644 index d74e6397a..000000000 --- a/Frameworks/WavPack/Files/pack_utils.c +++ /dev/null @@ -1,1445 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// pack_utils.c - -// This module provides the high-level API for creating WavPack files from -// audio data. It manages the buffers used to deinterleave the data passed -// in from the application into the individual streams and it handles the -// generation of riff headers and the "fixup" on the first WavPack block -// header for the case where the number of samples was unknown (or wrong). -// The actual audio stream compression is handled in the pack.c module. - -#include -#include -#include - -#include "wavpack_local.h" - -///////////////////////////// executable code //////////////////////////////// - -// Open context for writing WavPack files. The returned context pointer is used -// in all following calls to the library. The "blockout" function will be used -// to store the actual completed WavPack blocks and will be called with the id -// pointers containing user defined data (one for the wv file and one for the -// wvc file). A return value of NULL indicates that memory could not be -// allocated for the context. - -WavpackContext *WavpackOpenFileOutput (WavpackBlockOutput blockout, void *wv_id, void *wvc_id) -{ - WavpackContext *wpc = malloc (sizeof (WavpackContext)); - - if (!wpc) - return NULL; - - CLEAR (*wpc); - wpc->total_samples = -1; - wpc->stream_version = CUR_STREAM_VERS; - wpc->blockout = blockout; - wpc->wv_out = wv_id; - wpc->wvc_out = wvc_id; - return wpc; -} - -static int add_to_metadata (WavpackContext *wpc, void *data, uint32_t bcount, unsigned char id); - -// New for version 5.0, this function allows the application to store a file extension and a -// file_format identification. The extension would be used by the unpacker if the user had not -// specified the target filename, and specifically handles the case where the original file -// had the "wrong" extension for the file format (e.g., a Wave64 file having a "wav" extension) -// or an alternative (e.g., "bwf") or where the file format is not known. Specifying a file -// format besides the default WP_FORMAT_WAV will ensure that old decoders will not be able to -// see the non-wav wrapper provided with WavpackAddWrapper() (which they would end up putting -// on a file with a .wav extension). - -void WavpackSetFileInformation (WavpackContext *wpc, char *file_extension, unsigned char file_format) -{ - if (file_extension && strlen (file_extension) < sizeof (wpc->file_extension)) { - add_to_metadata (wpc, file_extension, (uint32_t) strlen (file_extension), ID_ALT_EXTENSION); - strcpy (wpc->file_extension, file_extension); - } - - wpc->file_format = file_format; -} - -// Set configuration for writing WavPack files. This must be done before -// sending any actual samples, however it is okay to send wrapper or other -// metadata before calling this. The "config" structure contains the following -// required information: - -// config->bytes_per_sample see WavpackGetBytesPerSample() for info -// config->bits_per_sample see WavpackGetBitsPerSample() for info -// config->channel_mask Microsoft standard (mono = 4, stereo = 3) -// config->num_channels self evident -// config->sample_rate self evident - -// In addition, the following fields and flags may be set: - -// config->flags: -// -------------- -// o CONFIG_HYBRID_FLAG select hybrid mode (must set bitrate) -// o CONFIG_JOINT_STEREO select joint stereo (must set override also) -// o CONFIG_JOINT_OVERRIDE override default joint stereo selection -// o CONFIG_HYBRID_SHAPE select hybrid noise shaping (set override & -// shaping_weight != 0.0) -// o CONFIG_SHAPE_OVERRIDE override default hybrid noise shaping -// (set CONFIG_HYBRID_SHAPE and shaping_weight) -// o CONFIG_FAST_FLAG "fast" compression mode -// o CONFIG_HIGH_FLAG "high" compression mode -// o CONFIG_BITRATE_KBPS hybrid bitrate is kbps, not bits / sample -// o CONFIG_CREATE_WVC create correction file -// o CONFIG_OPTIMIZE_WVC maximize bybrid compression (-cc option) -// o CONFIG_CALC_NOISE calc noise in hybrid mode -// o CONFIG_EXTRA_MODE extra processing mode (slow!) -// o CONFIG_SKIP_WVX no wvx stream for floats & large ints -// o CONFIG_MD5_CHECKSUM specify if you plan to store MD5 signature -// o CONFIG_CREATE_EXE specify if you plan to prepend sfx module -// o CONFIG_OPTIMIZE_MONO detect and optimize for mono files posing as -// stereo (uses a more recent stream format that -// is not compatible with decoders < 4.3) - -// config->bitrate hybrid bitrate in either bits/sample or kbps -// config->shaping_weight hybrid noise shaping coefficient override -// config->block_samples force samples per WavPack block (0 = use deflt) -// config->float_norm_exp select floating-point data (127 for +/-1.0) -// config->xmode extra mode processing value override - -// If the number of samples to be written is known then it should be passed -// here. If the duration is not known then pass -1. In the case that the size -// is not known (or the writing is terminated early) then it is suggested that -// the application retrieve the first block written and let the library update -// the total samples indication. A function is provided to do this update and -// it should be done to the "correction" file also. If this cannot be done -// (because a pipe is being used, for instance) then a valid WavPack will still -// be created, but when applications want to access that file they will have -// to seek all the way to the end to determine the actual duration. Also, if -// a RIFF header has been included then it should be updated as well or the -// WavPack file will not be directly unpackable to a valid wav file (although -// it will still be usable by itself). A return of FALSE indicates an error. -// -// The enhanced version of this function now allows setting the identities of -// any channels that are NOT standard Microsoft channels and are therefore not -// represented in the channel mask. WavPack files require that all the Microsoft -// channels come first (and in Microsoft order) and these are followed by any -// other channels (which can be in any order). -// -// The identities are provided in a NULL-terminated string (0x00 is not an allowed -// channel ID). The Microsoft channels may be provided as well (and will be checked) -// but it is really only necessary to provide the "unknown" channels. Any truly -// unknown channels are indicated with a 0xFF. -// -// The channel IDs so far reserved are listed here: -// -// 0: not allowed / terminator -// 1 - 18: Microsoft standard channels -// 30, 31: Stereo mix from RF64 (not really recommended, but RF64 specifies this) -// 33 - 44: Core Audio channels (see Core Audio specification) -// 127 - 128: Amio LeftHeight, Amio RightHeight -// 138 - 142: Amio BottomFrontLeft/Center/Right, Amio ProximityLeft/Right -// 200 - 207: Core Audio channels (see Core Audio specification) -// 221 - 224: Core Audio channels 301 - 305 (offset by 80) -// 255: Present but unknown or unused channel -// -// All other channel IDs are reserved. Ask if something you need is missing. - -// Table of channels that will automatically "pair" into a single stereo stream - -static const struct { unsigned char a, b; } stereo_pairs [] = { - { 1, 2 }, // FL, FR - { 5, 6 }, // BL, BR - { 7, 8 }, // FLC, FRC - { 10, 11 }, // SL, SR - { 13, 15 }, // TFL, TFR - { 16, 18 }, // TBL, TBR - { 30, 31 }, // stereo mix L,R (RF64) - { 33, 34 }, // Rls, Rrs - { 35, 36 }, // Lw, Rw - { 38, 39 }, // Lt, Rt - { 127, 128 }, // Lh, Rh - { 138, 140 }, // Bfl, Bfr - { 141, 142 }, // Pl, Pr - { 200, 201 }, // Amb_W, Amb_X - { 202, 203 }, // Amb_Y, Amb_Z - { 204, 205 }, // MS_Mid, MS_Side - { 206, 207 }, // XY_X, XY_Y - { 221, 222 }, // Hph_L, Hph_R -}; - -#define NUM_STEREO_PAIRS (sizeof (stereo_pairs) / sizeof (stereo_pairs [0])) - -// Legacy version of this function for compatibility with existing applications. Note that this version -// also generates older streams to be compatible with all decoders back to 4.0, but of course cannot be -// used with > 2^32 samples or non-Microsoft channels. The older stream version only differs in that it -// does not support the "mono optimization" feature where stereo blocks containing identical audio data -// in both channels are encoded in mono for better efficiency. - -int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples) -{ - config->flags |= CONFIG_COMPATIBLE_WRITE; // write earlier version streams - - if (total_samples == (uint32_t) -1) - return WavpackSetConfiguration64 (wpc, config, -1, NULL); - else - return WavpackSetConfiguration64 (wpc, config, total_samples, NULL); -} - -int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64_t total_samples, const unsigned char *chan_ids) -{ - uint32_t flags, bps = 0; - uint32_t chan_mask = config->channel_mask; - int num_chans = config->num_channels; - int i; - - if (!config->sample_rate) { - strcpy (wpc->error_message, "sample rate cannot be zero!"); - return FALSE; - } - - if (!num_chans) { - strcpy (wpc->error_message, "channel count cannot be zero!"); - return FALSE; - } - - wpc->stream_version = (config->flags & CONFIG_COMPATIBLE_WRITE) ? CUR_STREAM_VERS : MAX_STREAM_VERS; - - if ((config->qmode & QMODE_DSD_AUDIO) && config->bytes_per_sample == 1 && config->bits_per_sample == 8) { -#ifdef ENABLE_DSD - wpc->dsd_multiplier = 1; - flags = DSD_FLAG; - - for (i = 14; i >= 0; --i) - if (config->sample_rate % sample_rates [i] == 0) { - int divisor = config->sample_rate / sample_rates [i]; - - if (divisor && (divisor & (divisor - 1)) == 0) { - config->sample_rate /= divisor; - wpc->dsd_multiplier = divisor; - break; - } - } - - // most options that don't apply to DSD we can simply ignore for now, but NOT hybrid mode! - if (config->flags & CONFIG_HYBRID_FLAG) { - strcpy (wpc->error_message, "hybrid mode not available for DSD!"); - return FALSE; - } - - // with DSD, very few PCM options work (or make sense), so only allow those that do - config->flags &= (CONFIG_HIGH_FLAG | CONFIG_MD5_CHECKSUM | CONFIG_PAIR_UNDEF_CHANS); - config->float_norm_exp = config->xmode = 0; -#else - strcpy (wpc->error_message, "libwavpack not configured for DSD!"); - return FALSE; -#endif - } - else - flags = config->bytes_per_sample - 1; - - wpc->total_samples = total_samples; - wpc->config.sample_rate = config->sample_rate; - wpc->config.num_channels = config->num_channels; - wpc->config.channel_mask = config->channel_mask; - wpc->config.bits_per_sample = config->bits_per_sample; - wpc->config.bytes_per_sample = config->bytes_per_sample; - wpc->config.block_samples = config->block_samples; - wpc->config.flags = config->flags; - wpc->config.qmode = config->qmode; - - if (config->flags & CONFIG_VERY_HIGH_FLAG) - wpc->config.flags |= CONFIG_HIGH_FLAG; - - for (i = 0; i < 15; ++i) - if (wpc->config.sample_rate == sample_rates [i]) - break; - - flags |= i << SRATE_LSB; - - // all of this stuff only applies to PCM - - if (!(flags & DSD_FLAG)) { - if (config->float_norm_exp) { - if (config->bytes_per_sample != 4 || config->bits_per_sample != 32) { - strcpy (wpc->error_message, "incorrect bits/bytes configuration for float data!"); - return FALSE; - } - - wpc->config.float_norm_exp = config->float_norm_exp; - wpc->config.flags |= CONFIG_FLOAT_DATA; - flags |= FLOAT_DATA; - } - else { - if (config->bytes_per_sample < 1 || config->bytes_per_sample > 4) { - strcpy (wpc->error_message, "invalid bytes per sample!"); - return FALSE; - } - - if (config->bits_per_sample < 1 || config->bits_per_sample > config->bytes_per_sample * 8) { - strcpy (wpc->error_message, "invalid bits per sample!"); - return FALSE; - } - - flags |= ((config->bytes_per_sample * 8) - config->bits_per_sample) << SHIFT_LSB; - } - - if (config->flags & CONFIG_HYBRID_FLAG) { - flags |= HYBRID_FLAG | HYBRID_BITRATE | HYBRID_BALANCE; - - if (!(wpc->config.flags & CONFIG_SHAPE_OVERRIDE)) { - wpc->config.flags |= CONFIG_HYBRID_SHAPE | CONFIG_AUTO_SHAPING; - flags |= HYBRID_SHAPE | NEW_SHAPING; - } - else if (wpc->config.flags & CONFIG_HYBRID_SHAPE) { - wpc->config.shaping_weight = config->shaping_weight; - flags |= HYBRID_SHAPE | NEW_SHAPING; - } - - if (wpc->config.flags & (CONFIG_CROSS_DECORR | CONFIG_OPTIMIZE_WVC)) - flags |= CROSS_DECORR; - - if (config->flags & CONFIG_BITRATE_KBPS) { - bps = (uint32_t) floor (config->bitrate * 256000.0 / config->sample_rate / config->num_channels + 0.5); - - if (bps > (64 << 8)) - bps = 64 << 8; - } - else - bps = (uint32_t) floor (config->bitrate * 256.0 + 0.5); - } - else - flags |= CROSS_DECORR; - - if (!(config->flags & CONFIG_JOINT_OVERRIDE) || (config->flags & CONFIG_JOINT_STEREO)) - flags |= JOINT_STEREO; - - if (config->flags & CONFIG_CREATE_WVC) - wpc->wvc_flag = TRUE; - } - - // if a channel-identities string was specified, process that here, otherwise all channels - // not present in the channel mask are considered "unassigned" - - if (chan_ids) { - int lastchan = 0, mask_copy = chan_mask; - - if ((int) strlen ((char *) chan_ids) > num_chans) { // can't be more than num channels! - strcpy (wpc->error_message, "chan_ids longer than num channels!"); - return FALSE; - } - - // skip past channels that are specified in the channel mask (no reason to store those) - - while (*chan_ids) - if (*chan_ids <= 32 && *chan_ids > lastchan && (mask_copy & (1 << (*chan_ids-1)))) { - mask_copy &= ~(1 << (*chan_ids-1)); - lastchan = *chan_ids++; - } - else - break; - - // now scan the string for an actually defined channel (and don't store if there aren't any) - - for (i = 0; chan_ids [i]; i++) - if (chan_ids [i] != 0xff) { - wpc->channel_identities = (unsigned char *) strdup ((char *) chan_ids); - break; - } - } - - // This loop goes through all the channels and creates the Wavpack "streams" for them to go in. - // A stream can hold either one or two channels, so we have several rules to determine how many - // channels will go in each stream. - - for (wpc->current_stream = 0; num_chans; wpc->current_stream++) { - WavpackStream *wps = malloc (sizeof (WavpackStream)); - unsigned char left_chan_id = 0, right_chan_id = 0; - int pos, chans = 1; - - // allocate the stream and initialize the pointer to it - wpc->streams = realloc (wpc->streams, (wpc->current_stream + 1) * sizeof (wpc->streams [0])); - wpc->streams [wpc->current_stream] = wps; - CLEAR (*wps); - - // if there are any bits [still] set in the channel_mask, get the next one or two IDs from there - if (chan_mask) - for (pos = 0; pos < 32; ++pos) - if (chan_mask & (1 << pos)) { - if (left_chan_id) { - right_chan_id = pos + 1; - break; - } - else { - chan_mask &= ~(1 << pos); - left_chan_id = pos + 1; - } - } - - // next check for any channels identified in the channel-identities string - while (!right_chan_id && chan_ids && *chan_ids) - if (left_chan_id) - right_chan_id = *chan_ids; - else - left_chan_id = *chan_ids++; - - // assume anything we did not get is "unassigned" - if (!left_chan_id) - left_chan_id = right_chan_id = 0xff; - else if (!right_chan_id) - right_chan_id = 0xff; - - // if we have 2 channels, this is where we decide if we can combine them into one stream: - // 1. they are "unassigned" and we've been told to combine unassigned pairs, or - // 2. they appear together in the valid "pairings" list - if (num_chans >= 2) { - if ((config->flags & CONFIG_PAIR_UNDEF_CHANS) && left_chan_id == 0xff && right_chan_id == 0xff) - chans = 2; - else - for (i = 0; i < NUM_STEREO_PAIRS; ++i) - if ((left_chan_id == stereo_pairs [i].a && right_chan_id == stereo_pairs [i].b) || - (left_chan_id == stereo_pairs [i].b && right_chan_id == stereo_pairs [i].a)) { - if (right_chan_id <= 32 && (chan_mask & (1 << (right_chan_id-1)))) - chan_mask &= ~(1 << (right_chan_id-1)); - else if (chan_ids && *chan_ids == right_chan_id) - chan_ids++; - - chans = 2; - break; - } - } - - num_chans -= chans; - - if (num_chans && wpc->current_stream == NEW_MAX_STREAMS - 1) - break; - - memcpy (wps->wphdr.ckID, "wvpk", 4); - wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; - SET_TOTAL_SAMPLES (wps->wphdr, wpc->total_samples); - wps->wphdr.version = wpc->stream_version; - wps->wphdr.flags = flags; - wps->bits = bps; - - if (!wpc->current_stream) - wps->wphdr.flags |= INITIAL_BLOCK; - - if (!num_chans) - wps->wphdr.flags |= FINAL_BLOCK; - - if (chans == 1) { - wps->wphdr.flags &= ~(JOINT_STEREO | CROSS_DECORR | HYBRID_BALANCE); - wps->wphdr.flags |= MONO_FLAG; - } - } - - wpc->num_streams = wpc->current_stream; - wpc->current_stream = 0; - - if (num_chans) { - strcpy (wpc->error_message, "too many channels!"); - return FALSE; - } - - if (config->flags & CONFIG_EXTRA_MODE) - wpc->config.xmode = config->xmode ? config->xmode : 1; - - return TRUE; -} - -// This function allows setting the Core Audio File channel layout, many of which do not -// conform to the Microsoft ordering standard that Wavpack requires internally (at least for -// those channels present in the "channel mask"). In addition to the layout tag, this function -// allows a reordering string to be stored in the file to allow the unpacker to reorder the -// channels back to the specified layout (if it is aware of this feature and wants to restore -// the CAF order). The number of channels in the layout is specified in the lower nybble of -// the layout word, and if a reorder string is specified it must be that long. Note that all -// the reordering is actually done outside of this library, and that if reordering is done -// then the appropriate qmode bit must be set to ensure that any MD5 sum is stored with a new -// ID so that old decoders don't try to verify it (and to let the decoder know that a reorder -// might be required). -// -// Note: This function should only be used to encode Core Audio files in such a way that a -// verbatim archive can be created. Applications can just include the chan_ids parameter in -// the call to WavpackSetConfiguration64() if there are non-Microsoft channels to specify, -// or do nothing special if only Microsoft channels are present (the vast majority of cases). - -int WavpackSetChannelLayout (WavpackContext *wpc, uint32_t layout_tag, const unsigned char *reorder) -{ - int nchans = layout_tag & 0xff; - - if ((layout_tag & 0xff00ff00) || nchans > wpc->config.num_channels) - return FALSE; - - wpc->channel_layout = layout_tag; - - if (wpc->channel_reordering) { - free (wpc->channel_reordering); - wpc->channel_reordering = NULL; - } - - if (nchans && reorder) { - int min_index = 256, i; - - for (i = 0; i < nchans; ++i) - if (reorder [i] < min_index) - min_index = reorder [i]; - - wpc->channel_reordering = malloc (nchans); - - if (wpc->channel_reordering) - for (i = 0; i < nchans; ++i) - wpc->channel_reordering [i] = reorder [i] - min_index; - } - - return TRUE; -} - -// Prepare to actually pack samples by determining the size of the WavPack -// blocks and allocating sample buffers and initializing each stream. Call -// after WavpackSetConfiguration() and before WavpackPackSamples(). A return -// of FALSE indicates an error. - -static int write_metadata_block (WavpackContext *wpc); - -int WavpackPackInit (WavpackContext *wpc) -{ - if (wpc->metabytes > 16384) // 16384 bytes still leaves plenty of room for audio - write_metadata_block (wpc); // in this block (otherwise write a special one) - - // The default block size is a compromise. Longer blocks provide better encoding efficiency, - // but longer blocks adversely affect memory requirements and seeking performance. For WavPack - // version 5.0, the default block sizes have been reduced by half from the previous version, - // but the difference in encoding efficiency will generally be less than 0.1 percent. - - if (wpc->dsd_multiplier) { - wpc->block_samples = (wpc->config.sample_rate % 7) ? 48000 : 44100; - - if (wpc->config.flags & CONFIG_HIGH_FLAG) - wpc->block_samples /= 2; - - if (wpc->config.num_channels == 1) - wpc->block_samples *= 2; - - while (wpc->block_samples > 12000 && wpc->block_samples * wpc->config.num_channels > 300000) - wpc->block_samples /= 2; - } - else { - int divisor = (wpc->config.flags & CONFIG_HIGH_FLAG) ? 2 : 4; - - while (wpc->config.sample_rate % divisor) - divisor--; - - wpc->block_samples = wpc->config.sample_rate / divisor; - - while (wpc->block_samples > 12000 && wpc->block_samples * wpc->config.num_channels > 75000) - wpc->block_samples /= 2; - - while (wpc->block_samples * wpc->config.num_channels < 20000) - wpc->block_samples *= 2; - } - - if (wpc->config.block_samples) { - if ((wpc->config.flags & CONFIG_MERGE_BLOCKS) && - wpc->block_samples > (uint32_t) wpc->config.block_samples) { - wpc->block_boundary = wpc->config.block_samples; - wpc->block_samples /= wpc->config.block_samples; - wpc->block_samples *= wpc->config.block_samples; - } - else - wpc->block_samples = wpc->config.block_samples; - } - - wpc->ave_block_samples = wpc->block_samples; - wpc->max_samples = wpc->block_samples + (wpc->block_samples >> 1); - - for (wpc->current_stream = 0; wpc->current_stream < wpc->num_streams; wpc->current_stream++) { - WavpackStream *wps = wpc->streams [wpc->current_stream]; - - wps->sample_buffer = malloc (wpc->max_samples * (wps->wphdr.flags & MONO_FLAG ? 4 : 8)); - -#ifdef ENABLE_DSD - if (wps->wphdr.flags & DSD_FLAG) - pack_dsd_init (wpc); - else -#endif - pack_init (wpc); - } - - return TRUE; -} - -// Pack the specified samples. Samples must be stored in longs in the native -// endian format of the executing processor. The number of samples specified -// indicates composite samples (sometimes called "frames"). So, the actual -// number of data points would be this "sample_count" times the number of -// channels. Note that samples are accumulated here until enough exist to -// create a complete WavPack block (or several blocks for multichannel audio). -// If an application wants to break a block at a specific sample, then it must -// simply call WavpackFlushSamples() to force an early termination. Completed -// WavPack blocks are send to the function provided in the initial call to -// WavpackOpenFileOutput(). A return of FALSE indicates an error. - -static int pack_streams (WavpackContext *wpc, uint32_t block_samples); -static int create_riff_header (WavpackContext *wpc, int64_t total_samples, void *outbuffer); - -int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count) -{ - int nch = wpc->config.num_channels; - - while (sample_count) { - int32_t *source_pointer = sample_buffer; - unsigned int samples_to_copy; - - if (!wpc->riff_header_added && !wpc->riff_header_created && !wpc->file_format) { - char riff_header [128]; - - if (!add_to_metadata (wpc, riff_header, create_riff_header (wpc, wpc->total_samples, riff_header), ID_RIFF_HEADER)) - return FALSE; - } - - if (wpc->acc_samples + sample_count > wpc->max_samples) - samples_to_copy = wpc->max_samples - wpc->acc_samples; - else - samples_to_copy = sample_count; - - for (wpc->current_stream = 0; wpc->current_stream < wpc->num_streams; wpc->current_stream++) { - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int32_t *dptr, *sptr, cnt; - - dptr = wps->sample_buffer + wpc->acc_samples * (wps->wphdr.flags & MONO_FLAG ? 1 : 2); - sptr = source_pointer; - cnt = samples_to_copy; - - // This code used to just copy the 32-bit samples regardless of the actual size with the - // assumption that the caller had properly sign-extended the values (if they were smaller - // than 32 bits). However, several people have discovered that if the data isn't properly - // sign extended then ugly things happen (e.g. CRC errors that show up only on decode). - // To prevent this, we now explicitly sign-extend samples smaller than 32-bit when we - // copy, and the performance hit from doing this is very small (generally < 1%). - - if (wps->wphdr.flags & MONO_FLAG) { - switch (wpc->config.bytes_per_sample) { - case 1: - while (cnt--) { - *dptr++ = (signed char) *sptr; - sptr += nch; - } - - break; - - case 2: - while (cnt--) { - *dptr++ = (int16_t) *sptr; - sptr += nch; - } - - break; - - case 3: - while (cnt--) { - *dptr++ = (*sptr << 8) >> 8; - sptr += nch; - } - - break; - - default: - while (cnt--) { - *dptr++ = *sptr; - sptr += nch; - } - } - - source_pointer++; - } - else { - switch (wpc->config.bytes_per_sample) { - case 1: - while (cnt--) { - *dptr++ = (signed char) sptr [0]; - *dptr++ = (signed char) sptr [1]; - sptr += nch; - } - - break; - - case 2: - while (cnt--) { - *dptr++ = (int16_t) sptr [0]; - *dptr++ = (int16_t) sptr [1]; - sptr += nch; - } - - break; - - case 3: - while (cnt--) { - *dptr++ = (sptr [0] << 8) >> 8; - *dptr++ = (sptr [1] << 8) >> 8; - sptr += nch; - } - - break; - - default: - while (cnt--) { - *dptr++ = sptr [0]; - *dptr++ = sptr [1]; - sptr += nch; - } - } - - source_pointer += 2; - } - } - - sample_buffer += samples_to_copy * nch; - sample_count -= samples_to_copy; - - if ((wpc->acc_samples += samples_to_copy) == wpc->max_samples && - !pack_streams (wpc, wpc->block_samples)) - return FALSE; - } - - return TRUE; -} - -// Flush all accumulated samples into WavPack blocks. This is normally called -// after all samples have been sent to WavpackPackSamples(), but can also be -// called to terminate a WavPack block at a specific sample (in other words it -// is possible to continue after this operation). This is also called to -// dump non-audio blocks like those holding metadata for various purposes. -// A return of FALSE indicates an error. - -int WavpackFlushSamples (WavpackContext *wpc) -{ - while (wpc->acc_samples) { - uint32_t block_samples; - - if (wpc->acc_samples > wpc->block_samples) - block_samples = wpc->acc_samples / 2; - else - block_samples = wpc->acc_samples; - - if (!pack_streams (wpc, block_samples)) - return FALSE; - } - - if (wpc->metacount) - write_metadata_block (wpc); - - return TRUE; -} - -// Note: The following function is no longer required because a proper wav -// header is now automatically generated for the application. However, if the -// application wants to generate its own header or wants to include additional -// chunks, then this function can still be used in which case the automatic -// wav header generation is suppressed. - -// Add wrapper (currently RIFF only) to WavPack blocks. This should be called -// before sending any audio samples for the RIFF header or after all samples -// have been sent for any RIFF trailer. WavpackFlushSamples() should be called -// between sending the last samples and calling this for trailer data to make -// sure that headers and trailers don't get mixed up in very short files. If -// the exact contents of the RIFF header are not known because, for example, -// the file duration is uncertain or trailing chunks are possible, simply write -// a "dummy" header of the correct length. When all data has been written it -// will be possible to read the first block written and update the header -// directly. An example of this can be found in the Audition filter. A -// return of FALSE indicates an error. - -int WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount) -{ - int64_t index = WavpackGetSampleIndex64 (wpc); - unsigned char meta_id; - - if (!index || index == -1) { - wpc->riff_header_added = TRUE; - meta_id = wpc->file_format ? ID_ALT_HEADER : ID_RIFF_HEADER; - } - else { - wpc->riff_trailer_bytes += bcount; - meta_id = wpc->file_format ? ID_ALT_TRAILER : ID_RIFF_TRAILER; - } - - return add_to_metadata (wpc, data, bcount, meta_id); -} - -// Store computed MD5 sum in WavPack metadata. Note that the user must compute -// the 16 byte sum; it is not done here. A return of FALSE indicates an error. -// If any of the lower 8 bits of qmode are set, then this MD5 is stored with -// a metadata ID that old decoders do not recognize (because they would not -// interpret the qmode and would therefore fail the verification). - -int WavpackStoreMD5Sum (WavpackContext *wpc, unsigned char data [16]) -{ - return add_to_metadata (wpc, data, 16, (wpc->config.qmode & 0xff) ? ID_ALT_MD5_CHECKSUM : ID_MD5_CHECKSUM); -} - -#pragma pack(push,4) - -typedef struct { - char ckID [4]; - uint64_t chunkSize64; -} CS64Chunk; - -typedef struct { - uint64_t riffSize64, dataSize64, sampleCount64; - uint32_t tableLength; -} DS64Chunk; - -typedef struct { - char ckID [4]; - uint32_t ckSize; - char junk [28]; -} JunkChunk; - -#pragma pack(pop) - -#define DS64ChunkFormat "DDDL" - -static int create_riff_header (WavpackContext *wpc, int64_t total_samples, void *outbuffer) -{ - int do_rf64 = 0, write_junk = 1; - ChunkHeader ds64hdr, datahdr, fmthdr; - char *outptr = outbuffer; - RiffChunkHeader riffhdr; - DS64Chunk ds64_chunk; - JunkChunk junkchunk; - WaveHeader wavhdr; - - int64_t total_data_bytes, total_riff_bytes; - int32_t channel_mask = wpc->config.channel_mask; - int32_t sample_rate = wpc->config.sample_rate; - int bytes_per_sample = wpc->config.bytes_per_sample; - int bits_per_sample = wpc->config.bits_per_sample; - int format = (wpc->config.float_norm_exp) ? 3 : 1; - int num_channels = wpc->config.num_channels; - int wavhdrsize = 16; - - wpc->riff_header_created = TRUE; - - if (format == 3 && wpc->config.float_norm_exp != 127) { - strcpy (wpc->error_message, "can't create valid RIFF wav header for non-normalized floating data!"); - return FALSE; - } - - if (total_samples == -1) - total_samples = 0x7ffff000 / (bytes_per_sample * num_channels); - - total_data_bytes = total_samples * bytes_per_sample * num_channels; - - if (total_data_bytes > 0xff000000) { - write_junk = 0; - do_rf64 = 1; - } - - CLEAR (wavhdr); - - wavhdr.FormatTag = format; - wavhdr.NumChannels = num_channels; - wavhdr.SampleRate = sample_rate; - wavhdr.BytesPerSecond = sample_rate * num_channels * bytes_per_sample; - wavhdr.BlockAlign = bytes_per_sample * num_channels; - wavhdr.BitsPerSample = bits_per_sample; - - if (num_channels > 2 || channel_mask != 0x5 - num_channels) { - wavhdrsize = sizeof (wavhdr); - wavhdr.cbSize = 22; - wavhdr.ValidBitsPerSample = bits_per_sample; - wavhdr.SubFormat = format; - wavhdr.ChannelMask = channel_mask; - wavhdr.FormatTag = 0xfffe; - wavhdr.BitsPerSample = bytes_per_sample * 8; - wavhdr.GUID [4] = 0x10; - wavhdr.GUID [6] = 0x80; - wavhdr.GUID [9] = 0xaa; - wavhdr.GUID [11] = 0x38; - wavhdr.GUID [12] = 0x9b; - wavhdr.GUID [13] = 0x71; - } - - memcpy (riffhdr.ckID, do_rf64 ? "RF64" : "RIFF", sizeof (riffhdr.ckID)); - memcpy (riffhdr.formType, "WAVE", sizeof (riffhdr.formType)); - total_riff_bytes = sizeof (riffhdr) + wavhdrsize + sizeof (datahdr) + total_data_bytes + wpc->riff_trailer_bytes; - if (do_rf64) total_riff_bytes += sizeof (ds64hdr) + sizeof (ds64_chunk); - if (write_junk) total_riff_bytes += sizeof (junkchunk); - memcpy (fmthdr.ckID, "fmt ", sizeof (fmthdr.ckID)); - memcpy (datahdr.ckID, "data", sizeof (datahdr.ckID)); - fmthdr.ckSize = wavhdrsize; - - if (write_junk) { - CLEAR (junkchunk); - memcpy (junkchunk.ckID, "junk", sizeof (junkchunk.ckID)); - junkchunk.ckSize = sizeof (junkchunk) - 8; - WavpackNativeToLittleEndian (&junkchunk, ChunkHeaderFormat); - } - - if (do_rf64) { - memcpy (ds64hdr.ckID, "ds64", sizeof (ds64hdr.ckID)); - ds64hdr.ckSize = sizeof (ds64_chunk); - CLEAR (ds64_chunk); - ds64_chunk.riffSize64 = total_riff_bytes; - ds64_chunk.dataSize64 = total_data_bytes; - ds64_chunk.sampleCount64 = total_samples; - riffhdr.ckSize = (uint32_t) -1; - datahdr.ckSize = (uint32_t) -1; - WavpackNativeToLittleEndian (&ds64hdr, ChunkHeaderFormat); - WavpackNativeToLittleEndian (&ds64_chunk, DS64ChunkFormat); - } - else { - riffhdr.ckSize = (uint32_t) total_riff_bytes; - datahdr.ckSize = (uint32_t) total_data_bytes; - } - - WavpackNativeToLittleEndian (&riffhdr, ChunkHeaderFormat); - WavpackNativeToLittleEndian (&fmthdr, ChunkHeaderFormat); - WavpackNativeToLittleEndian (&wavhdr, WaveHeaderFormat); - WavpackNativeToLittleEndian (&datahdr, ChunkHeaderFormat); - - // write the RIFF chunks up to just before the data starts - - outptr = (char *) memcpy (outptr, &riffhdr, sizeof (riffhdr)) + sizeof (riffhdr); - - if (do_rf64) { - outptr = (char *) memcpy (outptr, &ds64hdr, sizeof (ds64hdr)) + sizeof (ds64hdr); - outptr = (char *) memcpy (outptr, &ds64_chunk, sizeof (ds64_chunk)) + sizeof (ds64_chunk); - } - - if (write_junk) - outptr = (char *) memcpy (outptr, &junkchunk, sizeof (junkchunk)) + sizeof (junkchunk); - - outptr = (char *) memcpy (outptr, &fmthdr, sizeof (fmthdr)) + sizeof (fmthdr); - outptr = (char *) memcpy (outptr, &wavhdr, wavhdrsize) + wavhdrsize; - outptr = (char *) memcpy (outptr, &datahdr, sizeof (datahdr)) + sizeof (datahdr); - - return (int)(outptr - (char *) outbuffer); -} - -static int block_add_checksum (unsigned char *buffer_start, unsigned char *buffer_end, int bytes); - -static int pack_streams (WavpackContext *wpc, uint32_t block_samples) -{ - uint32_t max_blocksize, max_chans = 1, bcount; - unsigned char *outbuff, *outend, *out2buff, *out2end; - int result = TRUE, i; - - // for calculating output (block) buffer size, first see if any streams are stereo - - for (i = 0; i < wpc->num_streams; i++) - if (!(wpc->streams [i]->wphdr.flags & MONO_FLAG)) { - max_chans = 2; - break; - } - - // then calculate maximum size based on bytes / sample - - max_blocksize = block_samples * max_chans * ((wpc->streams [0]->wphdr.flags & BYTES_STORED) + 1); - - // add margin based on how much "negative" compression is possible with pathological audio - - if ((wpc->config.flags & CONFIG_FLOAT_DATA) && !(wpc->config.flags & CONFIG_SKIP_WVX)) - max_blocksize += max_blocksize; // 100% margin for lossless float data - else - max_blocksize += max_blocksize >> 2; // otherwise 25% margin for everything else - - max_blocksize += wpc->metabytes + 1024; // finally, add metadata & another 1K margin - max_blocksize += max_blocksize & 1; // and make sure it's even so we detect overflow - - out2buff = (wpc->wvc_flag) ? malloc (max_blocksize) : NULL; - out2end = out2buff + max_blocksize; - outbuff = malloc (max_blocksize); - outend = outbuff + max_blocksize; - - for (wpc->current_stream = 0; wpc->current_stream < wpc->num_streams; wpc->current_stream++) { - WavpackStream *wps = wpc->streams [wpc->current_stream]; - uint32_t flags = wps->wphdr.flags; - - flags &= ~MAG_MASK; - flags += (1 << MAG_LSB) * ((flags & BYTES_STORED) * 8 + 7); - - SET_BLOCK_INDEX (wps->wphdr, wps->sample_index); - wps->wphdr.block_samples = block_samples; - wps->wphdr.flags = flags; - wps->block2buff = out2buff; - wps->block2end = out2end; - wps->blockbuff = outbuff; - wps->blockend = outend; - -#ifdef ENABLE_DSD - if (flags & DSD_FLAG) - result = pack_dsd_block (wpc, wps->sample_buffer); - else -#endif - result = pack_block (wpc, wps->sample_buffer); - - if (result) { - result = block_add_checksum (outbuff, outend, (flags & HYBRID_FLAG) ? 2 : 4); - - if (result && out2buff) - result = block_add_checksum (out2buff, out2end, 2); - } - - wps->blockbuff = wps->block2buff = NULL; - - if (wps->wphdr.block_samples != block_samples) - block_samples = wps->wphdr.block_samples; - - if (!result) { - strcpy (wpc->error_message, "output buffer overflowed!"); - break; - } - - bcount = ((WavpackHeader *) outbuff)->ckSize + 8; - WavpackNativeToLittleEndian ((WavpackHeader *) outbuff, WavpackHeaderFormat); - result = wpc->blockout (wpc->wv_out, outbuff, bcount); - - if (!result) { - strcpy (wpc->error_message, "can't write WavPack data, disk probably full!"); - break; - } - - wpc->filelen += bcount; - - if (out2buff) { - bcount = ((WavpackHeader *) out2buff)->ckSize + 8; - WavpackNativeToLittleEndian ((WavpackHeader *) out2buff, WavpackHeaderFormat); - result = wpc->blockout (wpc->wvc_out, out2buff, bcount); - - if (!result) { - strcpy (wpc->error_message, "can't write WavPack data, disk probably full!"); - break; - } - - wpc->file2len += bcount; - } - - if (wpc->acc_samples != block_samples) - memmove (wps->sample_buffer, wps->sample_buffer + block_samples * (flags & MONO_FLAG ? 1 : 2), - (wpc->acc_samples - block_samples) * sizeof (int32_t) * (flags & MONO_FLAG ? 1 : 2)); - } - - wpc->current_stream = 0; - wpc->ave_block_samples = (wpc->ave_block_samples * 0x7 + block_samples + 0x4) >> 3; - wpc->acc_samples -= block_samples; - free (outbuff); - - if (out2buff) - free (out2buff); - - return result; -} - -// Given the pointer to the first block written (to either a .wv or .wvc file), -// update the block with the actual number of samples written. If the wav -// header was generated by the library, then it is updated also. This should -// be done if WavpackSetConfiguration() was called with an incorrect number -// of samples (or -1). It is the responsibility of the application to read and -// rewrite the block. An example of this can be found in the Audition filter. - -static void block_update_checksum (unsigned char *buffer_start); - -void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block) -{ - uint32_t wrapper_size; - - WavpackLittleEndianToNative (first_block, WavpackHeaderFormat); - SET_TOTAL_SAMPLES (* (WavpackHeader *) first_block, WavpackGetSampleIndex64 (wpc)); - - if (wpc->riff_header_created && WavpackGetWrapperLocation (first_block, &wrapper_size)) { - unsigned char riff_header [128]; - - if (wrapper_size == create_riff_header (wpc, WavpackGetSampleIndex64 (wpc), riff_header)) - memcpy (WavpackGetWrapperLocation (first_block, NULL), riff_header, wrapper_size); - } - - block_update_checksum (first_block); - WavpackNativeToLittleEndian (first_block, WavpackHeaderFormat); -} - -// Note: The following function is no longer required because the wav header -// automatically generated for the application will also be updated by -// WavpackUpdateNumSamples (). However, if the application wants to generate -// its own header or wants to include additional chunks, then this function -// still must be used to update the application generated header. - -// Given the pointer to the first block written to a WavPack file, this -// function returns the location of the stored RIFF header that was originally -// written with WavpackAddWrapper(). This would normally be used to update -// the wav header to indicate that a different number of samples was actually -// written or if additional RIFF chunks are written at the end of the file. -// The "size" parameter can be set to non-NULL to obtain the exact size of the -// RIFF header, and the function will return FALSE if the header is not found -// in the block's metadata (or it is not a valid WavPack block). It is the -// responsibility of the application to read and rewrite the block. An example -// of this can be found in the Audition filter. - -static void *find_metadata (void *wavpack_block, int desired_id, uint32_t *size); - -void *WavpackGetWrapperLocation (void *first_block, uint32_t *size) -{ - void *loc; - - WavpackLittleEndianToNative (first_block, WavpackHeaderFormat); - loc = find_metadata (first_block, ID_RIFF_HEADER, size); - - if (!loc) - loc = find_metadata (first_block, ID_ALT_HEADER, size); - - WavpackNativeToLittleEndian (first_block, WavpackHeaderFormat); - - return loc; -} - -static void *find_metadata (void *wavpack_block, int desired_id, uint32_t *size) -{ - WavpackHeader *wphdr = wavpack_block; - unsigned char *dp, meta_id, c1, c2; - int32_t bcount, meta_bc; - - if (strncmp (wphdr->ckID, "wvpk", 4)) - return NULL; - - bcount = wphdr->ckSize - sizeof (WavpackHeader) + 8; - dp = (unsigned char *)(wphdr + 1); - - while (bcount >= 2) { - meta_id = *dp++; - c1 = *dp++; - - meta_bc = c1 << 1; - bcount -= 2; - - if (meta_id & ID_LARGE) { - if (bcount < 2) - break; - - c1 = *dp++; - c2 = *dp++; - meta_bc += ((uint32_t) c1 << 9) + ((uint32_t) c2 << 17); - bcount -= 2; - } - - if ((meta_id & ID_UNIQUE) == desired_id) { - if ((bcount - meta_bc) >= 0) { - if (size) - *size = meta_bc - ((meta_id & ID_ODD_SIZE) ? 1 : 0); - - return dp; - } - else - return NULL; - } - - bcount -= meta_bc; - dp += meta_bc; - } - - return NULL; -} - -int copy_metadata (WavpackMetadata *wpmd, unsigned char *buffer_start, unsigned char *buffer_end) -{ - uint32_t mdsize = wpmd->byte_length + (wpmd->byte_length & 1); - WavpackHeader *wphdr = (WavpackHeader *) buffer_start; - - mdsize += (wpmd->byte_length > 510) ? 4 : 2; - buffer_start += wphdr->ckSize + 8; - - if (buffer_start + mdsize >= buffer_end) - return FALSE; - - buffer_start [0] = wpmd->id | (wpmd->byte_length & 1 ? ID_ODD_SIZE : 0); - buffer_start [1] = (wpmd->byte_length + 1) >> 1; - - if (wpmd->byte_length > 510) { - buffer_start [0] |= ID_LARGE; - buffer_start [2] = (wpmd->byte_length + 1) >> 9; - buffer_start [3] = (wpmd->byte_length + 1) >> 17; - } - - if (wpmd->data && wpmd->byte_length) { - memcpy (buffer_start + (wpmd->byte_length > 510 ? 4 : 2), wpmd->data, wpmd->byte_length); - - if (wpmd->byte_length & 1) // if size is odd, make sure pad byte is a zero - buffer_start [mdsize - 1] = 0; - } - - wphdr->ckSize += mdsize; - return TRUE; -} - -static int add_to_metadata (WavpackContext *wpc, void *data, uint32_t bcount, unsigned char id) -{ - WavpackMetadata *mdp; - unsigned char *src = data; - - while (bcount) { - if (wpc->metacount) { - uint32_t bc = bcount; - - mdp = wpc->metadata + wpc->metacount - 1; - - if (mdp->id == id) { - if (wpc->metabytes + bcount > 1000000) - bc = 1000000 - wpc->metabytes; - - mdp->data = realloc (mdp->data, mdp->byte_length + bc); - memcpy ((char *) mdp->data + mdp->byte_length, src, bc); - mdp->byte_length += bc; - wpc->metabytes += bc; - bcount -= bc; - src += bc; - - if (wpc->metabytes >= 1000000 && !write_metadata_block (wpc)) - return FALSE; - } - } - - if (bcount) { - wpc->metadata = realloc (wpc->metadata, (wpc->metacount + 1) * sizeof (WavpackMetadata)); - mdp = wpc->metadata + wpc->metacount++; - mdp->byte_length = 0; - mdp->data = NULL; - mdp->id = id; - } - } - - return TRUE; -} - -static char *write_metadata (WavpackMetadata *wpmd, char *outdata) -{ - unsigned char id = wpmd->id, wordlen [3]; - - wordlen [0] = (wpmd->byte_length + 1) >> 1; - wordlen [1] = (wpmd->byte_length + 1) >> 9; - wordlen [2] = (wpmd->byte_length + 1) >> 17; - - if (wpmd->byte_length & 1) - id |= ID_ODD_SIZE; - - if (wordlen [1] || wordlen [2]) - id |= ID_LARGE; - - *outdata++ = id; - *outdata++ = wordlen [0]; - - if (id & ID_LARGE) { - *outdata++ = wordlen [1]; - *outdata++ = wordlen [2]; - } - - if (wpmd->data && wpmd->byte_length) { - memcpy (outdata, wpmd->data, wpmd->byte_length); - outdata += wpmd->byte_length; - - if (wpmd->byte_length & 1) - *outdata++ = 0; - } - - return outdata; -} - -static int write_metadata_block (WavpackContext *wpc) -{ - char *block_buff, *block_ptr; - WavpackHeader *wphdr; - - if (wpc->metacount) { - int metacount = wpc->metacount, block_size = sizeof (WavpackHeader); - WavpackMetadata *wpmdp = wpc->metadata; - - while (metacount--) { - block_size += wpmdp->byte_length + (wpmdp->byte_length & 1); - block_size += (wpmdp->byte_length > 510) ? 4 : 2; - wpmdp++; - } - - // allocate 6 extra bytes for 4-byte checksum (which we add last) - wphdr = (WavpackHeader *) (block_buff = malloc (block_size + 6)); - - CLEAR (*wphdr); - memcpy (wphdr->ckID, "wvpk", 4); - SET_TOTAL_SAMPLES (*wphdr, wpc->total_samples); - wphdr->version = wpc->stream_version; - wphdr->ckSize = block_size - 8; - wphdr->block_samples = 0; - - block_ptr = (char *)(wphdr + 1); - - wpmdp = wpc->metadata; - - while (wpc->metacount) { - block_ptr = write_metadata (wpmdp, block_ptr); - wpc->metabytes -= wpmdp->byte_length; - free_metadata (wpmdp++); - wpc->metacount--; - } - - free (wpc->metadata); - wpc->metadata = NULL; - // add a 4-byte checksum here (increases block size by 6) - block_add_checksum ((unsigned char *) block_buff, (unsigned char *) block_buff + (block_size += 6), 4); - WavpackNativeToLittleEndian ((WavpackHeader *) block_buff, WavpackHeaderFormat); - - if (!wpc->blockout (wpc->wv_out, block_buff, block_size)) { - free (block_buff); - strcpy (wpc->error_message, "can't write WavPack data, disk probably full!"); - return FALSE; - } - - free (block_buff); - } - - return TRUE; -} - -void free_metadata (WavpackMetadata *wpmd) -{ - if (wpmd->data) { - free (wpmd->data); - wpmd->data = NULL; - } -} - -// These two functions add or update the block checksums that were introduced in WavPack 5.0. -// The presence of the checksum is indicated by a flag in the wavpack header (HAS_CHECKSUM) -// and the actual metadata item should be the last one in the block, and can be either 2 or 4 -// bytes. Of course, older versions of the decoder will simply ignore both of these. - -static int block_add_checksum (unsigned char *buffer_start, unsigned char *buffer_end, int bytes) -{ - WavpackHeader *wphdr = (WavpackHeader *) buffer_start; -#ifdef BITSTREAM_SHORTS - uint16_t *csptr = (uint16_t*) buffer_start; -#else - unsigned char *csptr = buffer_start; -#endif - int bcount = wphdr->ckSize + 8, wcount; - uint32_t csum = (uint32_t) -1; - - if (bytes != 2 && bytes != 4) - return FALSE; - - if (bcount < sizeof (WavpackHeader) || (bcount & 1) || buffer_start + bcount + 2 + bytes > buffer_end) - return FALSE; - - wphdr->flags |= HAS_CHECKSUM; - wphdr->ckSize += 2 + bytes; - wcount = bcount >> 1; - -#ifdef BITSTREAM_SHORTS - while (wcount--) - csum = (csum * 3) + *csptr++; -#else - WavpackNativeToLittleEndian ((WavpackHeader *) buffer_start, WavpackHeaderFormat); - - while (wcount--) { - csum = (csum * 3) + csptr [0] + (csptr [1] << 8); - csptr += 2; - } - - WavpackLittleEndianToNative ((WavpackHeader *) buffer_start, WavpackHeaderFormat); -#endif - - buffer_start += bcount; - *buffer_start++ = ID_BLOCK_CHECKSUM; - *buffer_start++ = bytes >> 1; - - if (bytes == 4) { - *buffer_start++ = csum; - *buffer_start++ = csum >> 8; - *buffer_start++ = csum >> 16; - *buffer_start++ = csum >> 24; - } - else { - csum ^= csum >> 16; - *buffer_start++ = csum; - *buffer_start++ = csum >> 8; - } - - return TRUE; -} - -static void block_update_checksum (unsigned char *buffer_start) -{ - WavpackHeader *wphdr = (WavpackHeader *) buffer_start; - unsigned char *dp, meta_id, c1, c2; - uint32_t bcount, meta_bc; - - if (!(wphdr->flags & HAS_CHECKSUM)) - return; - - bcount = wphdr->ckSize - sizeof (WavpackHeader) + 8; - dp = (unsigned char *)(wphdr + 1); - - while (bcount >= 2) { - meta_id = *dp++; - c1 = *dp++; - - meta_bc = c1 << 1; - bcount -= 2; - - if (meta_id & ID_LARGE) { - if (bcount < 2) - return; - - c1 = *dp++; - c2 = *dp++; - meta_bc += ((uint32_t) c1 << 9) + ((uint32_t) c2 << 17); - bcount -= 2; - } - - if (bcount < meta_bc) - return; - - if ((meta_id & ID_UNIQUE) == ID_BLOCK_CHECKSUM) { -#ifdef BITSTREAM_SHORTS - uint16_t *csptr = (uint16_t*) buffer_start; -#else - unsigned char *csptr = buffer_start; -#endif - int wcount = (int)(dp - 2 - buffer_start) >> 1; - uint32_t csum = (uint32_t) -1; - - if ((meta_id & ID_ODD_SIZE) || meta_bc < 2 || meta_bc > 4) - return; - -#ifdef BITSTREAM_SHORTS - while (wcount--) - csum = (csum * 3) + *csptr++; -#else - WavpackNativeToLittleEndian ((WavpackHeader *) buffer_start, WavpackHeaderFormat); - - while (wcount--) { - csum = (csum * 3) + csptr [0] + (csptr [1] << 8); - csptr += 2; - } - - WavpackLittleEndianToNative ((WavpackHeader *) buffer_start, WavpackHeaderFormat); -#endif - - if (meta_bc == 4) { - *dp++ = csum; - *dp++ = csum >> 8; - *dp++ = csum >> 16; - *dp++ = csum >> 24; - return; - } - else { - csum ^= csum >> 16; - *dp++ = csum; - *dp++ = csum >> 8; - return; - } - } - - bcount -= meta_bc; - dp += meta_bc; - } -} diff --git a/Frameworks/WavPack/Files/read_words.c b/Frameworks/WavPack/Files/read_words.c deleted file mode 100644 index 0fed03cfa..000000000 --- a/Frameworks/WavPack/Files/read_words.c +++ /dev/null @@ -1,614 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// read_words.c - -// This module provides entropy word decoding functions using -// a variation on the Rice method. This was introduced in version 3.93 -// because it allows splitting the data into a "lossy" stream and a -// "correction" stream in a very efficient manner and is therefore ideal -// for the "hybrid" mode. For 4.0, the efficiency of this method was -// significantly improved by moving away from the normal Rice restriction of -// using powers of two for the modulus divisions and now the method can be -// used for both hybrid and pure lossless encoding. - -// Samples are divided by median probabilities at 5/7 (71.43%), 10/49 (20.41%), -// and 20/343 (5.83%). Each zone has 3.5 times fewer samples than the -// previous. Using standard Rice coding on this data would result in 1.4 -// bits per sample average (not counting sign bit). However, there is a -// very simple encoding that is over 99% efficient with this data and -// results in about 1.22 bits per sample. - -#include -#include - -#include "wavpack_local.h" - -#if defined (HAVE___BUILTIN_CTZ) || defined (_WIN64) -#define USE_CTZ_OPTIMIZATION // use ctz intrinsic (or Windows equivalent) to count trailing ones -#else -#define USE_NEXT8_OPTIMIZATION // optimization using a table to count trailing ones -#endif - -#define USE_BITMASK_TABLES // use tables instead of shifting for certain masking operations - -///////////////////////////// local table storage //////////////////////////// - -#ifdef USE_NEXT8_OPTIMIZATION -static const char ones_count_table [] = { - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5, - 0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,8 -}; -#endif - -///////////////////////////// executable code //////////////////////////////// - -static uint32_t __inline read_code (Bitstream *bs, uint32_t maxcode); - -// Read the next word from the bitstream "wvbits" and return the value. This -// function can be used for hybrid or lossless streams, but since an -// optimized version is available for lossless this function would normally -// be used for hybrid only. If a hybrid lossless stream is being read then -// the "correction" offset is written at the specified pointer. A return value -// of WORD_EOF indicates that the end of the bitstream was reached (all 1s) or -// some other error occurred. - -int32_t FASTCALL get_word (WavpackStream *wps, int chan, int32_t *correction) -{ - struct entropy_data *c = wps->w.c + chan; - uint32_t ones_count, low, mid, high; - int32_t value; - int sign; - - if (!wps->wvbits.ptr) - return WORD_EOF; - - if (correction) - *correction = 0; - - if (!(wps->w.c [0].median [0] & ~1) && !wps->w.holding_zero && !wps->w.holding_one && !(wps->w.c [1].median [0] & ~1)) { - uint32_t mask; - int cbits; - - if (wps->w.zeros_acc) { - if (--wps->w.zeros_acc) { - c->slow_level -= (c->slow_level + SLO) >> SLS; - return 0; - } - } - else { - for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); - - if (cbits == 33) - return WORD_EOF; - - if (cbits < 2) - wps->w.zeros_acc = cbits; - else { - for (mask = 1, wps->w.zeros_acc = 0; --cbits; mask <<= 1) - if (getbit (&wps->wvbits)) - wps->w.zeros_acc |= mask; - - wps->w.zeros_acc |= mask; - } - - if (wps->w.zeros_acc) { - c->slow_level -= (c->slow_level + SLO) >> SLS; - CLEAR (wps->w.c [0].median); - CLEAR (wps->w.c [1].median); - return 0; - } - } - } - - if (wps->w.holding_zero) - ones_count = wps->w.holding_zero = 0; - else { -#ifdef USE_CTZ_OPTIMIZATION - while (wps->wvbits.bc < LIMIT_ONES) { - if (++(wps->wvbits.ptr) == wps->wvbits.end) - wps->wvbits.wrap (&wps->wvbits); - - wps->wvbits.sr |= *(wps->wvbits.ptr) << wps->wvbits.bc; - wps->wvbits.bc += sizeof (*(wps->wvbits.ptr)) * 8; - } - -#ifdef _MSC_VER - { unsigned long res; _BitScanForward (&res, (unsigned long)~wps->wvbits.sr); ones_count = (uint32_t) res; } -#else - ones_count = __builtin_ctz (~wps->wvbits.sr); -#endif - - if (ones_count >= LIMIT_ONES) { - wps->wvbits.bc -= ones_count; - wps->wvbits.sr >>= ones_count; - - for (; ones_count < (LIMIT_ONES + 1) && getbit (&wps->wvbits); ++ones_count); - - if (ones_count == (LIMIT_ONES + 1)) - return WORD_EOF; - - if (ones_count == LIMIT_ONES) { - uint32_t mask; - int cbits; - - for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); - - if (cbits == 33) - return WORD_EOF; - - if (cbits < 2) - ones_count = cbits; - else { - for (mask = 1, ones_count = 0; --cbits; mask <<= 1) - if (getbit (&wps->wvbits)) - ones_count |= mask; - - ones_count |= mask; - } - - ones_count += LIMIT_ONES; - } - } - else { - wps->wvbits.bc -= ones_count + 1; - wps->wvbits.sr >>= ones_count + 1; - } -#elif defined (USE_NEXT8_OPTIMIZATION) - int next8; - - if (wps->wvbits.bc < 8) { - if (++(wps->wvbits.ptr) == wps->wvbits.end) - wps->wvbits.wrap (&wps->wvbits); - - next8 = (wps->wvbits.sr |= *(wps->wvbits.ptr) << wps->wvbits.bc) & 0xff; - wps->wvbits.bc += sizeof (*(wps->wvbits.ptr)) * 8; - } - else - next8 = wps->wvbits.sr & 0xff; - - if (next8 == 0xff) { - wps->wvbits.bc -= 8; - wps->wvbits.sr >>= 8; - - for (ones_count = 8; ones_count < (LIMIT_ONES + 1) && getbit (&wps->wvbits); ++ones_count); - - if (ones_count == (LIMIT_ONES + 1)) - return WORD_EOF; - - if (ones_count == LIMIT_ONES) { - uint32_t mask; - int cbits; - - for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); - - if (cbits == 33) - return WORD_EOF; - - if (cbits < 2) - ones_count = cbits; - else { - for (mask = 1, ones_count = 0; --cbits; mask <<= 1) - if (getbit (&wps->wvbits)) - ones_count |= mask; - - ones_count |= mask; - } - - ones_count += LIMIT_ONES; - } - } - else { - wps->wvbits.bc -= (ones_count = ones_count_table [next8]) + 1; - wps->wvbits.sr >>= ones_count + 1; - } -#else - for (ones_count = 0; ones_count < (LIMIT_ONES + 1) && getbit (&wps->wvbits); ++ones_count); - - if (ones_count >= LIMIT_ONES) { - uint32_t mask; - int cbits; - - if (ones_count == (LIMIT_ONES + 1)) - return WORD_EOF; - - for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); - - if (cbits == 33) - return WORD_EOF; - - if (cbits < 2) - ones_count = cbits; - else { - for (mask = 1, ones_count = 0; --cbits; mask <<= 1) - if (getbit (&wps->wvbits)) - ones_count |= mask; - - ones_count |= mask; - } - - ones_count += LIMIT_ONES; - } -#endif - - if (wps->w.holding_one) { - wps->w.holding_one = ones_count & 1; - ones_count = (ones_count >> 1) + 1; - } - else { - wps->w.holding_one = ones_count & 1; - ones_count >>= 1; - } - - wps->w.holding_zero = ~wps->w.holding_one & 1; - } - - if ((wps->wphdr.flags & HYBRID_FLAG) && !chan) - update_error_limit (wps); - - if (ones_count == 0) { - low = 0; - high = GET_MED (0) - 1; - DEC_MED0 (); - } - else { - low = GET_MED (0); - INC_MED0 (); - - if (ones_count == 1) { - high = low + GET_MED (1) - 1; - DEC_MED1 (); - } - else { - low += GET_MED (1); - INC_MED1 (); - - if (ones_count == 2) { - high = low + GET_MED (2) - 1; - DEC_MED2 (); - } - else { - low += (ones_count - 2) * GET_MED (2); - high = low + GET_MED (2) - 1; - INC_MED2 (); - } - } - } - - low &= 0x7fffffff; - high &= 0x7fffffff; - - if (low > high) // make sure high and low make sense - high = low; - - mid = (high + low + 1) >> 1; - - if (!c->error_limit) - mid = read_code (&wps->wvbits, high - low) + low; - else while (high - low > c->error_limit) { - if (getbit (&wps->wvbits)) - mid = (high + (low = mid) + 1) >> 1; - else - mid = ((high = mid - 1) + low + 1) >> 1; - } - - sign = getbit (&wps->wvbits); - - if (bs_is_open (&wps->wvcbits) && c->error_limit) { - value = read_code (&wps->wvcbits, high - low) + low; - - if (correction) - *correction = sign ? (mid - value) : (value - mid); - } - - if (wps->wphdr.flags & HYBRID_BITRATE) { - c->slow_level -= (c->slow_level + SLO) >> SLS; - c->slow_level += wp_log2 (mid); - } - - return sign ? ~mid : mid; -} - -// This is an optimized version of get_word() that is used for lossless only -// (error_limit == 0). Also, rather than obtaining a single sample, it can be -// used to obtain an entire buffer of either mono or stereo samples. - -int32_t get_words_lossless (WavpackStream *wps, int32_t *buffer, int32_t nsamples) -{ - struct entropy_data *c = wps->w.c; - uint32_t ones_count, low, high; - Bitstream *bs = &wps->wvbits; - int32_t csamples; -#ifdef USE_NEXT8_OPTIMIZATION - int32_t next8; -#endif - - if (nsamples && !bs->ptr) { - memset (buffer, 0, (wps->wphdr.flags & MONO_DATA) ? nsamples * 4 : nsamples * 8); - return nsamples; - } - - if (!(wps->wphdr.flags & MONO_DATA)) - nsamples *= 2; - - for (csamples = 0; csamples < nsamples; ++csamples) { - if (!(wps->wphdr.flags & MONO_DATA)) - c = wps->w.c + (csamples & 1); - - if (wps->w.holding_zero) { - wps->w.holding_zero = 0; - low = read_code (bs, GET_MED (0) - 1); - DEC_MED0 (); - buffer [csamples] = (getbit (bs)) ? ~low : low; - - if (++csamples == nsamples) - break; - - if (!(wps->wphdr.flags & MONO_DATA)) - c = wps->w.c + (csamples & 1); - } - - if (wps->w.c [0].median [0] < 2 && !wps->w.holding_one && wps->w.c [1].median [0] < 2) { - uint32_t mask; - int cbits; - - if (wps->w.zeros_acc) { - if (--wps->w.zeros_acc) { - buffer [csamples] = 0; - continue; - } - } - else { - for (cbits = 0; cbits < 33 && getbit (bs); ++cbits); - - if (cbits == 33) - break; - - if (cbits < 2) - wps->w.zeros_acc = cbits; - else { - for (mask = 1, wps->w.zeros_acc = 0; --cbits; mask <<= 1) - if (getbit (bs)) - wps->w.zeros_acc |= mask; - - wps->w.zeros_acc |= mask; - } - - if (wps->w.zeros_acc) { - CLEAR (wps->w.c [0].median); - CLEAR (wps->w.c [1].median); - buffer [csamples] = 0; - continue; - } - } - } - -#ifdef USE_CTZ_OPTIMIZATION - while (bs->bc < LIMIT_ONES) { - if (++(bs->ptr) == bs->end) - bs->wrap (bs); - - bs->sr |= *(bs->ptr) << bs->bc; - bs->bc += sizeof (*(bs->ptr)) * 8; - } - -#ifdef _MSC_VER - { unsigned long res; _BitScanForward (&res, (unsigned long)~wps->wvbits.sr); ones_count = (uint32_t) res; } -#else - ones_count = __builtin_ctz (~wps->wvbits.sr); -#endif - - if (ones_count >= LIMIT_ONES) { - bs->bc -= ones_count; - bs->sr >>= ones_count; - - for (; ones_count < (LIMIT_ONES + 1) && getbit (bs); ++ones_count); - - if (ones_count == (LIMIT_ONES + 1)) - break; - - if (ones_count == LIMIT_ONES) { - uint32_t mask; - int cbits; - - for (cbits = 0; cbits < 33 && getbit (bs); ++cbits); - - if (cbits == 33) - break; - - if (cbits < 2) - ones_count = cbits; - else { - for (mask = 1, ones_count = 0; --cbits; mask <<= 1) - if (getbit (bs)) - ones_count |= mask; - - ones_count |= mask; - } - - ones_count += LIMIT_ONES; - } - } - else { - bs->bc -= ones_count + 1; - bs->sr >>= ones_count + 1; - } -#elif defined (USE_NEXT8_OPTIMIZATION) - if (bs->bc < 8) { - if (++(bs->ptr) == bs->end) - bs->wrap (bs); - - next8 = (bs->sr |= *(bs->ptr) << bs->bc) & 0xff; - bs->bc += sizeof (*(bs->ptr)) * 8; - } - else - next8 = bs->sr & 0xff; - - if (next8 == 0xff) { - bs->bc -= 8; - bs->sr >>= 8; - - for (ones_count = 8; ones_count < (LIMIT_ONES + 1) && getbit (bs); ++ones_count); - - if (ones_count == (LIMIT_ONES + 1)) - break; - - if (ones_count == LIMIT_ONES) { - uint32_t mask; - int cbits; - - for (cbits = 0; cbits < 33 && getbit (bs); ++cbits); - - if (cbits == 33) - break; - - if (cbits < 2) - ones_count = cbits; - else { - for (mask = 1, ones_count = 0; --cbits; mask <<= 1) - if (getbit (bs)) - ones_count |= mask; - - ones_count |= mask; - } - - ones_count += LIMIT_ONES; - } - } - else { - bs->bc -= (ones_count = ones_count_table [next8]) + 1; - bs->sr >>= ones_count + 1; - } -#else - for (ones_count = 0; ones_count < (LIMIT_ONES + 1) && getbit (bs); ++ones_count); - - if (ones_count >= LIMIT_ONES) { - uint32_t mask; - int cbits; - - if (ones_count == (LIMIT_ONES + 1)) - break; - - for (cbits = 0; cbits < 33 && getbit (bs); ++cbits); - - if (cbits == 33) - break; - - if (cbits < 2) - ones_count = cbits; - else { - for (mask = 1, ones_count = 0; --cbits; mask <<= 1) - if (getbit (bs)) - ones_count |= mask; - - ones_count |= mask; - } - - ones_count += LIMIT_ONES; - } -#endif - - low = wps->w.holding_one; - wps->w.holding_one = ones_count & 1; - wps->w.holding_zero = ~ones_count & 1; - ones_count = (ones_count >> 1) + low; - - if (ones_count == 0) { - low = 0; - high = GET_MED (0) - 1; - DEC_MED0 (); - } - else { - low = GET_MED (0); - INC_MED0 (); - - if (ones_count == 1) { - high = low + GET_MED (1) - 1; - DEC_MED1 (); - } - else { - low += GET_MED (1); - INC_MED1 (); - - if (ones_count == 2) { - high = low + GET_MED (2) - 1; - DEC_MED2 (); - } - else { - low += (ones_count - 2) * GET_MED (2); - high = low + GET_MED (2) - 1; - INC_MED2 (); - } - } - } - - low += read_code (bs, high - low); - buffer [csamples] = (getbit (bs)) ? ~low : low; - } - - return (wps->wphdr.flags & MONO_DATA) ? csamples : (csamples / 2); -} - -// Read a single unsigned value from the specified bitstream with a value -// from 0 to maxcode. If there are exactly a power of two number of possible -// codes then this will read a fixed number of bits; otherwise it reads the -// minimum number of bits and then determines whether another bit is needed -// to define the code. - -static uint32_t __inline read_code (Bitstream *bs, uint32_t maxcode) -{ - unsigned long local_sr; - uint32_t extras, code; - int bitcount; - - if (maxcode < 2) - return maxcode ? getbit (bs) : 0; - - bitcount = count_bits (maxcode); -#ifdef USE_BITMASK_TABLES - extras = bitset [bitcount] - maxcode - 1; -#else - extras = (1 << bitcount) - maxcode - 1; -#endif - - local_sr = bs->sr; - - while (bs->bc < bitcount) { - if (++(bs->ptr) == bs->end) - bs->wrap (bs); - - local_sr |= (long)*(bs->ptr) << bs->bc; - bs->bc += sizeof (*(bs->ptr)) * 8; - } - -#ifdef USE_BITMASK_TABLES - if ((code = local_sr & bitmask [bitcount - 1]) >= extras) -#else - if ((code = local_sr & ((1 << (bitcount - 1)) - 1)) >= extras) -#endif - code = (code << 1) - extras + ((local_sr >> (bitcount - 1)) & 1); - else - bitcount--; - - if (sizeof (local_sr) < 8 && bs->bc > sizeof (local_sr) * 8) { - bs->bc -= bitcount; - bs->sr = *(bs->ptr) >> (sizeof (*(bs->ptr)) * 8 - bs->bc); - } - else { - bs->bc -= bitcount; - bs->sr = local_sr >> bitcount; - } - - return code; -} diff --git a/Frameworks/WavPack/Files/tag_utils.c b/Frameworks/WavPack/Files/tag_utils.c deleted file mode 100644 index 2040e1c40..000000000 --- a/Frameworks/WavPack/Files/tag_utils.c +++ /dev/null @@ -1,597 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// tag_utils.c - -// This module provides the high-level API for creating, reading and editing -// APEv2 tags on WavPack files. Read-only support is also provided for ID3v1 -// tags, but their use is not recommended. - -#include -#include - -#include "wavpack_local.h" - -#ifdef _WIN32 -#define stricmp(x,y) _stricmp(x,y) -#else -#define stricmp strcasecmp -#endif - -static int get_ape_tag_item (M_Tag *m_tag, const char *item, char *value, int size, int type); -static int get_id3_tag_item (M_Tag *m_tag, const char *item, char *value, int size); -static int get_ape_tag_item_indexed (M_Tag *m_tag, int index, char *item, int size, int type); -static int get_id3_tag_item_indexed (M_Tag *m_tag, int index, char *item, int size); -static int append_ape_tag_item (WavpackContext *wpc, const char *item, const char *value, int vsize, int type); -static int write_tag_blockout (WavpackContext *wpc); -static int write_tag_reader (WavpackContext *wpc); -static void tagcpy (char *dest, char *src, int tag_size); -static int tagdata (char *src, int tag_size); - -//////////////////// Global functions part of external API ///////////////////////// - -// Count and return the total number of tag items in the specified file. - -int WavpackGetNumTagItems (WavpackContext *wpc) -{ - int i = 0; - - while (WavpackGetTagItemIndexed (wpc, i, NULL, 0)) - ++i; - - return i; -} - -// Count and return the total number of binary tag items in the specified file. This applies -// only to APEv2 tags and was implemented as a separate function to avoid breaking the old API. - -int WavpackGetNumBinaryTagItems (WavpackContext *wpc) -{ - int i = 0; - - while (WavpackGetBinaryTagItemIndexed (wpc, i, NULL, 0)) - ++i; - - return i; -} - -// Attempt to get the specified item from the specified file's ID3v1 or APEv2 -// tag. The "size" parameter specifies the amount of space available at "value", -// if the desired item will not fit in this space then ellipses (...) will -// be appended and the string terminated. Only text data are supported. The -// actual length of the string is returned (or 0 if no matching value found). -// Note that with APEv2 tags the length might not be the same as the number of -// characters because UTF-8 encoding is used. Also, APEv2 tags can have multiple -// (NULL separated) strings for a single value (this is why the length is -// returned). If this function is called with a NULL "value" pointer (or a -// zero "length") then only the actual length of the value data is returned -// (not counting the terminating NULL). This can be used to determine the -// actual memory to be allocated beforehand. - -int WavpackGetTagItem (WavpackContext *wpc, const char *item, char *value, int size) -{ - M_Tag *m_tag = &wpc->m_tag; - - if (value && size) - *value = 0; - - if (m_tag->ape_tag_hdr.ID [0] == 'A') - return get_ape_tag_item (m_tag, item, value, size, APE_TAG_TYPE_TEXT); - else if (m_tag->id3_tag.tag_id [0] == 'T') - return get_id3_tag_item (m_tag, item, value, size); - else - return 0; -} - -// Attempt to get the specified binary item from the specified file's APEv2 -// tag. The "size" parameter specifies the amount of space available at "value". -// If the desired item will not fit in this space then nothing will be copied -// and 0 will be returned, otherwise the actual size will be returned. If this -// function is called with a NULL "value" pointer (or a zero "length") then only -// the actual length of the value data is returned and can be used to determine -// the actual memory to be allocated beforehand. - -int WavpackGetBinaryTagItem (WavpackContext *wpc, const char *item, char *value, int size) -{ - M_Tag *m_tag = &wpc->m_tag; - - if (value && size) - *value = 0; - - if (m_tag->ape_tag_hdr.ID [0] == 'A') - return get_ape_tag_item (m_tag, item, value, size, APE_TAG_TYPE_BINARY); - else - return 0; -} - -// This function looks up the tag item name by index and is used when the -// application wants to access all the items in the file's ID3v1 or APEv2 tag. -// Note that this function accesses only the item's name; WavpackGetTagItem() -// still must be called to get the actual value. The "size" parameter specifies -// the amount of space available at "item", if the desired item will not fit in -// this space then ellipses (...) will be appended and the string terminated. -// The actual length of the string is returned (or 0 if no item exists for -// index). If this function is called with a NULL "value" pointer (or a -// zero "length") then only the actual length of the item name is returned -// (not counting the terminating NULL). This can be used to determine the -// actual memory to be allocated beforehand. For binary tag values use the -// otherwise identical WavpackGetBinaryTagItemIndexed (); - -int WavpackGetTagItemIndexed (WavpackContext *wpc, int index, char *item, int size) -{ - M_Tag *m_tag = &wpc->m_tag; - - if (item && size) - *item = 0; - - if (m_tag->ape_tag_hdr.ID [0] == 'A') - return get_ape_tag_item_indexed (m_tag, index, item, size, APE_TAG_TYPE_TEXT); - else if (m_tag->id3_tag.tag_id [0] == 'T') - return get_id3_tag_item_indexed (m_tag, index, item, size); - else - return 0; -} - -int WavpackGetBinaryTagItemIndexed (WavpackContext *wpc, int index, char *item, int size) -{ - M_Tag *m_tag = &wpc->m_tag; - - if (item && size) - *item = 0; - - if (m_tag->ape_tag_hdr.ID [0] == 'A') - return get_ape_tag_item_indexed (m_tag, index, item, size, APE_TAG_TYPE_BINARY); - else - return 0; -} - -// These two functions are used to append APEv2 tags to WavPack files; one is -// for text values (UTF-8 encoded) and the other is for binary values. If no tag -// has been started, then an empty one will be allocated first. When finished, -// use WavpackWriteTag() to write the completed tag to the file. The purpose of -// the passed size parameter is obvious for binary values, but might not be for -// text values. Keep in mind that APEv2 text values can have multiple values -// that are NULL separated, so the size is required to know the extent of the -// value (although the final terminating NULL is not included in the passed -// size). If the specified item already exists, it will be replaced with the -// new value. ID3v1 tags are not supported. - -int WavpackAppendTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize) -{ - while (WavpackDeleteTagItem (wpc, item)); - return append_ape_tag_item (wpc, item, value, vsize, APE_TAG_TYPE_TEXT); -} - -int WavpackAppendBinaryTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize) -{ - while (WavpackDeleteTagItem (wpc, item)); - return append_ape_tag_item (wpc, item, value, vsize, APE_TAG_TYPE_BINARY); -} - -// Delete the specified tag item from the APEv2 tag on the specified WavPack file -// (fields cannot be deleted from ID3v1 tags). A return value of TRUE indicates -// that the item was found and successfully deleted. - -int WavpackDeleteTagItem (WavpackContext *wpc, const char *item) -{ - M_Tag *m_tag = &wpc->m_tag; - - if (m_tag->ape_tag_hdr.ID [0] == 'A') { - unsigned char *p = m_tag->ape_tag_data; - unsigned char *q = p + m_tag->ape_tag_hdr.length - sizeof (APE_Tag_Hdr); - int i; - - for (i = 0; i < m_tag->ape_tag_hdr.item_count; ++i) { - int vsize, isize; - - vsize = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); p += 8; // skip flags because we don't need them - for (isize = 0; p[isize] && p + isize < q; ++isize); - - if (vsize < 0 || vsize > m_tag->ape_tag_hdr.length || p + isize + vsize + 1 > q) - break; - - if (isize && vsize && !stricmp (item, (char *) p)) { - unsigned char *d = p - 8; - - p += isize + vsize + 1; - - while (p < q) - *d++ = *p++; - - m_tag->ape_tag_hdr.length = (int32_t)(d - m_tag->ape_tag_data) + sizeof (APE_Tag_Hdr); - m_tag->ape_tag_hdr.item_count--; - return 1; - } - else - p += isize + vsize + 1; - } - } - - return 0; -} - -// Once a APEv2 tag has been created with WavpackAppendTag(), this function is -// used to write the completed tag to the end of the WavPack file. Note that -// this function uses the same "blockout" function that is used to write -// regular WavPack blocks, although that's where the similarity ends. It is also -// used to write tags that have been edited on existing files. - -int WavpackWriteTag (WavpackContext *wpc) -{ - if (wpc->blockout) // this is the case for creating fresh WavPack files - return write_tag_blockout (wpc); - else // otherwise we are editing existing tags (OPEN_EDIT_TAGS) - return write_tag_reader (wpc); -} - -////////////////////////// local static functions ///////////////////////////// - -static int get_ape_tag_item (M_Tag *m_tag, const char *item, char *value, int size, int type) -{ - unsigned char *p = m_tag->ape_tag_data; - unsigned char *q = p + m_tag->ape_tag_hdr.length - sizeof (APE_Tag_Hdr); - int i; - - for (i = 0; i < m_tag->ape_tag_hdr.item_count && q - p > 8; ++i) { - int vsize, flags, isize; - - vsize = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); p += 4; - flags = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); p += 4; - for (isize = 0; p[isize] && p + isize < q; ++isize); - - if (vsize < 0 || vsize > m_tag->ape_tag_hdr.length || p + isize + vsize + 1 > q) - break; - - if (isize && vsize && !stricmp (item, (char *) p) && ((flags & 6) >> 1) == type) { - - if (!value || !size) - return vsize; - - if (type == APE_TAG_TYPE_BINARY) { - if (vsize <= size) { - memcpy (value, p + isize + 1, vsize); - return vsize; - } - else - return 0; - } - else if (vsize < size) { - memcpy (value, p + isize + 1, vsize); - value [vsize] = 0; - return vsize; - } - else if (size >= 4) { - memcpy (value, p + isize + 1, size - 1); - value [size - 4] = value [size - 3] = value [size - 2] = '.'; - value [size - 1] = 0; - return size - 1; - } - else - return 0; - } - else - p += isize + vsize + 1; - } - - return 0; -} - -static int get_id3_tag_item (M_Tag *m_tag, const char *item, char *value, int size) -{ - char lvalue [64]; - int len; - - lvalue [0] = 0; - - if (!stricmp (item, "title")) - tagcpy (lvalue, m_tag->id3_tag.title, sizeof (m_tag->id3_tag.title)); - else if (!stricmp (item, "artist")) - tagcpy (lvalue, m_tag->id3_tag.artist, sizeof (m_tag->id3_tag.artist)); - else if (!stricmp (item, "album")) - tagcpy (lvalue, m_tag->id3_tag.album, sizeof (m_tag->id3_tag.album)); - else if (!stricmp (item, "year")) - tagcpy (lvalue, m_tag->id3_tag.year, sizeof (m_tag->id3_tag.year)); - else if (!stricmp (item, "comment")) - tagcpy (lvalue, m_tag->id3_tag.comment, sizeof (m_tag->id3_tag.comment)); - else if (!stricmp (item, "track") && m_tag->id3_tag.comment [29] && !m_tag->id3_tag.comment [28]) - sprintf (lvalue, "%d", m_tag->id3_tag.comment [29]); - else - return 0; - - len = (int) strlen (lvalue); - - if (!value || !size) - return len; - - if (len < size) { - strcpy (value, lvalue); - return len; - } - else if (size >= 4) { - strncpy (value, lvalue, size - 1); - value [size - 4] = value [size - 3] = value [size - 2] = '.'; - value [size - 1] = 0; - return size - 1; - } - else - return 0; -} - -static int get_ape_tag_item_indexed (M_Tag *m_tag, int index, char *item, int size, int type) -{ - unsigned char *p = m_tag->ape_tag_data; - unsigned char *q = p + m_tag->ape_tag_hdr.length - sizeof (APE_Tag_Hdr); - int i; - - for (i = 0; i < m_tag->ape_tag_hdr.item_count && index >= 0 && q - p > 8; ++i) { - int vsize, flags, isize; - - vsize = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); p += 4; - flags = p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); p += 4; - for (isize = 0; p[isize] && p + isize < q; ++isize); - - if (vsize < 0 || vsize > m_tag->ape_tag_hdr.length || p + isize + vsize + 1 > q) - break; - - if (isize && vsize && ((flags & 6) >> 1) == type && !index--) { - - if (!item || !size) - return isize; - - if (isize < size) { - memcpy (item, p, isize); - item [isize] = 0; - return isize; - } - else if (size >= 4) { - memcpy (item, p, size - 1); - item [size - 4] = item [size - 3] = item [size - 2] = '.'; - item [size - 1] = 0; - return size - 1; - } - else - return 0; - } - else - p += isize + vsize + 1; - } - - return 0; -} - -static int get_id3_tag_item_indexed (M_Tag *m_tag, int index, char *item, int size) -{ - char lvalue [16]; - int len; - - lvalue [0] = 0; - - if (tagdata (m_tag->id3_tag.title, sizeof (m_tag->id3_tag.title)) && !index--) - strcpy (lvalue, "Title"); - else if (tagdata (m_tag->id3_tag.artist, sizeof (m_tag->id3_tag.artist)) && !index--) - strcpy (lvalue, "Artist"); - else if (tagdata (m_tag->id3_tag.album, sizeof (m_tag->id3_tag.album)) && !index--) - strcpy (lvalue, "Album"); - else if (tagdata (m_tag->id3_tag.year, sizeof (m_tag->id3_tag.year)) && !index--) - strcpy (lvalue, "Year"); - else if (tagdata (m_tag->id3_tag.comment, sizeof (m_tag->id3_tag.comment)) && !index--) - strcpy (lvalue, "Comment"); - else if (m_tag->id3_tag.comment [29] && !m_tag->id3_tag.comment [28] && !index--) - strcpy (lvalue, "Track"); - else - return 0; - - len = (int) strlen (lvalue); - - if (!item || !size) - return len; - - if (len < size) { - strcpy (item, lvalue); - return len; - } - else if (size >= 4) { - strncpy (item, lvalue, size - 1); - item [size - 4] = item [size - 3] = item [size - 2] = '.'; - item [size - 1] = 0; - return size - 1; - } - else - return 0; -} - -static int append_ape_tag_item (WavpackContext *wpc, const char *item, const char *value, int vsize, int type) -{ - M_Tag *m_tag = &wpc->m_tag; - int isize = (int) strlen (item); - - if (!m_tag->ape_tag_hdr.ID [0]) { - memcpy (m_tag->ape_tag_hdr.ID, "APETAGEX", sizeof (m_tag->ape_tag_hdr.ID)); - m_tag->ape_tag_hdr.version = 2000; - m_tag->ape_tag_hdr.length = sizeof (m_tag->ape_tag_hdr); - m_tag->ape_tag_hdr.item_count = 0; - m_tag->ape_tag_hdr.flags = APE_TAG_CONTAINS_HEADER; // we will include header on tags we originate - } - - if (m_tag->ape_tag_hdr.ID [0] == 'A') { - int new_item_len = vsize + isize + 9, flags = type << 1; - unsigned char *p; - - if (m_tag->ape_tag_hdr.length + new_item_len > APE_TAG_MAX_LENGTH) { - strcpy (wpc->error_message, "APEv2 tag exceeds maximum allowed length!"); - return FALSE; - } - - m_tag->ape_tag_hdr.item_count++; - m_tag->ape_tag_hdr.length += new_item_len; - p = m_tag->ape_tag_data = (unsigned char*)realloc (m_tag->ape_tag_data, m_tag->ape_tag_hdr.length); - p += m_tag->ape_tag_hdr.length - sizeof (APE_Tag_Hdr) - new_item_len; - - *p++ = (unsigned char) vsize; - *p++ = (unsigned char) (vsize >> 8); - *p++ = (unsigned char) (vsize >> 16); - *p++ = (unsigned char) (vsize >> 24); - - *p++ = (unsigned char) flags; - *p++ = (unsigned char) (flags >> 8); - *p++ = (unsigned char) (flags >> 16); - *p++ = (unsigned char) (flags >> 24); - - strcpy ((char *) p, item); - p += isize + 1; - memcpy (p, value, vsize); - - return TRUE; - } - else - return FALSE; -} - -// Append the stored APEv2 tag to the file being created using the "blockout" function callback. - -static int write_tag_blockout (WavpackContext *wpc) -{ - M_Tag *m_tag = &wpc->m_tag; - int result = TRUE; - - if (m_tag->ape_tag_hdr.ID [0] == 'A' && m_tag->ape_tag_hdr.item_count) { - - // only write header if it's specified in the flags - - if (m_tag->ape_tag_hdr.flags & APE_TAG_CONTAINS_HEADER) { - m_tag->ape_tag_hdr.flags |= APE_TAG_THIS_IS_HEADER; - WavpackNativeToLittleEndian (&m_tag->ape_tag_hdr, APE_Tag_Hdr_Format); - result = wpc->blockout (wpc->wv_out, &m_tag->ape_tag_hdr, sizeof (m_tag->ape_tag_hdr)); - WavpackLittleEndianToNative (&m_tag->ape_tag_hdr, APE_Tag_Hdr_Format); - } - - if (m_tag->ape_tag_hdr.length > sizeof (m_tag->ape_tag_hdr)) - result = wpc->blockout (wpc->wv_out, m_tag->ape_tag_data, m_tag->ape_tag_hdr.length - sizeof (m_tag->ape_tag_hdr)); - - m_tag->ape_tag_hdr.flags &= ~APE_TAG_THIS_IS_HEADER; // this is NOT header - WavpackNativeToLittleEndian (&m_tag->ape_tag_hdr, APE_Tag_Hdr_Format); - result = wpc->blockout (wpc->wv_out, &m_tag->ape_tag_hdr, sizeof (m_tag->ape_tag_hdr)); - WavpackLittleEndianToNative (&m_tag->ape_tag_hdr, APE_Tag_Hdr_Format); - } - - if (!result) - strcpy (wpc->error_message, "can't write WavPack data, disk probably full!"); - - return result; -} - -// Write the [potentially] edited tag to the existing WavPack file using the reader callback functions. - -static int write_tag_reader (WavpackContext *wpc) -{ - M_Tag *m_tag = &wpc->m_tag; - int32_t tag_size = 0; - int result; - - // before we write an edited (or new) tag into an existing file, make sure it's safe and possible - - if (m_tag->tag_begins_file) { - strcpy (wpc->error_message, "can't edit tags located at the beginning of files!"); - return FALSE; - } - - if (!wpc->reader->can_seek (wpc->wv_in)) { - strcpy (wpc->error_message, "can't edit tags on pipes or unseekable files!"); - return FALSE; - } - - if (!(wpc->open_flags & OPEN_EDIT_TAGS)) { - strcpy (wpc->error_message, "can't edit tags without OPEN_EDIT_TAGS flag!"); - return FALSE; - } - - if (m_tag->ape_tag_hdr.ID [0] == 'A' && m_tag->ape_tag_hdr.item_count && - m_tag->ape_tag_hdr.length > sizeof (m_tag->ape_tag_hdr)) - tag_size = m_tag->ape_tag_hdr.length; - - // only write header if it's specified in the flags - - if (tag_size && (m_tag->ape_tag_hdr.flags & APE_TAG_CONTAINS_HEADER)) - tag_size += sizeof (m_tag->ape_tag_hdr); - - result = !wpc->reader->set_pos_rel (wpc->wv_in, m_tag->tag_file_pos, SEEK_END); - - if (result && tag_size < -m_tag->tag_file_pos && !wpc->reader->truncate_here) { - int nullcnt = (int) (-m_tag->tag_file_pos - tag_size); - char zero [1] = { 0 }; - - while (nullcnt--) - wpc->reader->write_bytes (wpc->wv_in, &zero, 1); - } - - if (result && tag_size) { - if (m_tag->ape_tag_hdr.flags & APE_TAG_CONTAINS_HEADER) { - m_tag->ape_tag_hdr.flags |= APE_TAG_THIS_IS_HEADER; - WavpackNativeToLittleEndian (&m_tag->ape_tag_hdr, APE_Tag_Hdr_Format); - result = (wpc->reader->write_bytes (wpc->wv_in, &m_tag->ape_tag_hdr, sizeof (m_tag->ape_tag_hdr)) == sizeof (m_tag->ape_tag_hdr)); - WavpackLittleEndianToNative (&m_tag->ape_tag_hdr, APE_Tag_Hdr_Format); - } - - result = (wpc->reader->write_bytes (wpc->wv_in, m_tag->ape_tag_data, m_tag->ape_tag_hdr.length - sizeof (m_tag->ape_tag_hdr)) == sizeof (m_tag->ape_tag_hdr)); - m_tag->ape_tag_hdr.flags &= ~APE_TAG_THIS_IS_HEADER; // this is NOT header - WavpackNativeToLittleEndian (&m_tag->ape_tag_hdr, APE_Tag_Hdr_Format); - result = (wpc->reader->write_bytes (wpc->wv_in, &m_tag->ape_tag_hdr, sizeof (m_tag->ape_tag_hdr)) == sizeof (m_tag->ape_tag_hdr)); - WavpackLittleEndianToNative (&m_tag->ape_tag_hdr, APE_Tag_Hdr_Format); - } - - if (result && tag_size < -m_tag->tag_file_pos && wpc->reader->truncate_here) - result = !wpc->reader->truncate_here (wpc->wv_in); - - if (!result) - strcpy (wpc->error_message, "can't write WavPack data, disk probably full!"); - - return result; -} - -// Copy the specified ID3v1 tag value (with specified field size) from the -// source pointer to the destination, eliminating leading spaces and trailing -// spaces and nulls. - -static void tagcpy (char *dest, char *src, int tag_size) -{ - char *s1 = src, *s2 = src + tag_size - 1; - - if (*s2 && !s2 [-1]) - s2--; - - while (s1 <= s2) - if (*s1 == ' ') - ++s1; - else if (!*s2 || *s2 == ' ') - --s2; - else - break; - - while (*s1 && s1 <= s2) - *dest++ = *s1++; - - *dest = 0; -} - -static int tagdata (char *src, int tag_size) -{ - char *s1 = src, *s2 = src + tag_size - 1; - - if (*s2 && !s2 [-1]) - s2--; - - while (s1 <= s2) - if (*s1 == ' ') - ++s1; - else if (!*s2 || *s2 == ' ') - --s2; - else - break; - - return (*s1 && s1 <= s2); -} diff --git a/Frameworks/WavPack/Files/tags.c b/Frameworks/WavPack/Files/tags.c deleted file mode 100644 index bbde21aed..000000000 --- a/Frameworks/WavPack/Files/tags.c +++ /dev/null @@ -1,179 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// tags.c - -// This module provides support for reading metadata tags (either ID3v1 or -// APEv2) from WavPack files. No actual creation or manipulation of the tags -// is done in this module; this is just internal code to load the tags into -// memory. The high-level API functions are in the tag_utils.c module. - -#include -#include - -#include "wavpack_local.h" - -// This function attempts to load an ID3v1 or APEv2 tag from the specified -// file into the specified M_Tag structure. The ID3 tag fits in completely, -// but an APEv2 tag is variable length and so space must be allocated here -// to accommodate the data, and this will need to be freed later. A return -// value of TRUE indicates a valid tag was found and loaded. Note that the -// file pointer is undefined when this function exits. - -int load_tag (WavpackContext *wpc) -{ - int ape_tag_length, ape_tag_items; - M_Tag *m_tag = &wpc->m_tag; - - CLEAR (*m_tag); - - // This is a loop because we can try up to three times to look for an APEv2 tag. In order, we look: - // - // 1. At the end of the file for a APEv2 footer (this is the preferred location) - // 2. If there's instead an ID3v1 tag at the end of the file, try looking for an APEv2 footer right before that - // 3. If all else fails, look for an APEv2 header the the beginning of the file (use is strongly discouraged) - - while (1) { - - // seek based on specific location that we are looking for tag (see above list) - - if (m_tag->tag_begins_file) // case #3 - wpc->reader->set_pos_abs (wpc->wv_in, 0); - else if (m_tag->id3_tag.tag_id [0] == 'T') // case #2 - wpc->reader->set_pos_rel (wpc->wv_in, -(int32_t)(sizeof (APE_Tag_Hdr) + sizeof (ID3_Tag)), SEEK_END); - else // case #1 - wpc->reader->set_pos_rel (wpc->wv_in, -(int32_t)sizeof (APE_Tag_Hdr), SEEK_END); - - // read a possible APEv2 tag header/footer and see if there's one there... - - if (wpc->reader->read_bytes (wpc->wv_in, &m_tag->ape_tag_hdr, sizeof (APE_Tag_Hdr)) == sizeof (APE_Tag_Hdr) && - !strncmp (m_tag->ape_tag_hdr.ID, "APETAGEX", 8)) { - - WavpackLittleEndianToNative (&m_tag->ape_tag_hdr, APE_Tag_Hdr_Format); - - if (m_tag->ape_tag_hdr.version == 2000 && m_tag->ape_tag_hdr.item_count && - m_tag->ape_tag_hdr.length > sizeof (m_tag->ape_tag_hdr) && - m_tag->ape_tag_hdr.length <= APE_TAG_MAX_LENGTH && - (m_tag->ape_tag_data = (unsigned char *)malloc (m_tag->ape_tag_hdr.length)) != NULL) { - - ape_tag_items = m_tag->ape_tag_hdr.item_count; - ape_tag_length = m_tag->ape_tag_hdr.length; - - // If this is a APEv2 footer (which is normal if we are searching at the end of the file)... - - if (!(m_tag->ape_tag_hdr.flags & APE_TAG_THIS_IS_HEADER)) { - - if (m_tag->id3_tag.tag_id [0] == 'T') - m_tag->tag_file_pos = -(int32_t)sizeof (ID3_Tag); - else - m_tag->tag_file_pos = 0; - - m_tag->tag_file_pos -= ape_tag_length; - - // if the footer claims there is a header present also, we will read that and use it - // instead of the footer (after verifying it, of course) for enhanced robustness - - if (m_tag->ape_tag_hdr.flags & APE_TAG_CONTAINS_HEADER) - m_tag->tag_file_pos -= sizeof (APE_Tag_Hdr); - - wpc->reader->set_pos_rel (wpc->wv_in, m_tag->tag_file_pos, SEEK_END); - - if (m_tag->ape_tag_hdr.flags & APE_TAG_CONTAINS_HEADER) { - if (wpc->reader->read_bytes (wpc->wv_in, &m_tag->ape_tag_hdr, sizeof (APE_Tag_Hdr)) != - sizeof (APE_Tag_Hdr) || strncmp (m_tag->ape_tag_hdr.ID, "APETAGEX", 8)) { - free (m_tag->ape_tag_data); - CLEAR (*m_tag); - return FALSE; // something's wrong... - } - - WavpackLittleEndianToNative (&m_tag->ape_tag_hdr, APE_Tag_Hdr_Format); - - if (m_tag->ape_tag_hdr.version != 2000 || m_tag->ape_tag_hdr.item_count != ape_tag_items || - m_tag->ape_tag_hdr.length != ape_tag_length) { - free (m_tag->ape_tag_data); - CLEAR (*m_tag); - return FALSE; // something's wrong... - } - } - } - - if (wpc->reader->read_bytes (wpc->wv_in, m_tag->ape_tag_data, - ape_tag_length - sizeof (APE_Tag_Hdr)) != ape_tag_length - sizeof (APE_Tag_Hdr)) { - free (m_tag->ape_tag_data); - CLEAR (*m_tag); - return FALSE; // something's wrong... - } - else { - CLEAR (m_tag->id3_tag); // ignore ID3v1 tag if we found APEv2 tag - return TRUE; - } - } - } - - // we come here if the search for the APEv2 tag failed (otherwise we would have returned with it) - - if (m_tag->id3_tag.tag_id [0] == 'T') { // settle for the ID3v1 tag that we found - CLEAR (m_tag->ape_tag_hdr); - return TRUE; - } - - // if this was the search for the APEv2 tag at the beginning of the file (which is our - // last resort) then we have nothing, so return failure - - if (m_tag->tag_begins_file) { - CLEAR (*m_tag); - return FALSE; - } - - // If we get here, then we have failed the first APEv2 tag search (at end of file) and so now we - // look for an ID3v1 tag at the same position. If that succeeds, then we'll loop back and look for - // an APEv2 tag immediately before the ID3v1 tag, otherwise our last resort is to look for an - // APEv2 tag at the beginning of the file. These are strongly discouraged (and not editable) but - // they have been seen in the wild so we attempt to handle them here (at least well enough to - // allow a proper transcoding). - - m_tag->tag_file_pos = -(int32_t)sizeof (ID3_Tag); - wpc->reader->set_pos_rel (wpc->wv_in, m_tag->tag_file_pos, SEEK_END); - - if (wpc->reader->read_bytes (wpc->wv_in, &m_tag->id3_tag, sizeof (ID3_Tag)) != sizeof (ID3_Tag) || - strncmp (m_tag->id3_tag.tag_id, "TAG", 3)) { - m_tag->tag_begins_file = 1; // failed ID3v1, so look for APEv2 at beginning of file - CLEAR (m_tag->id3_tag); - } - } -} - -// Return TRUE is a valid ID3v1 or APEv2 tag has been loaded. - -int valid_tag (M_Tag *m_tag) -{ - if (m_tag->ape_tag_hdr.ID [0] == 'A') - return 'A'; - else if (m_tag->id3_tag.tag_id [0] == 'T') - return 'T'; - else - return 0; -} - -// Return FALSE if a valid APEv2 tag was only found at the beginning of the file (these are read-only -// because they cannot be edited without possibly shifting the entire file) - -int editable_tag (M_Tag *m_tag) -{ - return !m_tag->tag_begins_file; -} - -// Free the data for any APEv2 tag that was allocated. - -void free_tag (M_Tag *m_tag) -{ - if (m_tag->ape_tag_data) { - free (m_tag->ape_tag_data); - m_tag->ape_tag_data = NULL; - } -} diff --git a/Frameworks/WavPack/Files/unpack.c b/Frameworks/WavPack/Files/unpack.c deleted file mode 100644 index 883a8dc96..000000000 --- a/Frameworks/WavPack/Files/unpack.c +++ /dev/null @@ -1,817 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// unpack.c - -// This module actually handles the decompression of the audio data, except for -// the entropy decoding which is handled by the read_words.c module. For better -// efficiency, the conversion is isolated to tight loops that handle an entire -// buffer. - -#include -#include - -#include "wavpack_local.h" - -#ifdef OPT_ASM_X86 - #define DECORR_STEREO_PASS_CONT unpack_decorr_stereo_pass_cont_x86 - #define DECORR_STEREO_PASS_CONT_AVAILABLE unpack_cpu_has_feature_x86(CPU_FEATURE_MMX) - #define DECORR_MONO_PASS_CONT unpack_decorr_mono_pass_cont_x86 -#elif defined(OPT_ASM_X64) && (defined (_WIN64) || defined(__CYGWIN__) || defined(__MINGW64__) || defined(__midipix__)) - #define DECORR_STEREO_PASS_CONT unpack_decorr_stereo_pass_cont_x64win - #define DECORR_STEREO_PASS_CONT_AVAILABLE 1 - #define DECORR_MONO_PASS_CONT unpack_decorr_mono_pass_cont_x64win -#elif defined(OPT_ASM_X64) - #define DECORR_STEREO_PASS_CONT unpack_decorr_stereo_pass_cont_x64 - #define DECORR_STEREO_PASS_CONT_AVAILABLE 1 - #define DECORR_MONO_PASS_CONT unpack_decorr_mono_pass_cont_x64 -#elif defined(OPT_ASM_ARM) - #define DECORR_STEREO_PASS_CONT unpack_decorr_stereo_pass_cont_armv7 - #define DECORR_STEREO_PASS_CONT_AVAILABLE 1 - #define DECORR_MONO_PASS_CONT unpack_decorr_mono_pass_cont_armv7 -#endif - -#ifdef DECORR_STEREO_PASS_CONT -extern void DECORR_STEREO_PASS_CONT (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count, int32_t long_math); -extern void DECORR_MONO_PASS_CONT (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count, int32_t long_math); -#endif - -// This flag provides the functionality of terminating the decoding and muting -// the output when a lossy sample appears to be corrupt. This is automatic -// for lossless files because a corrupt sample is unambigious, but for lossy -// data it might be possible for this to falsely trigger (although I have never -// seen it). - -#define LOSSY_MUTE - -///////////////////////////// executable code //////////////////////////////// - -// This monster actually unpacks the WavPack bitstream(s) into the specified -// buffer as 32-bit integers or floats (depending on original data). Lossy -// samples will be clipped to their original limits (i.e. 8-bit samples are -// clipped to -128/+127) but are still returned in longs. It is up to the -// caller to potentially reformat this for the final output including any -// multichannel distribution, block alignment or endian compensation. The -// function unpack_init() must have been called and the entire WavPack block -// must still be visible (although wps->blockbuff will not be accessed again). -// For maximum clarity, the function is broken up into segments that handle -// various modes. This makes for a few extra infrequent flag checks, but -// makes the code easier to follow because the nesting does not become so -// deep. For maximum efficiency, the conversion is isolated to tight loops -// that handle an entire buffer. The function returns the total number of -// samples unpacked, which can be less than the number requested if an error -// occurs or the end of the block is reached. - -static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count); -static void decorr_mono_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count); -static void fixup_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count); - -int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - uint32_t flags = wps->wphdr.flags, crc = wps->crc, i; - int32_t mute_limit = (1L << ((flags & MAG_MASK) >> MAG_LSB)) + 2; - int32_t correction [2], read_word, *bptr; - struct decorr_pass *dpp; - int tcount, m = 0; - - // don't attempt to decode past the end of the block, but watch out for overflow! - - if (wps->sample_index + sample_count > GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples && - (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index) < sample_count) - sample_count = (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index); - - if (GET_BLOCK_INDEX (wps->wphdr) > wps->sample_index || wps->wphdr.block_samples < sample_count) - wps->mute_error = TRUE; - - if (wps->mute_error) { - if (wpc->reduced_channels == 1 || wpc->config.num_channels == 1 || (flags & MONO_FLAG)) - memset (buffer, 0, sample_count * 4); - else - memset (buffer, 0, sample_count * 8); - - wps->sample_index += sample_count; - return sample_count; - } - - if ((flags & HYBRID_FLAG) && !wps->block2buff) - mute_limit = (mute_limit * 2) + 128; - - //////////////// handle lossless or hybrid lossy mono data ///////////////// - - if (!wps->block2buff && (flags & MONO_DATA)) { - int32_t *eptr = buffer + sample_count; - - if (flags & HYBRID_FLAG) { - i = sample_count; - - for (bptr = buffer; bptr < eptr;) - if ((*bptr++ = get_word (wps, 0, NULL)) == WORD_EOF) { - i = (uint32_t)(bptr - buffer); - break; - } - } - else - i = get_words_lossless (wps, buffer, sample_count); - -#ifdef DECORR_MONO_PASS_CONT - if (sample_count < 16) - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) - decorr_mono_pass (dpp, buffer, sample_count); - else - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - int pre_samples = (dpp->term > MAX_TERM) ? 2 : dpp->term; - - decorr_mono_pass (dpp, buffer, pre_samples); - - DECORR_MONO_PASS_CONT (dpp, buffer + pre_samples, sample_count - pre_samples, - ((flags & MAG_MASK) >> MAG_LSB) > 15); - } -#else - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) - decorr_mono_pass (dpp, buffer, sample_count); -#endif - -#ifndef LOSSY_MUTE - if (!(flags & HYBRID_FLAG)) -#endif - for (bptr = buffer; bptr < eptr; ++bptr) { - if (labs (bptr [0]) > mute_limit) { - i = (uint32_t)(bptr - buffer); - break; - } - - crc = crc * 3 + bptr [0]; - } -#ifndef LOSSY_MUTE - else - for (bptr = buffer; bptr < eptr; ++bptr) - crc = crc * 3 + bptr [0]; -#endif - } - - /////////////// handle lossless or hybrid lossy stereo data /////////////// - - else if (!wps->block2buff && !(flags & MONO_DATA)) { - int32_t *eptr = buffer + (sample_count * 2); - - if (flags & HYBRID_FLAG) { - i = sample_count; - - for (bptr = buffer; bptr < eptr; bptr += 2) - if ((bptr [0] = get_word (wps, 0, NULL)) == WORD_EOF || - (bptr [1] = get_word (wps, 1, NULL)) == WORD_EOF) { - i = (uint32_t)(bptr - buffer) / 2; - break; - } - } - else - i = get_words_lossless (wps, buffer, sample_count); - -#ifdef DECORR_STEREO_PASS_CONT - if (sample_count < 16 || !DECORR_STEREO_PASS_CONT_AVAILABLE) { - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) - decorr_stereo_pass (dpp, buffer, sample_count); - - m = sample_count & (MAX_TERM - 1); - } - else - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - int pre_samples = (dpp->term < 0 || dpp->term > MAX_TERM) ? 2 : dpp->term; - - decorr_stereo_pass (dpp, buffer, pre_samples); - - DECORR_STEREO_PASS_CONT (dpp, buffer + pre_samples * 2, sample_count - pre_samples, - ((flags & MAG_MASK) >> MAG_LSB) >= 16); - } -#else - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) - decorr_stereo_pass (dpp, buffer, sample_count); - - m = sample_count & (MAX_TERM - 1); -#endif - - if (flags & JOINT_STEREO) - for (bptr = buffer; bptr < eptr; bptr += 2) { - bptr [0] += (bptr [1] -= (bptr [0] >> 1)); - crc += (crc << 3) + (bptr [0] << 1) + bptr [0] + bptr [1]; - } - else - for (bptr = buffer; bptr < eptr; bptr += 2) - crc += (crc << 3) + (bptr [0] << 1) + bptr [0] + bptr [1]; - -#ifndef LOSSY_MUTE - if (!(flags & HYBRID_FLAG)) -#endif - for (bptr = buffer; bptr < eptr; bptr += 16) - if (labs (bptr [0]) > mute_limit || labs (bptr [1]) > mute_limit) { - i = (uint32_t)(bptr - buffer) / 2; - break; - } - } - - /////////////////// handle hybrid lossless mono data //////////////////// - - else if ((flags & HYBRID_FLAG) && (flags & MONO_DATA)) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - - if ((read_word = get_word (wps, 0, correction)) == WORD_EOF) - break; - - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - int32_t sam, temp; - int k; - - if (dpp->term > MAX_TERM) { - if (dpp->term & 1) - sam = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - else - sam = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - - dpp->samples_A [1] = dpp->samples_A [0]; - k = 0; - } - else { - sam = dpp->samples_A [m]; - k = (m + dpp->term) & (MAX_TERM - 1); - } - - temp = apply_weight (dpp->weight_A, sam) + read_word; - update_weight (dpp->weight_A, dpp->delta, sam, read_word); - dpp->samples_A [k] = read_word = temp; - } - - m = (m + 1) & (MAX_TERM - 1); - - if (flags & HYBRID_SHAPE) { - int shaping_weight = (wps->dc.shaping_acc [0] += wps->dc.shaping_delta [0]) >> 16; - int32_t temp = -apply_weight (shaping_weight, wps->dc.error [0]); - - if ((flags & NEW_SHAPING) && shaping_weight < 0 && temp) { - if (temp == wps->dc.error [0]) - temp = (temp < 0) ? temp + 1 : temp - 1; - - wps->dc.error [0] = temp - correction [0]; - } - else - wps->dc.error [0] = -correction [0]; - - read_word += correction [0] - temp; - } - else - read_word += correction [0]; - - crc += (crc << 1) + read_word; - - if (labs (read_word) > mute_limit) - break; - - *bptr++ = read_word; - } - - //////////////////// handle hybrid lossless stereo data /////////////////// - - else if (wps->block2buff && !(flags & MONO_DATA)) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t left, right, left2, right2; - int32_t left_c = 0, right_c = 0; - - if ((left = get_word (wps, 0, correction)) == WORD_EOF || - (right = get_word (wps, 1, correction + 1)) == WORD_EOF) - break; - - if (flags & CROSS_DECORR) { - left_c = left + correction [0]; - right_c = right + correction [1]; - - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - int32_t sam_A, sam_B; - - if (dpp->term > 0) { - if (dpp->term > MAX_TERM) { - if (dpp->term & 1) { - sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - sam_B = 2 * dpp->samples_B [0] - dpp->samples_B [1]; - } - else { - sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - sam_B = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1; - } - } - else { - sam_A = dpp->samples_A [m]; - sam_B = dpp->samples_B [m]; - } - - left_c += apply_weight (dpp->weight_A, sam_A); - right_c += apply_weight (dpp->weight_B, sam_B); - } - else if (dpp->term == -1) { - left_c += apply_weight (dpp->weight_A, dpp->samples_A [0]); - right_c += apply_weight (dpp->weight_B, left_c); - } - else { - right_c += apply_weight (dpp->weight_B, dpp->samples_B [0]); - - if (dpp->term == -3) - left_c += apply_weight (dpp->weight_A, dpp->samples_A [0]); - else - left_c += apply_weight (dpp->weight_A, right_c); - } - } - - if (flags & JOINT_STEREO) - left_c += (right_c -= (left_c >> 1)); - } - - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - int32_t sam_A, sam_B; - - if (dpp->term > 0) { - int k; - - if (dpp->term > MAX_TERM) { - if (dpp->term & 1) { - sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - sam_B = 2 * dpp->samples_B [0] - dpp->samples_B [1]; - } - else { - sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - sam_B = (3 * dpp->samples_B [0] - dpp->samples_B [1]) >> 1; - } - - dpp->samples_A [1] = dpp->samples_A [0]; - dpp->samples_B [1] = dpp->samples_B [0]; - k = 0; - } - else { - sam_A = dpp->samples_A [m]; - sam_B = dpp->samples_B [m]; - k = (m + dpp->term) & (MAX_TERM - 1); - } - - left2 = apply_weight (dpp->weight_A, sam_A) + left; - right2 = apply_weight (dpp->weight_B, sam_B) + right; - - update_weight (dpp->weight_A, dpp->delta, sam_A, left); - update_weight (dpp->weight_B, dpp->delta, sam_B, right); - - dpp->samples_A [k] = left = left2; - dpp->samples_B [k] = right = right2; - } - else if (dpp->term == -1) { - left2 = left + apply_weight (dpp->weight_A, dpp->samples_A [0]); - update_weight_clip (dpp->weight_A, dpp->delta, dpp->samples_A [0], left); - left = left2; - right2 = right + apply_weight (dpp->weight_B, left2); - update_weight_clip (dpp->weight_B, dpp->delta, left2, right); - dpp->samples_A [0] = right = right2; - } - else { - right2 = right + apply_weight (dpp->weight_B, dpp->samples_B [0]); - update_weight_clip (dpp->weight_B, dpp->delta, dpp->samples_B [0], right); - right = right2; - - if (dpp->term == -3) { - right2 = dpp->samples_A [0]; - dpp->samples_A [0] = right; - } - - left2 = left + apply_weight (dpp->weight_A, right2); - update_weight_clip (dpp->weight_A, dpp->delta, right2, left); - dpp->samples_B [0] = left = left2; - } - } - - m = (m + 1) & (MAX_TERM - 1); - - if (!(flags & CROSS_DECORR)) { - left_c = left + correction [0]; - right_c = right + correction [1]; - - if (flags & JOINT_STEREO) - left_c += (right_c -= (left_c >> 1)); - } - - if (flags & JOINT_STEREO) - left += (right -= (left >> 1)); - - if (flags & HYBRID_SHAPE) { - int shaping_weight; - int32_t temp; - - correction [0] = left_c - left; - shaping_weight = (wps->dc.shaping_acc [0] += wps->dc.shaping_delta [0]) >> 16; - temp = -apply_weight (shaping_weight, wps->dc.error [0]); - - if ((flags & NEW_SHAPING) && shaping_weight < 0 && temp) { - if (temp == wps->dc.error [0]) - temp = (temp < 0) ? temp + 1 : temp - 1; - - wps->dc.error [0] = temp - correction [0]; - } - else - wps->dc.error [0] = -correction [0]; - - left = left_c - temp; - correction [1] = right_c - right; - shaping_weight = (wps->dc.shaping_acc [1] += wps->dc.shaping_delta [1]) >> 16; - temp = -apply_weight (shaping_weight, wps->dc.error [1]); - - if ((flags & NEW_SHAPING) && shaping_weight < 0 && temp) { - if (temp == wps->dc.error [1]) - temp = (temp < 0) ? temp + 1 : temp - 1; - - wps->dc.error [1] = temp - correction [1]; - } - else - wps->dc.error [1] = -correction [1]; - - right = right_c - temp; - } - else { - left = left_c; - right = right_c; - } - - if (labs (left) > mute_limit || labs (right) > mute_limit) - break; - - crc += (crc << 3) + (left << 1) + left + right; - *bptr++ = left; - *bptr++ = right; - } - else - i = 0; /* this line can't execute, but suppresses compiler warning */ - - if (i != sample_count) { - memset (buffer, 0, sample_count * (flags & MONO_FLAG ? 4 : 8)); - wps->mute_error = TRUE; - i = sample_count; - - if (bs_is_open (&wps->wvxbits)) - bs_close_read (&wps->wvxbits); - } - - if (m) - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) - if (dpp->term > 0 && dpp->term <= MAX_TERM) { - int32_t temp_A [MAX_TERM], temp_B [MAX_TERM]; - int k; - - memcpy (temp_A, dpp->samples_A, sizeof (dpp->samples_A)); - memcpy (temp_B, dpp->samples_B, sizeof (dpp->samples_B)); - - for (k = 0; k < MAX_TERM; k++) { - dpp->samples_A [k] = temp_A [m]; - dpp->samples_B [k] = temp_B [m]; - m = (m + 1) & (MAX_TERM - 1); - } - } - - fixup_samples (wpc, buffer, i); - - if ((flags & FLOAT_DATA) && (wpc->open_flags & OPEN_NORMALIZE)) - WavpackFloatNormalize (buffer, (flags & MONO_DATA) ? i : i * 2, - 127 - wps->float_norm_exp + wpc->norm_offset); - - if (flags & FALSE_STEREO) { - int32_t *dptr = buffer + i * 2; - int32_t *sptr = buffer + i; - int32_t c = i; - - while (c--) { - *--dptr = *--sptr; - *--dptr = *sptr; - } - } - - wps->sample_index += i; - wps->crc = crc; - - return i; -} - -// General function to perform mono decorrelation pass on specified buffer -// (although since this is the reverse function it might technically be called -// "correlation" instead). This version handles all sample resolutions and -// weight deltas. The dpp->samples_X[] data is returned normalized for term -// values 1-8. - -static void decorr_mono_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count) -{ - int32_t delta = dpp->delta, weight_A = dpp->weight_A; - int32_t *bptr, *eptr = buffer + sample_count, sam_A; - int m, k; - - switch (dpp->term) { - - case 17: - for (bptr = buffer; bptr < eptr; bptr++) { - sam_A = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - dpp->samples_A [1] = dpp->samples_A [0]; - dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0]; - update_weight (weight_A, delta, sam_A, bptr [0]); - bptr [0] = dpp->samples_A [0]; - } - - break; - - case 18: - for (bptr = buffer; bptr < eptr; bptr++) { - sam_A = (3 * dpp->samples_A [0] - dpp->samples_A [1]) >> 1; - dpp->samples_A [1] = dpp->samples_A [0]; - dpp->samples_A [0] = apply_weight (weight_A, sam_A) + bptr [0]; - update_weight (weight_A, delta, sam_A, bptr [0]); - bptr [0] = dpp->samples_A [0]; - } - - break; - - default: - for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr++) { - sam_A = dpp->samples_A [m]; - dpp->samples_A [k] = apply_weight (weight_A, sam_A) + bptr [0]; - update_weight (weight_A, delta, sam_A, bptr [0]); - bptr [0] = dpp->samples_A [k]; - m = (m + 1) & (MAX_TERM - 1); - k = (k + 1) & (MAX_TERM - 1); - } - - if (m) { - int32_t temp_samples [MAX_TERM]; - - memcpy (temp_samples, dpp->samples_A, sizeof (dpp->samples_A)); - - for (k = 0; k < MAX_TERM; k++, m++) - dpp->samples_A [k] = temp_samples [m & (MAX_TERM - 1)]; - } - - break; - } - - dpp->weight_A = weight_A; -} - -// General function to perform stereo decorrelation pass on specified buffer -// (although since this is the reverse function it might technically be called -// "correlation" instead). This version handles all sample resolutions and -// weight deltas. The dpp->samples_X[] data is *not* returned normalized for -// term values 1-8, so it should be normalized if it is going to be used to -// call this function again. - -static void decorr_stereo_pass (struct decorr_pass *dpp, int32_t *buffer, int32_t sample_count) -{ - int32_t *bptr, *eptr = buffer + (sample_count * 2); - int m, k; - - switch (dpp->term) { - case 17: - for (bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam, tmp; - - sam = 2 * dpp->samples_A [0] - dpp->samples_A [1]; - dpp->samples_A [1] = dpp->samples_A [0]; - bptr [0] = dpp->samples_A [0] = apply_weight (dpp->weight_A, sam) + (tmp = bptr [0]); - update_weight (dpp->weight_A, dpp->delta, sam, tmp); - - sam = 2 * dpp->samples_B [0] - dpp->samples_B [1]; - dpp->samples_B [1] = dpp->samples_B [0]; - bptr [1] = dpp->samples_B [0] = apply_weight (dpp->weight_B, sam) + (tmp = bptr [1]); - update_weight (dpp->weight_B, dpp->delta, sam, tmp); - } - - break; - - case 18: - for (bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam, tmp; - - sam = dpp->samples_A [0] + ((dpp->samples_A [0] - dpp->samples_A [1]) >> 1); - dpp->samples_A [1] = dpp->samples_A [0]; - bptr [0] = dpp->samples_A [0] = apply_weight (dpp->weight_A, sam) + (tmp = bptr [0]); - update_weight (dpp->weight_A, dpp->delta, sam, tmp); - - sam = dpp->samples_B [0] + ((dpp->samples_B [0] - dpp->samples_B [1]) >> 1); - dpp->samples_B [1] = dpp->samples_B [0]; - bptr [1] = dpp->samples_B [0] = apply_weight (dpp->weight_B, sam) + (tmp = bptr [1]); - update_weight (dpp->weight_B, dpp->delta, sam, tmp); - } - - break; - - default: - for (m = 0, k = dpp->term & (MAX_TERM - 1), bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam; - - sam = dpp->samples_A [m]; - dpp->samples_A [k] = apply_weight (dpp->weight_A, sam) + bptr [0]; - update_weight (dpp->weight_A, dpp->delta, sam, bptr [0]); - bptr [0] = dpp->samples_A [k]; - - sam = dpp->samples_B [m]; - dpp->samples_B [k] = apply_weight (dpp->weight_B, sam) + bptr [1]; - update_weight (dpp->weight_B, dpp->delta, sam, bptr [1]); - bptr [1] = dpp->samples_B [k]; - - m = (m + 1) & (MAX_TERM - 1); - k = (k + 1) & (MAX_TERM - 1); - } - - break; - - case -1: - for (bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam; - - sam = bptr [0] + apply_weight (dpp->weight_A, dpp->samples_A [0]); - update_weight_clip (dpp->weight_A, dpp->delta, dpp->samples_A [0], bptr [0]); - bptr [0] = sam; - dpp->samples_A [0] = bptr [1] + apply_weight (dpp->weight_B, sam); - update_weight_clip (dpp->weight_B, dpp->delta, sam, bptr [1]); - bptr [1] = dpp->samples_A [0]; - } - - break; - - case -2: - for (bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam; - - sam = bptr [1] + apply_weight (dpp->weight_B, dpp->samples_B [0]); - update_weight_clip (dpp->weight_B, dpp->delta, dpp->samples_B [0], bptr [1]); - bptr [1] = sam; - dpp->samples_B [0] = bptr [0] + apply_weight (dpp->weight_A, sam); - update_weight_clip (dpp->weight_A, dpp->delta, sam, bptr [0]); - bptr [0] = dpp->samples_B [0]; - } - - break; - - case -3: - for (bptr = buffer; bptr < eptr; bptr += 2) { - int32_t sam_A, sam_B; - - sam_A = bptr [0] + apply_weight (dpp->weight_A, dpp->samples_A [0]); - update_weight_clip (dpp->weight_A, dpp->delta, dpp->samples_A [0], bptr [0]); - sam_B = bptr [1] + apply_weight (dpp->weight_B, dpp->samples_B [0]); - update_weight_clip (dpp->weight_B, dpp->delta, dpp->samples_B [0], bptr [1]); - bptr [0] = dpp->samples_B [0] = sam_A; - bptr [1] = dpp->samples_A [0] = sam_B; - } - - break; - } -} - -// This is a helper function for unpack_samples() that applies several final -// operations. First, if the data is 32-bit float data, then that conversion -// is done in the float.c module (whether lossy or lossless) and we return. -// Otherwise, if the extended integer data applies, then that operation is -// executed first. If the unpacked data is lossy (and not corrected) then -// it is clipped and shifted in a single operation. Otherwise, if it's -// lossless then the last step is to apply the final shift (if any). - -static void fixup_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - uint32_t flags = wps->wphdr.flags; - int lossy_flag = (flags & HYBRID_FLAG) && !wps->block2buff; - int shift = (flags & SHIFT_MASK) >> SHIFT_LSB; - - if (flags & FLOAT_DATA) { - float_values (wps, buffer, (flags & MONO_DATA) ? sample_count : sample_count * 2); - return; - } - - if (flags & INT32_DATA) { - uint32_t count = (flags & MONO_DATA) ? sample_count : sample_count * 2; - int sent_bits = wps->int32_sent_bits, zeros = wps->int32_zeros; - int ones = wps->int32_ones, dups = wps->int32_dups; - uint32_t data, mask = (1 << sent_bits) - 1; - int32_t *dptr = buffer; - - if (bs_is_open (&wps->wvxbits)) { - uint32_t crc = wps->crc_x; - - while (count--) { -// if (sent_bits) { - getbits (&data, sent_bits, &wps->wvxbits); - *dptr = (*dptr << sent_bits) | (data & mask); -// } - - if (zeros) - *dptr <<= zeros; - else if (ones) - *dptr = ((*dptr + 1) << ones) - 1; - else if (dups) - *dptr = ((*dptr + (*dptr & 1)) << dups) - (*dptr & 1); - - crc = crc * 9 + (*dptr & 0xffff) * 3 + ((*dptr >> 16) & 0xffff); - dptr++; - } - - wps->crc_x = crc; - } - else if (!sent_bits && (zeros + ones + dups)) { - while (lossy_flag && (flags & BYTES_STORED) == 3 && shift < 8) { - if (zeros) - zeros--; - else if (ones) - ones--; - else if (dups) - dups--; - else - break; - - shift++; - } - - while (count--) { - if (zeros) - *dptr <<= zeros; - else if (ones) - *dptr = ((*dptr + 1) << ones) - 1; - else if (dups) - *dptr = ((*dptr + (*dptr & 1)) << dups) - (*dptr & 1); - - dptr++; - } - } - else - shift += zeros + sent_bits + ones + dups; - } - - if (lossy_flag) { - int32_t min_value, max_value, min_shifted, max_shifted; - - switch (flags & BYTES_STORED) { - case 0: - min_shifted = (min_value = -128 >> shift) << shift; - max_shifted = (max_value = 127 >> shift) << shift; - break; - - case 1: - min_shifted = (min_value = -32768 >> shift) << shift; - max_shifted = (max_value = 32767 >> shift) << shift; - break; - - case 2: - min_shifted = (min_value = -8388608 >> shift) << shift; - max_shifted = (max_value = 8388607 >> shift) << shift; - break; - - case 3: default: /* "default" suppresses compiler warning */ - min_shifted = (min_value = (int32_t) 0x80000000 >> shift) << shift; - max_shifted = (max_value = (int32_t) 0x7fffffff >> shift) << shift; - break; - } - - if (!(flags & MONO_DATA)) - sample_count *= 2; - - while (sample_count--) { - if (*buffer < min_value) - *buffer++ = min_shifted; - else if (*buffer > max_value) - *buffer++ = max_shifted; - else - *buffer++ <<= shift; - } - } - else if (shift) { - if (!(flags & MONO_DATA)) - sample_count *= 2; - - while (sample_count--) - *buffer++ <<= shift; - } -} - -// This function checks the crc value(s) for an unpacked block, returning the -// number of actual crc errors detected for the block. The block must be -// completely unpacked before this test is valid. For losslessly unpacked -// blocks of float or extended integer data the extended crc is also checked. -// Note that WavPack's crc is not a CCITT approved polynomial algorithm, but -// is a much simpler method that is virtually as robust for real world data. - -int check_crc_error (WavpackContext *wpc) -{ - int result = 0, stream; - - for (stream = 0; stream < wpc->num_streams; stream++) { - WavpackStream *wps = wpc->streams [stream]; - - if (wps->crc != wps->wphdr.crc) - ++result; - else if (bs_is_open (&wps->wvxbits) && wps->crc_x != wps->crc_wvx) - ++result; - } - - return result; -} diff --git a/Frameworks/WavPack/Files/unpack3.c b/Frameworks/WavPack/Files/unpack3.c deleted file mode 100644 index c0190e128..000000000 --- a/Frameworks/WavPack/Files/unpack3.c +++ /dev/null @@ -1,1703 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// unpack3.c - -// This module provides unpacking for WavPack files prior to version 4.0, -// not including "raw" files. As these modes are all obsolete and are no -// longer written, this code will not be fully documented other than the -// global functions. However, full documentation is provided in the version -// 3.97 source code. Note that this module does only the low-level sample -// unpacking; the actual opening of the file (and obtaining information -// from it) is handled in the unpack3_open.c module. - -#ifdef ENABLE_LEGACY - -#include -#include - -#include "wavpack_local.h" -#include "unpack3.h" - -#define ATTEMPT_ERROR_MUTING - -static int bs_open_read3 (Bitstream3 *bs, WavpackStreamReader64 *reader, void *id); -static uint32_t bs_unused_bytes (Bitstream3 *bs); -static unsigned char *bs_unused_data (Bitstream3 *bs); -static void init_words3 (WavpackStream3 *wps); - -//////////////////////////////// local macros ///////////////////////////////// - -#define apply_weight_n(bits, weight, sample) ((weight * sample + (1 << (bits - 1))) >> bits) - -#define update_weight_n(bits, weight, source, result) \ - if (source && result) { \ - if ((source ^ result) >= 0) { if (weight++ == (1 << bits)) weight--; } \ - else if (weight-- == min_weight) weight++; \ - } - -#define apply_weight24(weight, sample) (((((sample & 0xffff) * weight) >> 7) + \ - (((sample & ~0xffff) >> 7) * weight) + 1) >> 1) - -#define update_weight2(weight, source, result) \ - if (source && result) { \ - if ((source ^ result) >= 0) { if (weight++ == 256) weight--; } \ - else if (weight-- == min_weight) weight++; \ - } - -//////////////////////////////// local tables /////////////////////////////// - -// These three tables specify the characteristics of the decorrelation filters. -// Each term represents one layer of the sequential filter, where positive -// values indicate the relative sample involved from the same channel (1=prev) -// while -1 and -2 indicate cross channel decorrelation (in stereo only). The -// "simple_terms" table is no longer used for writing, but is kept for older -// file decoding. - -static const signed char extreme_terms [] = { 1,1,1,2,4,-1,1,2,3,6,-2,8,5,7,4,1,2,3 }; -static const signed char default_terms [] = { 1,1,1,-1,2,1,-2 }; -static const signed char simple_terms [] = { 1,1,1,1 }; - -///////////////////////////// executable code //////////////////////////////// - -// This function initializes everything required to unpack WavPack -// bitstreams and must be called before any unpacking is performed. Note -// that the (WavpackHeader3 *) in the WavpackStream3 struct must be valid. - -void unpack_init3 (WavpackStream3 *wps) -{ - int flags = wps->wphdr.flags; - struct decorr_pass *dpp; - int ti; - - CLEAR (wps->decorr_passes); - CLEAR (wps->dc); - - if (flags & EXTREME_DECORR) { - for (dpp = wps->decorr_passes, ti = 0; ti < sizeof (extreme_terms); ti++) - if (extreme_terms [sizeof (extreme_terms) - ti - 1] > 0 || (flags & CROSS_DECORR)) - dpp++->term = extreme_terms [sizeof (extreme_terms) - ti - 1]; - } - else if (flags & NEW_DECORR_FLAG) { - for (dpp = wps->decorr_passes, ti = 0; ti < sizeof (default_terms); ti++) - if (default_terms [sizeof (default_terms) - ti - 1] > 0 || (flags & CROSS_DECORR)) - dpp++->term = default_terms [sizeof (default_terms) - ti - 1]; - } - else - for (dpp = wps->decorr_passes, ti = 0; ti < sizeof (simple_terms); ti++) - dpp++->term = simple_terms [sizeof (simple_terms) - ti - 1]; - - wps->num_terms = (int)(dpp - wps->decorr_passes); - init_words3 (wps); -} - -#ifndef NO_SEEKING - -// This function returns the size (in bytes) required to save the unpacking -// context. Note that the (WavpackHeader3 *) in the WavpackStream3 struct -// must be valid. - -static int unpack_size (WavpackStream3 *wps) -{ - int flags = wps->wphdr.flags, byte_sum = 0, tcount; - struct decorr_pass *dpp; - - byte_sum += sizeof (wps->wvbits); - - if (flags & WVC_FLAG) - byte_sum += sizeof (wps->wvcbits); - - if (wps->wphdr.version == 3) { - if (wps->wphdr.bits) - byte_sum += sizeof (wps->w4); - else - byte_sum += sizeof (wps->w1); - - byte_sum += sizeof (wps->w3) + sizeof (wps->dc.crc); - } - else - byte_sum += sizeof (wps->w2); - - if (wps->wphdr.bits) - byte_sum += sizeof (wps->dc.error); - else - byte_sum += sizeof (wps->dc.sum_level) + sizeof (wps->dc.left_level) + - sizeof (wps->dc.right_level) + sizeof (wps->dc.diff_level); - - if (flags & OVER_20) - byte_sum += sizeof (wps->dc.last_extra_bits) + sizeof (wps->dc.extra_bits_count); - - if (!(flags & EXTREME_DECORR)) { - byte_sum += sizeof (wps->dc.sample); - byte_sum += sizeof (wps->dc.weight); - } - - if (flags & (HIGH_FLAG | NEW_HIGH_FLAG)) - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - if (dpp->term > 0) { - byte_sum += sizeof (dpp->samples_A [0]) * dpp->term; - byte_sum += sizeof (dpp->weight_A); - - if (!(flags & MONO_FLAG)) { - byte_sum += sizeof (dpp->samples_B [0]) * dpp->term; - byte_sum += sizeof (dpp->weight_B); - } - } - else { - byte_sum += sizeof (dpp->samples_A [0]) + sizeof (dpp->samples_B [0]); - byte_sum += sizeof (dpp->weight_A) + sizeof (dpp->weight_B); - } - } - - return byte_sum; -} - -// This function saves the unpacking context at the specified pointer and -// returns the updated pointer. The actual amount of data required can be -// determined beforehand by calling unpack_size() but must be allocated by -// the caller. - -static void *unpack_save (WavpackStream3 *wps, void *destin) -{ - int flags = wps->wphdr.flags, tcount; - struct decorr_pass *dpp; - - SAVE (destin, wps->wvbits); - - if (flags & WVC_FLAG) - SAVE (destin, wps->wvcbits); - - if (wps->wphdr.version == 3) { - if (wps->wphdr.bits) { - SAVE (destin, wps->w4); - } - else { - SAVE (destin, wps->w1); - } - - SAVE (destin, wps->w3); - SAVE (destin, wps->dc.crc); - } - else - SAVE (destin, wps->w2); - - if (wps->wphdr.bits) { - SAVE (destin, wps->dc.error); - } - else { - SAVE (destin, wps->dc.sum_level); - SAVE (destin, wps->dc.left_level); - SAVE (destin, wps->dc.right_level); - SAVE (destin, wps->dc.diff_level); - } - - if (flags & OVER_20) { - SAVE (destin, wps->dc.last_extra_bits); - SAVE (destin, wps->dc.extra_bits_count); - } - - if (!(flags & EXTREME_DECORR)) { - SAVE (destin, wps->dc.sample); - SAVE (destin, wps->dc.weight); - } - - if (flags & (HIGH_FLAG | NEW_HIGH_FLAG)) - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - if (dpp->term > 0) { - int count = dpp->term; - int index = wps->dc.m; - - SAVE (destin, dpp->weight_A); - - while (count--) { - SAVE (destin, dpp->samples_A [index]); - index = (index + 1) & (MAX_TERM - 1); - } - - if (!(flags & MONO_FLAG)) { - count = dpp->term; - index = wps->dc.m; - - SAVE (destin, dpp->weight_B); - - while (count--) { - SAVE (destin, dpp->samples_B [index]); - index = (index + 1) & (MAX_TERM - 1); - } - } - } - else { - SAVE (destin, dpp->weight_A); - SAVE (destin, dpp->weight_B); - SAVE (destin, dpp->samples_A [0]); - SAVE (destin, dpp->samples_B [0]); - } - } - - return destin; -} - -#endif - -// This monster actually unpacks the WavPack bitstream(s) into the specified -// buffer as longs, and serves as an extension to WavpackUnpackSamples(). -// Note that WavPack files created prior to version 4.0 could only contain 16 -// or 24 bit values, and these values are right-justified in the 32-bit values. -// So, if the original file contained 16-bit values, then the range of the -// returned longs would be +/- 32K. For maximum clarity, the function is -// broken up into segments that handle various modes. This makes for a few -// extra infrequent flag checks, but makes the code easier to follow because -// the nesting does not become so deep. For maximum efficiency, the conversion -// is isolated to tight loops that handle an entire buffer. - -static int32_t FASTCALL get_word1 (WavpackStream3 *wps, int chan); -static int32_t FASTCALL get_old_word1 (WavpackStream3 *wps, int chan); -static int32_t FASTCALL get_word2 (WavpackStream3 *wps, int chan); -static int32_t FASTCALL get_word3 (WavpackStream3 *wps, int chan); -static int32_t FASTCALL get_word4 (WavpackStream3 *wps, int chan, int32_t *correction); - -int32_t unpack_samples3 (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count) -{ - WavpackStream3 *wps = (WavpackStream3 *) wpc->stream3; - int shift = wps->wphdr.shift, flags = wps->wphdr.flags, min_weight = 0, m = wps->dc.m, tcount; -#ifndef NO_SEEKING - int points_index = wps->sample_index / (((uint32_t) wpc->total_samples >> 8) + 1); -#endif - int32_t min_value, max_value, min_shifted, max_shifted; - int32_t correction [2], crc = wps->dc.crc; - struct decorr_pass *dpp; - int32_t read_word, *bptr; - int32_t sample [2] [2]; - int weight [2] [1]; - unsigned int i; - -#ifdef ATTEMPT_ERROR_MUTING - int32_t mute_limit = (flags & BYTES_3) ? 8388608 : 32768; - int mute_block = 0; - - if (wps->wphdr.bits && !(flags & WVC_FLAG)) { - if (wps->wphdr.version < 3) - mute_limit *= 4; - else - mute_limit *= 2; - } -#endif - - if (wps->sample_index + sample_count > wpc->total_samples) - sample_count = (uint32_t) (wpc->total_samples - wps->sample_index); - - if (!sample_count) - return 0; - - if (!wps->sample_index) { - unpack_init3 (wps); - - bs_open_read3 (&wps->wvbits, wpc->reader, wpc->wv_in); - - if (wpc->wvc_flag) - bs_open_read3 (&wps->wvcbits, wpc->reader, wpc->wvc_in); - } - -#ifndef NO_SEEKING - if (!wps->index_points [points_index].saved) { - - if (!wps->unpack_data) - wps->unpack_data = (unsigned char *) malloc (256 * (wps->unpack_size = unpack_size (wps))); - - wps->index_points [points_index].sample_index = wps->sample_index; - unpack_save (wps, wps->unpack_data + points_index * wps->unpack_size); - wps->index_points [points_index].saved = TRUE; - } -#endif - - memcpy (sample, wps->dc.sample, sizeof (sample)); - memcpy (weight, wps->dc.weight, sizeof (weight)); - - if (wps->wphdr.bits) { - if (flags & (NEW_DECORR_FLAG | EXTREME_DECORR)) - min_weight = -256; - } - else - if (flags & NEW_DECORR_FLAG) - min_weight = (flags & EXTREME_DECORR) ? -512 : -256; - - if (flags & BYTES_3) { - min_shifted = (min_value = -8388608 >> shift) << shift; - max_shifted = (max_value = 8388607 >> shift) << shift; - } - else { - min_shifted = (min_value = -32768 >> shift) << shift; - max_shifted = (max_value = 32767 >> shift) << shift; - } - - ///////////////// handle version 3 lossless mono data ///////////////////// - - if (wps->wphdr.version == 3 && !wps->wphdr.bits && (flags & MONO_FLAG)) { - if (flags & FAST_FLAG) { - if (flags & OVER_20) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t temp; - - if ((read_word = get_word3 (wps, 0)) == WORD_EOF) - break; - - sample [0] [0] += sample [0] [1] += read_word; - getbits (&temp, 4, &wps->wvbits); - crc = crc * 3 + (temp = (temp & 0xf) + (sample [0] [0] << 4)); - *bptr++ = temp; - } - else - for (bptr = buffer, i = 0; i < sample_count; ++i) { - if ((read_word = get_word3 (wps, 0)) == WORD_EOF) - break; - - crc = crc * 3 + (sample [0] [0] += sample [0] [1] += read_word); - *bptr++ = sample [0] [0] << shift; - } - } - else if (flags & HIGH_FLAG) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t temp; - - if (flags & NEW_HIGH_FLAG) { - if ((read_word = get_word1 (wps, 0)) == WORD_EOF) - break; - } - else { - if ((read_word = get_old_word1 (wps, 0)) == WORD_EOF) - break; - } - - if (flags & EXTREME_DECORR) - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - int32_t sam = dpp->samples_A [m]; - - temp = apply_weight_n (9, dpp->weight_A, sam) + read_word; - update_weight_n (9, dpp->weight_A, sam, read_word); - dpp->samples_A [(m + dpp->term) & (MAX_TERM - 1)] = read_word = temp; - } - else - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - int32_t sam = dpp->samples_A [m]; - - temp = apply_weight_n (8, dpp->weight_A, sam) + read_word; - update_weight_n (8, dpp->weight_A, sam, read_word); - dpp->samples_A [(m + dpp->term) & (MAX_TERM - 1)] = read_word = temp; - } - - m = (m + 1) & (MAX_TERM - 1); - - if (flags & OVER_20) { - if (wps->dc.extra_bits_count < 8 || !getbit (&wps->wvbits)) { - getbits (&temp, 4, &wps->wvbits); - - if ((temp &= 0xf) != wps->dc.last_extra_bits) { - wps->dc.last_extra_bits = temp; - wps->dc.extra_bits_count = 0; - } - else - ++wps->dc.extra_bits_count; - } - - crc = crc * 3 + (temp = wps->dc.last_extra_bits + (read_word << 4)); - *bptr++ = temp; - } - else { - crc = crc * 3 + read_word; - *bptr++ = read_word << shift; - } - } - else - for (bptr = buffer, i = 0; i < sample_count; ++i) { - - int32_t temp; - - if ((read_word = get_word3 (wps, 0)) == WORD_EOF) - break; - - temp = sample [0] [0] + ((sample [0] [1] * weight [0] [0] + 128) >> 8) + read_word; - - if ((sample [0] [1] >= 0) == (read_word > 0)) { - if (weight [0] [0]++ == 256) - weight [0] [0]--; - } - else if (weight [0] [0]-- == 0) - weight [0] [0]++; - - sample [0] [0] += (sample [0] [1] = temp - sample [0] [0]); - - if (flags & OVER_20) { - if (wps->dc.extra_bits_count < 8 || !getbit (&wps->wvbits)) { - getbits (&temp, 4, &wps->wvbits); - - if ((temp &= 0xf) != wps->dc.last_extra_bits) { - wps->dc.last_extra_bits = temp; - wps->dc.extra_bits_count = 0; - } - else - ++wps->dc.extra_bits_count; - } - - crc = crc * 3 + (*bptr++ = temp = wps->dc.last_extra_bits + (sample [0] [0] << 4)); - } - else { - crc = crc * 3 + sample [0] [0]; - *bptr++ = sample [0] [0] << shift; - } - } - } - - //////////////// handle version 3 lossless stereo data //////////////////// - - else if (wps->wphdr.version == 3 && !wps->wphdr.bits && !(flags & MONO_FLAG)) { - int32_t left_level = wps->dc.left_level, right_level = wps->dc.right_level; - int32_t sum_level = wps->dc.sum_level, diff_level = wps->dc.diff_level; - - if (flags & FAST_FLAG) { - if (flags & OVER_20) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t sum, diff, temp; - - read_word = get_word3 (wps, 0); - - if (read_word == WORD_EOF) - break; - - sum = (read_word << 1) | ((diff = get_word3 (wps, 1)) & 1); - sample [0] [0] += sample [0] [1] += ((sum + diff) >> 1); - sample [1] [0] += sample [1] [1] += ((sum - diff) >> 1); - getbits (&temp, 8, &wps->wvbits); - crc = crc * 3 + (*bptr++ = (sample [0] [0] << 4) + ((temp >> 4) & 0xf)); - crc = crc * 3 + (*bptr++ = (sample [1] [0] << 4) + (temp & 0xf)); - } - else - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t sum, diff; - - read_word = get_word3 (wps, 0); - - if (read_word == WORD_EOF) - break; - - sum = (read_word << 1) | ((diff = get_word3 (wps, 1)) & 1); - sample [0] [1] += ((sum + diff) >> 1); - sample [1] [1] += ((sum - diff) >> 1); - crc = crc * 3 + (sample [0] [0] += sample [0] [1]); - crc = crc * 3 + (sample [1] [0] += sample [1] [1]); - *bptr++ = sample [0] [0] << shift; - *bptr++ = sample [1] [0] << shift; - } - } - else if (flags & HIGH_FLAG) { - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t sum, left, right, diff, left2, right2, extra_bits, next_word; - - if (flags & CROSS_DECORR) { - left = get_word1 (wps, 0); - - if (left == WORD_EOF) - break; - - right = get_word1 (wps, 1); - } - else { - if (flags & NEW_HIGH_FLAG) { - read_word = get_word1 (wps, 0); - - if (read_word == WORD_EOF) - break; - - next_word = get_word1 (wps, 1); - - if (right_level > left_level) { - if (left_level + right_level < sum_level + diff_level && right_level < diff_level) { - sum = (right = read_word) + (left = next_word); - diff = left - right; - } - else { - diff = read_word; - - if (sum_level < left_level) { - sum = (next_word << 1) | (diff & 1); - left = (sum + diff) >> 1; - right = (sum - diff) >> 1; - } - else - sum = next_word + (right = (left = next_word) - diff); - } - } - else { - if (left_level + right_level < sum_level + diff_level && left_level < diff_level) { - sum = (left = read_word) + (right = next_word); - diff = left - right; - } - else { - diff = read_word; - - if (sum_level < right_level) { - sum = (next_word << 1) | (diff & 1); - left = (sum + diff) >> 1; - right = (sum - diff) >> 1; - } - else - sum = (left = diff + (right = next_word)) + next_word; - } - } - } - else { - read_word = get_old_word1 (wps, 0); - - if (read_word == WORD_EOF) - break; - - next_word = get_old_word1 (wps, 1); - - if (sum_level <= right_level && sum_level <= left_level) { - sum = (next_word << 1) | (read_word & 1); - left = (sum + read_word) >> 1; - right = (sum - read_word) >> 1; - } - else if (left_level <= right_level) - sum = next_word + (right = (left = next_word) - read_word); - else - sum = next_word + (left = read_word + (right = next_word)); - - diff = left - right; - } - - sum_level = sum_level - (sum_level >> 8) + labs (sum >> 1); - left_level = left_level - (left_level >> 8) + labs (left); - right_level = right_level - (right_level >> 8) + labs (right); - diff_level = diff_level - (diff_level >> 8) + labs (diff); - - if (flags & JOINT_STEREO) { - left = diff; - right = sum >> 1; - } - } - - if (flags & EXTREME_DECORR) { - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) - if (dpp->term > 0) { - int32_t sam_A = dpp->samples_A [m], sam_B = dpp->samples_B [m]; - int k = (m + dpp->term) & (MAX_TERM - 1); - - left2 = apply_weight_n (9, dpp->weight_A, sam_A) + left; - right2 = apply_weight_n (9, dpp->weight_B, sam_B) + right; - - update_weight_n (9, dpp->weight_A, sam_A, left); - update_weight_n (9, dpp->weight_B, sam_B, right); - - dpp->samples_A [k] = left = left2; - dpp->samples_B [k] = right = right2; - } - else if (dpp->term == -1) { - left2 = left + apply_weight_n (9, dpp->weight_A, dpp->samples_A [0]); - update_weight_n (9, dpp->weight_A, dpp->samples_A [0], left); - left = left2; - right2 = right + apply_weight_n (9, dpp->weight_B, left); - update_weight_n (9, dpp->weight_B, left, right); - dpp->samples_A [0] = right = right2; - } - else { - right2 = right + apply_weight_n (9, dpp->weight_A, dpp->samples_A [0]); - update_weight_n (9, dpp->weight_A, dpp->samples_A [0], right); - right = right2; - left2 = left + apply_weight_n (9, dpp->weight_B, right); - update_weight_n (9, dpp->weight_B, right, left); - dpp->samples_A [0] = left = left2; - } - } - else { - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) - if (dpp->term > 0) { - int32_t sam_A = dpp->samples_A [m], sam_B = dpp->samples_B [m]; - int k = (m + dpp->term) & (MAX_TERM - 1); - - left2 = apply_weight_n (8, dpp->weight_A, sam_A) + left; - right2 = apply_weight_n (8, dpp->weight_B, sam_B) + right; - - update_weight_n (8, dpp->weight_A, sam_A, left); - update_weight_n (8, dpp->weight_B, sam_B, right); - - dpp->samples_A [k] = left = left2; - dpp->samples_B [k] = right = right2; - } - else if (dpp->term == -1) { - left2 = left + apply_weight_n (8, dpp->weight_A, dpp->samples_A [0]); - update_weight_n (8, dpp->weight_A, dpp->samples_A [0], left); - left = left2; - right2 = right + apply_weight_n (8, dpp->weight_B, left); - update_weight_n (8, dpp->weight_B, left, right); - dpp->samples_A [0] = right = right2; - } - else { - right2 = right + apply_weight_n (8, dpp->weight_A, dpp->samples_A [0]); - update_weight_n (8, dpp->weight_A, dpp->samples_A [0], right); - right = right2; - left2 = left + apply_weight_n (8, dpp->weight_B, right); - update_weight_n (8, dpp->weight_B, right, left); - dpp->samples_A [0] = left = left2; - } - } - - m = (m + 1) & (MAX_TERM - 1); - - if (flags & JOINT_STEREO) { - sum = (right << 1) | ((diff = left) & 1); - right = (sum - diff) >> 1; - left = (sum + diff) >> 1; - } - - if (flags & OVER_20) { - if (wps->dc.extra_bits_count < 8 || !getbit (&wps->wvbits)) { - getbits (&extra_bits, 8, &wps->wvbits); - - if ((extra_bits &= 0xff) != wps->dc.last_extra_bits) { - wps->dc.last_extra_bits = extra_bits; - wps->dc.extra_bits_count = 0; - } - else - ++wps->dc.extra_bits_count; - } - - crc = crc * 3 + (*bptr++ = left = (left << 4) + (wps->dc.last_extra_bits >> 4)); - crc = crc * 3 + (*bptr++ = right = (right << 4) + (wps->dc.last_extra_bits & 0xf)); - } - else { - crc = crc * 9 + left * 3 + right; - *bptr++ = left << shift; - *bptr++ = right << shift; - } - } - } - else - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t sum, left, right, left2, right2, extra_bits; - - read_word = get_word3 (wps, 0); - - if (read_word == WORD_EOF) - break; - - if (sum_level <= right_level && sum_level <= left_level) { - sum = (get_word3 (wps, 1) << 1) | (read_word & 1); - left = (sum + read_word) >> 1; - right = (sum - read_word) >> 1; - } - else if (left_level <= right_level) { - right = (left = get_word3 (wps, 1)) - read_word; - sum = left + right; - } - else { - left = read_word + (right = get_word3 (wps, 1)); - sum = right + left; - } - - sum_level = sum_level - (sum_level >> 8) + labs (sum >> 1); - left_level = left_level - (left_level >> 8) + labs (left); - right_level = right_level - (right_level >> 8) + labs (right); - - left2 = sample [0] [0] + ((sample [0] [1] * weight [0] [0] + 128) >> 8) + left; - right2 = sample [1] [0] + ((sample [1] [1] * weight [1] [0] + 128) >> 8) + right; - - if ((sample [0] [1] >= 0) == (left > 0)) { - if (weight [0] [0]++ == 256) - weight [0] [0]--; - } - else if (weight [0] [0]-- == 0) - weight [0] [0]++; - - if ((sample [1] [1] >= 0) == (right > 0)) { - if (weight [1] [0]++ == 256) - weight [1] [0]--; - } - else if (weight [1] [0]-- == 0) - weight [1] [0]++; - - sample [0] [0] += (sample [0] [1] = left2 - sample [0] [0]); - sample [1] [0] += (sample [1] [1] = right2 - sample [1] [0]); - - if (flags & OVER_20) { - if (wps->dc.extra_bits_count < 8 || !getbit (&wps->wvbits)) { - getbits (&extra_bits, 8, &wps->wvbits); - - if ((extra_bits &= 0xff) != wps->dc.last_extra_bits) { - wps->dc.last_extra_bits = extra_bits; - wps->dc.extra_bits_count = 0; - } - else - ++wps->dc.extra_bits_count; - } - - crc = crc * 3 + (*bptr++ = left2 = (sample [0] [0] << 4) + (wps->dc.last_extra_bits >> 4)); - crc = crc * 3 + (*bptr++ = right2 = (sample [1] [0] << 4) + (wps->dc.last_extra_bits & 0xf)); - } - else { - crc = crc * 9 + sample [0] [0] * 3 + sample [1] [0]; - *bptr++ = sample [0] [0] << shift; - *bptr++ = sample [1] [0] << shift; - } - } - - wps->dc.left_level = left_level; - wps->dc.right_level = right_level; - wps->dc.sum_level = sum_level; - wps->dc.diff_level = diff_level; - } - - //////////////// handle version 3 lossy/hybrid mono data ////////////////// - - else if (wps->wphdr.version == 3 && wps->wphdr.bits && (flags & MONO_FLAG)) { - if (flags & FAST_FLAG) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - - if ((read_word = get_word3 (wps, 0)) == WORD_EOF) - break; - - crc = crc * 3 + (sample [0] [0] += sample [0] [1] += read_word); - - if (sample [0] [0] < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] < -mute_limit) - mute_block = 1; -#endif - *bptr++ = min_shifted; - } - else if (sample [0] [0] > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] > mute_limit) - mute_block = 1; -#endif - *bptr++ = max_shifted; - } - else - *bptr++ = sample [0] [0] << shift; - } - else if (flags & (HIGH_FLAG | NEW_HIGH_FLAG)) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t temp; - - read_word = (flags & NEW_HIGH_FLAG) ? - get_word4 (wps, 0, correction) : get_word3 (wps, 0); - - if (read_word == WORD_EOF) - break; - - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - int32_t sam = dpp->samples_A [m]; - - temp = apply_weight24 (dpp->weight_A, sam) + read_word; - update_weight2 (dpp->weight_A, sam, read_word); - dpp->samples_A [(m + dpp->term) & (MAX_TERM - 1)] = read_word = temp; - } - - m = (m + 1) & (MAX_TERM - 1); - - if (flags & WVC_FLAG) { - if (flags & LOSSY_SHAPE) { - crc = crc * 3 + (read_word += correction [0] + wps->dc.error [0]); - wps->dc.error [0] = -correction [0]; - } - else - crc = crc * 3 + (read_word += correction [0]); - - *bptr++ = read_word << shift; - } - else { - crc = crc * 3 + read_word; - - if (read_word < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (read_word < -mute_limit) - mute_block = 1; -#endif - *bptr++ = min_shifted; - } - else if (read_word > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (read_word > mute_limit) - mute_block = 1; -#endif - *bptr++ = max_shifted; - } - else - *bptr++ = read_word << shift; - } - } - else - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t new_sample; - - if ((read_word = get_word3 (wps, 0)) == WORD_EOF) - break; - - new_sample = sample [0] [0] + ((sample [0] [1] * weight [0] [0] + 128) >> 8) + read_word; - - if ((sample [0] [1] >= 0) == (read_word > 0)) { - if (weight [0] [0]++ == 256) - weight [0] [0]--; - } - else if (weight [0] [0]-- == 0) - weight [0] [0]++; - - sample [0] [1] = new_sample - sample [0] [0]; - crc = crc * 3 + (sample [0] [0] = new_sample); - - if (sample [0] [0] < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] < -mute_limit) - mute_block = 1; -#endif - *bptr++ = min_shifted; - } - else if (sample [0] [0] > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] > mute_limit) - mute_block = 1; -#endif - *bptr++ = max_shifted; - } - else - *bptr++ = sample [0] [0] << shift; - } - } - - //////////////// handle version 3 lossy/hybrid stereo data //////////////// - - else if (wps->wphdr.version == 3 && wps->wphdr.bits && !(flags & MONO_FLAG)) { - if (flags & FAST_FLAG) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - - if ((read_word = get_word3 (wps, 0)) == WORD_EOF) - break; - - crc = crc * 3 + (sample [0] [0] += sample [0] [1] += read_word); - - if (sample [0] [0] < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] < -mute_limit) - mute_block = 1; -#endif - *bptr++ = min_shifted; - } - else if (sample [0] [0] > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] > mute_limit) - mute_block = 1; -#endif - *bptr++ = max_shifted; - } - else - *bptr++ = sample [0] [0] << shift; - - crc = crc * 3 + (sample [1] [0] += sample [1] [1] += get_word3 (wps, 1)); - - if (sample [1] [0] < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [1] [0] < -mute_limit) - mute_block = 1; -#endif - *bptr++ = min_shifted; - } - else if (sample [1] [0] > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [1] [0] > mute_limit) - mute_block = 1; -#endif - *bptr++ = max_shifted; - } - else - *bptr++ = sample [1] [0] << shift; - } - else if (flags & (HIGH_FLAG | NEW_HIGH_FLAG)) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t left, right, left2, right2, sum, diff; - - if (flags & NEW_HIGH_FLAG) { - left = get_word4 (wps, 0, correction); - right = get_word4 (wps, 1, correction + 1); - } - else { - left = get_word3 (wps, 0); - right = get_word3 (wps, 1); - } - - if (left == WORD_EOF) - break; - - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - int32_t sam_A = dpp->samples_A [m], sam_B = dpp->samples_B [m]; - int k = (m + dpp->term) & (MAX_TERM - 1); - - left2 = apply_weight24 (dpp->weight_A, sam_A) + left; - update_weight2 (dpp->weight_A, sam_A, left); - dpp->samples_A [k] = left = left2; - - right2 = apply_weight24 (dpp->weight_B, sam_B) + right; - update_weight2 (dpp->weight_B, sam_B, right); - dpp->samples_B [k] = right = right2; - } - - m = (m + 1) & (MAX_TERM - 1); - - if (flags & WVC_FLAG) { - if (flags & LOSSY_SHAPE) { - left += correction [0] + wps->dc.error [0]; - right += correction [1] + wps->dc.error [1]; - wps->dc.error [0] = -correction [0]; - wps->dc.error [1] = -correction [1]; - } - else { - left += correction [0]; - right += correction [1]; - } - } - - if (flags & JOINT_STEREO) { - right = ((sum = (right << 1) | (left & 1)) - (diff = left)) >> 1; - left = (sum + diff) >> 1; - } - - crc = crc * 9 + left * 3 + right; - - if (flags & WVC_FLAG) { - *bptr++ = left << shift; - *bptr++ = right << shift; - } - else { - if (left < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (left < -mute_limit) - mute_block = 1; -#endif - *bptr++ = min_shifted; - } - else if (left > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (left > mute_limit) - mute_block = 1; -#endif - *bptr++ = max_shifted; - } - else - *bptr++ = left << shift; - - if (right < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (right < -mute_limit) - mute_block = 1; -#endif - *bptr++ = min_shifted; - } - else if (right > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (right > mute_limit) - mute_block = 1; -#endif - *bptr++ = max_shifted; - } - else - *bptr++ = right << shift; - } - } - else - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t new_sample; - - if ((read_word = get_word3 (wps, 0)) == WORD_EOF) - break; - - new_sample = sample [0] [0] + ((sample [0] [1] * weight [0] [0] + 128) >> 8) + read_word; - - if ((sample [0] [1] >= 0) == (read_word > 0)) { - if (weight [0] [0]++ == 256) - weight [0] [0]--; - } - else if (weight [0] [0]-- == 0) - weight [0] [0]++; - - sample [0] [1] = new_sample - sample [0] [0]; - crc = crc * 3 + (sample [0] [0] = new_sample); - - read_word = get_word3 (wps, 1); - new_sample = sample [1] [0] + ((sample [1] [1] * weight [1] [0] + 128) >> 8) + read_word; - - if ((sample [1] [1] >= 0) == (read_word > 0)) { - if (weight [1] [0]++ == 256) - weight [1] [0]--; - } - else if (weight [1] [0]-- == 0) - weight [1] [0]++; - - sample [1] [1] = new_sample - sample [1] [0]; - crc = crc * 3 + (sample [1] [0] = new_sample); - - if (sample [0] [0] < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] < -mute_limit) - mute_block = 1; -#endif - *bptr++ = min_shifted; - } - else if (sample [0] [0] > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] > mute_limit) - mute_block = 1; -#endif - *bptr++ = max_shifted; - } - else - *bptr++ = sample [0] [0] << shift; - - if (sample [1] [0] < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [1] [0] < -mute_limit) - mute_block = 1; -#endif - *bptr++ = min_shifted; - } - else if (sample [1] [0] > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [1] [0] > mute_limit) - mute_block = 1; -#endif - *bptr++ = max_shifted; - } - else - *bptr++ = sample [1] [0] << shift; - } - } - - //////////////////// finally, handle version 2 data /////////////////////// - - else if (wps->wphdr.version == 2 && (flags & MONO_FLAG)) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - if ((read_word = get_word2 (wps, 0)) == WORD_EOF) - break; - - sample [0] [0] += sample [0] [1] += read_word; - - if (wps->wphdr.bits) { - if (sample [0] [0] < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] < -mute_limit) - mute_block = 1; -#endif - sample [0] [0] = min_value; - } - else if (sample [0] [0] > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] > mute_limit) - mute_block = 1; -#endif - sample [0] [0] = max_value; - } - } - - *bptr++ = sample [0] [0] << shift; - } - else if (wps->wphdr.version < 3 && !(flags & MONO_FLAG)) - for (bptr = buffer, i = 0; i < sample_count; ++i) { - int32_t sum, diff; - - read_word = get_word2 (wps, 0); - - if (read_word == WORD_EOF) - break; - - sum = (read_word << 1) | ((diff = get_word2 (wps, 1)) & 1); - sample [0] [0] += sample [0] [1] += ((sum + diff) >> 1); - sample [1] [0] += sample [1] [1] += ((sum - diff) >> 1); - - if (wps->wphdr.bits) { - if (sample [0] [0] < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] < -mute_limit) - mute_block = 1; -#endif - sample [0] [0] = min_value; - } - else if (sample [0] [0] > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [0] [0] > mute_limit) - mute_block = 1; -#endif - sample [0] [0] = max_value; - } - - if (sample [1] [0] < min_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [1] [0] < -mute_limit) - mute_block = 1; -#endif - sample [1] [0] = min_value; - } - else if (sample [1] [0] > max_value) { -#ifdef ATTEMPT_ERROR_MUTING - if (sample [1] [0] > mute_limit) - mute_block = 1; -#endif - sample [1] [0] = max_value; - } - } - - *bptr++ = sample [0] [0] << shift; - *bptr++ = sample [1] [0] << shift; - } - else - i = 0; /* can't get here, but suppresses warning */ - -#ifdef ATTEMPT_ERROR_MUTING - if (!wps->wphdr.bits || (flags & WVC_FLAG)) { - int32_t *eptr = buffer + sample_count * ((flags & MONO_FLAG) ? 1 : 2); - - for (bptr = buffer; bptr < eptr; bptr += 3) - if (*bptr > mute_limit || *bptr < -mute_limit) { - mute_block = 1; - break; - } - } - - if (mute_block) - memset (buffer, 0, sizeof (*buffer) * sample_count * ((flags & MONO_FLAG) ? 1 : 2)); -#endif - - if (i && (wps->sample_index += i) == wpc->total_samples) { - - if (wps->wphdr.version == 3 && crc != (wpc->wvc_flag ? wps->wphdr.crc2 : wps->wphdr.crc)) - wpc->crc_errors++; - - if (wpc->open_flags & OPEN_WRAPPER) { - unsigned char *temp = (unsigned char *)malloc (1024); - uint32_t bcount; - - if (bs_unused_bytes (&wps->wvbits)) { - wpc->wrapper_data = (unsigned char *)realloc (wpc->wrapper_data, wpc->wrapper_bytes + bs_unused_bytes (&wps->wvbits)); - memcpy (wpc->wrapper_data + wpc->wrapper_bytes, bs_unused_data (&wps->wvbits), bs_unused_bytes (&wps->wvbits)); - wpc->wrapper_bytes += bs_unused_bytes (&wps->wvbits); - } - - while (1) { - bcount = wpc->reader->read_bytes (wpc->wv_in, temp, 1024); - - if (!bcount) - break; - - wpc->wrapper_data = (unsigned char *)realloc (wpc->wrapper_data, wpc->wrapper_bytes + bcount); - memcpy (wpc->wrapper_data + wpc->wrapper_bytes, temp, bcount); - wpc->wrapper_bytes += bcount; - } - - free (temp); - - if (wpc->wrapper_bytes > 16) { - int c; - - for (c = 0; c < 16 && wpc->wrapper_data [c] == 0xff; ++c); - - if (c == 16) { - memmove (wpc->wrapper_data, wpc->wrapper_data + 16, wpc->wrapper_bytes - 16); - wpc->wrapper_bytes -= 16; - } - else { - free (wpc->wrapper_data); - wpc->wrapper_data = NULL; - wpc->wrapper_bytes = 0; - } - } - } - } - - memcpy (wps->dc.sample, sample, sizeof (sample)); - memcpy (wps->dc.weight, weight, sizeof (weight)); - wps->dc.crc = crc; - wps->dc.m = m; - - return i; -} - -// This function initializes everything required to receive words with this -// module and must be called BEFORE any other function in this module. - -static void init_words3 (WavpackStream3 *wps) -{ - CLEAR (wps->w1); - CLEAR (wps->w2); - CLEAR (wps->w3); - CLEAR (wps->w4); - - if (wps->wphdr.flags & MONO_FLAG) - wps->w4.bitrate = wps->wphdr.bits - 768; - else - wps->w4.bitrate = (wps->wphdr.bits / 2) - 768; -} - -static int32_t FASTCALL get_word1 (WavpackStream3 *wps, int chan) -{ - uint32_t tmp1, tmp2, avalue; - unsigned int ones_count; - int k; - - if ((wps->wphdr.flags & EXTREME_DECORR) && !(wps->wphdr.flags & OVER_20)) { - if (wps->w1.zeros_acc) { - if (--wps->w1.zeros_acc) - return 0; - } - else if (wps->w1.ave_level [0] [0] < 0x20 && wps->w1.ave_level [0] [1] < 0x20) { - int32_t mask; - int cbits; - - for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); - - if (cbits == 33) - return WORD_EOF; - - if (cbits < 2) - wps->w1.zeros_acc = cbits; - else { - for (mask = 1, wps->w1.zeros_acc = 0; --cbits; mask <<= 1) - if (getbit (&wps->wvbits)) - wps->w1.zeros_acc |= mask; - - wps->w1.zeros_acc |= mask; - } - - if (wps->w1.zeros_acc) - return 0; - } - } - - // count consecutive ones in bitstream, > 25 indicates error (or EOF) - - for (ones_count = 0; ones_count < 25 && getbit (&wps->wvbits); ++ones_count); - - if (ones_count == 25) - return WORD_EOF; - - k = (wps->w1.ave_level [0] [chan] + (wps->w1.ave_level [0] [chan] >> 3) + 0x40) >> 7; - k = count_bits (k); - - if (k & ~31) - return WORD_EOF; - - if (ones_count == 0) { - getbits (&avalue, k, &wps->wvbits); - avalue &= bitmask [k]; - } - else { - tmp1 = bitset [k]; - k = (wps->w1.ave_level [1] [chan] + (wps->w1.ave_level [1] [chan] >> 4) + 0x20) >> 6; - k = count_bits (k); - - if (k & ~31) - return WORD_EOF; - - if (ones_count == 1) { - getbits (&avalue, k, &wps->wvbits); - avalue &= bitmask [k]; - } - else { - tmp2 = bitset [k]; - - // If the ones count is exactly 24, then next 24 bits are literal - - if (ones_count == 24) { - getbits (&avalue, 24, &wps->wvbits); - avalue &= 0xffffff; - } - else { - k = (wps->w1.ave_level [2] [chan] + 0x10) >> 5; - k = count_bits (k); - - if (k & ~31) - return WORD_EOF; - - getbits (&avalue, k, &wps->wvbits); - avalue = (avalue & bitmask [k]) + (bitset [k] * (ones_count - 2)); - } - - wps->w1.ave_level [2] [chan] -= ((wps->w1.ave_level [2] [chan] + 0x8) >> 4); - wps->w1.ave_level [2] [chan] += avalue; - avalue += tmp2; - } - - wps->w1.ave_level [1] [chan] -= ((wps->w1.ave_level [1] [chan] + 0x10) >> 5); - wps->w1.ave_level [1] [chan] += avalue; - avalue += tmp1; - } - - wps->w1.ave_level [0] [chan] -= ((wps->w1.ave_level [0] [chan] + 0x20) >> 6); - wps->w1.ave_level [0] [chan] += avalue; - - return (avalue && getbit (&wps->wvbits)) ? -(int32_t)avalue : avalue; -} - -#define NUM_SAMPLES 128 - -static int32_t FASTCALL get_old_word1 (WavpackStream3 *wps, int chan) -{ - uint32_t avalue; - unsigned int bc; - int k; - - if (!wps->w1.index [chan]) { - - int guess_k = (wps->w1.ave_k [chan] + 128) >> 8, ones; - - for (ones = 0; ones < 72 && getbit (&wps->wvbits); ++ones); - - if (ones == 72) - return WORD_EOF; - - if (ones % 3 == 1) - wps->w1.k_value [chan] = guess_k - (ones / 3) - 1; - else - wps->w1.k_value [chan] = guess_k + ones - ((ones + 1) / 3); - - wps->w1.ave_k [chan] -= (wps->w1.ave_k [chan] + 0x10) >> 5; - wps->w1.ave_k [chan] += wps->w1.k_value [chan] << 3; - } - - if (++wps->w1.index [chan] == NUM_SAMPLES) - wps->w1.index [chan] = 0; - - k = wps->w1.k_value [chan]; - getbits (&avalue, k, &wps->wvbits); - - for (bc = 0; bc < 32 && getbit (&wps->wvbits); ++bc); - - if (bc == 32 || (k & ~31)) - return WORD_EOF; - - avalue = (avalue & bitmask [k]) + bitset [k] * bc; - return (avalue && getbit (&wps->wvbits)) ? -(int32_t)avalue : avalue; -} - -static int32_t FASTCALL get_word2 (WavpackStream3 *wps, int chan) -{ - int cbits, delta_dbits, dbits; - int32_t value, mask = 1; - - cbits = 0; - - while (getbit (&wps->wvbits)) - if ((cbits += 2) == 50) - return WORD_EOF; - - if (getbit (&wps->wvbits)) - cbits++; - - if (cbits == 0) - delta_dbits = 0; - else if (cbits & 1) { - delta_dbits = (cbits + 1) / 2; - - if (wps->w2.last_delta_sign [chan] > 0) - delta_dbits *= -1; - - wps->w2.last_delta_sign [chan] = delta_dbits; - } - else { - delta_dbits = cbits / 2; - - if (wps->w2.last_delta_sign [chan] <= 0) - delta_dbits *= -1; - } - - dbits = (wps->w2.last_dbits [chan] += delta_dbits); - - if (dbits < 0 || dbits > 20) - return WORD_EOF; - - if (!dbits) - return 0L; - - if (wps->wphdr.bits) { - for (value = 1L << (dbits - 1); --dbits; mask <<= 1) - if (dbits < wps->wphdr.bits && getbit (&wps->wvbits)) - value |= mask; - } - else - for (value = 1L << (dbits - 1); --dbits; mask <<= 1) - if (getbit (&wps->wvbits)) - value |= mask; - - return getbit (&wps->wvbits) ? -(int32_t)value : value; -} - -static int32_t FASTCALL get_word3 (WavpackStream3 *wps, int chan) -{ - int cbits, delta_dbits, dbits; - int32_t value; - - for (cbits = 0; cbits < 72 && getbit (&wps->wvbits); ++cbits); - - if (cbits == 72) - return WORD_EOF; - - if (cbits || getbit (&wps->wvbits)) - ++cbits; - - if (!((cbits + 1) % 3)) - delta_dbits = (cbits + 1) / 3; - else - delta_dbits = -(cbits - cbits / 3); - - if (chan) { - dbits = (wps->w3.ave_dbits [1] >> 8) + 1 + delta_dbits; - wps->w3.ave_dbits [1] -= (wps->w3.ave_dbits [1] + 0x10) >> 5; - wps->w3.ave_dbits [1] += dbits << 3; - } - else { - dbits = (wps->w3.ave_dbits [0] >> 8) + 1 + delta_dbits; - wps->w3.ave_dbits [0] -= (wps->w3.ave_dbits [0] + 0x10) >> 5; - wps->w3.ave_dbits [0] += dbits << 3; - } - - if (dbits < 0 || dbits > 24) - return WORD_EOF; - - if (!dbits) - return 0L; - - if (wps->wphdr.bits && dbits > wps->wphdr.bits) { - getbits (&value, wps->wphdr.bits, &wps->wvbits); - - if (value & bitset [wps->wphdr.bits - 1]) - return -(int32_t)(value & bitmask [wps->wphdr.bits]) << (dbits - wps->wphdr.bits); - else - return ((value & bitmask [wps->wphdr.bits - 1]) | bitset [wps->wphdr.bits - 1]) << (dbits - wps->wphdr.bits); - } - else { - getbits (&value, dbits, &wps->wvbits); - - if (value & bitset [dbits - 1]) - return -(int32_t)(value & bitmask [dbits]); - else - return (value & bitmask [dbits - 1]) | bitset [dbits - 1]; - } -} - -static int FASTCALL wp3_log2 (uint32_t avalue); - -static int32_t FASTCALL get_word4 (WavpackStream3 *wps, int chan, int32_t *correction) -{ - uint32_t base, ones_count, avalue; - int32_t value, low, mid, high; - int bitcount; - - // count consecutive ones in bitstream, > 25 indicates error (or EOF) - - for (ones_count = 0; ones_count < 25 && getbit (&wps->wvbits); ++ones_count); - - if (ones_count == 25) - return WORD_EOF; - - // if the ones count is exactly 24, then we switch to non-unary method - - if (ones_count == 24) { - int32_t mask; - int cbits; - - for (cbits = 0; cbits < 33 && getbit (&wps->wvbits); ++cbits); - - if (cbits == 33) - return WORD_EOF; - - if (cbits < 2) - ones_count = cbits; - else { - for (mask = 1, ones_count = 0; --cbits; mask <<= 1) - if (getbit (&wps->wvbits)) - ones_count |= mask; - - ones_count |= mask; - } - - ones_count += 24; - } - - if (!chan) { - int slow_log_0, slow_log_1, balance; - - if (wps->wphdr.flags & MONO_FLAG) { - wps->w4.bits_acc [0] += wps->w4.bitrate + wp3_log2 (wps->w4.fast_level [0]) - wp3_log2 (wps->w4.slow_level [0]) + (3 << 8); - - if (wps->w4.bits_acc [0] < 0) - wps->w4.bits_acc [0] = 0; - } - else { - slow_log_0 = wp3_log2 (wps->w4.slow_level [0]); - slow_log_1 = wp3_log2 (wps->w4.slow_level [1]); - - if (wps->wphdr.flags & JOINT_STEREO) - balance = (slow_log_1 - slow_log_0 + 257) >> 1; - else - balance = (slow_log_1 - slow_log_0 + 1) >> 1; - - wps->w4.bits_acc [0] += wps->w4.bitrate - balance + wp3_log2 (wps->w4.fast_level [0]) - slow_log_0 + (3 << 8); - wps->w4.bits_acc [1] += wps->w4.bitrate + balance + wp3_log2 (wps->w4.fast_level [1]) - slow_log_1 + (3 << 8); - - if (wps->w4.bits_acc [0] + wps->w4.bits_acc [1] < 0) - wps->w4.bits_acc [0] = wps->w4.bits_acc [1] = 0; - else if (wps->w4.bits_acc [0] < 0) { - wps->w4.bits_acc [1] += wps->w4.bits_acc [0]; - wps->w4.bits_acc [0] = 0; - } - else if (wps->w4.bits_acc [1] < 0) { - wps->w4.bits_acc [0] += wps->w4.bits_acc [1]; - wps->w4.bits_acc [1] = 0; - } - } - } - - base = (wps->w4.fast_level [chan] + 48) / 96; - bitcount = wps->w4.bits_acc [chan] >> 8; - wps->w4.bits_acc [chan] &= 0xff; - - if (!base) { - if (ones_count) - high = low = mid = (getbit (&wps->wvbits)) ? -(int32_t)ones_count : ones_count; - else - high = low = mid = 0; - } - else { - mid = (ones_count * 2 + 1) * base; - if (getbit (&wps->wvbits)) mid = -mid; - low = mid - base; - high = mid + base - 1; - - while (bitcount--) { - if (getbit (&wps->wvbits)) - mid = (high + (low = mid) + 1) >> 1; - else - mid = ((high = mid - 1) + low + 1) >> 1; - - if (high == low) - break; - } - } - - wps->w4.fast_level [chan] -= ((wps->w4.fast_level [chan] + 0x10) >> 5); - wps->w4.fast_level [chan] += (avalue = labs (mid)); - wps->w4.slow_level [chan] -= ((wps->w4.slow_level [chan] + 0x80) >> 8); - wps->w4.slow_level [chan] += avalue; - - if (bs_is_open (&wps->wvcbits)) { - - if (high != low) { - uint32_t maxcode = high - low; - int bitcount = count_bits (maxcode); - uint32_t extras = (1L << bitcount) - maxcode - 1; - - getbits (&avalue, bitcount - 1, &wps->wvcbits); - avalue &= bitmask [bitcount - 1]; - - if (avalue >= extras) { - avalue = (avalue << 1) - extras; - - if (getbit (&wps->wvcbits)) - ++avalue; - } - - value = (mid < 0) ? high - avalue : avalue + low; - - if (correction) - *correction = value - mid; - } - else if (correction) - *correction = 0; - } - - return mid; -} - -// This function calculates an approximate base-2 logarithm (with 8 bits of -// fraction) from the supplied value. Using logarithms makes comparing -// signal level values and calculating fractional bitrates much easier. - -static int FASTCALL wp3_log2 (uint32_t avalue) -{ - int dbits; - - if ((avalue += avalue >> 9) < (1 << 8)) { - dbits = nbits_table [avalue]; - return (dbits << 8) + ((avalue << (9 - dbits)) & 0xff); - } - else { - if (avalue < (1L << 16)) - dbits = nbits_table [avalue >> 8] + 8; - else if (avalue < (1L << 24)) - dbits = nbits_table [avalue >> 16] + 16; - else - dbits = nbits_table [avalue >> 24] + 24; - - return (dbits << 8) + ((avalue >> (dbits - 9)) & 0xff); - } -} - -static void bs_read3 (Bitstream3 *bs) -{ - uint32_t bytes_read; - - bytes_read = bs->reader->read_bytes (bs->id, bs->buf, bs->bufsiz); - bs->end = bs->buf + bytes_read; - bs->fpos += bytes_read; - - if (bs->end == bs->buf) { - memset (bs->buf, -1, bs->bufsiz); - bs->end += bs->bufsiz; - } - - bs->ptr = bs->buf; -} - -// Open the specified BitStream and associate with the specified file. The -// "bufsiz" field of the structure must be preset with the desired buffer -// size and the file's read pointer must be set to where the desired bit -// data is located. A return value of TRUE indicates an error in -// allocating buffer space. - -static int bs_open_read3 (Bitstream3 *bs, WavpackStreamReader64 *reader, void *id) -{ - bs->fpos = (bs->reader = reader)->get_pos (bs->id = id); - - if (!bs->buf) - bs->buf = (unsigned char *) malloc (bs->bufsiz); - - bs->end = bs->buf + bs->bufsiz; - bs->ptr = bs->end - 1; - bs->sr = bs->bc = 0; - bs->error = bs->buf ? 0 : 1; - bs->wrap = bs_read3; - return bs->error; -} - -static uint32_t bs_unused_bytes (Bitstream3 *bs) -{ - if (bs->bc < 8) { - bs->bc += 8; - bs->ptr++; - } - - return (uint32_t)(bs->end - bs->ptr); -} - -static unsigned char *bs_unused_data (Bitstream3 *bs) -{ - if (bs->bc < 8) { - bs->bc += 8; - bs->ptr++; - } - - return bs->ptr; -} - -#endif // ENABLE_LEGACY - diff --git a/Frameworks/WavPack/Files/unpack3.h b/Frameworks/WavPack/Files/unpack3.h deleted file mode 100644 index ae351f839..000000000 --- a/Frameworks/WavPack/Files/unpack3.h +++ /dev/null @@ -1,119 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2006 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// wavpack3.h - -// This header file contains all the additional definitions required for -// decoding old (versions 1, 2 & 3) WavPack files. - -typedef struct { - uint16_t FormatTag, NumChannels; - uint32_t SampleRate, BytesPerSecond; - uint16_t BlockAlign, BitsPerSample; -} WaveHeader3; - -#define WaveHeader3Format "SSLLSS" - -typedef struct { - char ckID [4]; - int32_t ckSize; - int16_t version; - int16_t bits; // added for version 2.00 - int16_t flags, shift; // added for version 3.00 - int32_t total_samples, crc, crc2; - char extension [4], extra_bc, extras [3]; -} WavpackHeader3; - -#define WavpackHeader3Format "4LSSSSLLL4L" - -// these flags added for version 3 - -#undef MONO_FLAG // these definitions changed for WavPack 4.0 -#undef CROSS_DECORR -#undef JOINT_STEREO - -#define MONO_FLAG 1 // not stereo -#define FAST_FLAG 2 // non-adaptive predictor and stereo mode -#define RAW_FLAG 4 // raw mode (no .wav header) -#define CALC_NOISE 8 // calc noise in lossy mode (no longer stored) -#define HIGH_FLAG 0x10 // high quality mode (all modes) -#define BYTES_3 0x20 // files have 3-byte samples -#define OVER_20 0x40 // samples are over 20 bits -#define WVC_FLAG 0x80 // create/use .wvc (no longer stored) -#define LOSSY_SHAPE 0x100 // noise shape (lossy mode only) -#define VERY_FAST_FLAG 0x200 // double fast (no longer stored) -#define NEW_HIGH_FLAG 0x400 // new high quality mode (lossless only) -#define CANCEL_EXTREME 0x800 // cancel EXTREME_DECORR -#define CROSS_DECORR 0x1000 // decorrelate chans (with EXTREME_DECORR flag) -#define NEW_DECORR_FLAG 0x2000 // new high-mode decorrelator -#define JOINT_STEREO 0x4000 // joint stereo (lossy and high lossless) -#define EXTREME_DECORR 0x8000 // extra decorrelation (+ enables other flags) - -#define STORED_FLAGS 0xfd77 // these are only flags that affect unpacking -#define NOT_STORED_FLAGS (~STORED_FLAGS & 0xffff) - -// BitStream stuff (bits.c) - -typedef struct bs3 { - void (*wrap)(struct bs3 *bs); - unsigned char *buf, *end, *ptr; - uint32_t bufsiz, sr; - int64_t fpos; - WavpackStreamReader64 *reader; - int error, bc; - void *id; -} Bitstream3; - -#define K_DEPTH 3 -#define MAX_NTERMS3 18 - -typedef struct { - WavpackHeader3 wphdr; - Bitstream3 wvbits, wvcbits; - uint32_t sample_index; - int num_terms; - -#ifndef NO_SEEKING - struct index_point { - char saved; - uint32_t sample_index; - } index_points [256]; - - unsigned char *unpack_data; - uint32_t unpack_size; -#endif - - struct { - int32_t sum_level, left_level, right_level, diff_level; - int last_extra_bits, extra_bits_count, m; - int32_t error [2], crc; - int32_t sample [2] [2]; - int weight [2] [1]; - } dc; - - struct decorr_pass decorr_passes [MAX_NTERMS3]; - - struct { - unsigned int index [2], k_value [2], ave_k [2]; - uint32_t zeros_acc, ave_level [K_DEPTH] [2]; - } w1; - - struct { int last_dbits [2], last_delta_sign [2], bit_limit; } w2; - - struct { int ave_dbits [2], bit_limit; } w3; - - struct { - uint32_t fast_level [2], slow_level [2]; - int bits_acc [2], bitrate; - } w4; -} WavpackStream3; - -#define SAVE(destin, item) { memcpy (destin, &item, sizeof (item)); destin = (char *) destin + sizeof (item); } -#define RESTORE(item, source) { memcpy (&item, source, sizeof (item)); source = (char *) source + sizeof (item); } - -void unpack_init3 (WavpackStream3 *wps); diff --git a/Frameworks/WavPack/Files/unpack3_open.c b/Frameworks/WavPack/Files/unpack3_open.c deleted file mode 100644 index 044f32ffc..000000000 --- a/Frameworks/WavPack/Files/unpack3_open.c +++ /dev/null @@ -1,289 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// unpack3_open.c - -// This module provides an extension to the open_utils.c module for handling -// WavPack files prior to version 4.0, not including "raw" files. As these -// modes are all obsolete and are no longer written, this code will not be -// fully documented other than the global functions. However, full documentation -// is provided in the version 3.97 source code. Note that this module only -// provides the functionality of opening the files and obtaining information -// from them; the actual audio decoding is located in the unpack3.c module. - -#ifdef ENABLE_LEGACY - -#include -#include - -#include "wavpack_local.h" -#include "unpack3.h" - -#define ATTEMPT_ERROR_MUTING - -// This provides an extension to the WavpackOpenFileRead () function contained -// in the wputils.c module. It is assumed that an 'R' had been read as the -// first character of the file/stream (indicating a non-raw pre version 4.0 -// WavPack file) and had been pushed back onto the stream (or simply seeked -// back to). - -WavpackContext *open_file3 (WavpackContext *wpc, char *error) -{ - RiffChunkHeader RiffChunkHeader; - ChunkHeader ChunkHeader; - WavpackHeader3 wphdr; - WavpackStream3 *wps; - WaveHeader3 wavhdr; - - CLEAR (wavhdr); - wpc->stream3 = wps = (WavpackStream3 *) malloc (sizeof (WavpackStream3)); - CLEAR (*wps); - - if (wpc->reader->read_bytes (wpc->wv_in, &RiffChunkHeader, sizeof (RiffChunkHeader)) != - sizeof (RiffChunkHeader)) { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - - if (!strncmp (RiffChunkHeader.ckID, "RIFF", 4) && !strncmp (RiffChunkHeader.formType, "WAVE", 4)) { - - if (wpc->open_flags & OPEN_WRAPPER) { - wpc->wrapper_data = (unsigned char *)malloc (wpc->wrapper_bytes = sizeof (RiffChunkHeader)); - memcpy (wpc->wrapper_data, &RiffChunkHeader, sizeof (RiffChunkHeader)); - } - - // If the first chunk is a wave RIFF header, then read the various chunks - // until we get to the "data" chunk (and WavPack header should follow). If - // the first chunk is not a RIFF, then we assume a "raw" WavPack file and - // the WavPack header must be first. - - while (1) { - - if (wpc->reader->read_bytes (wpc->wv_in, &ChunkHeader, sizeof (ChunkHeader)) != - sizeof (ChunkHeader)) { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - else { - if (wpc->open_flags & OPEN_WRAPPER) { - wpc->wrapper_data = (unsigned char *)realloc (wpc->wrapper_data, wpc->wrapper_bytes + sizeof (ChunkHeader)); - memcpy (wpc->wrapper_data + wpc->wrapper_bytes, &ChunkHeader, sizeof (ChunkHeader)); - wpc->wrapper_bytes += sizeof (ChunkHeader); - } - - WavpackLittleEndianToNative (&ChunkHeader, ChunkHeaderFormat); - - if (!strncmp (ChunkHeader.ckID, "fmt ", 4)) { - - if (ChunkHeader.ckSize < sizeof (wavhdr) || - wpc->reader->read_bytes (wpc->wv_in, &wavhdr, sizeof (wavhdr)) != sizeof (wavhdr)) { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - else if (wpc->open_flags & OPEN_WRAPPER) { - wpc->wrapper_data = (unsigned char *)realloc (wpc->wrapper_data, wpc->wrapper_bytes + sizeof (wavhdr)); - memcpy (wpc->wrapper_data + wpc->wrapper_bytes, &wavhdr, sizeof (wavhdr)); - wpc->wrapper_bytes += sizeof (wavhdr); - } - - WavpackLittleEndianToNative (&wavhdr, WaveHeader3Format); - - if (ChunkHeader.ckSize > sizeof (wavhdr)) { - uint32_t bytes_to_skip = (ChunkHeader.ckSize + 1 - sizeof (wavhdr)) & ~1L; - - if (bytes_to_skip > 1024 * 1024) { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - - if (wpc->open_flags & OPEN_WRAPPER) { - wpc->wrapper_data = (unsigned char *)realloc (wpc->wrapper_data, wpc->wrapper_bytes + bytes_to_skip); - wpc->reader->read_bytes (wpc->wv_in, wpc->wrapper_data + wpc->wrapper_bytes, bytes_to_skip); - wpc->wrapper_bytes += bytes_to_skip; - } - else { - unsigned char *temp = (unsigned char *)malloc (bytes_to_skip); - wpc->reader->read_bytes (wpc->wv_in, temp, bytes_to_skip); - free (temp); - } - } - } - else if (!strncmp (ChunkHeader.ckID, "data", 4)) - break; - else if ((ChunkHeader.ckSize + 1) & ~1L) { - uint32_t bytes_to_skip = (ChunkHeader.ckSize + 1) & ~1L; - - if (bytes_to_skip > 1024 * 1024) { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - - if (wpc->open_flags & OPEN_WRAPPER) { - wpc->wrapper_data = (unsigned char *)realloc (wpc->wrapper_data, wpc->wrapper_bytes + bytes_to_skip); - wpc->reader->read_bytes (wpc->wv_in, wpc->wrapper_data + wpc->wrapper_bytes, bytes_to_skip); - wpc->wrapper_bytes += bytes_to_skip; - } - else { - unsigned char *temp = (unsigned char *)malloc (bytes_to_skip); - wpc->reader->read_bytes (wpc->wv_in, temp, bytes_to_skip); - free (temp); - } - } - } - } - } - else { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - - if (wavhdr.FormatTag != 1 || !wavhdr.NumChannels || wavhdr.NumChannels > 2 || - !wavhdr.SampleRate || wavhdr.BitsPerSample < 16 || wavhdr.BitsPerSample > 24 || - wavhdr.BlockAlign / wavhdr.NumChannels > 3 || wavhdr.BlockAlign % wavhdr.NumChannels || - wavhdr.BlockAlign / wavhdr.NumChannels < (wavhdr.BitsPerSample + 7) / 8) { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - - wpc->total_samples = ChunkHeader.ckSize / wavhdr.NumChannels / - ((wavhdr.BitsPerSample > 16) ? 3 : 2); - - if (wpc->reader->read_bytes (wpc->wv_in, &wphdr, 10) != 10) { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - - if (((char *) &wphdr) [8] == 2 && (wpc->reader->read_bytes (wpc->wv_in, ((char *) &wphdr) + 10, 2) != 2)) { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - else if (((char *) &wphdr) [8] == 3 && (wpc->reader->read_bytes (wpc->wv_in, ((char *) &wphdr) + 10, - sizeof (wphdr) - 10) != sizeof (wphdr) - 10)) { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - - WavpackLittleEndianToNative (&wphdr, WavpackHeader3Format); - - // make sure this is a version we know about - - if (strncmp (wphdr.ckID, "wvpk", 4) || wphdr.version < 1 || wphdr.version > 3) { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - - // Because I ran out of flag bits in the WavPack header, an amazingly ugly - // kludge was forced upon me! This code takes care of preparing the flags - // field for internal use and checking for unknown formats we can't decode - - if (wphdr.version == 3) { - - if (wphdr.flags & EXTREME_DECORR) { - - if ((wphdr.flags & NOT_STORED_FLAGS) || - ((wphdr.bits) && - (((wphdr.flags & NEW_HIGH_FLAG) && - (wphdr.flags & (FAST_FLAG | HIGH_FLAG))) || - (wphdr.flags & CROSS_DECORR)))) { - if (error) strcpy (error, "not a valid WavPack file!"); - return WavpackCloseFile (wpc); - } - - if (wphdr.flags & CANCEL_EXTREME) - wphdr.flags &= ~(EXTREME_DECORR | CANCEL_EXTREME); - } - else - wphdr.flags &= ~CROSS_DECORR; - } - - // check to see if we should look for a "correction" file, and if so try - // to open it for reading, then set WVC_FLAG accordingly - - if (wpc->wvc_in && wphdr.version == 3 && wphdr.bits && (wphdr.flags & NEW_HIGH_FLAG)) { - wpc->file2len = wpc->reader->get_length (wpc->wvc_in); - wphdr.flags |= WVC_FLAG; - wpc->wvc_flag = TRUE; - } - else - wphdr.flags &= ~WVC_FLAG; - - // check WavPack version to handle special requirements of versions - // before 3.0 that had smaller headers - - if (wphdr.version < 3) { - wphdr.total_samples = (int32_t) wpc->total_samples; - wphdr.flags = wavhdr.NumChannels == 1 ? MONO_FLAG : 0; - wphdr.shift = 16 - wavhdr.BitsPerSample; - - if (wphdr.version == 1) - wphdr.bits = 0; - } - - wpc->config.sample_rate = wavhdr.SampleRate; - wpc->config.num_channels = wavhdr.NumChannels; - wpc->config.channel_mask = 5 - wavhdr.NumChannels; - - if (wphdr.flags & MONO_FLAG) - wpc->config.flags |= CONFIG_MONO_FLAG; - - if (wphdr.flags & EXTREME_DECORR) - wpc->config.flags |= CONFIG_HIGH_FLAG; - - if (wphdr.bits) { - if (wphdr.flags & NEW_HIGH_FLAG) - wpc->config.flags |= CONFIG_HYBRID_FLAG; - else - wpc->config.flags |= CONFIG_LOSSY_MODE; - } - else if (!(wphdr.flags & HIGH_FLAG)) - wpc->config.flags |= CONFIG_FAST_FLAG; - - wpc->config.bytes_per_sample = (wphdr.flags & BYTES_3) ? 3 : 2; - wpc->config.bits_per_sample = wavhdr.BitsPerSample; - - memcpy (&wps->wphdr, &wphdr, sizeof (wphdr)); - wps->wvbits.bufsiz = wps->wvcbits.bufsiz = 1024 * 1024; - return wpc; -} - -// return currently decoded sample index - -uint32_t get_sample_index3 (WavpackContext *wpc) -{ - WavpackStream3 *wps = (WavpackStream3 *) wpc->stream3; - - return (wps) ? wps->sample_index : (uint32_t) -1; -} - -int get_version3 (WavpackContext *wpc) -{ - WavpackStream3 *wps = (WavpackStream3 *) wpc->stream3; - - return (wps) ? wps->wphdr.version : 0; -} - -void free_stream3 (WavpackContext *wpc) -{ - WavpackStream3 *wps = (WavpackStream3 *) wpc->stream3; - - if (wps) { -#ifndef NO_SEEKING - if (wps->unpack_data) - free (wps->unpack_data); -#endif - if ((wps->wphdr.flags & WVC_FLAG) && wps->wvcbits.buf) - free (wps->wvcbits.buf); - - if (wps->wvbits.buf) - free (wps->wvbits.buf); - - free (wps); - } -} - -#endif // ENABLE_LEGACY diff --git a/Frameworks/WavPack/Files/unpack3_seek.c b/Frameworks/WavPack/Files/unpack3_seek.c deleted file mode 100644 index f1ed27fd7..000000000 --- a/Frameworks/WavPack/Files/unpack3_seek.c +++ /dev/null @@ -1,212 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// unpack3_seek.c - -// This module provides seeking support for WavPack files prior to version 4.0. - -#ifdef ENABLE_LEGACY -#ifndef NO_SEEKING - -#include -#include - -#include "wavpack_local.h" -#include "unpack3.h" - -static void *unpack_restore (WavpackStream3 *wps, void *source, int keep_resources); -static void bs_restore3 (Bitstream3 *bs); - -// This is an extension for WavpackSeekSample (). Note that because WavPack -// files created prior to version 4.0 are not inherently seekable, this -// function could take a long time if a forward seek is requested to an -// area that has not been played (or seeked through) yet. - -int seek_sample3 (WavpackContext *wpc, uint32_t desired_index) -{ - int points_index = desired_index / (((uint32_t) wpc->total_samples >> 8) + 1); - WavpackStream3 *wps = (WavpackStream3 *) wpc->stream3; - - if (desired_index >= wpc->total_samples) - return FALSE; - - while (points_index) - if (wps->index_points [points_index].saved && - wps->index_points [points_index].sample_index <= desired_index) - break; - else - points_index--; - - if (wps->index_points [points_index].saved) - if (wps->index_points [points_index].sample_index > wps->sample_index || - wps->sample_index > desired_index) { - wps->sample_index = wps->index_points [points_index].sample_index; - unpack_restore (wps, wps->unpack_data + points_index * wps->unpack_size, TRUE); - } - - if (desired_index > wps->sample_index) { - int32_t *buffer = (int32_t *) malloc (1024 * (wps->wphdr.flags & MONO_FLAG ? 4 : 8)); - uint32_t samples_to_skip = desired_index - wps->sample_index; - - while (1) { - if (samples_to_skip > 1024) { - if (unpack_samples3 (wpc, buffer, 1024) == 1024) - samples_to_skip -= 1024; - else - break; - } - else { - samples_to_skip -= unpack_samples3 (wpc, buffer, samples_to_skip); - break; - } - } - - free (buffer); - - if (samples_to_skip) - return FALSE; - } - - return TRUE; -} - -// This function restores the unpacking context from the specified pointer -// and returns the updated pointer. After this call, unpack_samples() will -// continue where it left off immediately before unpack_save() was called. -// If the WavPack files and bitstreams might have been closed and reopened, -// then the "keep_resources" flag should be set to avoid using the "old" -// resources that were originally saved (and are probably now invalid). - -static void *unpack_restore (WavpackStream3 *wps, void *source, int keep_resources) -{ - int flags = wps->wphdr.flags, tcount; - struct decorr_pass *dpp; - FILE *temp_file; - unsigned char *temp_buf; - - unpack_init3 (wps); - temp_file = wps->wvbits.id; - temp_buf = wps->wvbits.buf; - RESTORE (wps->wvbits, source); - - if (keep_resources) { - wps->wvbits.id = temp_file; - wps->wvbits.ptr += temp_buf - wps->wvbits.buf; - wps->wvbits.end += temp_buf - wps->wvbits.buf; - wps->wvbits.buf = temp_buf; - } - - bs_restore3 (&wps->wvbits); - - if (flags & WVC_FLAG) { - temp_file = wps->wvcbits.id; - temp_buf = wps->wvcbits.buf; - RESTORE (wps->wvcbits, source); - - if (keep_resources) { - wps->wvcbits.id = temp_file; - wps->wvcbits.ptr += temp_buf - wps->wvcbits.buf; - wps->wvcbits.end += temp_buf - wps->wvcbits.buf; - wps->wvcbits.buf = temp_buf; - } - - bs_restore3 (&wps->wvcbits); - } - - if (wps->wphdr.version == 3) { - if (wps->wphdr.bits) { - RESTORE (wps->w4, source); - } - else { - RESTORE (wps->w1, source); - } - - RESTORE (wps->w3, source); - RESTORE (wps->dc.crc, source); - } - else - RESTORE (wps->w2, source); - - if (wps->wphdr.bits) { - RESTORE (wps->dc.error, source); - } - else { - RESTORE (wps->dc.sum_level, source); - RESTORE (wps->dc.left_level, source); - RESTORE (wps->dc.right_level, source); - RESTORE (wps->dc.diff_level, source); - } - - if (flags & OVER_20) { - RESTORE (wps->dc.last_extra_bits, source); - RESTORE (wps->dc.extra_bits_count, source); - } - - if (!(flags & EXTREME_DECORR)) { - RESTORE (wps->dc.sample, source); - RESTORE (wps->dc.weight, source); - } - - if (flags & (HIGH_FLAG | NEW_HIGH_FLAG)) - for (tcount = wps->num_terms, dpp = wps->decorr_passes; tcount--; dpp++) { - if (dpp->term > 0) { - int count = dpp->term; - int index = wps->dc.m; - - RESTORE (dpp->weight_A, source); - - while (count--) { - RESTORE (dpp->samples_A [index], source); - index = (index + 1) & (MAX_TERM - 1); - } - - if (!(flags & MONO_FLAG)) { - count = dpp->term; - index = wps->dc.m; - - RESTORE (dpp->weight_B, source); - - while (count--) { - RESTORE (dpp->samples_B [index], source); - index = (index + 1) & (MAX_TERM - 1); - } - } - } - else { - RESTORE (dpp->weight_A, source); - RESTORE (dpp->weight_B, source); - RESTORE (dpp->samples_A [0], source); - RESTORE (dpp->samples_B [0], source); - } - } - - return source; -} - -// This function is called after a call to unpack_restore() has restored -// the BitStream structure to a previous state and causes any required data -// to be read from the file. This function is NOT supported for overlapped -// operation. - -static void bs_restore3 (Bitstream3 *bs) -{ - uint32_t bytes_to_read = (uint32_t)(bs->end - bs->ptr - 1), bytes_read; - - bs->reader->set_pos_abs (bs->id, bs->fpos - bytes_to_read); - - if (bytes_to_read > 0) { - - bytes_read = bs->reader->read_bytes (bs->id, bs->ptr + 1, bytes_to_read); - - if (bytes_to_read != bytes_read) - bs->end = bs->ptr + 1 + bytes_read; - } -} - -#endif // NO_SEEKING -#endif // ENABLE_LEGACY diff --git a/Frameworks/WavPack/Files/unpack_dsd.c b/Frameworks/WavPack/Files/unpack_dsd.c deleted file mode 100644 index d8d1ee283..000000000 --- a/Frameworks/WavPack/Files/unpack_dsd.c +++ /dev/null @@ -1,620 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** DSDPACK **** // -// Lossless DSD (Direct Stream Digital) Audio Compressor // -// Copyright (c) 2013 - 2016 David Bryant. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// unpack_dsd.c - -// This module actually handles the uncompression of the DSD audio data. - -#ifdef ENABLE_DSD - -#include -#include -#include - -#include "wavpack_local.h" - -///////////////////////////// executable code //////////////////////////////// - -// This function initializes the main range-encoded data for DSD audio samples - -static int init_dsd_block_fast (WavpackStream *wps, WavpackMetadata *wpmd); -static int init_dsd_block_high (WavpackStream *wps, WavpackMetadata *wpmd); -static int decode_fast (WavpackStream *wps, int32_t *output, int sample_count); -static int decode_high (WavpackStream *wps, int32_t *output, int sample_count); - -int init_dsd_block (WavpackContext *wpc, WavpackMetadata *wpmd) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - - if (wpmd->byte_length < 2) - return FALSE; - - wps->dsd.byteptr = (unsigned char *)wpmd->data; - wps->dsd.endptr = wps->dsd.byteptr + wpmd->byte_length; - wpc->dsd_multiplier = 1 << *wps->dsd.byteptr++; - wps->dsd.mode = *wps->dsd.byteptr++; - - if (!wps->dsd.mode) { - if (wps->dsd.endptr - wps->dsd.byteptr != wps->wphdr.block_samples * (wps->wphdr.flags & MONO_DATA ? 1 : 2)) { - return FALSE; - } - - wps->dsd.ready = 1; - return TRUE; - } - - if (wps->dsd.mode == 1) - return init_dsd_block_fast (wps, wpmd); - else if (wps->dsd.mode == 3) - return init_dsd_block_high (wps, wpmd); - else - return FALSE; -} - -int32_t unpack_dsd_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - uint32_t flags = wps->wphdr.flags; - - // don't attempt to decode past the end of the block, but watch out for overflow! - - if (wps->sample_index + sample_count > GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples && - (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index) < sample_count) - sample_count = (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index); - - if (GET_BLOCK_INDEX (wps->wphdr) > wps->sample_index || wps->wphdr.block_samples < sample_count) - wps->mute_error = TRUE; - - if (!wps->mute_error) { - if (!wps->dsd.mode) { - int total_samples = sample_count * ((flags & MONO_DATA) ? 1 : 2); - int32_t *bptr = buffer; - - if (wps->dsd.endptr - wps->dsd.byteptr < total_samples) - total_samples = (int)(wps->dsd.endptr - wps->dsd.byteptr); - - while (total_samples--) - wps->crc += (wps->crc << 1) + (*bptr++ = *wps->dsd.byteptr++); - } - else if (wps->dsd.mode == 1) { - if (!decode_fast (wps, buffer, sample_count)) - wps->mute_error = TRUE; - } - else if (!decode_high (wps, buffer, sample_count)) - wps->mute_error = TRUE; - } - - if (wps->mute_error) { - int samples_to_null; - if (wpc->reduced_channels == 1 || wpc->config.num_channels == 1 || (flags & MONO_FLAG)) - samples_to_null = sample_count; - else - samples_to_null = sample_count * 2; - - while (samples_to_null--) - *buffer++ = 0x55; - - wps->sample_index += sample_count; - return sample_count; - } - - if (flags & FALSE_STEREO) { - int32_t *dptr = buffer + sample_count * 2; - int32_t *sptr = buffer + sample_count; - int32_t c = sample_count; - - while (c--) { - *--dptr = *--sptr; - *--dptr = *sptr; - } - } - - wps->sample_index += sample_count; - - return sample_count; -} - -/*------------------------------------------------------------------------------------------------------------------------*/ - -// #define DSD_BYTE_READY(low,high) (((low) >> 24) == ((high) >> 24)) -// #define DSD_BYTE_READY(low,high) (!(((low) ^ (high)) >> 24)) -#define DSD_BYTE_READY(low,high) (!(((low) ^ (high)) & 0xff000000)) - -static int init_dsd_block_fast (WavpackStream *wps, WavpackMetadata *wpmd) -{ - unsigned char history_bits, max_probability, *lb_ptr; - int total_summed_probabilities = 0, bi, i; - - if (wps->dsd.byteptr == wps->dsd.endptr) - return FALSE; - - history_bits = *wps->dsd.byteptr++; - - if (wps->dsd.byteptr == wps->dsd.endptr || history_bits > MAX_HISTORY_BITS) - return FALSE; - - wps->dsd.history_bins = 1 << history_bits; - - free_dsd_tables (wps); - lb_ptr = wps->dsd.lookup_buffer = (unsigned char *)malloc (wps->dsd.history_bins * MAX_BYTES_PER_BIN); - wps->dsd.value_lookup = (unsigned char **)malloc (sizeof (*wps->dsd.value_lookup) * wps->dsd.history_bins); - memset (wps->dsd.value_lookup, 0, sizeof (*wps->dsd.value_lookup) * wps->dsd.history_bins); - wps->dsd.summed_probabilities = (int16_t (*)[256])malloc (sizeof (*wps->dsd.summed_probabilities) * wps->dsd.history_bins); - wps->dsd.probabilities = (unsigned char (*)[256])malloc (sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins); - - max_probability = *wps->dsd.byteptr++; - - if (max_probability < 0xff) { - unsigned char *outptr = (unsigned char *) wps->dsd.probabilities; - unsigned char *outend = outptr + sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins; - - while (outptr < outend && wps->dsd.byteptr < wps->dsd.endptr) { - int code = *wps->dsd.byteptr++; - - if (code > max_probability) { - int zcount = code - max_probability; - - while (outptr < outend && zcount--) - *outptr++ = 0; - } - else if (code) - *outptr++ = code; - else - break; - } - - if (outptr < outend || (wps->dsd.byteptr < wps->dsd.endptr && *wps->dsd.byteptr++)) - return FALSE; - } - else if (wps->dsd.endptr - wps->dsd.byteptr > (int) sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins) { - memcpy (wps->dsd.probabilities, wps->dsd.byteptr, sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins); - wps->dsd.byteptr += sizeof (*wps->dsd.probabilities) * wps->dsd.history_bins; - } - else - return FALSE; - - for (bi = 0; bi < wps->dsd.history_bins; ++bi) { - int32_t sum_values; - - for (sum_values = i = 0; i < 256; ++i) - wps->dsd.summed_probabilities [bi] [i] = sum_values += wps->dsd.probabilities [bi] [i]; - - if (sum_values) { - if ((total_summed_probabilities += sum_values) > wps->dsd.history_bins * MAX_BYTES_PER_BIN) - return FALSE; - - wps->dsd.value_lookup [bi] = lb_ptr; - - for (i = 0; i < 256; i++) { - int c = wps->dsd.probabilities [bi] [i]; - - while (c--) - *lb_ptr++ = i; - } - } - } - - if (wps->dsd.endptr - wps->dsd.byteptr < 4 || total_summed_probabilities > wps->dsd.history_bins * MAX_BYTES_PER_BIN) - return FALSE; - - for (i = 4; i--;) - wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; - - wps->dsd.p0 = wps->dsd.p1 = 0; - wps->dsd.low = 0; wps->dsd.high = 0xffffffff; - wps->dsd.ready = 1; - - return TRUE; -} - -static int decode_fast (WavpackStream *wps, int32_t *output, int sample_count) -{ - int total_samples = sample_count; - - if (!(wps->wphdr.flags & MONO_DATA)) - total_samples *= 2; - - while (total_samples--) { - int mult, index, code, i; - - if (!wps->dsd.summed_probabilities [wps->dsd.p0] [255]) - return 0; - - mult = (wps->dsd.high - wps->dsd.low) / wps->dsd.summed_probabilities [wps->dsd.p0] [255]; - - if (!mult) { - if (wps->dsd.endptr - wps->dsd.byteptr >= 4) - for (i = 4; i--;) - wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; - - wps->dsd.low = 0; - wps->dsd.high = 0xffffffff; - mult = wps->dsd.high / wps->dsd.summed_probabilities [wps->dsd.p0] [255]; - - if (!mult) - return 0; - } - - index = (wps->dsd.value - wps->dsd.low) / mult; - - if (index >= wps->dsd.summed_probabilities [wps->dsd.p0] [255]) - return 0; - - if ((*output++ = code = wps->dsd.value_lookup [wps->dsd.p0] [index])) - wps->dsd.low += wps->dsd.summed_probabilities [wps->dsd.p0] [code-1] * mult; - - wps->dsd.high = wps->dsd.low + wps->dsd.probabilities [wps->dsd.p0] [code] * mult - 1; - wps->crc += (wps->crc << 1) + code; - - if (wps->wphdr.flags & MONO_DATA) - wps->dsd.p0 = code & (wps->dsd.history_bins-1); - else { - wps->dsd.p0 = wps->dsd.p1; - wps->dsd.p1 = code & (wps->dsd.history_bins-1); - } - - while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) { - wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; - wps->dsd.high = (wps->dsd.high << 8) | 0xff; - wps->dsd.low <<= 8; - } - } - - return sample_count; -} - -/*------------------------------------------------------------------------------------------------------------------------*/ - -#define PTABLE_BITS 8 -#define PTABLE_BINS (1<> 8; c--;) - value += (DOWN - value) >> DECAY; - - for (i = 0; i < PTABLE_BINS/2; ++i) { - table [i] = value; - table [PTABLE_BINS-1-i] = 0x100ffff - value; - - if (value > 0x010000) { - rate += (rate * rate_s + 128) >> 8; - - for (c = (rate + 64) >> 7; c--;) - value += (DOWN - value) >> DECAY; - } - } -} - -static int init_dsd_block_high (WavpackStream *wps, WavpackMetadata *wpmd) -{ - uint32_t flags = wps->wphdr.flags; - int channel, rate_i, rate_s, i; - - if (wps->dsd.endptr - wps->dsd.byteptr < ((flags & MONO_DATA) ? 13 : 20)) - return FALSE; - - rate_i = *wps->dsd.byteptr++; - rate_s = *wps->dsd.byteptr++; - - if (rate_s != RATE_S) - return FALSE; - - if (!wps->dsd.ptable) - wps->dsd.ptable = (int32_t *)malloc (PTABLE_BINS * sizeof (*wps->dsd.ptable)); - - init_ptable (wps->dsd.ptable, rate_i, rate_s); - - for (channel = 0; channel < ((flags & MONO_DATA) ? 1 : 2); ++channel) { - DSDfilters *sp = wps->dsd.filters + channel; - - sp->filter1 = *wps->dsd.byteptr++ << (PRECISION - 8); - sp->filter2 = *wps->dsd.byteptr++ << (PRECISION - 8); - sp->filter3 = *wps->dsd.byteptr++ << (PRECISION - 8); - sp->filter4 = *wps->dsd.byteptr++ << (PRECISION - 8); - sp->filter5 = *wps->dsd.byteptr++ << (PRECISION - 8); - sp->filter6 = 0; - sp->factor = *wps->dsd.byteptr++ & 0xff; - sp->factor |= (*wps->dsd.byteptr++ << 8) & 0xff00; - sp->factor = (sp->factor << 16) >> 16; - } - - wps->dsd.high = 0xffffffff; - wps->dsd.low = 0x0; - - for (i = 4; i--;) - wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; - - wps->dsd.ready = 1; - - return TRUE; -} - -static int decode_high (WavpackStream *wps, int32_t *output, int sample_count) -{ - int total_samples = sample_count, stereo = (wps->wphdr.flags & MONO_DATA) ? 0 : 1; - DSDfilters *sp = wps->dsd.filters; - - while (total_samples--) { - int bitcount = 8; - - sp [0].value = sp [0].filter1 - sp [0].filter5 + ((sp [0].filter6 * sp [0].factor) >> 2); - - if (stereo) - sp [1].value = sp [1].filter1 - sp [1].filter5 + ((sp [1].filter6 * sp [1].factor) >> 2); - - while (bitcount--) { - int32_t *pp = wps->dsd.ptable + ((sp [0].value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK); - uint32_t split = wps->dsd.low + ((wps->dsd.high - wps->dsd.low) >> 8) * (*pp >> 16); - - if (wps->dsd.value <= split) { - wps->dsd.high = split; - *pp += (UP - *pp) >> DECAY; - sp [0].filter0 = -1; - } - else { - wps->dsd.low = split + 1; - *pp += (DOWN - *pp) >> DECAY; - sp [0].filter0 = 0; - } - - while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) { - wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; - wps->dsd.high = (wps->dsd.high << 8) | 0xff; - wps->dsd.low <<= 8; - } - - sp [0].value += sp [0].filter6 << 3; - sp [0].byte = (sp [0].byte << 1) | (sp [0].filter0 & 1); - sp [0].factor += (((sp [0].value ^ sp [0].filter0) >> 31) | 1) & ((sp [0].value ^ (sp [0].value - (sp [0].filter6 << 4))) >> 31); - sp [0].filter1 += ((sp [0].filter0 & VALUE_ONE) - sp [0].filter1) >> 6; - sp [0].filter2 += ((sp [0].filter0 & VALUE_ONE) - sp [0].filter2) >> 4; - sp [0].filter3 += (sp [0].filter2 - sp [0].filter3) >> 4; - sp [0].filter4 += (sp [0].filter3 - sp [0].filter4) >> 4; - sp [0].value = (sp [0].filter4 - sp [0].filter5) >> 4; - sp [0].filter5 += sp [0].value; - sp [0].filter6 += (sp [0].value - sp [0].filter6) >> 3; - sp [0].value = sp [0].filter1 - sp [0].filter5 + ((sp [0].filter6 * sp [0].factor) >> 2); - - if (!stereo) - continue; - - pp = wps->dsd.ptable + ((sp [1].value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK); - split = wps->dsd.low + ((wps->dsd.high - wps->dsd.low) >> 8) * (*pp >> 16); - - if (wps->dsd.value <= split) { - wps->dsd.high = split; - *pp += (UP - *pp) >> DECAY; - sp [1].filter0 = -1; - } - else { - wps->dsd.low = split + 1; - *pp += (DOWN - *pp) >> DECAY; - sp [1].filter0 = 0; - } - - while (DSD_BYTE_READY (wps->dsd.high, wps->dsd.low) && wps->dsd.byteptr < wps->dsd.endptr) { - wps->dsd.value = (wps->dsd.value << 8) | *wps->dsd.byteptr++; - wps->dsd.high = (wps->dsd.high << 8) | 0xff; - wps->dsd.low <<= 8; - } - - sp [1].value += sp [1].filter6 << 3; - sp [1].byte = (sp [1].byte << 1) | (sp [1].filter0 & 1); - sp [1].factor += (((sp [1].value ^ sp [1].filter0) >> 31) | 1) & ((sp [1].value ^ (sp [1].value - (sp [1].filter6 << 4))) >> 31); - sp [1].filter1 += ((sp [1].filter0 & VALUE_ONE) - sp [1].filter1) >> 6; - sp [1].filter2 += ((sp [1].filter0 & VALUE_ONE) - sp [1].filter2) >> 4; - sp [1].filter3 += (sp [1].filter2 - sp [1].filter3) >> 4; - sp [1].filter4 += (sp [1].filter3 - sp [1].filter4) >> 4; - sp [1].value = (sp [1].filter4 - sp [1].filter5) >> 4; - sp [1].filter5 += sp [1].value; - sp [1].filter6 += (sp [1].value - sp [1].filter6) >> 3; - sp [1].value = sp [1].filter1 - sp [1].filter5 + ((sp [1].filter6 * sp [1].factor) >> 2); - } - - wps->crc += (wps->crc << 1) + (*output++ = sp [0].byte & 0xff); - sp [0].factor -= (sp [0].factor + 512) >> 10; - - if (stereo) { - wps->crc += (wps->crc << 1) + (*output++ = wps->dsd.filters [1].byte & 0xff); - wps->dsd.filters [1].factor -= (wps->dsd.filters [1].factor + 512) >> 10; - } - } - - return sample_count; -} - -/*------------------------------------------------------------------------------------------------------------------------*/ - -#if 0 - -// 80 term DSD decimation filter -// < 1 dB down at 20 kHz -// > 108 dB stopband attenuation (fs/16) - -static const int32_t decm_filter [] = { - 4, 17, 56, 147, 336, 693, 1320, 2359, - 4003, 6502, 10170, 15392, 22623, 32389, 45275, 61920, - 82994, 109174, 141119, 179431, 224621, 277068, 336983, 404373, - 479004, 560384, 647741, 740025, 835917, 933849, 1032042, 1128551, - 1221329, 1308290, 1387386, 1456680, 1514425, 1559128, 1589610, 1605059, - 1605059, 1589610, 1559128, 1514425, 1456680, 1387386, 1308290, 1221329, - 1128551, 1032042, 933849, 835917, 740025, 647741, 560384, 479004, - 404373, 336983, 277068, 224621, 179431, 141119, 109174, 82994, - 61920, 45275, 32389, 22623, 15392, 10170, 6502, 4003, - 2359, 1320, 693, 336, 147, 56, 17, 4, -}; - -#define NUM_FILTER_TERMS 80 - -#else - -// 56 term decimation filter -// < 0.5 dB down at 20 kHz -// > 100 dB stopband attenuation (fs/12) - -static const int32_t decm_filter [] = { - 4, 17, 56, 147, 336, 692, 1315, 2337, - 3926, 6281, 9631, 14216, 20275, 28021, 37619, 49155, - 62616, 77870, 94649, 112551, 131049, 149507, 167220, 183448, - 197472, 208636, 216402, 220385, 220385, 216402, 208636, 197472, - 183448, 167220, 149507, 131049, 112551, 94649, 77870, 62616, - 49155, 37619, 28021, 20275, 14216, 9631, 6281, 3926, - 2337, 1315, 692, 336, 147, 56, 17, 4, -}; - -#define NUM_FILTER_TERMS 56 - -#endif - -#define HISTORY_BYTES ((NUM_FILTER_TERMS+7)/8) - -typedef struct { - unsigned char delay [HISTORY_BYTES]; -} DecimationChannel; - -typedef struct { - int32_t conv_tables [HISTORY_BYTES] [256]; - DecimationChannel *chans; - int num_channels; -} DecimationContext; - -void *decimate_dsd_init (int num_channels) -{ - DecimationContext *context = (DecimationContext *)malloc (sizeof (DecimationContext)); - double filter_sum = 0, filter_scale; - int skipped_terms, i, j; - - if (!context) - return context; - - memset (context, 0, sizeof (*context)); - context->num_channels = num_channels; - context->chans = (DecimationChannel *)malloc (num_channels * sizeof (DecimationChannel)); - - if (!context->chans) { - free (context); - return NULL; - } - - for (i = 0; i < NUM_FILTER_TERMS; ++i) - filter_sum += decm_filter [i]; - - filter_scale = ((1 << 23) - 1) / filter_sum * 16.0; - // fprintf (stderr, "convolution, %d terms, %f sum, %f scale\n", NUM_FILTER_TERMS, filter_sum, filter_scale); - - for (skipped_terms = i = 0; i < NUM_FILTER_TERMS; ++i) { - int scaled_term = (int) floor (decm_filter [i] * filter_scale + 0.5); - - if (scaled_term) { - for (j = 0; j < 256; ++j) - if (j & (0x80 >> (i & 0x7))) - context->conv_tables [i >> 3] [j] += scaled_term; - else - context->conv_tables [i >> 3] [j] -= scaled_term; - } - else - skipped_terms++; - } - - // fprintf (stderr, "%d terms skipped\n", skipped_terms); - - decimate_dsd_reset (context); - - return context; -} - -void decimate_dsd_reset (void *decimate_context) -{ - DecimationContext *context = (DecimationContext *) decimate_context; - int chan = 0, i; - - if (!context) - return; - - for (chan = 0; chan < context->num_channels; ++chan) - for (i = 0; i < HISTORY_BYTES; ++i) - context->chans [chan].delay [i] = 0x55; -} - -void decimate_dsd_run (void *decimate_context, int32_t *samples, int num_samples) -{ - DecimationContext *context = (DecimationContext *) decimate_context; - int chan = 0; - - if (!context) - return; - - while (num_samples) { - DecimationChannel *sp = context->chans + chan; - int sum = 0; - -#if (HISTORY_BYTES == 10) - sum += context->conv_tables [0] [sp->delay [0] = sp->delay [1]]; - sum += context->conv_tables [1] [sp->delay [1] = sp->delay [2]]; - sum += context->conv_tables [2] [sp->delay [2] = sp->delay [3]]; - sum += context->conv_tables [3] [sp->delay [3] = sp->delay [4]]; - sum += context->conv_tables [4] [sp->delay [4] = sp->delay [5]]; - sum += context->conv_tables [5] [sp->delay [5] = sp->delay [6]]; - sum += context->conv_tables [6] [sp->delay [6] = sp->delay [7]]; - sum += context->conv_tables [7] [sp->delay [7] = sp->delay [8]]; - sum += context->conv_tables [8] [sp->delay [8] = sp->delay [9]]; - sum += context->conv_tables [9] [sp->delay [9] = *samples]; -#elif (HISTORY_BYTES == 7) - sum += context->conv_tables [0] [sp->delay [0] = sp->delay [1]]; - sum += context->conv_tables [1] [sp->delay [1] = sp->delay [2]]; - sum += context->conv_tables [2] [sp->delay [2] = sp->delay [3]]; - sum += context->conv_tables [3] [sp->delay [3] = sp->delay [4]]; - sum += context->conv_tables [4] [sp->delay [4] = sp->delay [5]]; - sum += context->conv_tables [5] [sp->delay [5] = sp->delay [6]]; - sum += context->conv_tables [6] [sp->delay [6] = *samples]; -#else - int i; - - for (i = 0; i < HISTORY_BYTES-1; ++i) - sum += context->conv_tables [i] [sp->delay [i] = sp->delay [i+1]]; - - sum += context->conv_tables [i] [sp->delay [i] = *samples]; -#endif - - *samples++ = sum >> 4; - - if (++chan == context->num_channels) { - num_samples--; - chan = 0; - } - } -} - -void decimate_dsd_destroy (void *decimate_context) -{ - DecimationContext *context = (DecimationContext *) decimate_context; - - if (!context) - return; - - if (context->chans) - free (context->chans); - - free (context); -} - -#endif // ENABLE_DSD diff --git a/Frameworks/WavPack/Files/unpack_floats.c b/Frameworks/WavPack/Files/unpack_floats.c deleted file mode 100644 index cc045ddc5..000000000 --- a/Frameworks/WavPack/Files/unpack_floats.c +++ /dev/null @@ -1,134 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// unpack_floats.c - -// This module deals with the restoration of floating-point data. Note that no -// floating point math is involved here...the values are only processed with -// the macros that directly access the mantissa, exponent, and sign fields. -// That's why we use the f32 type instead of the built-in float type. - -#include - -#include "wavpack_local.h" - -static void float_values_nowvx (WavpackStream *wps, int32_t *values, int32_t num_values); - -void float_values (WavpackStream *wps, int32_t *values, int32_t num_values) -{ - uint32_t crc = wps->crc_x; - - if (!bs_is_open (&wps->wvxbits)) { - float_values_nowvx (wps, values, num_values); - return; - } - - while (num_values--) { - int shift_count = 0, exp = wps->float_max_exp; - f32 outval = 0; - uint32_t temp; - - if (*values == 0) { - if (wps->float_flags & FLOAT_ZEROS_SENT) { - if (getbit (&wps->wvxbits)) { - getbits (&temp, 23, &wps->wvxbits); - set_mantissa (outval, temp); - - if (exp >= 25) { - getbits (&temp, 8, &wps->wvxbits); - set_exponent (outval, temp); - } - - set_sign (outval, getbit (&wps->wvxbits)); - } - else if (wps->float_flags & FLOAT_NEG_ZEROS) - set_sign (outval, getbit (&wps->wvxbits)); - } - } - else { - *values <<= wps->float_shift; - - if (*values < 0) { - *values = -*values; - set_sign (outval, 1); - } - - if (*values == 0x1000000) { - if (getbit (&wps->wvxbits)) { - getbits (&temp, 23, &wps->wvxbits); - set_mantissa (outval, temp); - } - - set_exponent (outval, 255); - } - else { - if (exp) - while (!(*values & 0x800000) && --exp) { - shift_count++; - *values <<= 1; - } - - if (shift_count) { - if ((wps->float_flags & FLOAT_SHIFT_ONES) || - ((wps->float_flags & FLOAT_SHIFT_SAME) && getbit (&wps->wvxbits))) - *values |= ((1 << shift_count) - 1); - else if (wps->float_flags & FLOAT_SHIFT_SENT) { - getbits (&temp, shift_count, &wps->wvxbits); - *values |= temp & ((1 << shift_count) - 1); - } - } - - set_mantissa (outval, *values); - set_exponent (outval, exp); - } - } - - crc = crc * 27 + get_mantissa (outval) * 9 + get_exponent (outval) * 3 + get_sign (outval); - * (f32 *) values++ = outval; - } - - wps->crc_x = crc; -} - -static void float_values_nowvx (WavpackStream *wps, int32_t *values, int32_t num_values) -{ - while (num_values--) { - int shift_count = 0, exp = wps->float_max_exp; - f32 outval = 0; - - if (*values) { - *values <<= wps->float_shift; - - if (*values < 0) { - *values = -*values; - set_sign (outval, 1); - } - - if (*values >= 0x1000000) { - while (*values & 0xf000000) { - *values >>= 1; - ++exp; - } - } - else if (exp) { - while (!(*values & 0x800000) && --exp) { - shift_count++; - *values <<= 1; - } - - if (shift_count && (wps->float_flags & FLOAT_SHIFT_ONES)) - *values |= ((1 << shift_count) - 1); - } - - set_mantissa (outval, *values); - set_exponent (outval, exp); - } - - * (f32 *) values++ = outval; - } -} diff --git a/Frameworks/WavPack/Files/unpack_seek.c b/Frameworks/WavPack/Files/unpack_seek.c deleted file mode 100644 index 20592e72a..000000000 --- a/Frameworks/WavPack/Files/unpack_seek.c +++ /dev/null @@ -1,387 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// unpack_seek.c - -// This module provides the high-level API for unpacking audio data from -// a specific sample index (i.e., seeking). - -#ifndef NO_SEEKING - -#include -#include - -#include "wavpack_local.h" - -///////////////////////////// executable code //////////////////////////////// - -static int64_t find_sample (WavpackContext *wpc, void *infile, int64_t header_pos, int64_t sample); - -// Seek to the specified sample index, returning TRUE on success. Note that -// files generated with version 4.0 or newer will seek almost immediately. -// Older files can take quite long if required to seek through unplayed -// portions of the file, but will create a seek map so that reverse seeks -// (or forward seeks to already scanned areas) will be very fast. After a -// FALSE return the file should not be accessed again (other than to close -// it); this is a fatal error. - -int WavpackSeekSample (WavpackContext *wpc, uint32_t sample) -{ - return WavpackSeekSample64 (wpc, sample); -} - -int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample) -{ - WavpackStream *wps = wpc->streams ? wpc->streams [wpc->current_stream = 0] : NULL; - uint32_t bcount, samples_to_skip, samples_to_decode = 0; - int32_t *buffer; - - if (wpc->total_samples == -1 || sample >= wpc->total_samples || - !wpc->reader->can_seek (wpc->wv_in) || (wpc->open_flags & OPEN_STREAMING) || - (wpc->wvc_flag && !wpc->reader->can_seek (wpc->wvc_in))) - return FALSE; - -#ifdef ENABLE_LEGACY - if (wpc->stream3) - return seek_sample3 (wpc, (uint32_t) sample); -#endif - -#ifdef ENABLE_DSD - if (wpc->decimation_context) { // the decimation code needs some context to be sample accurate - if (sample < 16) { - samples_to_decode = (uint32_t) sample; - sample = 0; - } - else { - samples_to_decode = 16; - sample -= 16; - } - } -#endif - - if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) || sample < GET_BLOCK_INDEX (wps->wphdr) || - sample >= GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples) { - - free_streams (wpc); - wpc->filepos = find_sample (wpc, wpc->wv_in, wpc->filepos, sample); - - if (wpc->filepos == -1) - return FALSE; - - if (wpc->wvc_flag) { - wpc->file2pos = find_sample (wpc, wpc->wvc_in, 0, sample); - - if (wpc->file2pos == -1) - return FALSE; - } - } - - if (!wps->blockbuff) { - wpc->reader->set_pos_abs (wpc->wv_in, wpc->filepos); - wpc->reader->read_bytes (wpc->wv_in, &wps->wphdr, sizeof (WavpackHeader)); - WavpackLittleEndianToNative (&wps->wphdr, WavpackHeaderFormat); - - if ((wps->wphdr.ckSize & 1) || wps->wphdr.ckSize < 24 || wps->wphdr.ckSize >= 1024 * 1024) { - free_streams (wpc); - return FALSE; - } - - wps->blockbuff = (unsigned char *)malloc (wps->wphdr.ckSize + 8); - memcpy (wps->blockbuff, &wps->wphdr, sizeof (WavpackHeader)); - - if (wpc->reader->read_bytes (wpc->wv_in, wps->blockbuff + sizeof (WavpackHeader), wps->wphdr.ckSize - 24) != - wps->wphdr.ckSize - 24) { - free_streams (wpc); - return FALSE; - } - - // render corrupt blocks harmless - if (!WavpackVerifySingleBlock (wps->blockbuff, !(wpc->open_flags & OPEN_NO_CHECKSUM))) { - wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; - wps->wphdr.block_samples = 0; - memcpy (wps->blockbuff, &wps->wphdr, 32); - } - - SET_BLOCK_INDEX (wps->wphdr, GET_BLOCK_INDEX (wps->wphdr) - wpc->initial_index); - memcpy (wps->blockbuff, &wps->wphdr, sizeof (WavpackHeader)); - wps->init_done = FALSE; - - if (wpc->wvc_flag) { - wpc->reader->set_pos_abs (wpc->wvc_in, wpc->file2pos); - wpc->reader->read_bytes (wpc->wvc_in, &wps->wphdr, sizeof (WavpackHeader)); - WavpackLittleEndianToNative (&wps->wphdr, WavpackHeaderFormat); - - if ((wps->wphdr.ckSize & 1) || wps->wphdr.ckSize < 24 || wps->wphdr.ckSize >= 1024 * 1024) { - free_streams (wpc); - return FALSE; - } - - wps->block2buff = (unsigned char *)malloc (wps->wphdr.ckSize + 8); - memcpy (wps->block2buff, &wps->wphdr, sizeof (WavpackHeader)); - - if (wpc->reader->read_bytes (wpc->wvc_in, wps->block2buff + sizeof (WavpackHeader), wps->wphdr.ckSize - 24) != - wps->wphdr.ckSize - 24) { - free_streams (wpc); - return FALSE; - } - - // render corrupt blocks harmless - if (!WavpackVerifySingleBlock (wps->block2buff, !(wpc->open_flags & OPEN_NO_CHECKSUM))) { - wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; - wps->wphdr.block_samples = 0; - memcpy (wps->block2buff, &wps->wphdr, 32); - } - - SET_BLOCK_INDEX (wps->wphdr, GET_BLOCK_INDEX (wps->wphdr) - wpc->initial_index); - memcpy (wps->block2buff, &wps->wphdr, sizeof (WavpackHeader)); - } - - if (!wps->init_done && !unpack_init (wpc)) { - free_streams (wpc); - return FALSE; - } - - wps->init_done = TRUE; - } - - while (!wpc->reduced_channels && !(wps->wphdr.flags & FINAL_BLOCK)) { - if (++wpc->current_stream == wpc->num_streams) { - - if (wpc->num_streams == wpc->max_streams) { - free_streams (wpc); - return FALSE; - } - - wpc->streams = (WavpackStream **)realloc (wpc->streams, (wpc->num_streams + 1) * sizeof (wpc->streams [0])); - wps = wpc->streams [wpc->num_streams++] = (WavpackStream *)malloc (sizeof (WavpackStream)); - CLEAR (*wps); - bcount = read_next_header (wpc->reader, wpc->wv_in, &wps->wphdr); - - if (bcount == (uint32_t) -1) { - free_streams (wpc); - return FALSE; - } - - wps->blockbuff = (unsigned char *)malloc (wps->wphdr.ckSize + 8); - memcpy (wps->blockbuff, &wps->wphdr, 32); - - if (wpc->reader->read_bytes (wpc->wv_in, wps->blockbuff + 32, wps->wphdr.ckSize - 24) != - wps->wphdr.ckSize - 24) { - free_streams (wpc); - return FALSE; - } - - // render corrupt blocks harmless - if (!WavpackVerifySingleBlock (wps->blockbuff, !(wpc->open_flags & OPEN_NO_CHECKSUM))) { - wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; - wps->wphdr.block_samples = 0; - memcpy (wps->blockbuff, &wps->wphdr, 32); - } - - wps->init_done = FALSE; - - if (wpc->wvc_flag && !read_wvc_block (wpc)) { - free_streams (wpc); - return FALSE; - } - - if (!wps->init_done && !unpack_init (wpc)) { - free_streams (wpc); - return FALSE; - } - - wps->init_done = TRUE; - } - else - wps = wpc->streams [wpc->current_stream]; - } - - if (sample < wps->sample_index) { - for (wpc->current_stream = 0; wpc->current_stream < wpc->num_streams; wpc->current_stream++) - if (!unpack_init (wpc)) - return FALSE; - else - wpc->streams [wpc->current_stream]->init_done = TRUE; - } - - samples_to_skip = (uint32_t) (sample - wps->sample_index); - - if (samples_to_skip > 131072) { - free_streams (wpc); - return FALSE; - } - - if (samples_to_skip) { - buffer = (int32_t *)malloc (samples_to_skip * 8); - - for (wpc->current_stream = 0; wpc->current_stream < wpc->num_streams; wpc->current_stream++) -#ifdef ENABLE_DSD - if (wpc->streams [wpc->current_stream]->wphdr.flags & DSD_FLAG) - unpack_dsd_samples (wpc, buffer, samples_to_skip); - else -#endif - unpack_samples (wpc, buffer, samples_to_skip); - - free (buffer); - } - - wpc->current_stream = 0; - -#ifdef ENABLE_DSD - if (wpc->decimation_context) - decimate_dsd_reset (wpc->decimation_context); - - if (samples_to_decode) { - buffer = (int32_t *)malloc (samples_to_decode * wpc->config.num_channels * 4); - - if (buffer) { - WavpackUnpackSamples (wpc, buffer, samples_to_decode); - free (buffer); - } - } -#endif - - return TRUE; -} - -// Find a valid WavPack header, searching either from the current file position -// (or from the specified position if not -1) and store it (endian corrected) -// at the specified pointer. The return value is the exact file position of the -// header, although we may have actually read past it. Because this function -// is used for seeking to a specific audio sample, it only considers blocks -// that contain audio samples for the initial stream to be valid. - -#define BUFSIZE 4096 - -static int64_t find_header (WavpackStreamReader64 *reader, void *id, int64_t filepos, WavpackHeader *wphdr) -{ - unsigned char *buffer = (unsigned char *)malloc (BUFSIZE), *sp = buffer, *ep = buffer; - - if (filepos != (uint32_t) -1 && reader->set_pos_abs (id, filepos)) { - free (buffer); - return -1; - } - - while (1) { - int bleft; - - if (sp < ep) { - bleft = (int)(ep - sp); - memmove (buffer, sp, bleft); - ep -= (sp - buffer); - sp = buffer; - } - else { - if (sp > ep) - if (reader->set_pos_rel (id, (int32_t)(sp - ep), SEEK_CUR)) { - free (buffer); - return -1; - } - - sp = ep = buffer; - bleft = 0; - } - - ep += reader->read_bytes (id, ep, BUFSIZE - bleft); - - if (ep - sp < 32) { - free (buffer); - return -1; - } - - while (sp + 32 <= ep) - if (*sp++ == 'w' && *sp == 'v' && *++sp == 'p' && *++sp == 'k' && - !(*++sp & 1) && sp [2] < 16 && !sp [3] && (sp [2] || sp [1] || *sp >= 24) && sp [5] == 4 && - sp [4] >= (MIN_STREAM_VERS & 0xff) && sp [4] <= (MAX_STREAM_VERS & 0xff) && sp [18] < 3 && !sp [19]) { - memcpy (wphdr, sp - 4, sizeof (*wphdr)); - WavpackLittleEndianToNative (wphdr, WavpackHeaderFormat); - - if (wphdr->block_samples && (wphdr->flags & INITIAL_BLOCK)) { - free (buffer); - return reader->get_pos (id) - (ep - sp + 4); - } - - if (wphdr->ckSize > 1024) - sp += wphdr->ckSize - 1024; - } - } -} - -// Find the WavPack block that contains the specified sample. If "header_pos" -// is zero, then no information is assumed except the total number of samples -// in the file and its size in bytes. If "header_pos" is non-zero then we -// assume that it is the file position of the valid header image contained in -// the first stream and we can limit our search to either the portion above -// or below that point. If a .wvc file is being used, then this must be called -// for that file also. - -static int64_t find_sample (WavpackContext *wpc, void *infile, int64_t header_pos, int64_t sample) -{ - WavpackStream *wps = wpc->streams [wpc->current_stream]; - int64_t file_pos1 = 0, file_pos2 = wpc->reader->get_length (infile); - int64_t sample_pos1 = 0, sample_pos2 = wpc->total_samples; - double ratio = 0.96; - int file_skip = 0; - - if (sample >= wpc->total_samples) - return -1; - - if (header_pos && wps->wphdr.block_samples) { - if (GET_BLOCK_INDEX (wps->wphdr) > sample) { - sample_pos2 = GET_BLOCK_INDEX (wps->wphdr); - file_pos2 = header_pos; - } - else if (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples <= sample) { - sample_pos1 = GET_BLOCK_INDEX (wps->wphdr); - file_pos1 = header_pos; - } - else - return header_pos; - } - - while (1) { - double bytes_per_sample; - int64_t seek_pos; - - bytes_per_sample = (double) file_pos2 - file_pos1; - bytes_per_sample /= sample_pos2 - sample_pos1; - seek_pos = file_pos1 + (file_skip ? 32 : 0); - seek_pos += (int64_t)(bytes_per_sample * (sample - sample_pos1) * ratio); - seek_pos = find_header (wpc->reader, infile, seek_pos, &wps->wphdr); - - if (seek_pos != (int64_t) -1) - SET_BLOCK_INDEX (wps->wphdr, GET_BLOCK_INDEX (wps->wphdr) - wpc->initial_index); - - if (seek_pos == (int64_t) -1 || seek_pos >= file_pos2) { - if (ratio > 0.0) { - if ((ratio -= 0.24) < 0.0) - ratio = 0.0; - } - else - return -1; - } - else if (GET_BLOCK_INDEX (wps->wphdr) > sample) { - sample_pos2 = GET_BLOCK_INDEX (wps->wphdr); - file_pos2 = seek_pos; - } - else if (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples <= sample) { - - if (seek_pos == file_pos1) - file_skip = 1; - else { - sample_pos1 = GET_BLOCK_INDEX (wps->wphdr); - file_pos1 = seek_pos; - } - } - else - return seek_pos; - } -} - -#endif - diff --git a/Frameworks/WavPack/Files/unpack_utils.c b/Frameworks/WavPack/Files/unpack_utils.c deleted file mode 100644 index ce7d7da9d..000000000 --- a/Frameworks/WavPack/Files/unpack_utils.c +++ /dev/null @@ -1,411 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// unpack_utils.c - -// This module provides the high-level API for unpacking audio data from -// WavPack files. It manages the buffers used to interleave the data passed -// back to the application from the individual streams. The actual audio -// stream decompression is handled in the unpack.c module. - -#include -#include - -#include "wavpack_local.h" - -///////////////////////////// executable code //////////////////////////////// - -// Unpack the specified number of samples from the current file position. -// Note that "samples" here refers to "complete" samples, which would be -// 2 longs for stereo files or even more for multichannel files, so the -// required memory at "buffer" is 4 * samples * num_channels bytes. The -// audio data is returned right-justified in 32-bit longs in the endian -// mode native to the executing processor. So, if the original data was -// 16-bit, then the values returned would be +/-32k. Floating point data -// can also be returned if the source was floating point data (and this -// can be optionally normalized to +/-1.0 by using the appropriate flag -// in the call to WavpackOpenFileInput ()). The actual number of samples -// unpacked is returned, which should be equal to the number requested unless -// the end of fle is encountered or an error occurs. After all samples have -// been unpacked then 0 will be returned. - -uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples) -{ - WavpackStream *wps = wpc->streams ? wpc->streams [wpc->current_stream = 0] : NULL; - int num_channels = wpc->config.num_channels, file_done = FALSE; - uint32_t bcount, samples_unpacked = 0, samples_to_unpack; - int32_t *bptr = buffer; - -#ifdef ENABLE_LEGACY - if (wpc->stream3) - return unpack_samples3 (wpc, buffer, samples); -#endif - - while (samples) { - - // if the current block has no audio, or it's not the first block of a multichannel - // sequence, or the sample we're on is past the last sample in this block...we need - // to free up the streams and read the next block - - if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) || - wps->sample_index >= GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples) { - - int64_t nexthdrpos; - - if (wpc->wrapper_bytes >= MAX_WRAPPER_BYTES) - break; - - free_streams (wpc); - nexthdrpos = wpc->reader->get_pos (wpc->wv_in); - bcount = read_next_header (wpc->reader, wpc->wv_in, &wps->wphdr); - - if (bcount == (uint32_t) -1) - break; - - wpc->filepos = nexthdrpos + bcount; - - // allocate the memory for the entire raw block and read it in - - wps->blockbuff = (unsigned char *)malloc (wps->wphdr.ckSize + 8); - - if (!wps->blockbuff) - break; - - memcpy (wps->blockbuff, &wps->wphdr, 32); - - if (wpc->reader->read_bytes (wpc->wv_in, wps->blockbuff + 32, wps->wphdr.ckSize - 24) != - wps->wphdr.ckSize - 24) { - strcpy (wpc->error_message, "can't read all of last block!"); - wps->wphdr.block_samples = 0; - wps->wphdr.ckSize = 24; - break; - } - - // render corrupt blocks harmless - if (!WavpackVerifySingleBlock (wps->blockbuff, !(wpc->open_flags & OPEN_NO_CHECKSUM))) { - wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; - wps->wphdr.block_samples = 0; - memcpy (wps->blockbuff, &wps->wphdr, 32); - } - - // potentially adjusting block_index must be done AFTER verifying block - - if (wpc->open_flags & OPEN_STREAMING) - SET_BLOCK_INDEX (wps->wphdr, wps->sample_index = 0); - else - SET_BLOCK_INDEX (wps->wphdr, GET_BLOCK_INDEX (wps->wphdr) - wpc->initial_index); - - memcpy (wps->blockbuff, &wps->wphdr, 32); - wps->init_done = FALSE; // we have not yet called unpack_init() for this block - - // if this block has audio, but not the sample index we were expecting, flag an error - - if (wps->wphdr.block_samples && wps->sample_index != GET_BLOCK_INDEX (wps->wphdr)) - wpc->crc_errors++; - - // if this block has audio, and we're in hybrid lossless mode, read the matching wvc block - - if (wps->wphdr.block_samples && wpc->wvc_flag) - read_wvc_block (wpc); - - // if the block does NOT have any audio, call unpack_init() to process non-audio stuff - - if (!wps->wphdr.block_samples) { - if (!wps->init_done && !unpack_init (wpc)) - wpc->crc_errors++; - - wps->init_done = TRUE; - } - } - - // if the current block has no audio, or it's not the first block of a multichannel - // sequence, or the sample we're on is past the last sample in this block...we need - // to loop back and read the next block - - if (!wps->wphdr.block_samples || !(wps->wphdr.flags & INITIAL_BLOCK) || - wps->sample_index >= GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples) - continue; - - // There seems to be some missing data, like a block was corrupted or something. - // If it's not too much data, just fill in with silence here and loop back. - - if (wps->sample_index < GET_BLOCK_INDEX (wps->wphdr)) { - int32_t zvalue = (wps->wphdr.flags & DSD_FLAG) ? 0x55 : 0; - - samples_to_unpack = (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) - wps->sample_index); - - if (!samples_to_unpack || samples_to_unpack > 262144) { - strcpy (wpc->error_message, "discontinuity found, aborting file!"); - wps->wphdr.block_samples = 0; - wps->wphdr.ckSize = 24; - break; - } - - if (samples_to_unpack > samples) - samples_to_unpack = samples; - - wps->sample_index += samples_to_unpack; - samples_unpacked += samples_to_unpack; - samples -= samples_to_unpack; - - samples_to_unpack *= (wpc->reduced_channels ? wpc->reduced_channels : num_channels); - - while (samples_to_unpack--) - *bptr++ = zvalue; - - continue; - } - - // calculate number of samples to process from this block, then initialize the decoder for - // this block if we haven't already - - samples_to_unpack = (uint32_t) (GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index); - - if (samples_to_unpack > samples) - samples_to_unpack = samples; - - if (!wps->init_done && !unpack_init (wpc)) - wpc->crc_errors++; - - wps->init_done = TRUE; - - // if this block is not the final block of a multichannel sequence (and we're not truncating - // to stereo), then enter this conditional block...otherwise we just unpack the samples directly - - if (!wpc->reduced_channels && !(wps->wphdr.flags & FINAL_BLOCK)) { - int32_t *temp_buffer = (int32_t *)malloc (samples_to_unpack * 8), *src, *dst; - int offset = 0; // offset to next channel in sequence (0 to num_channels - 1) - uint32_t samcnt; - - // since we are getting samples from multiple bocks in a multichannel sequence, we must - // allocate a temporary buffer to unpack to so that we can re-interleave the samples - - if (!temp_buffer) - break; - - // loop through all the streams... - - while (1) { - - // if the stream has not been allocated and corresponding block read, do that here... - - if (wpc->current_stream == wpc->num_streams) { - wpc->streams = (WavpackStream **)realloc (wpc->streams, (wpc->num_streams + 1) * sizeof (wpc->streams [0])); - - if (!wpc->streams) - break; - - wps = wpc->streams [wpc->num_streams++] = (WavpackStream *)malloc (sizeof (WavpackStream)); - - if (!wps) - break; - - CLEAR (*wps); - bcount = read_next_header (wpc->reader, wpc->wv_in, &wps->wphdr); - - if (bcount == (uint32_t) -1) { - wpc->streams [0]->wphdr.block_samples = 0; - wpc->streams [0]->wphdr.ckSize = 24; - file_done = TRUE; - break; - } - - wps->blockbuff = (unsigned char *)malloc (wps->wphdr.ckSize + 8); - - if (!wps->blockbuff) - break; - - memcpy (wps->blockbuff, &wps->wphdr, 32); - - if (wpc->reader->read_bytes (wpc->wv_in, wps->blockbuff + 32, wps->wphdr.ckSize - 24) != - wps->wphdr.ckSize - 24) { - wpc->streams [0]->wphdr.block_samples = 0; - wpc->streams [0]->wphdr.ckSize = 24; - file_done = TRUE; - break; - } - - // render corrupt blocks harmless - if (!WavpackVerifySingleBlock (wps->blockbuff, !(wpc->open_flags & OPEN_NO_CHECKSUM))) { - wps->wphdr.ckSize = sizeof (WavpackHeader) - 8; - wps->wphdr.block_samples = 0; - memcpy (wps->blockbuff, &wps->wphdr, 32); - } - - // potentially adjusting block_index must be done AFTER verifying block - - if (wpc->open_flags & OPEN_STREAMING) - SET_BLOCK_INDEX (wps->wphdr, wps->sample_index = 0); - else - SET_BLOCK_INDEX (wps->wphdr, GET_BLOCK_INDEX (wps->wphdr) - wpc->initial_index); - - memcpy (wps->blockbuff, &wps->wphdr, 32); - - // if this block has audio, and we're in hybrid lossless mode, read the matching wvc block - - if (wpc->wvc_flag) - read_wvc_block (wpc); - - // initialize the unpacker for this block - - if (!unpack_init (wpc)) - wpc->crc_errors++; - - wps->init_done = TRUE; - } - else - wps = wpc->streams [wpc->current_stream]; - - // unpack the correct number of samples (either mono or stereo) into the temp buffer - -#ifdef ENABLE_DSD - if (wps->wphdr.flags & DSD_FLAG) - unpack_dsd_samples (wpc, src = temp_buffer, samples_to_unpack); - else -#endif - unpack_samples (wpc, src = temp_buffer, samples_to_unpack); - - samcnt = samples_to_unpack; - dst = bptr + offset; - - // if the block is mono, copy the samples from the single channel into the destination - // using num_channels as the stride - - if (wps->wphdr.flags & MONO_FLAG) { - while (samcnt--) { - dst [0] = *src++; - dst += num_channels; - } - - offset++; - } - - // if the block is stereo, and we don't have room for two more channels, just copy one - // and flag an error - - else if (offset == num_channels - 1) { - while (samcnt--) { - dst [0] = src [0]; - dst += num_channels; - src += 2; - } - - wpc->crc_errors++; - offset++; - } - - // otherwise copy the stereo samples into the destination - - else { - while (samcnt--) { - dst [0] = *src++; - dst [1] = *src++; - dst += num_channels; - } - - offset += 2; - } - - // check several clues that we're done with this set of blocks and exit if we are; else do next stream - - if ((wps->wphdr.flags & FINAL_BLOCK) || wpc->current_stream == wpc->max_streams - 1 || offset == num_channels) - break; - else - wpc->current_stream++; - } - - // if we didn't get all the channels we expected, mute the buffer and flag an error - - if (offset != num_channels) { - if (wps->wphdr.flags & DSD_FLAG) { - int samples_to_zero = samples_to_unpack * num_channels; - int32_t *zptr = bptr; - - while (samples_to_zero--) - *zptr++ = 0x55; - } - else - memset (bptr, 0, samples_to_unpack * num_channels * 4); - - wpc->crc_errors++; - } - - // go back to the first stream (we're going to leave them all loaded for now because they might have more samples) - // and free the temp buffer - - wps = wpc->streams [wpc->current_stream = 0]; - free (temp_buffer); - } - // catch the error situation where we have only one channel but run into a stereo block - // (this avoids overwriting the caller's buffer) - else if (!(wps->wphdr.flags & MONO_FLAG) && (num_channels == 1 || wpc->reduced_channels == 1)) { - memset (bptr, 0, samples_to_unpack * sizeof (*bptr)); - wps->sample_index += samples_to_unpack; - wpc->crc_errors++; - } -#ifdef ENABLE_DSD - else if (wps->wphdr.flags & DSD_FLAG) - unpack_dsd_samples (wpc, bptr, samples_to_unpack); -#endif - else - unpack_samples (wpc, bptr, samples_to_unpack); - - if (file_done) { - strcpy (wpc->error_message, "can't read all of last block!"); - break; - } - - if (wpc->reduced_channels) - bptr += samples_to_unpack * wpc->reduced_channels; - else - bptr += samples_to_unpack * num_channels; - - samples_unpacked += samples_to_unpack; - samples -= samples_to_unpack; - - // if we just finished a block, check for a calculated crc error - // (and back up the streams a little if possible in case we passed a header) - - if (wps->sample_index == GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples) { - if (check_crc_error (wpc)) { - int32_t *zptr = bptr, zvalue = (wps->wphdr.flags & DSD_FLAG) ? 0x55 : 0; - uint32_t samples_to_zero = wps->wphdr.block_samples; - - if (samples_to_zero > samples_to_unpack) - samples_to_zero = samples_to_unpack; - - samples_to_zero *= (wpc->reduced_channels ? wpc->reduced_channels : num_channels); - - while (samples_to_zero--) - *--zptr = zvalue; - - if (wps->blockbuff && wpc->reader->can_seek (wpc->wv_in)) { - int32_t rseek = ((WavpackHeader *) wps->blockbuff)->ckSize / 3; - wpc->reader->set_pos_rel (wpc->wv_in, (rseek > 16384) ? -16384 : -rseek, SEEK_CUR); - } - - if (wpc->wvc_flag && wps->block2buff && wpc->reader->can_seek (wpc->wvc_in)) { - int32_t rseek = ((WavpackHeader *) wps->block2buff)->ckSize / 3; - wpc->reader->set_pos_rel (wpc->wvc_in, (rseek > 16384) ? -16384 : -rseek, SEEK_CUR); - } - - wpc->crc_errors++; - } - } - - if (wpc->total_samples != -1 && wps->sample_index == wpc->total_samples) - break; - } - -#ifdef ENABLE_DSD - if (wpc->decimation_context) - decimate_dsd_run (wpc->decimation_context, buffer, samples_unpacked); -#endif - - return samples_unpacked; -} diff --git a/Frameworks/WavPack/Files/utils.c b/Frameworks/WavPack/Files/utils.c deleted file mode 100644 index d59bad0bc..000000000 --- a/Frameworks/WavPack/Files/utils.c +++ /dev/null @@ -1,770 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2006 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// utils.c - -// This module provides general purpose utilities for the WavPack command-line -// utilities and the self-extraction module. - -#if defined(_WIN32) -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#elif defined(__GNUC__) || defined(__sun) -#include -#include -#endif - -#include -#include -#include -#include -#include - -#include "wavpack.h" -#include "utils.h" - -#ifdef _WIN32 -#include "win32_unicode_support.h" -#define fprintf fprintf_utf8 -#define fputs fputs_utf8 -#define remove(f) unlink_utf8(f) -#endif - -#ifdef _WIN32 - -int copy_timestamp (const char *src_filename, const char *dst_filename) -{ - wchar_t *src_filename_utf16 = utf8_to_utf16(src_filename); - wchar_t *dst_filename_utf16 = utf8_to_utf16(dst_filename); - FILETIME last_modified; - HANDLE src, dst; - int res = TRUE; - - if (*src_filename == '-' || *dst_filename == '-') - return res; - - if (!src_filename_utf16 || !dst_filename_utf16) - return FALSE; - - src = CreateFileW (src_filename_utf16, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); - - dst = CreateFileW (dst_filename_utf16, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, - OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); - - if (src == INVALID_HANDLE_VALUE || dst == INVALID_HANDLE_VALUE || - !GetFileTime (src, NULL, NULL, &last_modified) || - !SetFileTime (dst, NULL, NULL, &last_modified)) - res = FALSE; - - if (src != INVALID_HANDLE_VALUE) - CloseHandle (src); - - if (dst != INVALID_HANDLE_VALUE) - CloseHandle (dst); - - free (src_filename_utf16); - free (dst_filename_utf16); - - return res; -} - -#else - -#include -#include - -int copy_timestamp(const char *src_filename, const char *dst_filename) -{ - struct stat fileinfo; - struct timeval times[2]; - - if (strcmp(src_filename, "-") == 0 || strcmp(dst_filename, "-") == 0) - return TRUE; - - if (stat(src_filename, &fileinfo)) - return FALSE; /* stat failed */ - - times[0].tv_sec = fileinfo.st_atime; - times[0].tv_usec = 0; - - times[1].tv_sec = fileinfo.st_mtime; - times[1].tv_usec = 0; - - if (utimes(dst_filename, times)) - return FALSE; /* utimes failed */ - - return TRUE; -} - -#endif - -////////////////////////////////////////////////////////////////////////////// -// This function parses a filename (with or without full path) and returns // -// a pointer to the extension (including the "."). If no extension is found // -// then NULL is returned. Extensions with more than 4 letters don't count. // -////////////////////////////////////////////////////////////////////////////// - -#if defined(_WIN32) - -char *filespec_ext (char *filespec) -{ - char *cp = filespec + strlen (filespec); - - while (--cp >= filespec) { - - if (*cp == '\\' || *cp == ':') - return NULL; - - if (*cp == '.') { - if (strlen (cp+1) && strlen (cp+1) <= 4) - return cp; - else - return NULL; - } - } - - return NULL; -} - -#else - -char *filespec_ext (char *filespec) -{ - char *cp = filespec + strlen (filespec); - - while (--cp >= filespec) { - - if (*cp == '/') - return NULL; - - if (*cp == '.') { - if (strlen (cp+1) && strlen (cp+1) <= 4) - return cp; - else - return NULL; - } - } - - return NULL; -} - -#endif - -////////////////////////////////////////////////////////////////////////////// -// This function determines if the specified filespec is a valid pathname. // -// If not, NULL is returned. If it is in the format of a pathname, then the // -// original pointer is returned. If the format is ambiguous, then a lookup // -// is performed to determine if it is in fact a valid path, and if so a "\" // -// is appended so that the pathname can be used and the original pointer is // -// returned. // -////////////////////////////////////////////////////////////////////////////// - -#if (defined(__GNUC__) || defined(__sun)) && !defined(_WIN32) - -char *filespec_path (char *filespec) -{ - char *cp = filespec + strlen (filespec); - glob_t globs; - struct stat fstats; - - if (cp == filespec || filespec_wild (filespec)) - return NULL; - - if (*--cp == '/') - return filespec; - - if (*cp == '.' && cp == filespec) - return strcat (filespec, "/"); - - if (glob (filespec, GLOB_MARK|GLOB_NOSORT, NULL, &globs) == 0 && - globs.gl_pathc > 0) - { - /* test if the file is a directory */ - if (stat(globs.gl_pathv[0], &fstats) == 0 && (fstats.st_mode & S_IFDIR)) { - filespec[0] = '\0'; - strcat (filespec, globs.gl_pathv[0]); - globfree(&globs); - return filespec; - } - } - globfree(&globs); - - return NULL; -} - -#else - -char *filespec_path (char *filespec) -{ - char *cp = filespec + strlen (filespec); - struct _wfinddata_t wfinddata; - wchar_t *filespec_utf16; - intptr_t file; - - if (cp == filespec || filespec_wild (filespec)) - return NULL; - - --cp; - - if (*cp == '\\' || *cp == ':') - return filespec; - - if (*cp == '.' && cp == filespec) - return strcat (filespec, "\\"); - - filespec_utf16 = utf8_to_utf16(filespec); - - if (!filespec_utf16) - return NULL; - - if ((file = _wfindfirst (filespec_utf16, &wfinddata)) != (intptr_t) -1 && - (wfinddata.attrib & _A_SUBDIR)) { - _findclose (file); - free (filespec_utf16); - return strcat (filespec, "\\"); - } - - if (file != -1L) - _findclose(file); - - free (filespec_utf16); - return NULL; -} - -#endif - -////////////////////////////////////////////////////////////////////////////// -// This function returns non-NULL if the specified filename spec has any // -// wildcard characters. // -////////////////////////////////////////////////////////////////////////////// - -char *filespec_wild (char *filespec) -{ - return strpbrk (filespec, "*?"); -} - -////////////////////////////////////////////////////////////////////////////// -// This function parses a filename (with or without full path) and returns // -// a pointer to the actual filename, or NULL if no filename can be found. // -////////////////////////////////////////////////////////////////////////////// - -#if defined(_WIN32) - -char *filespec_name (char *filespec) -{ - char *cp = filespec + strlen (filespec); - - while (--cp >= filespec) { - - if (*cp == '\\' || *cp == ':') - break; - } - - if (strlen (cp + 1)) - return cp + 1; - else - return NULL; -} - -#else - -char *filespec_name (char *filespec) -{ - char *cp = filespec + strlen (filespec); - - while (--cp >= filespec) - if (*cp == '/') - break; - - if (strlen (cp + 1)) - return cp + 1; - else - return NULL; -} - -#endif - -////////////////////////////////////////////////////////////////////////////// -// This function allows the user to type 'y', 'n', or 'a' (with Enter) in // -// response to a system query. The return value is the key typed as // -// lowercase (regardless of the typed case). // -////////////////////////////////////////////////////////////////////////////// - -static int waiting_input; - -char yna (void) -{ - char choice = 0; - int key; - - waiting_input = 1; - - while (1) { -#if defined(_WIN32) - key = _getch (); -#else - key = fgetc(stdin); -#endif - if (key == 3) { - fprintf (stderr, "^C\n"); - exit (1); - } - else if (key == EOF) { - fprintf (stderr, "\r\n"); - exit (1); - } - else if (key == '\r' || key == '\n') { - if (choice) { - fprintf (stderr, "\r\n"); - fflush (stderr); - break; - } - else { - fprintf (stderr, "%c", 7); - fflush (stderr); - } - } - else if (key == 'Y' || key == 'y') { -#ifdef _WIN32 - fprintf (stderr, "%c\b", key); - fflush (stderr); -#endif - choice = 'y'; - } - else if (key == 'N' || key == 'n') { -#ifdef _WIN32 - fprintf (stderr, "%c\b", key); - fflush (stderr); -#endif - choice = 'n'; - } - else if (key == 'A' || key == 'a') { -#ifdef _WIN32 - fprintf (stderr, "%c\b", key); - fflush (stderr); -#endif - choice = 'a'; - } - else { - fprintf (stderr, "%c", 7); - fflush (stderr); - } - } - - waiting_input = 0; - - return choice; -} - -////////////////////////////////////////////////////////////////////////////// -// Display the specified message on the console through stderr. Note that // -// the cursor may start anywhere in the line and all text already on the // -// line is erased. A terminating newline is not needed and function works // -// with printf strings and args. // -////////////////////////////////////////////////////////////////////////////// - -extern int debug_logging_mode; - -#ifdef _WIN32 - -int get_app_path (char *app_path) -{ - static char file_path [MAX_PATH], tried, result; - - HINSTANCE hinstLib; - FARPROC ProcAdd; - - if (tried) { - if (result) - strcpy (app_path, file_path); - - return result; - } - - tried = TRUE; - hinstLib = LoadLibrary ("shell32.dll"); - - if (hinstLib) { - ProcAdd = GetProcAddress (hinstLib, "SHGetFolderPathA"); - - if (ProcAdd && SUCCEEDED ((ProcAdd) (NULL, CSIDL_APPDATA | 0x8000, NULL, 0, file_path))) - result = TRUE; - - if (!result) { - ProcAdd = GetProcAddress (hinstLib, "SHGetSpecialFolderPathA"); - - if (ProcAdd && SUCCEEDED ((ProcAdd) (NULL, file_path, CSIDL_APPDATA, TRUE))) - result = TRUE; - } - - FreeLibrary (hinstLib); - } - - if (!result) { - hinstLib = LoadLibrary ("shfolder.dll"); - - if (hinstLib) { - ProcAdd = GetProcAddress (hinstLib, "SHGetFolderPathA"); - - if (ProcAdd && SUCCEEDED ((ProcAdd) (NULL, CSIDL_APPDATA | 0x8000, NULL, 0, file_path))) - result = TRUE; - - FreeLibrary (hinstLib); - } - } - - if (result) - strcpy (app_path, file_path); - - return result; -} - -void error_line (char *error, ...) -{ - char error_msg [512]; - va_list argptr; - - error_msg [0] = '\r'; - va_start (argptr, error); - vsprintf (error_msg + 1, error, argptr); - va_end (argptr); - fputs (error_msg, stderr); - finish_line (); - - if (debug_logging_mode) { - char file_path [MAX_PATH]; - FILE *error_log = NULL; - - if (get_app_path (file_path)) { - strcat (file_path, "\\WavPack\\wavpack.log"); - error_log = fopen (file_path, "a+"); - - if (!error_log) { - get_app_path (file_path); - strcat (file_path, "\\WavPack"); - - if (CreateDirectory (file_path, NULL)) { - strcat (file_path, "\\wavpack.log"); - error_log = fopen (file_path, "a+"); - } - } - } - - if (!error_log) - error_log = fopen ("c:\\wavpack.log", "a+"); - - if (error_log) { - fputs (error_msg + 1, error_log); - fputc ('\n', error_log); - fclose (error_log); - } - } -} - -#else - -void error_line (char *error, ...) -{ - char error_msg [512]; - va_list argptr; - - error_msg [0] = '\r'; - va_start (argptr, error); - vsprintf (error_msg + 1, error, argptr); - va_end (argptr); - fputs (error_msg, stderr); - finish_line (); -} - -#endif - -////////////////////////////////////////////////////////////////////////////// -// Function to intercept ^C or ^Break typed at the console. // -////////////////////////////////////////////////////////////////////////////// -#if defined(_WIN32) -static int break_flag; - -BOOL WINAPI ctrl_handler (DWORD ctrl) -{ - if (ctrl == CTRL_C_EVENT) { - break_flag = TRUE; - return TRUE; - } - - if (ctrl == CTRL_BREAK_EVENT) { - - if (waiting_input) { - return FALSE; - } - else { - break_flag = TRUE; - return TRUE; - } - } - - return FALSE; -} - -////////////////////////////////////////////////////////////////////////////// -// Function to initialize console for intercepting ^C and ^Break. // -////////////////////////////////////////////////////////////////////////////// - -void setup_break (void) -{ - HANDLE hConIn = GetStdHandle (STD_INPUT_HANDLE); - - SetConsoleMode (hConIn, ENABLE_PROCESSED_INPUT); - FlushConsoleInputBuffer (hConIn); - SetConsoleCtrlHandler (ctrl_handler, TRUE); - break_flag = 0; -} - -////////////////////////////////////////////////////////////////////////////// -// Function to determine whether ^C or ^Break has been issued by user. // -////////////////////////////////////////////////////////////////////////////// - -int check_break (void) -{ - return break_flag; -} - -////////////////////////////////////////////////////////////////////////////// -// Function to clear the stderr console to the end of the current line (and // -// go to the beginning next line). // -////////////////////////////////////////////////////////////////////////////// - -void finish_line (void) -{ - HANDLE hConIn = GetStdHandle (STD_ERROR_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO coninfo; - - if (hConIn && GetConsoleScreenBufferInfo (hConIn, &coninfo) && - (coninfo.dwCursorPosition.X || coninfo.dwCursorPosition.Y)) { - unsigned char spaces = coninfo.dwSize.X - coninfo.dwCursorPosition.X; - - while (spaces--) - fputc (' ', stderr); - } - else - fprintf (stderr, " \n"); - - fflush (stderr); -} -#else -////////////////////////////////////////////////////////////////////////////// -// Function to clear the stderr console to the end of the current line (and // -// go to the beginning next line). // -////////////////////////////////////////////////////////////////////////////// - -void finish_line (void) -{ - fprintf (stderr, " \n"); - fflush (stderr); -} - -////////////////////////////////////////////////////////////////////////////// -// Function to initialize console for intercepting ^C and ^Break. // -////////////////////////////////////////////////////////////////////////////// - -#include - -static int break_flag; - -static void int_handler(int s) -{ - break_flag = 1; -} - -void setup_break (void) -{ - struct sigaction sigIntHandler; - - break_flag = 0; - sigIntHandler.sa_handler = int_handler; - sigemptyset (&sigIntHandler.sa_mask); - sigIntHandler.sa_flags = 0; - sigaction (SIGINT, &sigIntHandler, NULL); -} - -////////////////////////////////////////////////////////////////////////////// -// Function to determine whether ^C or ^Break has been issued by user. // -////////////////////////////////////////////////////////////////////////////// - -int check_break (void) -{ - return break_flag; -} - -#endif - -//////////////////////////// File I/O Wrapper //////////////////////////////// - -int DoReadFile (FILE *hFile, void *lpBuffer, uint32_t nNumberOfBytesToRead, uint32_t *lpNumberOfBytesRead) -{ - uint32_t bcount; - - *lpNumberOfBytesRead = 0; - - while (nNumberOfBytesToRead) { - bcount = (uint32_t) fread ((unsigned char *) lpBuffer + *lpNumberOfBytesRead, 1, nNumberOfBytesToRead, hFile); - - if (bcount) { - *lpNumberOfBytesRead += bcount; - nNumberOfBytesToRead -= bcount; - } - else - break; - } - - return !ferror (hFile); -} - -int DoWriteFile (FILE *hFile, void *lpBuffer, uint32_t nNumberOfBytesToWrite, uint32_t *lpNumberOfBytesWritten) -{ - uint32_t bcount; - - *lpNumberOfBytesWritten = 0; - - while (nNumberOfBytesToWrite) { - bcount = (uint32_t) fwrite ((unsigned char *) lpBuffer + *lpNumberOfBytesWritten, 1, nNumberOfBytesToWrite, hFile); - - if (bcount) { - *lpNumberOfBytesWritten += bcount; - nNumberOfBytesToWrite -= bcount; - } - else - break; - } - - return !ferror (hFile); -} - -#ifdef _WIN32 - -int64_t DoGetFileSize (FILE *hFile) -{ - LARGE_INTEGER Size; - HANDLE fHandle; - - if (hFile == NULL) - return 0; - - fHandle = (HANDLE)_get_osfhandle(_fileno(hFile)); - if (fHandle == INVALID_HANDLE_VALUE) - return 0; - - Size.u.LowPart = GetFileSize(fHandle, &Size.u.HighPart); - - if (Size.u.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR) - return 0; - - return (int64_t)Size.QuadPart; -} - -int64_t DoGetFilePosition (FILE *hFile) -{ - return _ftelli64 (hFile); -} - -int DoSetFilePositionAbsolute (FILE *hFile, int64_t pos) -{ - return _fseeki64 (hFile, pos, SEEK_SET); -} - -int DoSetFilePositionRelative (FILE *hFile, int64_t pos, int mode) -{ - return _fseeki64 (hFile, pos, mode); -} - -#else - -int64_t DoGetFileSize (FILE *hFile) -{ - struct stat statbuf; - - if (!hFile || fstat (fileno (hFile), &statbuf) || !S_ISREG(statbuf.st_mode)) - return 0; - - return (int64_t) statbuf.st_size; -} - -int64_t DoGetFilePosition (FILE *hFile) -{ - return ftell (hFile); -} - -int DoSetFilePositionAbsolute (FILE *hFile, int64_t pos) -{ - return fseek (hFile, pos, SEEK_SET); -} - -int DoSetFilePositionRelative (FILE *hFile, int64_t pos, int mode) -{ - return fseek (hFile, pos, mode); -} - -#endif - -// if ungetc() is not available, a seek of -1 is fine also because we do not -// change the byte read. - -int DoUngetc (int c, FILE *hFile) -{ - return ungetc (c, hFile); -} - -int DoCloseHandle (FILE *hFile) -{ - return hFile ? !fclose (hFile) : 0; -} - -int DoTruncateFile (FILE *hFile) -{ - if (hFile) { - fflush (hFile); -#if defined(_WIN32) - return !_chsize (_fileno (hFile), 0); -#else - return !ftruncate(fileno (hFile), 0); -#endif - } - - return 0; -} - -int DoDeleteFile (char *filename) -{ - return filename ? !remove (filename) : 0; -} - -///////////////////////////////////////////////////////////////////////////////// -// Function to set the name of the console window. This is very handy for // -// displaying progress of batch operations with the console window minimized. // -///////////////////////////////////////////////////////////////////////////////// - -#ifdef _WIN32 - -void DoSetConsoleTitle (char *text) -{ - SetConsoleTitle (text); -} - -#else - -void DoSetConsoleTitle (char *text) -{ - fprintf (stderr, "\033]0;%s\007", text); - fflush (stderr); -} - -#endif - diff --git a/Frameworks/WavPack/Files/utils.h b/Frameworks/WavPack/Files/utils.h deleted file mode 100644 index 4d2dc7ce2..000000000 --- a/Frameworks/WavPack/Files/utils.h +++ /dev/null @@ -1,61 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2006 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// utils.h - -#ifndef UTILS_H -#define UTILS_H - -#ifndef PATH_MAX -#ifdef MAX_PATH -#define PATH_MAX MAX_PATH -#elif defined (MAXPATHLEN) -#define PATH_MAX MAXPATHLEN -#else -#define PATH_MAX 1024 -#endif -#endif - -#if defined(_WIN32) -#undef VERSION_OS -#ifdef _WIN64 -#define VERSION_OS "Win64" -#else -#define VERSION_OS "Win32" -#endif -#define PACKAGE_VERSION "5.2.0" -#endif - -#define FALSE 0 -#define TRUE 1 - -#define CLEAR(destin) memset (&destin, 0, sizeof (destin)); - -int copy_timestamp (const char *src_filename, const char *dst_filename); -char *filespec_ext (char *filespec), *filespec_path (char *filespec); -char *filespec_name (char *filespec), *filespec_wild (char *filespec); -void error_line (char *error, ...); -void setup_break (void), finish_line (void); -int check_break (void); -char yna (void); - -int DoReadFile (FILE *hFile, void *lpBuffer, uint32_t nNumberOfBytesToRead, uint32_t *lpNumberOfBytesRead); -int DoWriteFile (FILE *hFile, void *lpBuffer, uint32_t nNumberOfBytesToWrite, uint32_t *lpNumberOfBytesWritten); -int64_t DoGetFileSize (FILE *hFile); -int64_t DoGetFilePosition (FILE *hFile); -int DoSetFilePositionAbsolute (FILE *hFile, int64_t pos); -int DoSetFilePositionRelative (FILE *hFile, int64_t pos, int mode); -int DoUngetc (int c, FILE *hFile); -int DoCloseHandle (FILE *hFile); -int DoTruncateFile (FILE *hFile); -int DoDeleteFile (char *filename); -void DoSetConsoleTitle (char *text); - -#define FN_FIT(fn) ((strlen (fn) > 30) ? filespec_name (fn) : fn) - -#endif diff --git a/Frameworks/WavPack/Files/wavpack_local.h b/Frameworks/WavPack/Files/wavpack_local.h deleted file mode 100644 index 67c55cd31..000000000 --- a/Frameworks/WavPack/Files/wavpack_local.h +++ /dev/null @@ -1,707 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2019 David Bryant. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// wavpack_local.h - -#ifndef WAVPACK_LOCAL_H -#define WAVPACK_LOCAL_H - -#include "wavpack.h" - -#if defined(_WIN32) -#define strdup(x) _strdup(x) -#define FASTCALL __fastcall -#else -#define FASTCALL -#endif - -#if defined(_WIN32) || \ - (defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && (BYTE_ORDER == LITTLE_ENDIAN)) || \ - (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) -#define BITSTREAM_SHORTS // use 16-bit "shorts" for reading/writing bitstreams (instead of chars) - // (only works on little-endian machines) -#endif - -#include - -// This header file contains all the definitions required by WavPack. - -#if defined(_MSC_VER) && _MSC_VER < 1600 -#include -typedef unsigned __int64 uint64_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int8 uint8_t; -typedef __int64 int64_t; -typedef __int32 int32_t; -typedef __int16 int16_t; -typedef __int8 int8_t; -#else -#include -#endif - -// Because the C99 specification states that "The order of allocation of -// bit-fields within a unit (high-order to low-order or low-order to -// high-order) is implementation-defined" (6.7.2.1), I decided to change -// the representation of floating-point values from a structure of -// bit-fields to a 32-bit integer with access macros. Note that the WavPack -// library doesn't use any floating-point math to implement compression of -// floating-point data (although a little floating-point math is used in -// high-level functions unrelated to the codec). - -typedef int32_t f32; - -#define get_mantissa(f) ((f) & 0x7fffff) -#define get_magnitude(f) ((f) & 0x7fffffff) -#define get_exponent(f) (((f) >> 23) & 0xff) -#define get_sign(f) (((f) >> 31) & 0x1) - -#define set_mantissa(f,v) (f) ^= (((f) ^ (v)) & 0x7fffff) -#define set_exponent(f,v) (f) ^= (((f) ^ ((v) << 23)) & 0x7f800000) -#define set_sign(f,v) (f) ^= (((f) ^ ((v) << 31)) & 0x80000000) - -#include - -#define FALSE 0 -#define TRUE 1 - -// ID3v1 and APEv2 TAG formats (may occur at the end of WavPack files) - -typedef struct { - char tag_id [3], title [30], artist [30], album [30]; - char year [4], comment [30], genre; -} ID3_Tag; - -typedef struct { - char ID [8]; - int32_t version, length, item_count, flags; - char res [8]; -} APE_Tag_Hdr; - -#define APE_Tag_Hdr_Format "8LLLL" - -#define APE_TAG_TYPE_TEXT 0x0 -#define APE_TAG_TYPE_BINARY 0x1 -#define APE_TAG_THIS_IS_HEADER 0x20000000 -#define APE_TAG_CONTAINS_HEADER 0x80000000 -#define APE_TAG_MAX_LENGTH (1024 * 1024 * 16) - -typedef struct { - int64_t tag_file_pos; - int tag_begins_file; - ID3_Tag id3_tag; - APE_Tag_Hdr ape_tag_hdr; - unsigned char *ape_tag_data; -} M_Tag; - -// or-values for "flags" - -#define CUR_STREAM_VERS 0x407 // universally compatible stream version - - -//////////////////////////// WavPack Metadata ///////////////////////////////// - -// This is an internal representation of metadata. - -typedef struct { - int32_t byte_length; - void *data; - unsigned char id; -} WavpackMetadata; - -#define ID_UNIQUE 0x3f -#define ID_OPTIONAL_DATA 0x20 -#define ID_ODD_SIZE 0x40 -#define ID_LARGE 0x80 - -#define ID_DUMMY 0x0 -#define ID_ENCODER_INFO 0x1 -#define ID_DECORR_TERMS 0x2 -#define ID_DECORR_WEIGHTS 0x3 -#define ID_DECORR_SAMPLES 0x4 -#define ID_ENTROPY_VARS 0x5 -#define ID_HYBRID_PROFILE 0x6 -#define ID_SHAPING_WEIGHTS 0x7 -#define ID_FLOAT_INFO 0x8 -#define ID_INT32_INFO 0x9 -#define ID_WV_BITSTREAM 0xa -#define ID_WVC_BITSTREAM 0xb -#define ID_WVX_BITSTREAM 0xc -#define ID_CHANNEL_INFO 0xd -#define ID_DSD_BLOCK 0xe - -#define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1) -#define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2) -#define ID_ALT_HEADER (ID_OPTIONAL_DATA | 0x3) -#define ID_ALT_TRAILER (ID_OPTIONAL_DATA | 0x4) -#define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5) -#define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6) -#define ID_SAMPLE_RATE (ID_OPTIONAL_DATA | 0x7) -#define ID_ALT_EXTENSION (ID_OPTIONAL_DATA | 0x8) -#define ID_ALT_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x9) -#define ID_NEW_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0xa) -#define ID_CHANNEL_IDENTITIES (ID_OPTIONAL_DATA | 0xb) -#define ID_BLOCK_CHECKSUM (ID_OPTIONAL_DATA | 0xf) - -#define CONFIG_BYTES_STORED 3 // 1-4 bytes/sample -#define CONFIG_MONO_FLAG 4 // not stereo -#define CONFIG_FLOAT_DATA 0x80 // ieee 32-bit floating point data - -#define CONFIG_AUTO_SHAPING 0x4000 // automatic noise shaping -#define CONFIG_LOSSY_MODE 0x1000000 // obsolete (for information) - -/* - * These config flags were never actually used, or are no longer used, or are - * used for something else now. They may be used in the future for what they - * say, or for something else. WavPack files in the wild *may* have some of - * these bit set in their config flags (with these older meanings), but only - * if the stream version is 0x410 or less than 0x407. Of course, this is not - * very important because once the file has been encoded, the config bits are - * just for information purposes (i.e., they do not affect decoding), - * -#define CONFIG_ADOBE_MODE 0x100 // "adobe" mode for 32-bit floats -#define CONFIG_VERY_FAST_FLAG 0x400 // double fast -#define CONFIG_COPY_TIME 0x20000 // copy file-time from source -#define CONFIG_QUALITY_MODE 0x200000 // psychoacoustic quality mode -#define CONFIG_RAW_FLAG 0x400000 // raw mode (not implemented yet) -#define CONFIG_QUIET_MODE 0x10000000 // don't report progress % -#define CONFIG_IGNORE_LENGTH 0x20000000 // ignore length in wav header -#define CONFIG_NEW_RIFF_HEADER 0x40000000 // generate new RIFF wav header - * - */ - -#define EXTRA_SCAN_ONLY 1 -#define EXTRA_STEREO_MODES 2 -#define EXTRA_TRY_DELTAS 8 -#define EXTRA_ADJUST_DELTAS 16 -#define EXTRA_SORT_FIRST 32 -#define EXTRA_BRANCHES 0x1c0 -#define EXTRA_SKIP_8TO16 512 -#define EXTRA_TERMS 0x3c00 -#define EXTRA_DUMP_TERMS 16384 -#define EXTRA_SORT_LAST 32768 - -//////////////////////////////// WavPack Stream /////////////////////////////// - -// This internal structure contains everything required to handle a WavPack -// "stream", which is defined as a stereo or mono stream of audio samples. For -// multichannel audio several of these would be required. Each stream contains -// pointers to hold a complete allocated block of WavPack data, although it's -// possible to decode WavPack blocks without buffering an entire block. - -typedef struct bs { -#ifdef BITSTREAM_SHORTS - uint16_t *buf, *end, *ptr; -#else - unsigned char *buf, *end, *ptr; -#endif - void (*wrap)(struct bs *bs); - int error, bc; - uint32_t sr; -} Bitstream; - -#define MAX_WRAPPER_BYTES 16777216 -#define NEW_MAX_STREAMS 4096 -#define OLD_MAX_STREAMS 8 -#define MAX_NTERMS 16 -#define MAX_TERM 8 - -// DSD-specific definitions - -#define MAX_HISTORY_BITS 5 // maximum number of history bits in DSD "fast" mode - // note that 5 history bits requires 32 history bins -#define MAX_BYTES_PER_BIN 1280 // maximum bytes for the value lookup array (per bin) - // such that the total storage per bin = 2K (also - // counting probabilities and summed_probabilities) - -// Note that this structure is directly accessed in assembly files, so modify with care - -struct decorr_pass { - int32_t term, delta, weight_A, weight_B; - int32_t samples_A [MAX_TERM], samples_B [MAX_TERM]; - int32_t aweight_A, aweight_B; - int32_t sum_A, sum_B; -}; - -typedef struct { - signed char joint_stereo, delta, terms [MAX_NTERMS+1]; -} WavpackDecorrSpec; - -struct entropy_data { - uint32_t median [3], slow_level, error_limit; -}; - -struct words_data { - uint32_t bitrate_delta [2], bitrate_acc [2]; - uint32_t pend_data, holding_one, zeros_acc; - int holding_zero, pend_count; - struct entropy_data c [2]; -}; - -typedef struct { - int32_t value, filter0, filter1, filter2, filter3, filter4, filter5, filter6, factor, byte; -} DSDfilters; - -typedef struct { - WavpackHeader wphdr; - struct words_data w; - - unsigned char *blockbuff, *blockend; - unsigned char *block2buff, *block2end; - int32_t *sample_buffer; - - int64_t sample_index; - int bits, num_terms, mute_error, joint_stereo, false_stereo, shift; - int num_decorrs, num_passes, best_decorr, mask_decorr; - uint32_t crc, crc_x, crc_wvx; - Bitstream wvbits, wvcbits, wvxbits; - int init_done, wvc_skip; - float delta_decay; - - unsigned char int32_sent_bits, int32_zeros, int32_ones, int32_dups; - unsigned char float_flags, float_shift, float_max_exp, float_norm_exp; - - struct { - int32_t shaping_acc [2], shaping_delta [2], error [2]; - double noise_sum, noise_ave, noise_max; - int16_t *shaping_data, *shaping_array; - int32_t shaping_samples; - } dc; - - struct decorr_pass decorr_passes [MAX_NTERMS], analysis_pass; - const WavpackDecorrSpec *decorr_specs; - - struct { - unsigned char *byteptr, *endptr, (*probabilities) [256], *lookup_buffer, **value_lookup, mode, ready; - int history_bins, p0, p1; - int16_t (*summed_probabilities) [256]; - uint32_t low, high, value; - DSDfilters filters [2]; - int32_t *ptable; - } dsd; - -} WavpackStream; - -// flags for float_flags: - -#define FLOAT_SHIFT_ONES 1 // bits left-shifted into float = '1' -#define FLOAT_SHIFT_SAME 2 // bits left-shifted into float are the same -#define FLOAT_SHIFT_SENT 4 // bits shifted into float are sent literally -#define FLOAT_ZEROS_SENT 8 // "zeros" are not all real zeros -#define FLOAT_NEG_ZEROS 0x10 // contains negative zeros -#define FLOAT_EXCEPTIONS 0x20 // contains exceptions (inf, nan, etc.) - -/////////////////////////////// WavPack Context /////////////////////////////// - -// This internal structure holds everything required to encode or decode WavPack -// files. It is recommended that direct access to this structure be minimized -// and the provided utilities used instead. - -struct WavpackContext { - WavpackConfig config; - - WavpackMetadata *metadata; - uint32_t metabytes; - int metacount; - - unsigned char *wrapper_data; - uint32_t wrapper_bytes; - - WavpackBlockOutput blockout; - void *wv_out, *wvc_out; - - WavpackStreamReader64 *reader; - void *wv_in, *wvc_in; - - int64_t filelen, file2len, filepos, file2pos, total_samples, initial_index; - uint32_t crc_errors, first_flags; - int wvc_flag, open_flags, norm_offset, reduced_channels, lossy_blocks, version_five; - uint32_t block_samples, ave_block_samples, block_boundary, max_samples, acc_samples, riff_trailer_bytes; - int riff_header_added, riff_header_created; - M_Tag m_tag; - - int current_stream, num_streams, max_streams, stream_version; - WavpackStream **streams; - void *stream3; - - // these items were added in 5.0 to support alternate file types (especially CAF & DSD) - unsigned char file_format, *channel_reordering, *channel_identities; - uint32_t channel_layout, dsd_multiplier; - void *decimation_context; - char file_extension [8]; - - void (*close_callback)(void *wpc); - char error_message [80]; -}; - -//////////////////////// function prototypes and macros ////////////////////// - -#define CLEAR(destin) memset (&destin, 0, sizeof (destin)); - -//////////////////////////////// decorrelation ////////////////////////////// -// modules: pack.c, unpack.c, unpack_floats.c, extra1.c, extra2.c - -// #define SKIP_DECORRELATION // experimental switch to disable all decorrelation on encode - -// These macros implement the weight application and update operations -// that are at the heart of the decorrelation loops. Note that there are -// sometimes two and even three versions of each macro. Theses should be -// equivalent and produce identical results, but some may perform better -// or worse on a given architecture. - -#if 1 // PERFCOND - apply decorrelation weight when no 32-bit overflow possible -#define apply_weight_i(weight, sample) ((weight * sample + 512) >> 10) -#else -#define apply_weight_i(weight, sample) ((((weight * sample) >> 8) + 2) >> 2) -#endif - -#if 1 // PERFCOND - apply decorrelation weight when 32-bit overflow is possible -#define apply_weight_f(weight, sample) (((((sample & 0xffff) * weight) >> 9) + \ - (((sample & ~0xffff) >> 9) * weight) + 1) >> 1) -#elif 1 -#define apply_weight_f(weight, sample) ((int32_t)((weight * (int64_t) sample + 512) >> 10)) -#else -#define apply_weight_f(weight, sample) ((int32_t)floor(((double) weight * sample + 512.0) / 1024.0)) -#endif - -#if 1 // PERFCOND - universal version that checks input magnitude or always uses long version -#define apply_weight(weight, sample) (sample != (int16_t) sample ? \ - apply_weight_f (weight, sample) : apply_weight_i (weight, sample)) -#else -#define apply_weight(weight, sample) (apply_weight_f (weight, sample)) -#endif - -#if 1 // PERFCOND -#define update_weight(weight, delta, source, result) \ - if (source && result) { int32_t s = (int32_t) (source ^ result) >> 31; weight = (delta ^ s) + (weight - s); } -#elif 1 -#define update_weight(weight, delta, source, result) \ - if (source && result) weight += (((source ^ result) >> 30) | 1) * delta; -#else -#define update_weight(weight, delta, source, result) \ - if (source && result) (source ^ result) < 0 ? (weight -= delta) : (weight += delta); -#endif - -#define update_weight_clip(weight, delta, source, result) \ - if (source && result) { \ - const int32_t s = (source ^ result) >> 31; \ - if ((weight = (weight ^ s) + (delta - s)) > 1024) weight = 1024; \ - weight = (weight ^ s) - s; \ - } - -void pack_init (WavpackContext *wpc); -int pack_block (WavpackContext *wpc, int32_t *buffer); -void send_general_metadata (WavpackContext *wpc); -void free_metadata (WavpackMetadata *wpmd); -int copy_metadata (WavpackMetadata *wpmd, unsigned char *buffer_start, unsigned char *buffer_end); -double WavpackGetEncodedNoise (WavpackContext *wpc, double *peak); -int unpack_init (WavpackContext *wpc); -int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd); -int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd); -int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd); -int read_shaping_info (WavpackStream *wps, WavpackMetadata *wpmd); -int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count); -int check_crc_error (WavpackContext *wpc); -int scan_float_data (WavpackStream *wps, f32 *values, int32_t num_values); -void send_float_data (WavpackStream *wps, f32 *values, int32_t num_values); -void float_values (WavpackStream *wps, int32_t *values, int32_t num_values); -void dynamic_noise_shaping (WavpackContext *wpc, int32_t *buffer, int shortening_allowed); -void execute_stereo (WavpackContext *wpc, int32_t *samples, int no_history, int do_samples); -void execute_mono (WavpackContext *wpc, int32_t *samples, int no_history, int do_samples); - -////////////////////////// DSD related (including decimation) ////////////////////////// -// modules: pack_dsd.c unpack_dsd.c - -void pack_dsd_init (WavpackContext *wpc); -int pack_dsd_block (WavpackContext *wpc, int32_t *buffer); -int init_dsd_block (WavpackContext *wpc, WavpackMetadata *wpmd); -int32_t unpack_dsd_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count); - -void *decimate_dsd_init (int num_channels); -void decimate_dsd_reset (void *decimate_context); -void decimate_dsd_run (void *decimate_context, int32_t *samples, int num_samples); -void decimate_dsd_destroy (void *decimate_context); - -///////////////////////////////// CPU feature detection //////////////////////////////// - -int unpack_cpu_has_feature_x86 (int findex), pack_cpu_has_feature_x86 (int findex); - -#define CPU_FEATURE_MMX 23 - -///////////////////////////// pre-4.0 version decoding //////////////////////////// -// modules: unpack3.c, unpack3_open.c, unpack3_seek.c - -WavpackContext *open_file3 (WavpackContext *wpc, char *error); -int32_t unpack_samples3 (WavpackContext *wpc, int32_t *buffer, uint32_t sample_count); -int seek_sample3 (WavpackContext *wpc, uint32_t desired_index); -uint32_t get_sample_index3 (WavpackContext *wpc); -void free_stream3 (WavpackContext *wpc); -int get_version3 (WavpackContext *wpc); - -////////////////////////////// bitstream macros & functions ///////////////////////////// - -#define bs_is_open(bs) ((bs)->ptr != NULL) -uint32_t bs_close_read (Bitstream *bs); - -#define getbit(bs) ( \ - (((bs)->bc) ? \ - ((bs)->bc--, (bs)->sr & 1) : \ - (((++((bs)->ptr) != (bs)->end) ? (void) 0 : (bs)->wrap (bs)), (bs)->bc = sizeof (*((bs)->ptr)) * 8 - 1, ((bs)->sr = *((bs)->ptr)) & 1) \ - ) ? \ - ((bs)->sr >>= 1, 1) : \ - ((bs)->sr >>= 1, 0) \ -) - -#define getbits(value, nbits, bs) do { \ - while ((nbits) > (bs)->bc) { \ - if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \ - (bs)->sr |= (int32_t)*((bs)->ptr) << (bs)->bc; \ - (bs)->bc += sizeof (*((bs)->ptr)) * 8; \ - } \ - *(value) = (bs)->sr; \ - if ((bs)->bc > 32) { \ - (bs)->bc -= (nbits); \ - (bs)->sr = *((bs)->ptr) >> (sizeof (*((bs)->ptr)) * 8 - (bs)->bc); \ - } \ - else { \ - (bs)->bc -= (nbits); \ - (bs)->sr >>= (nbits); \ - } \ -} while (0) - -#define putbit(bit, bs) do { if (bit) (bs)->sr |= (1 << (bs)->bc); \ - if (++((bs)->bc) == sizeof (*((bs)->ptr)) * 8) { \ - *((bs)->ptr) = (bs)->sr; \ - (bs)->sr = (bs)->bc = 0; \ - if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \ - }} while (0) - -#define putbit_0(bs) do { \ - if (++((bs)->bc) == sizeof (*((bs)->ptr)) * 8) { \ - *((bs)->ptr) = (bs)->sr; \ - (bs)->sr = (bs)->bc = 0; \ - if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \ - }} while (0) - -#define putbit_1(bs) do { (bs)->sr |= (1 << (bs)->bc); \ - if (++((bs)->bc) == sizeof (*((bs)->ptr)) * 8) { \ - *((bs)->ptr) = (bs)->sr; \ - (bs)->sr = (bs)->bc = 0; \ - if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \ - }} while (0) - -#define putbits(value, nbits, bs) do { \ - (bs)->sr |= (int32_t)(value) << (bs)->bc; \ - if (((bs)->bc += (nbits)) >= sizeof (*((bs)->ptr)) * 8) \ - do { \ - *((bs)->ptr) = (bs)->sr; \ - (bs)->sr >>= sizeof (*((bs)->ptr)) * 8; \ - if (((bs)->bc -= sizeof (*((bs)->ptr)) * 8) > 32 - sizeof (*((bs)->ptr)) * 8) \ - (bs)->sr |= ((value) >> ((nbits) - (bs)->bc)); \ - if (++((bs)->ptr) == (bs)->end) (bs)->wrap (bs); \ - } while ((bs)->bc >= sizeof (*((bs)->ptr)) * 8); \ -} while (0) - -///////////////////////////// entropy encoder / decoder //////////////////////////// -// modules: entropy_utils.c, read_words.c, write_words.c - -// these control the time constant "slow_level" which is used for hybrid mode -// that controls bitrate as a function of residual level (HYBRID_BITRATE). -#define SLS 8 -#define SLO ((1 << (SLS - 1))) - -#define LIMIT_ONES 16 // maximum consecutive 1s sent for "div" data - -// these control the time constant of the 3 median level breakpoints -#define DIV0 128 // 5/7 of samples -#define DIV1 64 // 10/49 of samples -#define DIV2 32 // 20/343 of samples - -// this macro retrieves the specified median breakpoint (without frac; min = 1) -#define GET_MED(med) (((c->median [med]) >> 4) + 1) - -// These macros update the specified median breakpoints. Note that the median -// is incremented when the sample is higher than the median, else decremented. -// They are designed so that the median will never drop below 1 and the value -// is essentially stationary if there are 2 increments for every 5 decrements. - -#define INC_MED0() (c->median [0] += ((c->median [0] + DIV0) / DIV0) * 5) -#define DEC_MED0() (c->median [0] -= ((c->median [0] + (DIV0-2)) / DIV0) * 2) -#define INC_MED1() (c->median [1] += ((c->median [1] + DIV1) / DIV1) * 5) -#define DEC_MED1() (c->median [1] -= ((c->median [1] + (DIV1-2)) / DIV1) * 2) -#define INC_MED2() (c->median [2] += ((c->median [2] + DIV2) / DIV2) * 5) -#define DEC_MED2() (c->median [2] -= ((c->median [2] + (DIV2-2)) / DIV2) * 2) - -#ifdef HAVE___BUILTIN_CLZ -#define count_bits(av) ((av) ? 32 - __builtin_clz (av) : 0) -#elif defined (_WIN64) -static __inline int count_bits (uint32_t av) { unsigned long res; return _BitScanReverse (&res, av) ? (int)(res + 1) : 0; } -#else -#define count_bits(av) ( \ - (av) < (1 << 8) ? nbits_table [av] : \ - ( \ - (av) < (1L << 16) ? nbits_table [(av) >> 8] + 8 : \ - ((av) < (1L << 24) ? nbits_table [(av) >> 16] + 16 : nbits_table [(av) >> 24] + 24) \ - ) \ -) -#endif - -void init_words (WavpackStream *wps); -void write_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd); -void write_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd); -int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd); -int read_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd); -int32_t FASTCALL send_word (WavpackStream *wps, int32_t value, int chan); -void send_words_lossless (WavpackStream *wps, int32_t *buffer, int32_t nsamples); -int32_t FASTCALL get_word (WavpackStream *wps, int chan, int32_t *correction); -int32_t get_words_lossless (WavpackStream *wps, int32_t *buffer, int32_t nsamples); -void flush_word (WavpackStream *wps); -int32_t nosend_word (WavpackStream *wps, int32_t value, int chan); -void scan_word (WavpackStream *wps, int32_t *samples, uint32_t num_samples, int dir); -void update_error_limit (WavpackStream *wps); - -extern const uint32_t bitset [32]; -extern const uint32_t bitmask [32]; -extern const char nbits_table [256]; - -int wp_log2s (int32_t value); -int32_t wp_exp2s (int log); -int FASTCALL wp_log2 (uint32_t avalue); - -#ifdef OPT_ASM_X86 -#define LOG2BUFFER log2buffer_x86 -#elif defined(OPT_ASM_X64) && (defined (_WIN64) || defined(__CYGWIN__) || defined(__MINGW64__) || defined(__midipix__)) -#define LOG2BUFFER log2buffer_x64win -#elif defined(OPT_ASM_X64) -#define LOG2BUFFER log2buffer_x64 -#else -#define LOG2BUFFER log2buffer -#endif - -uint32_t LOG2BUFFER (int32_t *samples, uint32_t num_samples, int limit); - -signed char store_weight (int weight); -int restore_weight (signed char weight); - -#define WORD_EOF ((int32_t)(1L << 31)) - -void WavpackFloatNormalize (int32_t *values, int32_t num_values, int delta_exp); - -/////////////////////////// high-level unpacking API and support //////////////////////////// -// modules: open_utils.c, unpack_utils.c, unpack_seek.c, unpack_floats.c - -WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset); -WavpackContext *WavpackOpenFileInputEx (WavpackStreamReader *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset); -WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int flags, int norm_offset); - -#define OPEN_WVC 0x1 // open/read "correction" file -#define OPEN_TAGS 0x2 // read ID3v1 / APEv2 tags (seekable file) -#define OPEN_WRAPPER 0x4 // make audio wrapper available (i.e. RIFF) -#define OPEN_2CH_MAX 0x8 // open multichannel as stereo (no downmix) -#define OPEN_NORMALIZE 0x10 // normalize floating point data to +/- 1.0 -#define OPEN_STREAMING 0x20 // "streaming" mode blindly unpacks blocks - // w/o regard to header file position info -#define OPEN_EDIT_TAGS 0x40 // allow editing of tags -#define OPEN_FILE_UTF8 0x80 // assume filenames are UTF-8 encoded, not ANSI (Windows only) - -// new for version 5 - -#define OPEN_DSD_NATIVE 0x100 // open DSD files as bitstreams - // (returned as 8-bit "samples" stored in 32-bit words) -#define OPEN_DSD_AS_PCM 0x200 // open DSD files as 24-bit PCM (decimated 8x) -#define OPEN_ALT_TYPES 0x400 // application is aware of alternate file types & qmode - // (just affects retrieving wrappers & MD5 checksums) -#define OPEN_NO_CHECKSUM 0x800 // don't verify block checksums before decoding - -int WavpackGetMode (WavpackContext *wpc); - -int WavpackGetQualifyMode (WavpackContext *wpc); -int WavpackGetVersion (WavpackContext *wpc); -uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples); -int WavpackSeekSample (WavpackContext *wpc, uint32_t sample); -int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample); -int WavpackGetMD5Sum (WavpackContext *wpc, unsigned char data [16]); - -int WavpackVerifySingleBlock (unsigned char *buffer, int verify_checksum); -uint32_t read_next_header (WavpackStreamReader64 *reader, void *id, WavpackHeader *wphdr); -int read_wvc_block (WavpackContext *wpc); - -/////////////////////////// high-level packing API and support //////////////////////////// -// modules: pack_utils.c, pack_floats.c - -WavpackContext *WavpackOpenFileOutput (WavpackBlockOutput blockout, void *wv_id, void *wvc_id); -int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples); -int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64_t total_samples, const unsigned char *chan_ids); -int WavpackPackInit (WavpackContext *wpc); -int WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount); -int WavpackPackSamples (WavpackContext *wpc, int32_t *sample_buffer, uint32_t sample_count); -int WavpackFlushSamples (WavpackContext *wpc); -int WavpackStoreMD5Sum (WavpackContext *wpc, unsigned char data [16]); -void WavpackSeekTrailingWrapper (WavpackContext *wpc); -void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block); -void *WavpackGetWrapperLocation (void *first_block, uint32_t *size); - -/////////////////////////////////// common utilities //////////////////////////////////// -// module: common_utils.c - -extern const uint32_t sample_rates [16]; -uint32_t WavpackGetLibraryVersion (void); -const char *WavpackGetLibraryVersionString (void); -uint32_t WavpackGetSampleRate (WavpackContext *wpc); -int WavpackGetBitsPerSample (WavpackContext *wpc); -int WavpackGetBytesPerSample (WavpackContext *wpc); -int WavpackGetNumChannels (WavpackContext *wpc); -int WavpackGetChannelMask (WavpackContext *wpc); -int WavpackGetReducedChannels (WavpackContext *wpc); -int WavpackGetFloatNormExp (WavpackContext *wpc); -uint32_t WavpackGetNumSamples (WavpackContext *wpc); -int64_t WavpackGetNumSamples64 (WavpackContext *wpc); -uint32_t WavpackGetSampleIndex (WavpackContext *wpc); -int64_t WavpackGetSampleIndex64 (WavpackContext *wpc); -char *WavpackGetErrorMessage (WavpackContext *wpc); -int WavpackGetNumErrors (WavpackContext *wpc); -int WavpackLossyBlocks (WavpackContext *wpc); -uint32_t WavpackGetWrapperBytes (WavpackContext *wpc); -unsigned char *WavpackGetWrapperData (WavpackContext *wpc); -void WavpackFreeWrapper (WavpackContext *wpc); -double WavpackGetProgress (WavpackContext *wpc); -uint32_t WavpackGetFileSize (WavpackContext *wpc); -int64_t WavpackGetFileSize64 (WavpackContext *wpc); -double WavpackGetRatio (WavpackContext *wpc); -double WavpackGetAverageBitrate (WavpackContext *wpc, int count_wvc); -double WavpackGetInstantBitrate (WavpackContext *wpc); -WavpackContext *WavpackCloseFile (WavpackContext *wpc); -void WavpackLittleEndianToNative (void *data, char *format); -void WavpackNativeToLittleEndian (void *data, char *format); -void WavpackBigEndianToNative (void *data, char *format); -void WavpackNativeToBigEndian (void *data, char *format); - -void install_close_callback (WavpackContext *wpc, void cb_func (void *wpc)); -void free_dsd_tables (WavpackStream *wps); -void free_streams (WavpackContext *wpc); - -/////////////////////////////////// tag utilities //////////////////////////////////// -// modules: tags.c, tag_utils.c - -int WavpackGetNumTagItems (WavpackContext *wpc); -int WavpackGetTagItem (WavpackContext *wpc, const char *item, char *value, int size); -int WavpackGetTagItemIndexed (WavpackContext *wpc, int index, char *item, int size); -int WavpackGetNumBinaryTagItems (WavpackContext *wpc); -int WavpackGetBinaryTagItem (WavpackContext *wpc, const char *item, char *value, int size); -int WavpackGetBinaryTagItemIndexed (WavpackContext *wpc, int index, char *item, int size); -int WavpackAppendTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize); -int WavpackAppendBinaryTagItem (WavpackContext *wpc, const char *item, const char *value, int vsize); -int WavpackDeleteTagItem (WavpackContext *wpc, const char *item); -int WavpackWriteTag (WavpackContext *wpc); -int load_tag (WavpackContext *wpc); -void free_tag (M_Tag *m_tag); -int valid_tag (M_Tag *m_tag); -int editable_tag (M_Tag *m_tag); - -#endif - diff --git a/Frameworks/WavPack/Files/wavpack_version.h b/Frameworks/WavPack/Files/wavpack_version.h deleted file mode 100644 index c60a769ad..000000000 --- a/Frameworks/WavPack/Files/wavpack_version.h +++ /dev/null @@ -1,19 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2019 David Bryant. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// wavpack_version.h - -#ifndef WAVPACK_VERSION_H -#define WAVPACK_VERSION_H - -#define LIBWAVPACK_MAJOR 5 -#define LIBWAVPACK_MINOR 2 -#define LIBWAVPACK_MICRO 0 -#define LIBWAVPACK_VERSION_STRING "5.2.0" - -#endif diff --git a/Frameworks/WavPack/Files/write_words.c b/Frameworks/WavPack/Files/write_words.c deleted file mode 100644 index 762caf229..000000000 --- a/Frameworks/WavPack/Files/write_words.c +++ /dev/null @@ -1,688 +0,0 @@ -//////////////////////////////////////////////////////////////////////////// -// **** WAVPACK **** // -// Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2013 Conifer Software. // -// All Rights Reserved. // -// Distributed under the BSD Software License (see license.txt) // -//////////////////////////////////////////////////////////////////////////// - -// write_words.c - -// This module provides entropy word encoding functions using -// a variation on the Rice method. This was introduced in version 3.93 -// because it allows splitting the data into a "lossy" stream and a -// "correction" stream in a very efficient manner and is therefore ideal -// for the "hybrid" mode. For 4.0, the efficiency of this method was -// significantly improved by moving away from the normal Rice restriction of -// using powers of two for the modulus divisions and now the method can be -// used for both hybrid and pure lossless encoding. - -// Samples are divided by median probabilities at 5/7 (71.43%), 10/49 (20.41%), -// and 20/343 (5.83%). Each zone has 3.5 times fewer samples than the -// previous. Using standard Rice coding on this data would result in 1.4 -// bits per sample average (not counting sign bit). However, there is a -// very simple encoding that is over 99% efficient with this data and -// results in about 1.22 bits per sample. - -#include -#include - -#include "wavpack_local.h" - -///////////////////////////// executable code //////////////////////////////// - -// Initialize entropy encoder for the specified stream. In lossless mode there -// are no parameters to select; in hybrid mode the bitrate mode and value need -// be initialized. - -static void word_set_bitrate (WavpackStream *wps); - -void init_words (WavpackStream *wps) -{ - CLEAR (wps->w); - - if (wps->wphdr.flags & HYBRID_FLAG) - word_set_bitrate (wps); -} - -// Set up parameters for hybrid mode based on header flags and "bits" field. -// This is currently only set up for the HYBRID_BITRATE mode in which the -// allowed error varies with the residual level (from "slow_level"). The -// simpler mode (which is not used yet) has the error level directly -// controlled from the metadata. - -static void word_set_bitrate (WavpackStream *wps) -{ - int bitrate_0, bitrate_1; - - if (wps->wphdr.flags & HYBRID_BITRATE) { - if (wps->wphdr.flags & FALSE_STEREO) - bitrate_0 = (wps->bits * 2 - 512) < 568 ? 0 : (wps->bits * 2 - 512) - 568; - else - bitrate_0 = wps->bits < 568 ? 0 : wps->bits - 568; - - if (!(wps->wphdr.flags & MONO_DATA)) { - - if (wps->wphdr.flags & HYBRID_BALANCE) - bitrate_1 = (wps->wphdr.flags & JOINT_STEREO) ? 256 : 0; - else { - bitrate_1 = bitrate_0; - - if (wps->wphdr.flags & JOINT_STEREO) { - if (bitrate_0 < 128) { - bitrate_1 += bitrate_0; - bitrate_0 = 0; - } - else { - bitrate_0 -= 128; - bitrate_1 += 128; - } - } - } - } - else - bitrate_1 = 0; - } - else - bitrate_0 = bitrate_1 = 0; - - wps->w.bitrate_acc [0] = (int32_t) bitrate_0 << 16; - wps->w.bitrate_acc [1] = (int32_t) bitrate_1 << 16; -} - -// Allocates the correct space in the metadata structure and writes the -// current median values to it. Values are converted from 32-bit unsigned -// to our internal 16-bit wp_log2 values, and read_entropy_vars () is called -// to read the values back because we must compensate for the loss through -// the log function. - -void write_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd) -{ - unsigned char *byteptr; - int temp; - - byteptr = wpmd->data = malloc (12); - wpmd->id = ID_ENTROPY_VARS; - - *byteptr++ = temp = wp_log2 (wps->w.c [0].median [0]); - *byteptr++ = temp >> 8; - *byteptr++ = temp = wp_log2 (wps->w.c [0].median [1]); - *byteptr++ = temp >> 8; - *byteptr++ = temp = wp_log2 (wps->w.c [0].median [2]); - *byteptr++ = temp >> 8; - - if (!(wps->wphdr.flags & MONO_DATA)) { - *byteptr++ = temp = wp_log2 (wps->w.c [1].median [0]); - *byteptr++ = temp >> 8; - *byteptr++ = temp = wp_log2 (wps->w.c [1].median [1]); - *byteptr++ = temp >> 8; - *byteptr++ = temp = wp_log2 (wps->w.c [1].median [2]); - *byteptr++ = temp >> 8; - } - - wpmd->byte_length = (int32_t)(byteptr - (unsigned char *) wpmd->data); - read_entropy_vars (wps, wpmd); -} - -// Allocates enough space in the metadata structure and writes the current -// high word of the bitrate accumulator and the slow_level values to it. The -// slow_level values are converted from 32-bit unsigned to our internal 16-bit -// wp_log2 values. Afterward, read_entropy_vars () is called to read the values -// back because we must compensate for the loss through the log function and -// the truncation of the bitrate. - -void write_hybrid_profile (WavpackStream *wps, WavpackMetadata *wpmd) -{ - unsigned char *byteptr; - int temp; - - word_set_bitrate (wps); - byteptr = wpmd->data = malloc (512); - wpmd->id = ID_HYBRID_PROFILE; - - if (wps->wphdr.flags & HYBRID_BITRATE) { - *byteptr++ = temp = wp_log2s (wps->w.c [0].slow_level); - *byteptr++ = temp >> 8; - - if (!(wps->wphdr.flags & MONO_DATA)) { - *byteptr++ = temp = wp_log2s (wps->w.c [1].slow_level); - *byteptr++ = temp >> 8; - } - } - - *byteptr++ = temp = wps->w.bitrate_acc [0] >> 16; - *byteptr++ = temp >> 8; - - if (!(wps->wphdr.flags & MONO_DATA)) { - *byteptr++ = temp = wps->w.bitrate_acc [1] >> 16; - *byteptr++ = temp >> 8; - } - - if (wps->w.bitrate_delta [0] | wps->w.bitrate_delta [1]) { - *byteptr++ = temp = wp_log2s (wps->w.bitrate_delta [0]); - *byteptr++ = temp >> 8; - - if (!(wps->wphdr.flags & MONO_DATA)) { - *byteptr++ = temp = wp_log2s (wps->w.bitrate_delta [1]); - *byteptr++ = temp >> 8; - } - } - - wpmd->byte_length = (int32_t)(byteptr - (unsigned char *) wpmd->data); - read_hybrid_profile (wps, wpmd); -} - -// This function writes the specified word to the open bitstream "wvbits" and, -// if the bitstream "wvcbits" is open, writes any correction data there. This -// function will work for either lossless or hybrid but because a version -// optimized for lossless exits below, it would normally be used for the hybrid -// mode only. The return value is the actual value stored to the stream (even -// if a correction file is being created) and is used as feedback to the -// predictor. - -int32_t FASTCALL send_word (WavpackStream *wps, int32_t value, int chan) -{ - struct entropy_data *c = wps->w.c + chan; - uint32_t ones_count, low, mid, high; - int sign = (value < 0) ? 1 : 0; - - if (wps->w.c [0].median [0] < 2 && !wps->w.holding_zero && wps->w.c [1].median [0] < 2) { - if (wps->w.zeros_acc) { - if (value) - flush_word (wps); - else { - c->slow_level -= (c->slow_level + SLO) >> SLS; - wps->w.zeros_acc++; - return 0; - } - } - else if (value) - putbit_0 (&wps->wvbits); - else { - c->slow_level -= (c->slow_level + SLO) >> SLS; - CLEAR (wps->w.c [0].median); - CLEAR (wps->w.c [1].median); - wps->w.zeros_acc = 1; - return 0; - } - } - - if (sign) - value = ~value; - - if ((wps->wphdr.flags & HYBRID_FLAG) && !chan) - update_error_limit (wps); - - if (value < (int32_t) GET_MED (0)) { - ones_count = low = 0; - high = GET_MED (0) - 1; - DEC_MED0 (); - } - else { - low = GET_MED (0); - INC_MED0 (); - - if (value - low < GET_MED (1)) { - ones_count = 1; - high = low + GET_MED (1) - 1; - DEC_MED1 (); - } - else { - low += GET_MED (1); - INC_MED1 (); - - if (value - low < GET_MED (2)) { - ones_count = 2; - high = low + GET_MED (2) - 1; - DEC_MED2 (); - } - else { - ones_count = 2 + (value - low) / GET_MED (2); - low += (ones_count - 2) * GET_MED (2); - high = low + GET_MED (2) - 1; - INC_MED2 (); - } - } - } - - mid = (high + low + 1) >> 1; - - if (wps->w.holding_zero) { - if (ones_count) - wps->w.holding_one++; - - flush_word (wps); - - if (ones_count) { - wps->w.holding_zero = 1; - ones_count--; - } - else - wps->w.holding_zero = 0; - } - else - wps->w.holding_zero = 1; - - wps->w.holding_one = ones_count * 2; - - if (!c->error_limit) { - if (high != low) { - uint32_t maxcode = high - low, code = value - low; - int bitcount = count_bits (maxcode); - uint32_t extras = bitset [bitcount] - maxcode - 1; - - if (code < extras) { - wps->w.pend_data |= code << wps->w.pend_count; - wps->w.pend_count += bitcount - 1; - } - else { - wps->w.pend_data |= ((code + extras) >> 1) << wps->w.pend_count; - wps->w.pend_count += bitcount - 1; - wps->w.pend_data |= ((code + extras) & 1) << wps->w.pend_count++; - } - } - - mid = value; - } - else - while (high - low > c->error_limit) - if (value < (int32_t) mid) { - mid = ((high = mid - 1) + low + 1) >> 1; - wps->w.pend_count++; - } - else { - mid = (high + (low = mid) + 1) >> 1; - wps->w.pend_data |= bitset [wps->w.pend_count++]; - } - - wps->w.pend_data |= ((int32_t) sign << wps->w.pend_count++); - - if (!wps->w.holding_zero) - flush_word (wps); - - if (bs_is_open (&wps->wvcbits) && c->error_limit) { - uint32_t code = value - low, maxcode = high - low; - int bitcount = count_bits (maxcode); - uint32_t extras = bitset [bitcount] - maxcode - 1; - - if (bitcount) { - if (code < extras) - putbits (code, bitcount - 1, &wps->wvcbits); - else { - putbits ((code + extras) >> 1, bitcount - 1, &wps->wvcbits); - putbit ((code + extras) & 1, &wps->wvcbits); - } - } - } - - if (wps->wphdr.flags & HYBRID_BITRATE) { - c->slow_level -= (c->slow_level + SLO) >> SLS; - c->slow_level += wp_log2 (mid); - } - - return sign ? ~mid : mid; -} - -// This function is an optimized version of send_word() that only handles -// lossless (error_limit == 0) and sends an entire buffer of either mono or -// stereo data rather than a single sample. Unlike the generalized -// send_word(), it does not return values because it always encodes -// the exact value passed. - -void send_words_lossless (WavpackStream *wps, int32_t *buffer, int32_t nsamples) -{ - struct entropy_data *c = wps->w.c; - int32_t value, csamples; - - if (!(wps->wphdr.flags & MONO_DATA)) - nsamples *= 2; - - for (csamples = 0; csamples < nsamples; ++csamples) { - int sign = ((value = *buffer++) < 0) ? 1 : 0; - uint32_t ones_count, low, high; - - if (!(wps->wphdr.flags & MONO_DATA)) - c = wps->w.c + (csamples & 1); - - if (wps->w.c [0].median [0] < 2 && !wps->w.holding_zero && wps->w.c [1].median [0] < 2) { - if (wps->w.zeros_acc) { - if (value) - flush_word (wps); - else { - wps->w.zeros_acc++; - continue; - } - } - else if (value) - putbit_0 (&wps->wvbits); - else { - CLEAR (wps->w.c [0].median); - CLEAR (wps->w.c [1].median); - wps->w.zeros_acc = 1; - continue; - } - } - - if (sign) - value = ~value; - - if (value < (int32_t) GET_MED (0)) { - ones_count = low = 0; - high = GET_MED (0) - 1; - DEC_MED0 (); - } - else { - low = GET_MED (0); - INC_MED0 (); - - if (value - low < GET_MED (1)) { - ones_count = 1; - high = low + GET_MED (1) - 1; - DEC_MED1 (); - } - else { - low += GET_MED (1); - INC_MED1 (); - - if (value - low < GET_MED (2)) { - ones_count = 2; - high = low + GET_MED (2) - 1; - DEC_MED2 (); - } - else { - ones_count = 2 + (value - low) / GET_MED (2); - low += (ones_count - 2) * GET_MED (2); - high = low + GET_MED (2) - 1; - INC_MED2 (); - } - } - } - - if (wps->w.holding_zero) { - if (ones_count) - wps->w.holding_one++; - - flush_word (wps); - - if (ones_count) { - wps->w.holding_zero = 1; - ones_count--; - } - else - wps->w.holding_zero = 0; - } - else - wps->w.holding_zero = 1; - - wps->w.holding_one = ones_count * 2; - - if (high != low) { - uint32_t maxcode = high - low, code = value - low; - int bitcount = count_bits (maxcode); - uint32_t extras = bitset [bitcount] - maxcode - 1; - - if (code < extras) { - wps->w.pend_data |= code << wps->w.pend_count; - wps->w.pend_count += bitcount - 1; - } - else { - wps->w.pend_data |= ((code + extras) >> 1) << wps->w.pend_count; - wps->w.pend_count += bitcount - 1; - wps->w.pend_data |= ((code + extras) & 1) << wps->w.pend_count++; - } - } - - wps->w.pend_data |= ((int32_t) sign << wps->w.pend_count++); - - if (!wps->w.holding_zero) - flush_word (wps); - } -} - -// Used by send_word() and send_word_lossless() to actually send most the -// accumulated data onto the bitstream. This is also called directly from -// clients when all words have been sent. - -void flush_word (WavpackStream *wps) -{ - if (wps->w.zeros_acc) { - int cbits = count_bits (wps->w.zeros_acc); - - while (cbits--) - putbit_1 (&wps->wvbits); - - putbit_0 (&wps->wvbits); - - while (wps->w.zeros_acc > 1) { - putbit (wps->w.zeros_acc & 1, &wps->wvbits); - wps->w.zeros_acc >>= 1; - } - - wps->w.zeros_acc = 0; - } - - if (wps->w.holding_one) { -#ifdef LIMIT_ONES - if (wps->w.holding_one >= LIMIT_ONES) { - int cbits; - - putbits ((1L << LIMIT_ONES) - 1, LIMIT_ONES + 1, &wps->wvbits); - wps->w.holding_one -= LIMIT_ONES; - cbits = count_bits (wps->w.holding_one); - - while (cbits--) - putbit_1 (&wps->wvbits); - - putbit_0 (&wps->wvbits); - - while (wps->w.holding_one > 1) { - putbit (wps->w.holding_one & 1, &wps->wvbits); - wps->w.holding_one >>= 1; - } - - wps->w.holding_zero = 0; - } - else - putbits (bitmask [wps->w.holding_one], wps->w.holding_one, &wps->wvbits); - - wps->w.holding_one = 0; -#else - do { - putbit_1 (&wps->wvbits); - } while (--wps->w.holding_one); -#endif - } - - if (wps->w.holding_zero) { - putbit_0 (&wps->wvbits); - wps->w.holding_zero = 0; - } - - if (wps->w.pend_count) { - putbits (wps->w.pend_data, wps->w.pend_count, &wps->wvbits); - wps->w.pend_data = wps->w.pend_count = 0; - } -} - -// This function is similar to send_word() except that no data is actually -// written to any stream, but it does return the value that would have been -// sent to a hybrid stream. It is used to determine beforehand how much noise -// will be added to samples. - -int32_t nosend_word (WavpackStream *wps, int32_t value, int chan) -{ - struct entropy_data *c = wps->w.c + chan; - uint32_t ones_count, low, mid, high; - int sign = (value < 0) ? 1 : 0; - - if (sign) - value = ~value; - - if ((wps->wphdr.flags & HYBRID_FLAG) && !chan) - update_error_limit (wps); - - if (value < (int32_t) GET_MED (0)) { - low = 0; - high = GET_MED (0) - 1; - DEC_MED0 (); - } - else { - low = GET_MED (0); - INC_MED0 (); - - if (value - low < GET_MED (1)) { - high = low + GET_MED (1) - 1; - DEC_MED1 (); - } - else { - low += GET_MED (1); - INC_MED1 (); - - if (value - low < GET_MED (2)) { - high = low + GET_MED (2) - 1; - DEC_MED2 (); - } - else { - ones_count = 2 + (value - low) / GET_MED (2); - low += (ones_count - 2) * GET_MED (2); - high = low + GET_MED (2) - 1; - INC_MED2 (); - } - } - } - - mid = (high + low + 1) >> 1; - - if (!c->error_limit) - mid = value; - else - while (high - low > c->error_limit) - if (value < (int32_t) mid) - mid = ((high = mid - 1) + low + 1) >> 1; - else - mid = (high + (low = mid) + 1) >> 1; - - c->slow_level -= (c->slow_level + SLO) >> SLS; - c->slow_level += wp_log2 (mid); - - return sign ? ~mid : mid; -} - -// This function is used to scan some number of samples to set the variables -// "slow_level" and the "median" array. In pure symmetrical encoding mode this -// would not be needed because these values would simply be continued from the -// previous block. However, in the -X modes and the 32-bit modes we cannot do -// this because parameters may change between blocks and the variables might -// not apply. This function can work in mono or stereo and can scan a block -// in either direction. - -static void scan_word_pass (WavpackStream *wps, int32_t *samples, uint32_t num_samples, int dir) -{ - uint32_t flags = wps->wphdr.flags, value, low; - struct entropy_data *c = wps->w.c; - int chan; - - if (flags & MONO_DATA) { - if (dir < 0) { - samples += (num_samples - 1); - dir = -1; - } - else - dir = 1; - } - else { - if (dir < 0) { - samples += (num_samples - 1) * 2; - dir = -2; - } - else - dir = 2; - } - - while (num_samples--) { - - value = labs (samples [chan = 0]); - - if (flags & HYBRID_BITRATE) { - wps->w.c [0].slow_level -= (wps->w.c [0].slow_level + SLO) >> SLS; - wps->w.c [0].slow_level += wp_log2 (value); - } - - if (value < GET_MED (0)) { - DEC_MED0 (); - } - else { - low = GET_MED (0); - INC_MED0 (); - - if (value - low < GET_MED (1)) { - DEC_MED1 (); - } - else { - low += GET_MED (1); - INC_MED1 (); - - if (value - low < GET_MED (2)) { - DEC_MED2 (); - } - else { - INC_MED2 (); - } - } - } - - if (!(flags & MONO_DATA)) { - value = labs (samples [chan = 1]); - c++; - - if (wps->wphdr.flags & HYBRID_BITRATE) { - wps->w.c [1].slow_level -= (wps->w.c [1].slow_level + SLO) >> SLS; - wps->w.c [1].slow_level += wp_log2 (value); - } - - if (value < GET_MED (0)) { - DEC_MED0 (); - } - else { - low = GET_MED (0); - INC_MED0 (); - - if (value - low < GET_MED (1)) { - DEC_MED1 (); - } - else { - low += GET_MED (1); - INC_MED1 (); - - if (value - low < GET_MED (2)) { - DEC_MED2 (); - } - else { - INC_MED2 (); - } - } - } - - c--; - } - - samples += dir; - } -} - -// Wrapper for scan_word_pass() than ensures that at least 2048 samples are processed by -// potentially making multiple passes through the data. See description of scan_word_pass() -// for more details. - -void scan_word (WavpackStream *wps, int32_t *samples, uint32_t num_samples, int dir) -{ - init_words (wps); - - if (num_samples) { - int passes = (2048 + num_samples - 1) / num_samples; // i.e., ceil (2048.0 / num_samples) - - while (passes--) - scan_word_pass (wps, samples, num_samples, dir); - } -} - diff --git a/Frameworks/WavPack/Info.plist b/Frameworks/WavPack/Info.plist deleted file mode 100644 index 5c18bd9f9..000000000 --- a/Frameworks/WavPack/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${EXECUTABLE_NAME} - CFBundleIconFile - - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - ${PRODUCT_NAME} - CFBundlePackageType - FMWK - CFBundleSignature - ???? - CFBundleVersion - 1.0 - NSPrincipalClass - - - diff --git a/Frameworks/WavPack/WavPack.xcodeproj/project.pbxproj b/Frameworks/WavPack/WavPack.xcodeproj/project.pbxproj deleted file mode 100644 index 157697ed7..000000000 --- a/Frameworks/WavPack/WavPack.xcodeproj/project.pbxproj +++ /dev/null @@ -1,554 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 8310BA351D7377850055CEC5 /* common_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA281D7377850055CEC5 /* common_utils.c */; }; - 8310BA361D7377850055CEC5 /* decorr_tables.h in Headers */ = {isa = PBXBuildFile; fileRef = 8310BA291D7377850055CEC5 /* decorr_tables.h */; }; - 8310BA371D7377850055CEC5 /* decorr_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA2A1D7377850055CEC5 /* decorr_utils.c */; }; - 8310BA381D7377850055CEC5 /* entropy_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA2B1D7377850055CEC5 /* entropy_utils.c */; }; - 8310BA391D7377850055CEC5 /* open_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA2C1D7377850055CEC5 /* open_utils.c */; }; - 8310BA3A1D7377850055CEC5 /* read_words.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA2D1D7377850055CEC5 /* read_words.c */; }; - 8310BA3B1D7377850055CEC5 /* tag_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA2E1D7377850055CEC5 /* tag_utils.c */; }; - 8310BA3C1D7377850055CEC5 /* unpack_dsd.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA2F1D7377850055CEC5 /* unpack_dsd.c */; }; - 8310BA3D1D7377850055CEC5 /* unpack_floats.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA301D7377850055CEC5 /* unpack_floats.c */; }; - 8310BA3E1D7377850055CEC5 /* unpack_seek.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA311D7377850055CEC5 /* unpack_seek.c */; }; - 8310BA3F1D7377850055CEC5 /* unpack_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA321D7377850055CEC5 /* unpack_utils.c */; }; - 8310BA401D7377850055CEC5 /* unpack3_open.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA331D7377850055CEC5 /* unpack3_open.c */; }; - 8310BA411D7377850055CEC5 /* unpack3_seek.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA341D7377850055CEC5 /* unpack3_seek.c */; }; - 8310BA431D7377B80055CEC5 /* write_words.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA421D7377B80055CEC5 /* write_words.c */; }; - 8310BA4A1D7377DC0055CEC5 /* open_filename.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA441D7377DC0055CEC5 /* open_filename.c */; }; - 8310BA4B1D7377DC0055CEC5 /* open_legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA451D7377DC0055CEC5 /* open_legacy.c */; }; - 8310BA4C1D7377DC0055CEC5 /* pack_dns.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA461D7377DC0055CEC5 /* pack_dns.c */; }; - 8310BA4D1D7377DC0055CEC5 /* pack_dsd.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA471D7377DC0055CEC5 /* pack_dsd.c */; }; - 8310BA4E1D7377DC0055CEC5 /* pack_floats.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA481D7377DC0055CEC5 /* pack_floats.c */; }; - 8310BA4F1D7377DC0055CEC5 /* pack_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 8310BA491D7377DC0055CEC5 /* pack_utils.c */; }; - 83DD1DD017FA038A00249519 /* utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DD1DCD17FA038A00249519 /* utils.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 83DD1DD117FA038A00249519 /* wavpack_local.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DD1DCE17FA038A00249519 /* wavpack_local.h */; }; - 83DD1DD217FA038A00249519 /* wavpack_version.h in Headers */ = {isa = PBXBuildFile; fileRef = 83DD1DCF17FA038A00249519 /* wavpack_version.h */; }; - 83DD1DD417FA03F900249519 /* tags.c in Sources */ = {isa = PBXBuildFile; fileRef = 83DD1DD317FA03F900249519 /* tags.c */; }; - 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; }; - 8E7574B309F31BB90080F1EE /* md5.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E7574AF09F31BB90080F1EE /* md5.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8E7574B409F31BB90080F1EE /* unpack3.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E7574B009F31BB90080F1EE /* unpack3.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8E7574B509F31BB90080F1EE /* wavpack.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E7574B109F31BB90080F1EE /* wavpack.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 8E7574C609F31BD50080F1EE /* extra1.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E7574B809F31BD50080F1EE /* extra1.c */; }; - 8E7574C709F31BD50080F1EE /* extra2.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E7574B909F31BD50080F1EE /* extra2.c */; }; - 8E7574C909F31BD50080F1EE /* md5.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E7574BB09F31BD50080F1EE /* md5.c */; }; - 8E7574CB09F31BD50080F1EE /* pack.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E7574BD09F31BD50080F1EE /* pack.c */; }; - 8E7574CC09F31BD50080F1EE /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E7574BE09F31BD50080F1EE /* unpack.c */; }; - 8E7574CD09F31BD50080F1EE /* unpack3.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E7574BF09F31BD50080F1EE /* unpack3.c */; }; - 8E7574CE09F31BD50080F1EE /* utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E7574C009F31BD50080F1EE /* utils.c */; }; - 8E7574F509F31C7D0080F1EE /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8E7574F409F31C7D0080F1EE /* libiconv.dylib */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 8310BA281D7377850055CEC5 /* common_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = common_utils.c; path = Files/common_utils.c; sourceTree = ""; }; - 8310BA291D7377850055CEC5 /* decorr_tables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = decorr_tables.h; path = Files/decorr_tables.h; sourceTree = ""; }; - 8310BA2A1D7377850055CEC5 /* decorr_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = decorr_utils.c; path = Files/decorr_utils.c; sourceTree = ""; }; - 8310BA2B1D7377850055CEC5 /* entropy_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = entropy_utils.c; path = Files/entropy_utils.c; sourceTree = ""; }; - 8310BA2C1D7377850055CEC5 /* open_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = open_utils.c; path = Files/open_utils.c; sourceTree = ""; }; - 8310BA2D1D7377850055CEC5 /* read_words.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = read_words.c; path = Files/read_words.c; sourceTree = ""; }; - 8310BA2E1D7377850055CEC5 /* tag_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tag_utils.c; path = Files/tag_utils.c; sourceTree = ""; }; - 8310BA2F1D7377850055CEC5 /* unpack_dsd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack_dsd.c; path = Files/unpack_dsd.c; sourceTree = ""; }; - 8310BA301D7377850055CEC5 /* unpack_floats.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack_floats.c; path = Files/unpack_floats.c; sourceTree = ""; }; - 8310BA311D7377850055CEC5 /* unpack_seek.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack_seek.c; path = Files/unpack_seek.c; sourceTree = ""; }; - 8310BA321D7377850055CEC5 /* unpack_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack_utils.c; path = Files/unpack_utils.c; sourceTree = ""; }; - 8310BA331D7377850055CEC5 /* unpack3_open.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack3_open.c; path = Files/unpack3_open.c; sourceTree = ""; }; - 8310BA341D7377850055CEC5 /* unpack3_seek.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unpack3_seek.c; path = Files/unpack3_seek.c; sourceTree = ""; }; - 8310BA421D7377B80055CEC5 /* write_words.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = write_words.c; path = Files/write_words.c; sourceTree = ""; }; - 8310BA441D7377DC0055CEC5 /* open_filename.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = open_filename.c; path = Files/open_filename.c; sourceTree = ""; }; - 8310BA451D7377DC0055CEC5 /* open_legacy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = open_legacy.c; path = Files/open_legacy.c; sourceTree = ""; }; - 8310BA461D7377DC0055CEC5 /* pack_dns.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pack_dns.c; path = Files/pack_dns.c; sourceTree = ""; }; - 8310BA471D7377DC0055CEC5 /* pack_dsd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pack_dsd.c; path = Files/pack_dsd.c; sourceTree = ""; }; - 8310BA481D7377DC0055CEC5 /* pack_floats.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pack_floats.c; path = Files/pack_floats.c; sourceTree = ""; }; - 8310BA491D7377DC0055CEC5 /* pack_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pack_utils.c; path = Files/pack_utils.c; sourceTree = ""; }; - 833F683A1CDBCAB200AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; - 835C889B22CC188A001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; - 83747BDC2862D5C50021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = ""; }; - 838EE8D329A8600D00CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = ""; }; - 83DD1DCD17FA038A00249519 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = utils.h; path = Files/utils.h; sourceTree = ""; }; - 83DD1DCE17FA038A00249519 /* wavpack_local.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wavpack_local.h; path = Files/wavpack_local.h; sourceTree = ""; }; - 83DD1DCF17FA038A00249519 /* wavpack_version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wavpack_version.h; path = Files/wavpack_version.h; sourceTree = ""; }; - 83DD1DD317FA03F900249519 /* tags.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tags.c; path = Files/tags.c; sourceTree = ""; }; - 83F0E6CD287CAB4400D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = ""; }; - 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; - 8DC2EF5B0486A6940098B216 /* WavPack.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WavPack.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 8E7574AF09F31BB90080F1EE /* md5.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = md5.h; path = Files/md5.h; sourceTree = ""; }; - 8E7574B009F31BB90080F1EE /* unpack3.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = unpack3.h; path = Files/unpack3.h; sourceTree = ""; }; - 8E7574B109F31BB90080F1EE /* wavpack.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = wavpack.h; path = Files/wavpack.h; sourceTree = ""; }; - 8E7574B809F31BD50080F1EE /* extra1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = extra1.c; path = Files/extra1.c; sourceTree = ""; }; - 8E7574B909F31BD50080F1EE /* extra2.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = extra2.c; path = Files/extra2.c; sourceTree = ""; }; - 8E7574BB09F31BD50080F1EE /* md5.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = md5.c; path = Files/md5.c; sourceTree = ""; }; - 8E7574BD09F31BD50080F1EE /* pack.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pack.c; path = Files/pack.c; sourceTree = ""; }; - 8E7574BE09F31BD50080F1EE /* unpack.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = unpack.c; path = Files/unpack.c; sourceTree = ""; }; - 8E7574BF09F31BD50080F1EE /* unpack3.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = unpack3.c; path = Files/unpack3.c; sourceTree = ""; }; - 8E7574C009F31BD50080F1EE /* utils.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = utils.c; path = Files/utils.c; sourceTree = ""; }; - 8E7574F409F31C7D0080F1EE /* libiconv.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libiconv.dylib; path = /usr/lib/libiconv.dylib; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 8DC2EF560486A6940098B216 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 8E7574F509F31C7D0080F1EE /* libiconv.dylib in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 034768DFFF38A50411DB9C8B /* Products */ = { - isa = PBXGroup; - children = ( - 8DC2EF5B0486A6940098B216 /* WavPack.framework */, - ); - name = Products; - sourceTree = ""; - }; - 0867D691FE84028FC02AAC07 /* WavPack */ = { - isa = PBXGroup; - children = ( - 83747BDB2862D5C50021245F /* Xcode-config */, - 8E7574A909F31B9A0080F1EE /* Headers */, - 8E7574A809F31B940080F1EE /* Source */, - 089C1665FE841158C02AAC07 /* Resources */, - 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, - 034768DFFF38A50411DB9C8B /* Products */, - ); - name = WavPack; - sourceTree = ""; - }; - 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */ = { - isa = PBXGroup; - children = ( - 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */, - 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */, - ); - name = "External Frameworks and Libraries"; - sourceTree = ""; - }; - 089C1665FE841158C02AAC07 /* Resources */ = { - isa = PBXGroup; - children = ( - 8DC2EF5A0486A6940098B216 /* Info.plist */, - 089C1666FE841158C02AAC07 /* InfoPlist.strings */, - ); - name = Resources; - sourceTree = ""; - }; - 1058C7B0FEA5585E11CA2CBB /* Linked Frameworks */ = { - isa = PBXGroup; - children = ( - 8E7574F409F31C7D0080F1EE /* libiconv.dylib */, - ); - name = "Linked Frameworks"; - sourceTree = ""; - }; - 1058C7B2FEA5585E11CA2CBB /* Other Frameworks */ = { - isa = PBXGroup; - children = ( - ); - name = "Other Frameworks"; - sourceTree = ""; - }; - 83747BDB2862D5C50021245F /* Xcode-config */ = { - isa = PBXGroup; - children = ( - 83747BDC2862D5C50021245F /* Shared.xcconfig */, - ); - name = "Xcode-config"; - path = "../../Xcode-config"; - sourceTree = ""; - }; - 8E7574A809F31B940080F1EE /* Source */ = { - isa = PBXGroup; - children = ( - 8310BA441D7377DC0055CEC5 /* open_filename.c */, - 8310BA451D7377DC0055CEC5 /* open_legacy.c */, - 8310BA461D7377DC0055CEC5 /* pack_dns.c */, - 8310BA471D7377DC0055CEC5 /* pack_dsd.c */, - 8310BA481D7377DC0055CEC5 /* pack_floats.c */, - 8310BA491D7377DC0055CEC5 /* pack_utils.c */, - 8310BA421D7377B80055CEC5 /* write_words.c */, - 8310BA281D7377850055CEC5 /* common_utils.c */, - 8310BA2A1D7377850055CEC5 /* decorr_utils.c */, - 8310BA2B1D7377850055CEC5 /* entropy_utils.c */, - 8310BA2C1D7377850055CEC5 /* open_utils.c */, - 8310BA2D1D7377850055CEC5 /* read_words.c */, - 8310BA2E1D7377850055CEC5 /* tag_utils.c */, - 8310BA2F1D7377850055CEC5 /* unpack_dsd.c */, - 8310BA301D7377850055CEC5 /* unpack_floats.c */, - 8310BA311D7377850055CEC5 /* unpack_seek.c */, - 8310BA321D7377850055CEC5 /* unpack_utils.c */, - 8310BA331D7377850055CEC5 /* unpack3_open.c */, - 8310BA341D7377850055CEC5 /* unpack3_seek.c */, - 83DD1DD317FA03F900249519 /* tags.c */, - 8E7574B809F31BD50080F1EE /* extra1.c */, - 8E7574B909F31BD50080F1EE /* extra2.c */, - 8E7574BB09F31BD50080F1EE /* md5.c */, - 8E7574BD09F31BD50080F1EE /* pack.c */, - 8E7574BE09F31BD50080F1EE /* unpack.c */, - 8E7574BF09F31BD50080F1EE /* unpack3.c */, - 8E7574C009F31BD50080F1EE /* utils.c */, - ); - name = Source; - sourceTree = ""; - }; - 8E7574A909F31B9A0080F1EE /* Headers */ = { - isa = PBXGroup; - children = ( - 8310BA291D7377850055CEC5 /* decorr_tables.h */, - 83DD1DCD17FA038A00249519 /* utils.h */, - 83DD1DCE17FA038A00249519 /* wavpack_local.h */, - 83DD1DCF17FA038A00249519 /* wavpack_version.h */, - 8E7574AF09F31BB90080F1EE /* md5.h */, - 8E7574B009F31BB90080F1EE /* unpack3.h */, - 8E7574B109F31BB90080F1EE /* wavpack.h */, - ); - name = Headers; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 8DC2EF500486A6940098B216 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 8E7574B309F31BB90080F1EE /* md5.h in Headers */, - 83DD1DD117FA038A00249519 /* wavpack_local.h in Headers */, - 8E7574B409F31BB90080F1EE /* unpack3.h in Headers */, - 83DD1DD017FA038A00249519 /* utils.h in Headers */, - 83DD1DD217FA038A00249519 /* wavpack_version.h in Headers */, - 8310BA361D7377850055CEC5 /* decorr_tables.h in Headers */, - 8E7574B509F31BB90080F1EE /* wavpack.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 8DC2EF4F0486A6940098B216 /* WavPack Framework */ = { - isa = PBXNativeTarget; - buildConfigurationList = 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "WavPack Framework" */; - buildPhases = ( - 8DC2EF500486A6940098B216 /* Headers */, - 8DC2EF520486A6940098B216 /* Resources */, - 8DC2EF540486A6940098B216 /* Sources */, - 8DC2EF560486A6940098B216 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "WavPack Framework"; - productInstallPath = "$(HOME)/Library/Frameworks"; - productName = WavPack; - productReference = 8DC2EF5B0486A6940098B216 /* WavPack.framework */; - productType = "com.apple.product-type.framework"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 0867D690FE84028FC02AAC07 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 1620; - TargetAttributes = { - 8DC2EF4F0486A6940098B216 = { - DevelopmentTeam = ""; - ProvisioningStyle = Manual; - }; - }; - }; - buildConfigurationList = 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "WavPack" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 1; - knownRegions = ( - en, - es, - Base, - pl, - tr, - ); - mainGroup = 0867D691FE84028FC02AAC07 /* WavPack */; - productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 8DC2EF4F0486A6940098B216 /* WavPack Framework */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 8DC2EF520486A6940098B216 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 8DC2EF540486A6940098B216 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 8310BA4A1D7377DC0055CEC5 /* open_filename.c in Sources */, - 8310BA4B1D7377DC0055CEC5 /* open_legacy.c in Sources */, - 8310BA4C1D7377DC0055CEC5 /* pack_dns.c in Sources */, - 8310BA4D1D7377DC0055CEC5 /* pack_dsd.c in Sources */, - 8310BA4E1D7377DC0055CEC5 /* pack_floats.c in Sources */, - 8310BA4F1D7377DC0055CEC5 /* pack_utils.c in Sources */, - 8310BA431D7377B80055CEC5 /* write_words.c in Sources */, - 8310BA351D7377850055CEC5 /* common_utils.c in Sources */, - 8310BA371D7377850055CEC5 /* decorr_utils.c in Sources */, - 8310BA381D7377850055CEC5 /* entropy_utils.c in Sources */, - 8310BA391D7377850055CEC5 /* open_utils.c in Sources */, - 8310BA3A1D7377850055CEC5 /* read_words.c in Sources */, - 8310BA3B1D7377850055CEC5 /* tag_utils.c in Sources */, - 8310BA3C1D7377850055CEC5 /* unpack_dsd.c in Sources */, - 8310BA3D1D7377850055CEC5 /* unpack_floats.c in Sources */, - 8310BA3E1D7377850055CEC5 /* unpack_seek.c in Sources */, - 8310BA3F1D7377850055CEC5 /* unpack_utils.c in Sources */, - 8310BA401D7377850055CEC5 /* unpack3_open.c in Sources */, - 8310BA411D7377850055CEC5 /* unpack3_seek.c in Sources */, - 83DD1DD417FA03F900249519 /* tags.c in Sources */, - 8E7574C609F31BD50080F1EE /* extra1.c in Sources */, - 8E7574C709F31BD50080F1EE /* extra2.c in Sources */, - 8E7574C909F31BD50080F1EE /* md5.c in Sources */, - 8E7574CB09F31BD50080F1EE /* pack.c in Sources */, - 8E7574CC09F31BD50080F1EE /* unpack.c in Sources */, - 8E7574CD09F31BD50080F1EE /* unpack3.c in Sources */, - 8E7574CE09F31BD50080F1EE /* utils.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 089C1666FE841158C02AAC07 /* InfoPlist.strings */ = { - isa = PBXVariantGroup; - children = ( - 833F683A1CDBCAB200AFB9F0 /* es */, - 835C889B22CC188A001B4B3F /* en */, - 83F0E6CD287CAB4400D84594 /* pl */, - 838EE8D329A8600D00CD0580 /* tr */, - ); - name = InfoPlist.strings; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 1DEB91AE08733DA50010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_VERSION = A; - GCC_DYNAMIC_NO_PIC = NO; - GCC_MODEL_TUNING = G5; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - ENABLE_DSD, - ENABLE_LEGACY, - PACK, - UNPACK, - USE_FSTREAMS, - TAGS, - SEEKING, - VER3, - "PACKAGE_NAME='\"wavpack\"'", - "PACKAGE_TARNAME='\"wavpack\"'", - "PACKAGE_VERSION='\"5.2.0\"'", - "PACKAGE_STRING='\"wavpack 5.2.0\"'", - "PACKAGE_BUGREPORT='\"bryant@wavpack.com\"'", - "VERSION_OS='\"Darwin\"'", - ); - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = "@loader_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = org.cogx.lib.wavpack; - PRODUCT_NAME = WavPack; - SDKROOT = macosx; - SKIP_INSTALL = YES; - WRAPPER_EXTENSION = framework; - ZERO_LINK = YES; - }; - name = Debug; - }; - 1DEB91AF08733DA50010E9CD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_IDENTITY = ""; - COMBINE_HIDPI_IMAGES = YES; - DEAD_CODE_STRIPPING = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - FRAMEWORK_VERSION = A; - GCC_MODEL_TUNING = G5; - GCC_PRECOMPILE_PREFIX_HEADER = NO; - GCC_PREFIX_HEADER = ""; - GCC_PREPROCESSOR_DEFINITIONS = ( - ENABLE_DSD, - ENABLE_LEGACY, - PACK, - UNPACK, - USE_FSTREAMS, - TAGS, - SEEKING, - VER3, - "PACKAGE_NAME='\"wavpack\"'", - "PACKAGE_TARNAME='\"wavpack\"'", - "PACKAGE_VERSION='\"4.70.0\"'", - "PACKAGE_STRING='\"wavpack 4.70.0\"'", - "PACKAGE_BUGREPORT='\"bryant@wavpack.com\"'", - "VERSION_OS='\"Darwin\"'", - ); - INFOPLIST_FILE = Info.plist; - INSTALL_PATH = "@loader_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = org.cogx.lib.wavpack; - PRODUCT_NAME = WavPack; - SDKROOT = macosx; - SKIP_INSTALL = YES; - WRAPPER_EXTENSION = framework; - }; - name = Release; - }; - 1DEB91B208733DA50010E9CD /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 83747BDC2862D5C50021245F /* Shared.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_INHIBIT_ALL_WARNINGS = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; - ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = "-Wframe-larger-than=4000"; - OTHER_CPLUSPLUSFLAGS = "-Wframe-larger-than=16000"; - SDKROOT = macosx; - SYMROOT = ../../build; - }; - name = Debug; - }; - 1DEB91B308733DA50010E9CD /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 83747BDC2862D5C50021245F /* Shared.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_INHIBIT_ALL_WARNINGS = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.13; - OTHER_CFLAGS = "-Wframe-larger-than=4000"; - OTHER_CPLUSPLUSFLAGS = "-Wframe-larger-than=16000"; - SDKROOT = macosx; - SYMROOT = ../../build; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 1DEB91AD08733DA50010E9CD /* Build configuration list for PBXNativeTarget "WavPack Framework" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB91AE08733DA50010E9CD /* Debug */, - 1DEB91AF08733DA50010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 1DEB91B108733DA50010E9CD /* Build configuration list for PBXProject "WavPack" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 1DEB91B208733DA50010E9CD /* Debug */, - 1DEB91B308733DA50010E9CD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 0867D690FE84028FC02AAC07 /* Project object */; -} diff --git a/Frameworks/WavPack/WavPack.xcodeproj/xcshareddata/xcschemes/WavPack Framework.xcscheme b/Frameworks/WavPack/WavPack.xcodeproj/xcshareddata/xcschemes/WavPack Framework.xcscheme deleted file mode 100644 index af61ef3fe..000000000 --- a/Frameworks/WavPack/WavPack.xcodeproj/xcshareddata/xcschemes/WavPack Framework.xcscheme +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Frameworks/WavPack/en.lproj/InfoPlist.strings b/Frameworks/WavPack/en.lproj/InfoPlist.strings deleted file mode 100644 index 7080cf949..000000000 Binary files a/Frameworks/WavPack/en.lproj/InfoPlist.strings and /dev/null differ diff --git a/Frameworks/WavPack/es.lproj/InfoPlist.strings b/Frameworks/WavPack/es.lproj/InfoPlist.strings deleted file mode 100644 index cde2c3450..000000000 --- a/Frameworks/WavPack/es.lproj/InfoPlist.strings +++ /dev/null @@ -1,3 +0,0 @@ -/* Localized versions of Info.plist keys */ - -NSHumanReadableCopyright = "© __MyCompanyName__, 2006"; diff --git a/Frameworks/WavPack/pl.lproj/InfoPlist.strings b/Frameworks/WavPack/pl.lproj/InfoPlist.strings deleted file mode 100644 index 7080cf949..000000000 Binary files a/Frameworks/WavPack/pl.lproj/InfoPlist.strings and /dev/null differ diff --git a/Frameworks/WavPack/tr.lproj/InfoPlist.strings b/Frameworks/WavPack/tr.lproj/InfoPlist.strings deleted file mode 100644 index 7080cf949..000000000 Binary files a/Frameworks/WavPack/tr.lproj/InfoPlist.strings and /dev/null differ diff --git a/Plugins/WavPack/WavPack.xcodeproj/project.pbxproj b/Plugins/WavPack/WavPack.xcodeproj/project.pbxproj index 2ff86d91a..68825a14e 100644 --- a/Plugins/WavPack/WavPack.xcodeproj/project.pbxproj +++ b/Plugins/WavPack/WavPack.xcodeproj/project.pbxproj @@ -8,28 +8,10 @@ /* Begin PBXBuildFile section */ 1745C4DA0B90C42500A6768C /* WavPackDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 1745C4D60B90C42500A6768C /* WavPackDecoder.m */; }; - 17F562D80C3BDA6C0019975C /* WavPack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17F562CA0C3BDA5A0019975C /* WavPack.framework */; }; - 17F562DB0C3BDA6E0019975C /* WavPack.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17F562CA0C3BDA5A0019975C /* WavPack.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + 83E83F792D964AFE0054365C /* libwavpack.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 83E83F782D964AFE0054365C /* libwavpack.a */; }; 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ -/* Begin PBXContainerItemProxy section */ - 17F562C90C3BDA5A0019975C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 17F562C20C3BDA5A0019975C /* WavPack.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 8DC2EF5B0486A6940098B216; - remoteInfo = WavPack; - }; - 17F562DC0C3BDA830019975C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 17F562C20C3BDA5A0019975C /* WavPack.xcodeproj */; - proxyType = 1; - remoteGlobalIDString = 8DC2EF4F0486A6940098B216; - remoteInfo = WavPack; - }; -/* End PBXContainerItemProxy section */ - /* Begin PBXCopyFilesBuildPhase section */ 1745C4FE0B90C4CD00A6768C /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; @@ -37,7 +19,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - 17F562DB0C3BDA6E0019975C /* WavPack.framework in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -50,11 +31,11 @@ 1745C4D50B90C42500A6768C /* WavPackDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WavPackDecoder.h; sourceTree = ""; }; 1745C4D60B90C42500A6768C /* WavPackDecoder.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = WavPackDecoder.m; sourceTree = ""; }; 177FCF940B90C9450011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; - 17F562C20C3BDA5A0019975C /* WavPack.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = WavPack.xcodeproj; path = ../../Frameworks/WavPack/WavPack.xcodeproj; sourceTree = SOURCE_ROOT; }; 32DBCF630370AF2F00C91783 /* WavPack_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WavPack_Prefix.pch; sourceTree = ""; }; 834A42AA287AEFC300EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = ""; }; 83747BE62862D8D60021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = ""; }; 83849133180819EB00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = ""; }; + 83E83F782D964AFE0054365C /* libwavpack.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libwavpack.a; path = /Users/chris/Source/Repos/cog/ThirdParty/WavPack/lib/libwavpack.a; sourceTree = ""; }; 8D5B49B6048680CD000E48DA /* WavPack.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WavPack.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; @@ -65,8 +46,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 17F562D80C3BDA6C0019975C /* WavPack.framework in Frameworks */, 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */, + 83E83F792D964AFE0054365C /* libwavpack.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -118,7 +99,7 @@ 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = { isa = PBXGroup; children = ( - 17F562C20C3BDA5A0019975C /* WavPack.xcodeproj */, + 83E83F782D964AFE0054365C /* libwavpack.a */, 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */, ); name = "Linked Frameworks"; @@ -134,14 +115,6 @@ name = "Other Frameworks"; sourceTree = ""; }; - 17F562C30C3BDA5A0019975C /* Products */ = { - isa = PBXGroup; - children = ( - 17F562CA0C3BDA5A0019975C /* WavPack.framework */, - ); - name = Products; - sourceTree = ""; - }; 19C28FB8FE9D52D311CA2CBB /* Products */ = { isa = PBXGroup; children = ( @@ -182,7 +155,6 @@ buildRules = ( ); dependencies = ( - 17F562DD0C3BDA830019975C /* PBXTargetDependency */, ); name = "WavPack Plugin"; productInstallPath = "$(HOME)/Library/Bundles"; @@ -215,12 +187,6 @@ ); mainGroup = 089C166AFE841209C02AAC07 /* WavPack */; projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 17F562C30C3BDA5A0019975C /* Products */; - ProjectRef = 17F562C20C3BDA5A0019975C /* WavPack.xcodeproj */; - }, - ); projectRoot = ""; targets = ( 8D5B49AC048680CD000E48DA /* WavPack Plugin */, @@ -228,16 +194,6 @@ }; /* End PBXProject section */ -/* Begin PBXReferenceProxy section */ - 17F562CA0C3BDA5A0019975C /* WavPack.framework */ = { - isa = PBXReferenceProxy; - fileType = wrapper.framework; - path = WavPack.framework; - remoteRef = 17F562C90C3BDA5A0019975C /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - /* Begin PBXResourcesBuildPhase section */ 8D5B49AF048680CD000E48DA /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -259,14 +215,6 @@ }; /* End PBXSourcesBuildPhase section */ -/* Begin PBXTargetDependency section */ - 17F562DD0C3BDA830019975C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = WavPack; - targetProxy = 17F562DC0C3BDA830019975C /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - /* Begin XCBuildConfiguration section */ 1DEB913B08733D840010E9CD /* Debug */ = { isa = XCBuildConfiguration; @@ -286,8 +234,10 @@ GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = WavPack_Prefix.pch; + HEADER_SEARCH_PATHS = ../../ThirdParty/WavPack/include; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/Bundles"; + LIBRARY_SEARCH_PATHS = ../../ThirdParty/WavPack/lib; PRODUCT_BUNDLE_IDENTIFIER = org.cogx.wavpack; PRODUCT_NAME = WavPack; SDKROOT = macosx; @@ -312,8 +262,10 @@ GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = WavPack_Prefix.pch; + HEADER_SEARCH_PATHS = ../../ThirdParty/WavPack/include; INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/Bundles"; + LIBRARY_SEARCH_PATHS = ../../ThirdParty/WavPack/lib; PRODUCT_BUNDLE_IDENTIFIER = org.cogx.wavpack; PRODUCT_NAME = WavPack; SDKROOT = macosx; diff --git a/Plugins/WavPack/WavPackDecoder.h b/Plugins/WavPack/WavPackDecoder.h index 1ec80d281..4d7b5358c 100644 --- a/Plugins/WavPack/WavPackDecoder.h +++ b/Plugins/WavPack/WavPackDecoder.h @@ -11,7 +11,7 @@ #define ChunkHeader WavPackChunkHeader -#import +#import @interface WavPackReader : NSObject { id source; @@ -34,6 +34,9 @@ int32_t *inputBuffer; size_t inputBufferSize; + uint8_t *outputBuffer; + size_t outputBufferSize; + BOOL isDSD; BOOL isLossy; diff --git a/Plugins/WavPack/WavPackDecoder.m b/Plugins/WavPack/WavPackDecoder.m index 553d58bfb..b53866775 100644 --- a/Plugins/WavPack/WavPackDecoder.m +++ b/Plugins/WavPack/WavPackDecoder.m @@ -10,7 +10,31 @@ #import "Logging.h" +#import + +static int worker_threads; + +int get_default_worker_threads (void) +{ + int num_processors = 1; + + size_t len = sizeof (num_processors); + int mib[2] = { CTL_HW, HW_NCPU }; + sysctl (mib, 2, &num_processors, &len, NULL, 0); + + if (num_processors <= 1) + return 0; + else if (num_processors > 4) + return 4; + else + return num_processors; +} + @implementation WavPackReader ++ (void)initialize { + worker_threads = get_default_worker_threads (); +} + - (id)initWithSource:(id)s { self = [super init]; if(self) { @@ -137,6 +161,9 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) { if(![s seekable]) open_flags |= OPEN_STREAMING; + if (worker_threads) + open_flags |= worker_threads << OPEN_THREADS_SHFT; + wpc = WavpackOpenFileInputEx(&reader, (__bridge void *)(wv), (__bridge void *)(wvc), error, open_flags, 0); if(!wpc) { DLog(@"Unable to open file.."); @@ -199,6 +226,15 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) { */ - (AudioChunk *)readAudio { int32_t frames = 1024; + if(worker_threads) { + if(channels <= 2) + frames = (worker_threads + 1) * 48000; + else + frames = 48000; + + while(frames * channels > 8388608 / sizeof(int32_t)) + frames >>= 1; + } id audioChunkClass = NSClassFromString(@"AudioChunk"); AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]]; @@ -211,12 +247,22 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) { int32_t *alias32; const size_t bufferSize = frames * [chunk format].mBytesPerFrame; - uint8_t buffer[bufferSize]; - void *buf = (void *)buffer; + void *buf = (void *)outputBuffer; + if(!buf || outputBufferSize < bufferSize) { + buf = realloc(outputBuffer, bufferSize); + if(!buf) { + return nil; + } + outputBuffer = (uint8_t *)buf; + } size_t newSize = frames * sizeof(int32_t) * channels; if(!inputBuffer || newSize > inputBufferSize) { - inputBuffer = realloc(inputBuffer, inputBufferSize = newSize); + void *inp = realloc(inputBuffer, inputBufferSize = newSize); + if(!inp) { + return nil; + } + inputBuffer = (int32_t *)inp; } samplesRead = WavpackUnpackSamples(wpc, inputBuffer, frames); @@ -263,7 +309,7 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) { frame += samplesRead; [chunk setStreamTimestamp:streamTimestamp]; - [chunk assignSamples:buffer frameCount:samplesRead]; + [chunk assignSamples:outputBuffer frameCount:samplesRead]; return chunk; } @@ -291,6 +337,11 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) { inputBuffer = NULL; inputBufferSize = 0; } + if(outputBuffer) { + free(outputBuffer); + outputBuffer = NULL; + outputBufferSize = 0; + } wvc = nil; wv = nil; } diff --git a/ThirdParty/BASS/README.md b/ThirdParty/BASS/README.md index 139657dc7..af1403fe4 100644 --- a/ThirdParty/BASS/README.md +++ b/ThirdParty/BASS/README.md @@ -12,8 +12,8 @@ already use @rpath now. As of editing, they are: BASS 2.4.17 -BASSMIDI 2.4.14.1 -BASSFLAC 2.4.5.3 -BASSOPUS 2.4.2.3 +BASSMIDI 2.4.15.3 +BASSFLAC 2.4.5.5 +BASSOPUS 2.4.3 BASS_MPC 2.4.1.2 -BASSWV 2.4.7.3 +BASSWV 2.4.7.4 diff --git a/ThirdParty/BASS/bassmidi.h b/ThirdParty/BASS/bassmidi.h index fce6e6d47..59c04ed77 100644 --- a/ThirdParty/BASS/bassmidi.h +++ b/ThirdParty/BASS/bassmidi.h @@ -1,6 +1,6 @@ /* BASSMIDI 2.4 C/C++ header file - Copyright (c) 2006-2022 Un4seen Developments Ltd. + Copyright (c) 2006-2024 Un4seen Developments Ltd. See the BASSMIDI.CHM file for more detailed documentation */ @@ -25,6 +25,8 @@ extern "C" { #ifndef BASSMIDIDEF #define BASSMIDIDEF(f) WINAPI f +#else +#define NOBASSMIDIOVERLOADS #endif typedef DWORD HSOUNDFONT; // soundfont handle @@ -58,6 +60,7 @@ typedef DWORD HSOUNDFONT; // soundfont handle #define BASS_SYNC_MIDI_KEYSIG 0x10007 // Additional BASS_MIDI_StreamCreateFile/etc flags +#define BASS_MIDI_NODRUMPARAMUSER 0x200 #define BASS_MIDI_NODRUMPARAM 0x400 #define BASS_MIDI_NOSYSRESET 0x800 #define BASS_MIDI_DECAYEND 0x1000 @@ -76,8 +79,10 @@ typedef DWORD HSOUNDFONT; // soundfont handle #define BASS_MIDI_FONT_LINATTMOD 0x100000 #define BASS_MIDI_FONT_LINDECVOL 0x200000 #define BASS_MIDI_FONT_NORAMPIN 0x400000 -#define BASS_MIDI_FONT_NOLIMITS 0x800000 +#define BASS_MIDI_FONT_NOSBLIMITS 0x800000 +#define BASS_MIDI_FONT_NOLIMITS BASS_MIDI_FONT_NOSBLIMITS #define BASS_MIDI_FONT_MINFX 0x1000000 +#define BASS_MIDI_FONT_SBLIMITS 0x2000000 typedef struct { HSOUNDFONT font; // soundfont @@ -136,6 +141,7 @@ typedef struct { #define BASS_MIDI_MARK_TRACK 7 // track name #define BASS_MIDI_MARK_INST 8 // instrument name #define BASS_MIDI_MARK_TRACKSTART 9 // track start (SMF2) +#define BASS_MIDI_MARK_SEQSPEC 10 // sequencer-specific #define BASS_MIDI_MARK_TICK 0x10000 // flag: get position in ticks (otherwise bytes) // MIDI events @@ -278,6 +284,9 @@ typedef struct { #define BASS_ATTRIB_MIDI_SPEED 0x12008 #define BASS_ATTRIB_MIDI_REVERB 0x12009 #define BASS_ATTRIB_MIDI_VOL 0x1200a +#define BASS_ATTRIB_MIDI_QUEUE_TICK 0x1200b +#define BASS_ATTRIB_MIDI_QUEUE_BYTE 0x1200c +#define BASS_ATTRIB_MIDI_QUEUE_ASYNC 0x1200d #define BASS_ATTRIB_MIDI_TRACK_VOL 0x12100 // + track # // Additional tag type @@ -369,6 +378,7 @@ BOOL BASSMIDIDEF(BASS_MIDI_InStop)(DWORD device); #ifdef __cplusplus } +#ifndef NOBASSMIDIOVERLOADS static inline BOOL BASS_MIDI_StreamSetFonts(HSTREAM handle, const BASS_MIDI_FONTEX *fonts, DWORD count) { return BASS_MIDI_StreamSetFonts(handle, (const void*)fonts, count | BASS_MIDI_FONT_EX); @@ -389,6 +399,13 @@ static inline DWORD BASS_MIDI_StreamGetFonts(HSTREAM handle, BASS_MIDI_FONTEX2 * return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count | BASS_MIDI_FONT_EX2); } +#if __cplusplus >= 200707 || _MSC_VER >= 1600 +static inline DWORD BASS_MIDI_StreamGetFonts(HSTREAM handle, decltype(nullptr) fonts, DWORD count) +{ + return BASS_MIDI_StreamGetFonts(handle, (void*)fonts, count); +} +#endif + #ifdef _WIN32 static inline HSTREAM BASS_MIDI_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags, DWORD freq) { @@ -416,6 +433,7 @@ static inline BOOL BASS_MIDI_FontUnpack(HSOUNDFONT handle, const WCHAR *outfile, } #endif #endif +#endif #ifdef __OBJC__ #undef BOOL diff --git a/Frameworks/WavPack/Files/wavpack.h b/ThirdParty/WavPack/include/wavpack.h similarity index 93% rename from Frameworks/WavPack/Files/wavpack.h rename to ThirdParty/WavPack/include/wavpack.h index 7a8b9823d..24ccfb13b 100644 --- a/Frameworks/WavPack/Files/wavpack.h +++ b/ThirdParty/WavPack/include/wavpack.h @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////// // **** WAVPACK **** // // Hybrid Lossless Wavefile Compressor // -// Copyright (c) 1998 - 2019 David Bryant. // +// Copyright (c) 1998 - 2024 David Bryant. // // All Rights Reserved. // // Distributed under the BSD Software License (see license.txt) // //////////////////////////////////////////////////////////////////////////// @@ -146,6 +146,15 @@ typedef struct { #define MIN_STREAM_VERS 0x402 // lowest stream version we'll decode #define MAX_STREAM_VERS 0x410 // highest stream version we'll decode or encode +#define WAVPACK_MAX_CHANS 4096 // max channels handled by WavPack format & library + +// This sets the maximum number of channels that the current WavPack CLI applications +// accept. It's somewhat arbitrary because the actual WavPack format and library can +// handle up to 4096 channels. However, anything beyond 256 channels is obviously +// a niche case and is not well tested, so this lower limit is defined for now. + +#define WAVPACK_MAX_CLI_CHANS 256 + // These are the mask bit definitions for the metadata chunk id byte (see format.txt) #define ID_UNIQUE 0x3f @@ -167,6 +176,7 @@ typedef struct { #define ID_WVC_BITSTREAM 0xb #define ID_WVX_BITSTREAM 0xc #define ID_CHANNEL_INFO 0xd +#define ID_DSD_BLOCK 0xe #define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1) #define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2) @@ -178,6 +188,8 @@ typedef struct { #define ID_ALT_EXTENSION (ID_OPTIONAL_DATA | 0x8) #define ID_ALT_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x9) #define ID_NEW_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0xa) +#define ID_CHANNEL_IDENTITIES (ID_OPTIONAL_DATA | 0xb) +#define ID_WVX_NEW_BITSTREAM (ID_OPTIONAL_DATA | ID_WVX_BITSTREAM) #define ID_BLOCK_CHECKSUM (ID_OPTIONAL_DATA | 0xf) ///////////////////////// WavPack Configuration /////////////////////////////// @@ -190,7 +202,7 @@ typedef struct { float bitrate, shaping_weight; int bits_per_sample, bytes_per_sample; int qmode, flags, xmode, num_channels, float_norm_exp; - int32_t block_samples, extra_flags, sample_rate, channel_mask; + int32_t block_samples, worker_threads, sample_rate, channel_mask; unsigned char md5_checksum [16], md5_read; int num_tag_strings; // this field is not used char **tag_strings; // this field is not used @@ -209,7 +221,7 @@ typedef struct { #define CONFIG_DYNAMIC_SHAPING 0x20000 // dynamic noise shaping #define CONFIG_CREATE_EXE 0x40000 // create executable #define CONFIG_CREATE_WVC 0x80000 // create correction file -#define CONFIG_OPTIMIZE_WVC 0x100000 // maximize bybrid compression +#define CONFIG_OPTIMIZE_WVC 0x100000 // maximize hybrid compression #define CONFIG_COMPATIBLE_WRITE 0x400000 // write files for decoders < 4.3 #define CONFIG_CALC_NOISE 0x800000 // calc noise in hybrid mode #define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode @@ -217,6 +229,7 @@ typedef struct { #define CONFIG_MD5_CHECKSUM 0x8000000 // store MD5 signature #define CONFIG_MERGE_BLOCKS 0x10000000 // merge blocks of equal redundancy (for lossyWAV) #define CONFIG_PAIR_UNDEF_CHANS 0x20000000 // encode undefined channels in stereo pairs +#define CONFIG_OPTIMIZE_32BIT 0x40000000 // new optimizations for 32-bit integer files #define CONFIG_OPTIMIZE_MONO 0x80000000 // optimize for mono streams posing as stereo // The lower 8 bits of qmode indicate the use of new features in version 5 that (presently) @@ -244,6 +257,7 @@ typedef struct { #define QMODE_CHANS_UNASSIGNED 0x400 // user specified "..." in --channel-order option #define QMODE_IGNORE_LENGTH 0x800 // user specified to ignore length in file header #define QMODE_RAW_PCM 0x1000 // user specified raw PCM format (no header present) +#define QMODE_EVEN_BYTE_DEPTH 0x2000 // user specified to force even byte bit-depth ////////////// Callbacks used for reading & writing WavPack streams ////////// @@ -316,6 +330,11 @@ WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int f // (just affects retrieving wrappers & MD5 checksums) #define OPEN_NO_CHECKSUM 0x800 // don't verify block checksums before decoding +// new for multithreaded + +#define OPEN_THREADS_SHFT 12 // specify number of additional worker threads here for +#define OPEN_THREADS_MASK 0xF000 // decode; 0 to disable, otherwise 1-15 added threads + int WavpackGetMode (WavpackContext *wpc); #define MODE_WVC 0x1 @@ -385,11 +404,12 @@ int WavpackWriteTag (WavpackContext *wpc); WavpackContext *WavpackOpenFileOutput (WavpackBlockOutput blockout, void *wv_id, void *wvc_id); void WavpackSetFileInformation (WavpackContext *wpc, char *file_extension, unsigned char file_format); -#define WP_FORMAT_WAV 0 // Microsoft RIFF, including BWF and RF64 varients +#define WP_FORMAT_WAV 0 // Microsoft RIFF, including BWF and RF64 variants #define WP_FORMAT_W64 1 // Sony Wave64 #define WP_FORMAT_CAF 2 // Apple CoreAudio #define WP_FORMAT_DFF 3 // Philips DSDIFF #define WP_FORMAT_DSF 4 // Sony DSD Format +#define WP_FORMAT_AIF 5 // Apple AIFF int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples); int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64_t total_samples, const unsigned char *chan_ids); diff --git a/ThirdParty/libraries-debug-overlay.tar.xz b/ThirdParty/libraries-debug-overlay.tar.xz index 622526c5e..57d17a28f 100644 Binary files a/ThirdParty/libraries-debug-overlay.tar.xz and b/ThirdParty/libraries-debug-overlay.tar.xz differ diff --git a/ThirdParty/libraries.tar.xz b/ThirdParty/libraries.tar.xz index 8376b0b45..119b60636 100644 Binary files a/ThirdParty/libraries.tar.xz and b/ThirdParty/libraries.tar.xz differ