Updated WavPack decoder to 5.2.0
parent
3e6d599452
commit
9ca13ad471
|
@ -1,3 +1,11 @@
|
|||
David Bryant <david@wavpack.com>
|
||||
Sebastian Dröge <slomo@circular-chaos.org>
|
||||
Joachim Henke <j-o@users.sourceforge.net>
|
||||
Joël R. Langlois <joel.r.langlois@gmail.com>
|
||||
Alexis Ballier <aballier@gentoo.org>
|
||||
Stephen <stephengroat@users.noreply.github.com>
|
||||
Phil Eichinger <phil@zankapfel.net>
|
||||
Sebastian Ramacher <sramacher@debian.org>
|
||||
luxagen <hello@luxagen.com>
|
||||
Martin Koegler <martin.koegler@chello.at>
|
||||
nu774 <honeycomb77@gmail.com>
|
||||
|
|
|
@ -1,630 +1,366 @@
|
|||
-------------------------------
|
||||
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
|
||||
2019-12-14 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/wvunpack.c
|
||||
-s option: add "5.1 surround side" and "7.1 surround" to reported channel configurations
|
||||
|
||||
2019-12-13 David Bryant <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* src/open_utils.c:
|
||||
fix possible memory leak on opening corrupted files
|
||||
|
||||
2019-12-08 David Bryant <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* cli/import_id3.c:
|
||||
issue #69: add TPUB (Publisher) to accepted ID3v2 tag fields
|
||||
|
||||
2019-03-05 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/wave64.c:
|
||||
issue #68: clear WaveHeader at start to prevent uninitialized read
|
||||
|
||||
2019-03-05 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/dsdiff.c:
|
||||
issue #67: make sure sample rate is specified and non-zero in DFF files
|
||||
|
||||
2019-03-04 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/caff.c:
|
||||
issue #66: make sure CAF files have a "desc" chunk
|
||||
|
||||
2019-03-02 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/dsdiff.c:
|
||||
issue #65: makre sure DSDIFF files have a valid channel count
|
||||
|
||||
2018-12-23 evpobr <evpobr@gmail.com>
|
||||
|
||||
* include/wavpack.h src/wavpack_local.h:
|
||||
remove duplication so that wavpack_local.h can include wavpack.h
|
||||
|
||||
2018-12-16 evpobr <evpobr@gmail.com>
|
||||
|
||||
* Makefile.am, CMakeLists.txt
|
||||
add CMake project
|
||||
|
||||
2018-12-09 orbea <orbea@fredslev.dk>
|
||||
|
||||
* cli/Makefile.am:
|
||||
fix command-line builds with slibtool
|
||||
|
||||
2018-12-08 Ørjan Malde <foxyred333@gmail.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* src/pack_utils.c:
|
||||
issue #53: error on zero sample rate
|
||||
- CVE-2018-19840
|
||||
|
||||
2018-11-29 David Bryant <david@wavpack.com>
|
||||
|
||||
* src/open_utils.c:
|
||||
issue #54: fix potential out-of-bounds heap read
|
||||
- CVE-2018-19841
|
||||
|
||||
2018-11-29 David Bryant <david@wavpack.com>
|
||||
|
||||
* src/open_filename.c:
|
||||
Windows only: use wvc file when verifying encode when source is stdin
|
||||
|
||||
2018-09-03 Mike Tzou <Chocobo1@users.noreply.github.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* src/unpack_armv7.S:
|
||||
fix thumb interworking on ARM by adding .type for assembly functions
|
||||
|
||||
2018-04-30 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/import_id3.c, cli/wavpack.c:
|
||||
allow ID3v2.3 tag import from any file type (not just DSF)
|
||||
|
||||
2018-04-29 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/import_id3.c:
|
||||
handle ID3v2.3 TXXX tags using description for APEv2 item name (w/ case formatting)
|
||||
|
||||
2018-04-24 David Bryant <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* src/common_utils.c:
|
||||
fix memory leaks
|
||||
|
||||
2018-02-11 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/caff.c:
|
||||
issue #26, fix buffer overflows and bad allocs on corrupt CAF files
|
||||
- CVE-2018-7254
|
||||
|
||||
2018-02-10 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/dsdiff.c:
|
||||
issue #28, do not overwrite heap on corrupt DSDIFF file
|
||||
- CVE-2018-7253
|
||||
|
||||
2018-02-04 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/riff.c:
|
||||
issue #27, do not overwrite stack on corrupt RF64 file
|
||||
- CVE-2018-6767
|
||||
|
||||
2017-10-29 David Bryant <david@wavpack.com>
|
||||
|
||||
* src/read_words.c:
|
||||
issue #24, another C++ compiler fix, this time for _BitScanForward()
|
||||
|
||||
2017-10-28 David Bryant <david@wavpack.com>
|
||||
|
||||
* Makefile.am:
|
||||
add README.md to extra distribution files
|
||||
|
||||
2017-10-20 Joël R. Langlois <joel.r.langlois@gmail.com>
|
||||
|
||||
* README, README.md:
|
||||
Updated README to Markdown format.
|
||||
|
||||
2017-10-12 Joël R. Langlois <joel.r.langlois@gmail.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* cli/import_id3.c:
|
||||
experimental fix to handle ID3v2.3 tags that [incorrectly] use synchsafe for the frame size
|
||||
|
||||
2017-08-31 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/wavpack.c
|
||||
briefly describe other utilities in help displays for wavpack
|
||||
|
||||
2017-07-24 David Bryant <david@wavpack.com>
|
||||
|
||||
* cli/md5.h
|
||||
do not try to use libcrypto on OS X
|
||||
|
||||
2017-07-23 David Bryant <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* src/write_words.c:
|
||||
improve quality of scan_word() results on very short blocks (via multiple passes)
|
||||
|
||||
2017-03-01 David Bryant <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <aballier@gentoo.org>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* cli/import_id3.c, cli/wvtag.c:
|
||||
fix GitHub issue #19 (new dependency on wchar_t) by removing dependency
|
||||
|
||||
2017-01-22 David Bryant <david@wavpack.com>
|
||||
|
||||
* .travis.yml:
|
||||
do more exhaustive testing for Travis (but should be faster)
|
||||
|
||||
2017-01-22 Stephen <stephengroat@users.noreply.github.com>
|
||||
|
||||
* .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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* doc/wavpack_doc.html:
|
||||
update user manual for 5.1.0 and wvtag
|
||||
|
||||
2017-01-14 David Bryant <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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 <david@wavpack.com>
|
||||
|
||||
* 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
|
||||
|
|
|
@ -0,0 +1,717 @@
|
|||
---------------------------------
|
||||
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
|
|
@ -1,113 +0,0 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2016 David Bryant. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
This package contains all the source code required to build the WavPack
|
||||
library (libwavpack) and the command-line programs and it has been tested
|
||||
on many platforms. 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.
|
||||
|
||||
On Windows there are solution and project files for Visual Studio 2008 and
|
||||
additional sourcecode to build the CoolEdit/Audition plugin and the 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
|
||||
|
||||
To build everything on Linux, type:
|
||||
|
||||
1. ./configure [--disable-asm] [--enable-man] [--enable-rpath] [--enable-tests]
|
||||
2. make
|
||||
3. make install (optionally, 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". On Windows a third-party Pthreads library is
|
||||
required, so I am not including this in the build for now.
|
||||
|
||||
Notes:
|
||||
|
||||
1. There are three documentation files contained in the distribution:
|
||||
|
||||
doc/wavpack_doc.html contains user-targeted documentation for the
|
||||
command-line programs
|
||||
|
||||
doc/library_use.txt contains a detailed description of the API provided
|
||||
by WavPack library appropriate for read and writing
|
||||
WavPack files and manipulating APEv2 tags
|
||||
|
||||
doc/file_format.txt 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". The
|
||||
section on WavPack can be found here:
|
||||
|
||||
www.wavpack.com/WavPack.pdf
|
||||
|
||||
2. 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 (and 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: the "char" type must be 8-bits (signed or unsigned), a "short"
|
||||
must be 16-bits and the "int" and "long" types must be at least 32-bits.
|
||||
|
||||
3. 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:
|
||||
|
||||
VER4_ONLY to only handle WavPack files from version 4.0 onward
|
||||
(this is highly recommended for most applications
|
||||
because pre-4.0 WavPack files are very old)
|
||||
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
|
||||
|
||||
4. There are alternate versions of this library available specifically designed
|
||||
for "resource limited" CPUs or 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 encoder" is also designed for embedded use and
|
||||
handles the pure lossless, lossy, and hybrid lossless modes. Neither of the
|
||||
"tiny" versions use any memory allocation functions nor do they require
|
||||
floating-point arithmetic support.
|
||||
|
||||
5. Questions or comments should be directed to david@wavpack.com
|
|
@ -0,0 +1,136 @@
|
|||
<img src="http://www.rarewares.org/wavpack/logos/wavpacklogo.png" width="250"></img>
|
||||
|
||||
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).
|
|
@ -11,7 +11,7 @@
|
|||
// 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 dependancies and this is done so that applications that statically
|
||||
// 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.
|
||||
|
@ -40,7 +40,7 @@ const uint32_t sample_rates [] = { 6000, 8000, 9600, 11025, 12000, 16000, 22050,
|
|||
// 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 conatins a valid ID3v1 or APEv2 tag
|
||||
// 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)
|
||||
|
@ -164,7 +164,7 @@ uint32_t WavpackGetSampleIndex (WavpackContext *wpc)
|
|||
int64_t WavpackGetSampleIndex64 (WavpackContext *wpc)
|
||||
{
|
||||
if (wpc) {
|
||||
#ifndef VER4_ONLY
|
||||
#ifdef ENABLE_LEGACY
|
||||
if (wpc->stream3)
|
||||
return get_sample_index3 (wpc);
|
||||
else if (wpc->streams && wpc->streams [0])
|
||||
|
@ -292,6 +292,13 @@ double WavpackGetInstantBitrate (WavpackContext *wpc)
|
|||
// 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)
|
||||
{
|
||||
|
@ -301,11 +308,60 @@ uint32_t WavpackGetChannelLayout (WavpackContext *wpc, unsigned char *reorder)
|
|||
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);
|
||||
|
||||
|
@ -315,7 +371,7 @@ WavpackContext *WavpackCloseFile (WavpackContext *wpc)
|
|||
free (wpc->streams);
|
||||
}
|
||||
|
||||
#ifndef VER4_ONLY
|
||||
#ifdef ENABLE_LEGACY
|
||||
if (wpc->stream3)
|
||||
free_stream3 (wpc);
|
||||
#endif
|
||||
|
@ -328,6 +384,19 @@ WavpackContext *WavpackCloseFile (WavpackContext *wpc)
|
|||
|
||||
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);
|
||||
|
||||
|
@ -335,8 +404,10 @@ WavpackContext *WavpackCloseFile (WavpackContext *wpc)
|
|||
free_tag (&wpc->m_tag);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DSD
|
||||
if (wpc->decimation_context)
|
||||
decimate_dsd_destroy (wpc->decimation_context);
|
||||
#endif
|
||||
|
||||
free (wpc);
|
||||
|
||||
|
@ -374,6 +445,15 @@ 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.
|
||||
|
@ -440,7 +520,7 @@ int WavpackGetReducedChannels (WavpackContext *wpc)
|
|||
}
|
||||
|
||||
// Free all memory allocated for raw WavPack blocks (for all allocated streams)
|
||||
// and free all additonal streams. This does not free the default stream ([0])
|
||||
// and free all additional streams. This does not free the default stream ([0])
|
||||
// which is always kept around.
|
||||
|
||||
void free_streams (WavpackContext *wpc)
|
||||
|
@ -468,31 +548,9 @@ void free_streams (WavpackContext *wpc)
|
|||
wpc->streams [si]->dc.shaping_data = NULL;
|
||||
}
|
||||
|
||||
if (wpc->streams [si]->dsd.probabilities) {
|
||||
free (wpc->streams [si]->dsd.probabilities);
|
||||
wpc->streams [si]->dsd.probabilities = NULL;
|
||||
}
|
||||
|
||||
if (wpc->streams [si]->dsd.summed_probabilities) {
|
||||
free (wpc->streams [si]->dsd.summed_probabilities);
|
||||
wpc->streams [si]->dsd.summed_probabilities = NULL;
|
||||
}
|
||||
|
||||
if (wpc->streams [si]->dsd.value_lookup) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < wpc->streams [si]->dsd.history_bins; ++i)
|
||||
if (wpc->streams [si]->dsd.value_lookup [i])
|
||||
free (wpc->streams [si]->dsd.value_lookup [i]);
|
||||
|
||||
free (wpc->streams [si]->dsd.value_lookup);
|
||||
wpc->streams [si]->dsd.value_lookup = NULL;
|
||||
}
|
||||
|
||||
if (wpc->streams [si]->dsd.ptable) {
|
||||
free (wpc->streams [si]->dsd.ptable);
|
||||
wpc->streams [si]->dsd.ptable = NULL;
|
||||
}
|
||||
#ifdef ENABLE_DSD
|
||||
free_dsd_tables (wpc->streams [si]);
|
||||
#endif
|
||||
|
||||
if (si) {
|
||||
wpc->num_streams--;
|
||||
|
@ -504,6 +562,34 @@ void free_streams (WavpackContext *wpc)
|
|||
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;
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand `-c -o'.
|
||||
|
||||
scriptversion=2005-05-14.22
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand `-c -o'.
|
||||
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file `INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
eat=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as `compile cc -o foo foo.c'.
|
||||
# So we strip `-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no `-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# `.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use `[/.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
File diff suppressed because it is too large
Load Diff
|
@ -32,7 +32,7 @@
|
|||
int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||
{
|
||||
int termcnt = wpmd->byte_length;
|
||||
unsigned char *byteptr = wpmd->data;
|
||||
unsigned char *byteptr = (unsigned char *)wpmd->data;
|
||||
struct decorr_pass *dpp;
|
||||
|
||||
if (termcnt > MAX_NTERMS)
|
||||
|
@ -61,7 +61,7 @@ int read_decorr_terms (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||
{
|
||||
int termcnt = wpmd->byte_length, tcount;
|
||||
char *byteptr = wpmd->data;
|
||||
char *byteptr = (char *)wpmd->data;
|
||||
struct decorr_pass *dpp;
|
||||
|
||||
if (!(wps->wphdr.flags & MONO_DATA))
|
||||
|
@ -93,7 +93,7 @@ int read_decorr_weights (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
|
||||
int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||
{
|
||||
unsigned char *byteptr = wpmd->data;
|
||||
unsigned char *byteptr = (unsigned char *)wpmd->data;
|
||||
unsigned char *endptr = byteptr + wpmd->byte_length;
|
||||
struct decorr_pass *dpp;
|
||||
int tcount;
|
||||
|
@ -171,14 +171,14 @@ int read_decorr_samples (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
int read_shaping_info (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||
{
|
||||
if (wpmd->byte_length == 2) {
|
||||
char *byteptr = wpmd->data;
|
||||
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 = wpmd->data;
|
||||
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)));
|
||||
|
|
|
@ -104,13 +104,13 @@ static const unsigned char exp2_table [] = {
|
|||
|
||||
///////////////////////////// executable code ////////////////////////////////
|
||||
|
||||
// Read the median log2 values from the specifed metadata structure, convert
|
||||
// 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 = wpmd->data;
|
||||
unsigned char *byteptr = (unsigned char *)wpmd->data;
|
||||
|
||||
if (wpmd->byte_length != ((wps->wphdr.flags & MONO_DATA) ? 6 : 12))
|
||||
return FALSE;
|
||||
|
@ -128,14 +128,14 @@ int read_entropy_vars (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
// Read the hybrid related values from the specifed metadata structure, convert
|
||||
// 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 = wpmd->data;
|
||||
unsigned char *byteptr = (unsigned char *)wpmd->data;
|
||||
unsigned char *endptr = byteptr + wpmd->byte_length;
|
||||
|
||||
if (wps->wphdr.flags & HYBRID_BITRATE) {
|
||||
|
|
|
@ -20,11 +20,11 @@
|
|||
// 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 small blocks this seems to work correctly,
|
||||
// but with longer blocks it seems to actually hurt compression (for reasons I
|
||||
// cannot explain), so it's disabled by default
|
||||
// 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
|
||||
#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
|
||||
|
@ -36,7 +36,7 @@
|
|||
|
||||
#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__))
|
||||
#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
|
||||
|
|
|
@ -21,11 +21,11 @@
|
|||
// 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 small blocks this seems to work correctly,
|
||||
// but with longer blocks it seems to actually hurt compression (for reasons I
|
||||
// cannot explain), so it's disabled by default
|
||||
// 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
|
||||
#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
|
||||
|
@ -39,7 +39,7 @@
|
|||
#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__))
|
||||
#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
|
||||
|
|
|
@ -1,242 +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) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
WavPack 4.0 File / Block Format
|
||||
-------------------------------
|
||||
|
||||
December 9, 2006
|
||||
David Bryant
|
||||
|
||||
updated: April 29, 2007
|
||||
updated: Sept 26, 2009
|
||||
|
||||
1.0 INTRODUCTION
|
||||
|
||||
A WavPack 4.0 file consists of a series of WavPack audio blocks. It may also
|
||||
contain tags and other information, but these must be outside the blocks
|
||||
(either before, in-between, or after) and are ignored for the purpose of
|
||||
unpacking audio data. The WavPack blocks are easy to identify by their unique
|
||||
header data, and by looking in the header it is very easy to determine the total
|
||||
size of the block (both in physical bytes and compressed samples) and the audio
|
||||
format stored. There are no specialized seek tables.
|
||||
|
||||
The blocks are completely independent in that they can be decoded to mono or
|
||||
stereo audio all by themselves. The blocks may contain any number of samples
|
||||
(well, up to 131072), either stereo or mono. Obviously, putting more samples
|
||||
in each block is more efficient because of reduced header overhead, but they are
|
||||
reasonably efficient down to even a thousand samples. I have set the max size to
|
||||
1 MB for the whole block, but this is arbitrary. The blocks may be lossless or
|
||||
lossy. Currently the hybrid/lossy modes are basically CBR, but I am planning a
|
||||
quality based VBR version also, and all the provisions exist for this in the
|
||||
format.
|
||||
|
||||
For multichannel audio, the data is divided into some number of stereo and mono
|
||||
streams and multiplexed into separate blocks which repeat in sequence. A flag
|
||||
in the header indicates whether the block is the first or the last in the
|
||||
sequence (for simple mono or stereo files both of these would always be set).
|
||||
The speaker assignments are in standard Microsoft order and the channel_mask is
|
||||
transmitted in a separate piece of metadata. Channels that naturally belong
|
||||
together (i.e. left and right pairs) are put into stereo blocks and other
|
||||
channels are put into mono block. So, for example, a standard 5.1 audio stream
|
||||
would have a channel_mask of 0x3F and be organized into 4 blocks in sequence:
|
||||
|
||||
1. stereo block (front left + front right) (INITIAL_BLOCK)
|
||||
2. mono block (front center)
|
||||
3. mono block (low frequency effects)
|
||||
4. stereo block (back left + back right) (FINAL_BLOCK)
|
||||
|
||||
Correction files (.wvc) have an identical structure to the main file (.wv) and
|
||||
there is a one-to-one correspondence between main file blocks that contain audio
|
||||
and their correction file match (blocks that do not contain audio do not exist
|
||||
in the correction file). The only difference in the headers of main blocks and
|
||||
correction blocks is the size and the CRC value, although it is easy (if a
|
||||
little ugly) to tell the blocks apart by looking at the metadata ids.
|
||||
|
||||
The format is designed with hardware decoding in mind, and so it is possible to
|
||||
decode regular stereo (or mono) WavPack files without buffering an entire block,
|
||||
which allows the memory requirements to be reduced to only a few kilobytes if
|
||||
desired. This is not true of multichannel files, and this also restricts
|
||||
playback of high-resolution files to 24 bits of precision (although neither of
|
||||
these would be associated with low-cost playback equipment).
|
||||
|
||||
2.0 BLOCK HEADER
|
||||
|
||||
Here is the 32-byte little-endian header at the front of every WavPack block:
|
||||
|
||||
typedef struct {
|
||||
char ckID [4]; // "wvpk"
|
||||
uint32_t ckSize; // size of entire block (minus 8, of course)
|
||||
uint16_t version; // 0x402 to 0x410 are currently valid for decode
|
||||
uchar track_no; // track number (0 if not used, like now)
|
||||
uchar index_no; // track sub-index (0 if not used, like now)
|
||||
uint32_t total_samples; // total samples for entire file, but this is
|
||||
// only valid if block_index == 0 and a value of
|
||||
// -1 indicates unknown length
|
||||
uint32_t block_index; // index of first sample in block relative to
|
||||
// beginning of file (normally this would start
|
||||
// at 0 for the first block)
|
||||
uint32_t block_samples; // number of samples in this block (0 = no audio)
|
||||
uint32_t flags; // various flags for id and decoding
|
||||
uint32_t crc; // crc for actual decoded data
|
||||
} WavpackHeader;
|
||||
|
||||
Note that in this context the meaning of "samples" refers to a complete
|
||||
sample for all channels (sometimes called a "frame"). Therefore, in a stereo
|
||||
or multichannel file the actual number of numeric samples is this value
|
||||
multiplied by the number of channels. This effectively limits the size of an
|
||||
on-disk WavPack file to (2^32)-2 samples, although this should not be a big
|
||||
restriction for most applications (that is over 24 hours at 44.1 kHz, no
|
||||
matter how many channels).
|
||||
|
||||
There is no limit to the size of the WavPack file itself, although the
|
||||
library currently cannot seek in WavPack files over 4 gig. Also, the .wav
|
||||
format itself has a 4 gig limit, so this limits the size of the source and
|
||||
destination files (although this is planned to be resolved with the W64
|
||||
and RIFF64 file formats).
|
||||
|
||||
Normally, the first block of a WavPack file that contains audio samples
|
||||
(blocks may contains only metadata) would have "block_index" == 0 and
|
||||
"total_samples" would be equal to the total number of samples in the
|
||||
file. However, there are some possible exceptions to this rule. For example,
|
||||
a file may be created such that its total length is unknown (i.e. with
|
||||
pipes) and in this case total_samples == -1. For these files, the WavPack
|
||||
decoder will attempt to seek to the end of the file to determine the actual
|
||||
length, and if this is impossible then the length is simply unknown.
|
||||
|
||||
Another case is where a WavPack file is created by cutting a portion out of a
|
||||
longer WavPack file (or from a WavPack stream). Since this file would start
|
||||
with a block that didn't have "block_index" == 0, the length would be unknown
|
||||
until a seek to end was performed. In fact, an on-disk file would still be
|
||||
perfectly playable and seekable as long as there were less than (2^32)-2 total
|
||||
samples (the "block_index" could even wrap).
|
||||
|
||||
It is also possible to have streamed WavPack data. In this case both the
|
||||
"block_index" and "total_samples" fields are ignored for every block and the
|
||||
decoder simply decodes every block encountered indefinitely.
|
||||
|
||||
The "flags" field contains information for decoding the block along with some
|
||||
general information including sample size and format, hybrid/lossless,
|
||||
mono/stereo and sampling rate (if one of 15 standard rates). Here are the
|
||||
(little-endian) bit assignments:
|
||||
|
||||
bits 1,0: // 00 = 1 byte / sample (1-8 bits / sample)
|
||||
// 01 = 2 bytes / sample (1-16 bits / sample)
|
||||
// 10 = 3 bytes / sample (1-24 bits / sample)
|
||||
// 11 = 4 bytes / sample (1-32 bits / sample)
|
||||
bit 2: // 0 = stereo output; 1 = mono output
|
||||
bit 3: // 0 = lossless mode; 1 = hybrid mode
|
||||
bit 4: // 0 = true stereo; 1 = joint stereo (mid/side)
|
||||
bit 5: // 0 = independent channels; 1 = cross-channel decorrelation
|
||||
bit 6: // 0 = flat noise spectrum in hybrid; 1 = hybrid noise shaping
|
||||
bit 7: // 0 = integer data; 1 = floating point data
|
||||
bit 8: // 1 = extended size integers (> 24-bit) or shifted integers
|
||||
bit 9: // 0 = hybrid mode parameters control noise level
|
||||
// 1 = hybrid mode parameters control bitrate
|
||||
bit 10: // 1 = hybrid noise balanced between channels
|
||||
bit 11: // 1 = initial block in sequence (for multichannel)
|
||||
bit 12: // 1 = final block in sequence (for multichannel)
|
||||
bits 17-13: // amount of data left-shift after decode (0-31 places)
|
||||
bits 22-18: // maximum magnitude of decoded data
|
||||
// (number of bits integers require minus 1)
|
||||
bits 26-23: // sampling rate (1111 = unknown/custom)
|
||||
bits 27-28: // reserved (but decoders should ignore if set)
|
||||
bit 29: // 1 = use IIR for negative hybrid noise shaping
|
||||
bit 30: // 1 = false stereo (data is mono but output is stereo)
|
||||
bit 31: // reserved (decoders should refuse to decode if set)
|
||||
|
||||
|
||||
3.0 METADATA SUB-BLOCKS
|
||||
|
||||
Following the 32-byte header to the end of the block are a series of "metadata"
|
||||
sub-blocks. These may from 2 bytes long to the size of the entire block and are
|
||||
extremely easy to parse (even without knowing what they mean). These mostly
|
||||
contain extra information needed to decode the audio, but may also contain user
|
||||
information that is not required for decoding and that could be used in the
|
||||
future without breaking existing decoders. The final sub-block is usually the
|
||||
compressed audio bitstream itself, although this is not a strict rule.
|
||||
|
||||
The format of the metadata is:
|
||||
|
||||
uchar id; // mask meaning
|
||||
// ---- -------
|
||||
// 0x1f metadata function
|
||||
// 0x20 decoder need not understand metadata
|
||||
// 0x40 actual data byte length is 1 less
|
||||
// 0x80 large block (> 255 words)
|
||||
|
||||
uchar word_size; // small block: data size in words (padded)
|
||||
or...
|
||||
uchar word_size [3]; // large block: data size in words (padded,
|
||||
little-endian)
|
||||
|
||||
uint16_t data [word_size]; // data, padded to an even # of bytes
|
||||
|
||||
The currently assigned metadata ids are:
|
||||
|
||||
ID_DUMMY 0x0 // could be used to pad WavPack blocks
|
||||
ID_DECORR_TERMS 0x2 // decorrelation terms & deltas (fixed)
|
||||
ID_DECORR_WEIGHTS 0x3 // initial decorrelation weights
|
||||
ID_DECORR_SAMPLES 0x4 // decorrelation sample history
|
||||
ID_ENTROPY_VARS 0x5 // initial entropy variables
|
||||
ID_HYBRID_PROFILE 0x6 // entropy variables specific to hybrid mode
|
||||
ID_SHAPING_WEIGHTS 0x7 // info needed for hybrid lossless (wvc) mode
|
||||
ID_FLOAT_INFO 0x8 // specific info for floating point decode
|
||||
ID_INT32_INFO 0x9 // specific info for decoding integers > 24
|
||||
// bits, or data requiring shift after decode
|
||||
ID_WV_BITSTREAM 0xa // normal compressed audio bitstream (wv file)
|
||||
ID_WVC_BITSTREAM 0xb // correction file bitstream (wvc file)
|
||||
ID_WVX_BITSTREAM 0xc // special extended bitstream for floating
|
||||
// point data or integers > 24 bit (can be
|
||||
// in either wv or wvc file, depending...)
|
||||
ID_CHANNEL_INFO 0xd // contains channel count and channel_mask
|
||||
|
||||
ID_RIFF_HEADER 0x21 // RIFF header for .wav files (before audio)
|
||||
ID_RIFF_TRAILER 0x22 // RIFF trailer for .wav files (after audio)
|
||||
ID_CONFIG_BLOCK 0x25 // some encoding details for info purposes
|
||||
ID_MD5_CHECKSUM 0x26 // 16-byte MD5 sum of raw audio data
|
||||
ID_SAMPLE_RATE 0x27 // non-standard sampling rate info
|
||||
|
||||
Note: unlisted ids are reserved.
|
||||
|
||||
The RIFF header and trailer are optional for most playback purposes, however
|
||||
older decoders (< 4.40) will not decode to .wav files unless at least the
|
||||
ID_RIFF_HEADER is present. In the future these could be used to encode other
|
||||
uncompressed audio formats (like AIFF).
|
||||
|
||||
4.0 METADATA TAGS
|
||||
|
||||
These tags are not to be confused with the metadata sub-blocks described above
|
||||
but are specialized tags for storing user data on many formats of audio files.
|
||||
The tags recommended for use with WavPack files (and the ones that the WavPack
|
||||
supplied plugins and programs will work with) are ID3v1 and APEv2. The ID3v1
|
||||
tags are somewhat primitive and limited, but are supported for legacy purposes.
|
||||
The more recommended tagging format is APEv2 because of its rich functionality
|
||||
and broad software support (it is also used on Monkey's Audio and Musepack
|
||||
files). Both the APEv2 tags and/or ID3v1 tags must come at the end of the
|
||||
WavPack file, with the ID3v1 coming last if both are present.
|
||||
|
||||
For the APEv2 tags, the following field names are officially supported and
|
||||
recommended by WavPack (although there are no restrictions on what field names
|
||||
may be used):
|
||||
|
||||
Artist
|
||||
Title
|
||||
Album
|
||||
Track
|
||||
Year
|
||||
Genre
|
||||
Comment
|
||||
Cuesheet (note: may include replay gain info as remarks)
|
||||
Replaygain_Track_Gain
|
||||
Replaygain_Track_Peak
|
||||
Replaygain_Album_Gain
|
||||
Replaygain_Album_Peak
|
||||
Cover Art (Front)
|
||||
Cover Art (Back)
|
||||
Log
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
Copyright (c) 1998 - 2013 Conifer Software
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Conifer Software nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,264 +1,291 @@
|
|||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||
* MD5 Message-Digest Algorithm (RFC 1321).
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
* Homepage:
|
||||
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
* Author:
|
||||
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Brutally hacked by John Walker back from ANSI C to K&R (no
|
||||
prototypes) to maintain the tradition that Netfone will compile
|
||||
with Sun's original "cc". */
|
||||
#ifndef HAVE_LIBCRYPTO
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <memory.h> /* for memcpy() */
|
||||
#include "md5.h"
|
||||
|
||||
#ifdef sgi
|
||||
#define HIGHFIRST
|
||||
#endif
|
||||
/*
|
||||
* 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)))
|
||||
|
||||
#ifdef sun
|
||||
#define HIGHFIRST
|
||||
#endif
|
||||
/*
|
||||
* 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);
|
||||
|
||||
#ifndef HIGHFIRST
|
||||
#define byteReverse(buf, len) /* Nothing */
|
||||
/*
|
||||
* 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
|
||||
/*
|
||||
* Note: this code is harmless on little-endian machines.
|
||||
*/
|
||||
void byteReverse(buf, longs)
|
||||
unsigned char *buf; unsigned longs;
|
||||
{
|
||||
uint32 t;
|
||||
do {
|
||||
t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||
((unsigned) buf[1] << 8 | buf[0]);
|
||||
*(uint32 *) buf = t;
|
||||
buf += 4;
|
||||
} while (--longs);
|
||||
}
|
||||
#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
|
||||
|
||||
/*
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
* This processes one or more 64-byte data blocks, but does NOT update the bit
|
||||
* counters. There are no alignment requirements.
|
||||
*/
|
||||
void MD5Init(ctx)
|
||||
struct MD5Context *ctx;
|
||||
static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
const unsigned char *ptr;
|
||||
MD5_u32plus a, b, c, d;
|
||||
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
void MD5Update(ctx, buf, len)
|
||||
struct MD5Context *ctx; unsigned char *buf; unsigned len;
|
||||
void MD5_Init(MD5_CTX *ctx)
|
||||
{
|
||||
uint32 t;
|
||||
ctx->a = 0x67452301;
|
||||
ctx->b = 0xefcdab89;
|
||||
ctx->c = 0x98badcfe;
|
||||
ctx->d = 0x10325476;
|
||||
|
||||
/* Update bitcount */
|
||||
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
|
||||
ctx->bits[1]++; /* Carry from low to high */
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||
|
||||
/* Handle any leading odd-sized chunks */
|
||||
|
||||
if (t) {
|
||||
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||
|
||||
t = 64 - t;
|
||||
if (len < t) {
|
||||
memcpy(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memcpy(p, buf, t);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
/* Process data in 64-byte chunks */
|
||||
|
||||
while (len >= 64) {
|
||||
memcpy(ctx->in, buf, 64);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
|
||||
memcpy(ctx->in, buf, len);
|
||||
ctx->lo = 0;
|
||||
ctx->hi = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
void MD5Final(digest, ctx)
|
||||
unsigned char digest[16]; struct MD5Context *ctx;
|
||||
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||
{
|
||||
uint32 *ptr32 = (uint32 *) ctx->in;
|
||||
unsigned count;
|
||||
unsigned char *p;
|
||||
MD5_u32plus saved_lo;
|
||||
unsigned long used, available;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
saved_lo = ctx->lo;
|
||||
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
|
||||
ctx->hi++;
|
||||
ctx->hi += size >> 29;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
used = saved_lo & 0x3f;
|
||||
|
||||
/* Bytes of padding needed to make 64 bytes */
|
||||
count = 64 - 1 - count;
|
||||
if (used) {
|
||||
available = 64 - used;
|
||||
|
||||
/* Pad out to 56 mod 64 */
|
||||
if (count < 8) {
|
||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||
memset(p, 0, count);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, ptr32);
|
||||
if (size < available) {
|
||||
memcpy(&ctx->buffer[used], data, size);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now fill the next block with 56 bytes */
|
||||
memset(ctx->in, 0, 56);
|
||||
} else {
|
||||
/* Pad block to 56 bytes */
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
byteReverse(ctx->in, 14);
|
||||
memcpy(&ctx->buffer[used], data, available);
|
||||
data = (const unsigned char *)data + available;
|
||||
size -= available;
|
||||
body(ctx, ctx->buffer, 64);
|
||||
}
|
||||
|
||||
/* Append length in bits and transform */
|
||||
ptr32 [14] = ctx->bits[0];
|
||||
ptr32 [15] = ctx->bits[1];
|
||||
if (size >= 64) {
|
||||
data = body(ctx, data, size & ~(unsigned long)0x3f);
|
||||
size &= 0x3f;
|
||||
}
|
||||
|
||||
MD5Transform(ctx->buf, ptr32);
|
||||
byteReverse((unsigned char *) ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, 16);
|
||||
memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
|
||||
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);
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
void MD5Transform(buf, in)
|
||||
uint32 buf[4]; uint32 in[16];
|
||||
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
|
||||
{
|
||||
register uint32 a, b, c, d;
|
||||
unsigned long used, available;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
used = ctx->lo & 0x3f;
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
ctx->buffer[used++] = 0x80;
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
available = 64 - used;
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
if (available < 8) {
|
||||
memset(&ctx->buffer[used], 0, available);
|
||||
body(ctx, ctx->buffer, 64);
|
||||
used = 0;
|
||||
available = 64;
|
||||
}
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
memset(&ctx->buffer[used], 0, available - 8);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
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
|
||||
|
|
|
@ -1,26 +1,45 @@
|
|||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
#if defined (__alpha__) || defined (__x86_64__)
|
||||
typedef unsigned int uint32;
|
||||
#else
|
||||
typedef unsigned long uint32;
|
||||
#endif
|
||||
|
||||
struct MD5Context {
|
||||
uint32 buf[4];
|
||||
uint32 bits[2];
|
||||
unsigned char in[64];
|
||||
};
|
||||
|
||||
extern void MD5Init (struct MD5Context *ctx);
|
||||
extern void MD5Update (struct MD5Context *ctx, unsigned char *buf, unsigned len);
|
||||
extern void MD5Final (unsigned char digest[16], struct MD5Context *ctx);
|
||||
extern void MD5Transform (uint32 buf[4], uint32 in[16]);
|
||||
|
||||
/*
|
||||
* This is needed to make RSAREF happy on some MS-DOS compilers.
|
||||
* 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 <solar at openwall.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
typedef struct MD5Context MD5_CTX;
|
||||
|
||||
#endif /* !MD5_H */
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
#include <openssl/md5.h>
|
||||
#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
|
||||
|
|
|
@ -52,6 +52,14 @@
|
|||
#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)
|
||||
|
@ -120,7 +128,7 @@ static int64_t get_length (void *id)
|
|||
FILE *file = id;
|
||||
struct stat statbuf;
|
||||
|
||||
if (!file || fstat (fileno (file), &statbuf) || !(statbuf.st_mode & S_IFREG))
|
||||
if (!file || fstat (fileno (file), &statbuf) || !S_ISREG(statbuf.st_mode))
|
||||
return 0;
|
||||
|
||||
return statbuf.st_size;
|
||||
|
@ -133,7 +141,7 @@ static int can_seek (void *id)
|
|||
FILE *file = id;
|
||||
struct stat statbuf;
|
||||
|
||||
return file && !fstat (fileno (file), &statbuf) && (statbuf.st_mode & S_IFREG);
|
||||
return file && !fstat (fileno (file), &statbuf) && S_ISREG(statbuf.st_mode);
|
||||
}
|
||||
|
||||
static int32_t write_bytes (void *id, void *data, int32_t bcount)
|
||||
|
@ -239,7 +247,7 @@ WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int f
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (wv_id != stdin && (flags & OPEN_WVC)) {
|
||||
if (*infilename != '-' && (flags & OPEN_WVC)) {
|
||||
char *in2filename = malloc (strlen (infilename) + 10);
|
||||
|
||||
strcpy (in2filename, infilename);
|
||||
|
@ -279,7 +287,7 @@ 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);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2016 David Bryant. //
|
||||
// Copyright (c) 1998 - 2019 David Bryant. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -24,49 +24,49 @@ typedef struct {
|
|||
|
||||
static int32_t trans_read_bytes (void *id, void *data, int32_t bcount)
|
||||
{
|
||||
WavpackReaderTranslator *trans = id;
|
||||
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 = id;
|
||||
WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id;
|
||||
return trans->reader->write_bytes (trans->id, data, bcount);
|
||||
}
|
||||
|
||||
static int64_t trans_get_pos (void *id)
|
||||
{
|
||||
WavpackReaderTranslator *trans = 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 = id;
|
||||
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 = id;
|
||||
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 = id;
|
||||
WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id;
|
||||
return trans->reader->push_back_byte (trans->id, c);
|
||||
}
|
||||
|
||||
static int64_t trans_get_length (void *id)
|
||||
{
|
||||
WavpackReaderTranslator *trans = id;
|
||||
WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id;
|
||||
return trans->reader->get_length (trans->id);
|
||||
}
|
||||
|
||||
static int trans_can_seek (void *id)
|
||||
{
|
||||
WavpackReaderTranslator *trans = id;
|
||||
WavpackReaderTranslator *trans = (WavpackReaderTranslator *)id;
|
||||
return trans->reader->can_seek (trans->id);
|
||||
}
|
||||
|
||||
|
@ -76,42 +76,36 @@ static int trans_close_stream (void *id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// 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 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 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.
|
||||
// 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 = malloc (sizeof (WavpackReaderTranslator));
|
||||
trans_wv = (WavpackReaderTranslator *)malloc (sizeof (WavpackReaderTranslator));
|
||||
trans_wv->reader = reader;
|
||||
trans_wv->id = wv_id;
|
||||
}
|
||||
|
||||
if (wvc_id) {
|
||||
trans_wvc = malloc (sizeof (WavpackReaderTranslator));
|
||||
trans_wvc = (WavpackReaderTranslator *)malloc (sizeof (WavpackReaderTranslator));
|
||||
trans_wvc->reader = reader;
|
||||
trans_wvc->id = wvc_id;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,315 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2016 David Bryant. //
|
||||
// Copyright (c) 1998 - 2019 David Bryant. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -33,7 +33,7 @@ static int seek_eof_information (WavpackContext *wpc, int64_t *final_index, int
|
|||
|
||||
WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *wv_id, void *wvc_id, char *error, int flags, int norm_offset)
|
||||
{
|
||||
WavpackContext *wpc = malloc (sizeof (WavpackContext));
|
||||
WavpackContext *wpc = (WavpackContext *)malloc (sizeof (WavpackContext));
|
||||
WavpackStream *wps;
|
||||
int num_blocks = 0;
|
||||
unsigned char first_byte;
|
||||
|
@ -67,7 +67,6 @@ WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *w
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef VER4_ONLY
|
||||
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);
|
||||
|
@ -75,17 +74,22 @@ WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *w
|
|||
|
||||
wpc->reader->push_back_byte (wpc->wv_in, first_byte);
|
||||
|
||||
if (first_byte == 'R')
|
||||
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 = malloc ((wpc->num_streams = 1) * sizeof (wpc->streams [0]));
|
||||
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 = malloc (sizeof (WavpackStream));
|
||||
wpc->streams [0] = wps = (WavpackStream *)malloc (sizeof (WavpackStream));
|
||||
if (!wps) {
|
||||
if (error) strcpy (error, "can't allocate memory");
|
||||
return WavpackCloseFile (wpc);
|
||||
|
@ -104,7 +108,7 @@ WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *w
|
|||
}
|
||||
|
||||
wpc->filepos += bcount;
|
||||
wps->blockbuff = malloc (wps->wphdr.ckSize + 8);
|
||||
wps->blockbuff = (unsigned char *)malloc (wps->wphdr.ckSize + 8);
|
||||
if (!wps->blockbuff) {
|
||||
if (error) strcpy (error, "can't allocate memory");
|
||||
return WavpackCloseFile (wpc);
|
||||
|
@ -116,25 +120,40 @@ WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *w
|
|||
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 && !(flags & OPEN_STREAMING)) {
|
||||
if (GET_BLOCK_INDEX (wps->wphdr) || GET_TOTAL_SAMPLES (wps->wphdr) == -1) {
|
||||
wpc->initial_index = GET_BLOCK_INDEX (wps->wphdr);
|
||||
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;
|
||||
if (wpc->reader->can_seek (wpc->wv_in)) {
|
||||
int64_t final_index = -1;
|
||||
|
||||
seek_eof_information (wpc, &final_index, FALSE);
|
||||
seek_eof_information (wpc, &final_index, FALSE);
|
||||
|
||||
if (final_index != -1)
|
||||
wpc->total_samples = final_index - wpc->initial_index;
|
||||
if (final_index != -1)
|
||||
wpc->total_samples = final_index - wpc->initial_index;
|
||||
}
|
||||
}
|
||||
else
|
||||
wpc->total_samples = GET_TOTAL_SAMPLES (wps->wphdr);
|
||||
}
|
||||
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;
|
||||
|
@ -158,6 +177,11 @@ WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *w
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -173,6 +197,7 @@ WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *w
|
|||
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;
|
||||
|
@ -188,6 +213,10 @@ WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *w
|
|||
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;
|
||||
|
@ -214,7 +243,7 @@ WavpackContext *WavpackOpenFileInputEx64 (WavpackStreamReader64 *reader, void *w
|
|||
int WavpackGetVersion (WavpackContext *wpc)
|
||||
{
|
||||
if (wpc) {
|
||||
#ifndef VER4_ONLY
|
||||
#ifdef ENABLE_LEGACY
|
||||
if (wpc->stream3)
|
||||
return get_version3 (wpc);
|
||||
#endif
|
||||
|
@ -334,7 +363,7 @@ int unpack_init (WavpackContext *wpc)
|
|||
// These functions handle specific metadata types and are called directly
|
||||
// during WavPack block parsing by process_metadata() at the bottom.
|
||||
|
||||
// This function initialzes the main bitstream for audio samples, which must
|
||||
// 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)
|
||||
|
@ -346,7 +375,7 @@ static int init_wv_bitstream (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
// This function initialzes the "correction" bitstream for audio samples,
|
||||
// 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)
|
||||
|
@ -358,7 +387,7 @@ static int init_wvc_bitstream (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
// This function initialzes the "extra" bitstream for audio samples which
|
||||
// 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
|
||||
|
@ -367,7 +396,7 @@ static int init_wvc_bitstream (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
|
||||
static int init_wvx_bitstream (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||
{
|
||||
unsigned char *cp = wpmd->data;
|
||||
unsigned char *cp = (unsigned char *)wpmd->data;
|
||||
|
||||
if (wpmd->byte_length <= 4 || (wpmd->byte_length & 1))
|
||||
return FALSE;
|
||||
|
@ -388,7 +417,7 @@ static int init_wvx_bitstream (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
static int read_int32_info (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||
{
|
||||
int bytecnt = wpmd->byte_length;
|
||||
char *byteptr = wpmd->data;
|
||||
char *byteptr = (char *)wpmd->data;
|
||||
|
||||
if (bytecnt != 4)
|
||||
return FALSE;
|
||||
|
@ -404,7 +433,7 @@ static int read_int32_info (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
static int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||
{
|
||||
int bytecnt = wpmd->byte_length;
|
||||
char *byteptr = wpmd->data;
|
||||
char *byteptr = (char *)wpmd->data;
|
||||
|
||||
if (bytecnt != 4)
|
||||
return FALSE;
|
||||
|
@ -423,7 +452,7 @@ static int read_float_info (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
static int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
||||
{
|
||||
int bytecnt = wpmd->byte_length, shift = 0, mask_bits;
|
||||
unsigned char *byteptr = wpmd->data;
|
||||
unsigned char *byteptr = (unsigned char *)wpmd->data;
|
||||
uint32_t mask = 0;
|
||||
|
||||
if (!bytecnt || bytecnt > 7)
|
||||
|
@ -439,7 +468,7 @@ static int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
|
||||
if (wpc->config.num_channels < wpc->max_streams)
|
||||
return FALSE;
|
||||
|
||||
|
||||
byteptr += 3;
|
||||
mask = *byteptr++;
|
||||
mask |= (uint32_t) *byteptr++ << 8;
|
||||
|
@ -470,12 +499,29 @@ static int read_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
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 = wpmd->data;
|
||||
unsigned char *byteptr = (unsigned char *)wpmd->data;
|
||||
|
||||
if (bytecnt >= 3) {
|
||||
wpc->config.flags &= 0xff;
|
||||
|
@ -506,7 +552,7 @@ static int read_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
static int read_new_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
||||
{
|
||||
int bytecnt = wpmd->byte_length;
|
||||
unsigned char *byteptr = wpmd->data;
|
||||
unsigned char *byteptr = (unsigned char *)wpmd->data;
|
||||
|
||||
wpc->version_five = 1; // just having this block signals version 5.0
|
||||
|
||||
|
@ -519,7 +565,7 @@ static int read_new_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
|
||||
// if there's any data, the first two bytes are file_format and qmode flags
|
||||
|
||||
if (bytecnt) {
|
||||
if (bytecnt >= 2) {
|
||||
wpc->file_format = *byteptr++;
|
||||
wpc->config.qmode = (wpc->config.qmode & ~0xff) | *byteptr++;
|
||||
bytecnt -= 2;
|
||||
|
@ -544,7 +590,7 @@ static int read_new_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
if (bytecnt > nchans)
|
||||
return FALSE;
|
||||
|
||||
wpc->channel_reordering = malloc (nchans);
|
||||
wpc->channel_reordering = (unsigned char *)malloc (nchans);
|
||||
|
||||
// note that redundant reordering info is not stored, so we fill in the rest
|
||||
|
||||
|
@ -552,6 +598,10 @@ static int read_new_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
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
|
||||
|
@ -572,7 +622,7 @@ static int read_new_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
static int read_sample_rate (WavpackContext *wpc, WavpackMetadata *wpmd)
|
||||
{
|
||||
int bytecnt = wpmd->byte_length;
|
||||
unsigned char *byteptr = wpmd->data;
|
||||
unsigned char *byteptr = (unsigned char *)wpmd->data;
|
||||
|
||||
if (bytecnt == 3 || bytecnt == 4) {
|
||||
wpc->config.sample_rate = (int32_t) *byteptr++;
|
||||
|
@ -597,7 +647,7 @@ static int read_sample_rate (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
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 = realloc (wpc->wrapper_data, wpc->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);
|
||||
|
@ -685,6 +735,9 @@ static int process_metadata (WavpackContext *wpc, WavpackMetadata *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);
|
||||
|
||||
|
@ -704,7 +757,12 @@ static int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
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))
|
||||
|
@ -732,6 +790,15 @@ static int process_metadata (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
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;
|
||||
}
|
||||
|
@ -887,7 +954,7 @@ static int match_wvc_header (WavpackHeader *wv_hdr, WavpackHeader *wvc_hdr)
|
|||
return (wvci - wvi < 0) ? 1 : -1;
|
||||
}
|
||||
|
||||
if (GET_BLOCK_INDEX (*wvc_hdr) > GET_BLOCK_INDEX (*wv_hdr))
|
||||
if (((GET_BLOCK_INDEX (*wvc_hdr) - GET_BLOCK_INDEX (*wv_hdr)) << 24) < 0)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
|
@ -905,6 +972,7 @@ 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;
|
||||
|
||||
|
@ -918,6 +986,8 @@ int read_wvc_block (WavpackContext *wpc)
|
|||
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
|
||||
|
@ -929,13 +999,12 @@ int read_wvc_block (WavpackContext *wpc)
|
|||
compare_result = match_wvc_header (&wps->wphdr, &wphdr);
|
||||
|
||||
if (!compare_result) {
|
||||
wps->block2buff = malloc (wphdr.ckSize + 8);
|
||||
wps->block2buff = (unsigned char *)malloc (wphdr.ckSize + 8);
|
||||
if (!wps->block2buff)
|
||||
return FALSE;
|
||||
memcpy (wps->block2buff, &wphdr, 32);
|
||||
|
||||
if (wpc->reader->read_bytes (wpc->wvc_in, wps->block2buff + 32, wphdr.ckSize - 24) !=
|
||||
wphdr.ckSize - 24 || (wphdr.flags & UNKNOWN_FLAGS)) {
|
||||
wphdr.ckSize - 24) {
|
||||
free (wps->block2buff);
|
||||
wps->block2buff = NULL;
|
||||
wps->wvc_skip = TRUE;
|
||||
|
@ -943,7 +1012,19 @@ int read_wvc_block (WavpackContext *wpc)
|
|||
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;
|
||||
}
|
||||
|
@ -981,7 +1062,7 @@ static int seek_eof_information (WavpackContext *wpc, int64_t *final_index, int
|
|||
|
||||
// start 1MB from the end-of-file, or from the start if the file is not that big
|
||||
|
||||
if (reader->get_length (id) > 1048576LL)
|
||||
if (reader->get_length (id) > (int64_t) 1048576)
|
||||
reader->set_pos_rel (id, -1048576, SEEK_END);
|
||||
else
|
||||
reader->set_pos_abs (id, 0);
|
||||
|
@ -1013,7 +1094,7 @@ static int seek_eof_information (WavpackContext *wpc, int64_t *final_index, int
|
|||
// beginning of the file) and try again
|
||||
|
||||
if (!blocks) {
|
||||
if (current_pos > 2000000LL)
|
||||
if (current_pos > (int64_t) 2000000)
|
||||
reader->set_pos_rel (id, -2000000, SEEK_CUR);
|
||||
else
|
||||
reader->set_pos_abs (id, 0);
|
||||
|
@ -1041,7 +1122,7 @@ static int seek_eof_information (WavpackContext *wpc, int64_t *final_index, int
|
|||
audio_blocks++;
|
||||
}
|
||||
else if (!audio_blocks) {
|
||||
if (current_pos > 1048576LL)
|
||||
if (current_pos > (int64_t) 1048576)
|
||||
reader->set_pos_rel (id, -1048576, SEEK_CUR);
|
||||
else
|
||||
reader->set_pos_abs (id, 0);
|
||||
|
@ -1082,7 +1163,7 @@ static int seek_eof_information (WavpackContext *wpc, int64_t *final_index, int
|
|||
meta_id &= ID_UNIQUE;
|
||||
|
||||
if (get_wrapper && (meta_id == ID_RIFF_TRAILER || (alt_types && meta_id == ID_ALT_TRAILER)) && meta_bc) {
|
||||
wpc->wrapper_data = realloc (wpc->wrapper_data, wpc->wrapper_bytes + 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);
|
||||
|
@ -1115,3 +1196,89 @@ static int seek_eof_information (WavpackContext *wpc, int64_t *final_index, int
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
|
|
@ -336,6 +336,19 @@ static void write_channel_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
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
|
||||
|
@ -374,7 +387,7 @@ static void write_new_config_info (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
|
||||
wpmd->id = ID_NEW_CONFIG_BLOCK;
|
||||
|
||||
if (wpc->file_format || wpc->config.qmode || wpc->channel_layout) {
|
||||
if (wpc->file_format || (wpc->config.qmode & 0xff) || wpc->channel_layout) {
|
||||
*byteptr++ = (char) wpc->file_format;
|
||||
*byteptr++ = (char) wpc->config.qmode;
|
||||
|
||||
|
@ -454,6 +467,13 @@ int pack_block (WavpackContext *wpc, int32_t *buffer)
|
|||
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);
|
||||
|
@ -462,7 +482,7 @@ int pack_block (WavpackContext *wpc, int32_t *buffer)
|
|||
}
|
||||
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;
|
||||
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),
|
||||
|
@ -474,10 +494,9 @@ int pack_block (WavpackContext *wpc, int32_t *buffer)
|
|||
}
|
||||
|
||||
// This code scans stereo data to check whether it can be stored as mono data
|
||||
// (i.e., all L/R samples identical). This used to be an option because
|
||||
// decoders < 4.30 pre-dated this feature, but now it's standard.
|
||||
// (i.e., all L/R samples identical). Only available with MAX_STREAM_VERS.
|
||||
|
||||
if (!(flags & MONO_FLAG)) {
|
||||
if (!(flags & MONO_FLAG) && wpc->stream_version == MAX_STREAM_VERS) {
|
||||
int32_t lor = 0, diff = 0;
|
||||
int32_t *sptr, *dptr, i;
|
||||
|
||||
|
@ -511,6 +530,9 @@ int pack_block (WavpackContext *wpc, int32_t *buffer)
|
|||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
@ -534,12 +556,23 @@ int pack_block (WavpackContext *wpc, int32_t *buffer)
|
|||
wps->wphdr.flags = flags;
|
||||
}
|
||||
|
||||
if ((flags & FLOAT_DATA) || (flags & MAG_MASK) >> MAG_LSB >= 24) {
|
||||
// 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 (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)) {
|
||||
|
@ -547,14 +580,14 @@ int pack_block (WavpackContext *wpc, int32_t *buffer)
|
|||
orig_data = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
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 {
|
||||
else { // otherwise, we're lossy, so no copy
|
||||
if (flags & FLOAT_DATA) {
|
||||
wps->float_norm_exp = wpc->config.float_norm_exp;
|
||||
|
||||
|
@ -565,20 +598,30 @@ int pack_block (WavpackContext *wpc, int32_t *buffer)
|
|||
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) {
|
||||
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->num_terms = 0;
|
||||
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)
|
||||
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;
|
||||
|
||||
|
@ -590,6 +633,8 @@ int pack_block (WavpackContext *wpc, int32_t *buffer)
|
|||
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;
|
||||
|
||||
|
@ -601,6 +646,8 @@ int pack_block (WavpackContext *wpc, int32_t *buffer)
|
|||
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,
|
||||
|
@ -609,6 +656,10 @@ int pack_block (WavpackContext *wpc, int32_t *buffer)
|
|||
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;
|
||||
|
@ -866,6 +917,12 @@ void send_general_metadata (WavpackContext *wpc)
|
|||
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) {
|
||||
|
@ -902,7 +959,7 @@ void send_general_metadata (WavpackContext *wpc)
|
|||
(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__))
|
||||
#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
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
// This module actually handles the compression of the DSD audio data.
|
||||
|
||||
#ifdef ENABLE_DSD
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
@ -165,7 +167,6 @@ int pack_dsd_block (WavpackContext *wpc, int32_t *buffer)
|
|||
// #define DSD_BYTE_READY(low,high) (!(((low) ^ (high)) >> 24))
|
||||
#define DSD_BYTE_READY(low,high) (!(((low) ^ (high)) & 0xff000000))
|
||||
|
||||
#define MAX_HISTORY_BITS 5
|
||||
#define MAX_PROBABILITY 0xa0 // set to 0xff to disable RLE encoding for probabilities table
|
||||
|
||||
#if (MAX_PROBABILITY < 0xff)
|
||||
|
@ -351,8 +352,8 @@ static int encode_buffer_fast (WavpackStream *wps, int32_t *buffer, int num_samp
|
|||
// 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 * 1280) {
|
||||
int max_sum = 0, sum_values = 0, largest_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) {
|
||||
|
@ -452,7 +453,7 @@ static int encode_buffer_fast (WavpackStream *wps, int32_t *buffer, int num_samp
|
|||
#define DOWN 0x00010000
|
||||
#define DECAY 8
|
||||
|
||||
#define PRECISION 24
|
||||
#define PRECISION 20
|
||||
#define VALUE_ONE (1 << PRECISION)
|
||||
#define PRECISION_USE 12
|
||||
|
||||
|
@ -505,20 +506,16 @@ static int normalize_ptable (int *ptable)
|
|||
|
||||
static int encode_buffer_high (WavpackStream *wps, int32_t *buffer, int num_samples, unsigned char *destination)
|
||||
{
|
||||
uint32_t flags = wps->wphdr.flags, crc = 0xffffffff;
|
||||
unsigned int high = 0xffffffff, low = 0;
|
||||
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;
|
||||
int channel;
|
||||
|
||||
if (!(flags & MONO_DATA))
|
||||
num_samples *= 2;
|
||||
|
||||
if (num_samples < 280)
|
||||
if (num_samples * (stereo + 1) < 280)
|
||||
return -1;
|
||||
|
||||
*dp++ = 2;
|
||||
ep = destination + num_samples - 10;
|
||||
*dp++ = 3;
|
||||
ep = destination + num_samples * (stereo + 1) - 10;
|
||||
|
||||
if (!wps->sample_index) {
|
||||
if (!wps->dsd.ptable)
|
||||
|
@ -543,58 +540,55 @@ static int encode_buffer_high (WavpackStream *wps, int32_t *buffer, int num_samp
|
|||
*dp++ = RATE_S;
|
||||
}
|
||||
|
||||
for (channel = 0; channel < ((flags & MONO_DATA) ? 1 : 2); ++channel) {
|
||||
for (channel = 0; channel <= stereo; ++channel) {
|
||||
sp = wps->dsd.filters + channel;
|
||||
|
||||
*dp++ = (sp->filter1 + 32768) >> 16;
|
||||
*dp++ = (sp->filter2 + 32768) >> 16;
|
||||
*dp++ = (sp->filter3 + 32768) >> 16;
|
||||
*dp++ = (sp->filter4 + 32768) >> 16;
|
||||
*dp++ = (sp->filter5 + 32768) >> 16;
|
||||
*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->filter1 = ((sp->filter1 + 32768) >> 16) << 16;
|
||||
sp->filter2 = ((sp->filter2 + 32768) >> 16) << 16;
|
||||
sp->filter3 = ((sp->filter3 + 32768) >> 16) << 16;
|
||||
sp->filter4 = ((sp->filter4 + 32768) >> 16) << 16;
|
||||
sp->filter5 = ((sp->filter5 + 32768) >> 16) << 16;
|
||||
sp->filter6 = 0;
|
||||
sp->factor = (sp->factor << 16) >> 16;
|
||||
}
|
||||
|
||||
channel = 0;
|
||||
sp = wps->dsd.filters;
|
||||
|
||||
while (dp < ep && num_samples--) {
|
||||
int byte = (*buffer++ & 0xff), bitcount = 8;
|
||||
sp = wps->dsd.filters + channel;
|
||||
int bitcount = 8;
|
||||
|
||||
crc += (crc << 1) + byte;
|
||||
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--) {
|
||||
int value = sp->filter1 - sp->filter5 + sp->filter6 * (sp->factor >> 2);
|
||||
int index = (value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK;
|
||||
int *val = wps->dsd.ptable + index;
|
||||
int32_t *pp = wps->dsd.ptable + ((sp [0].value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK);
|
||||
|
||||
value += sp->filter6 << 3;
|
||||
|
||||
if (byte & 0x80) {
|
||||
high = low + (((high - low) >> 24) ? ((high - low) >> 8) * (*val >> 16) : (((high - low) * (*val >> 16)) >> 8));
|
||||
*val += (UP - *val) >> DECAY;
|
||||
sp->filter1 += (VALUE_ONE - sp->filter1) >> 6;
|
||||
sp->filter2 += (VALUE_ONE - sp->filter2) >> 4;
|
||||
|
||||
if ((value ^ (value - (sp->filter6 << 4))) < 0)
|
||||
sp->factor -= (value >> 31) | 1;
|
||||
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) >> 24) ? ((high - low) >> 8) * (*val >> 16) : (((high - low) * (*val >> 16)) >> 8));
|
||||
*val += (DOWN - *val) >> DECAY;
|
||||
sp->filter1 -= sp->filter1 >> 6;
|
||||
sp->filter2 -= sp->filter2 >> 4;
|
||||
|
||||
if ((value ^ (value - (sp->filter6 << 4))) < 0)
|
||||
sp->factor += (value >> 31) | 1;
|
||||
low += 1 + ((high - low) >> 8) * (*pp >> 16);
|
||||
*pp += (DOWN - *pp) >> DECAY;
|
||||
sp [0].filter0 = 0;
|
||||
}
|
||||
|
||||
while (DSD_BYTE_READY (high, low)) {
|
||||
|
@ -603,15 +597,57 @@ static int encode_buffer_high (WavpackStream *wps, int32_t *buffer, int num_samp
|
|||
low <<= 8;
|
||||
}
|
||||
|
||||
sp->filter3 += (sp->filter2 - sp->filter3) >> 4;
|
||||
sp->filter4 += (sp->filter3 - sp->filter4) >> 4;
|
||||
sp->filter5 += value = (sp->filter4 - sp->filter5) >> 4;
|
||||
sp->filter6 += (value - sp->filter6) >> 3;
|
||||
byte <<= 1;
|
||||
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;
|
||||
}
|
||||
|
||||
if (!(flags & MONO_DATA))
|
||||
channel ^= 1;
|
||||
sp [0].factor -= (sp->factor + 512) >> 10;
|
||||
|
||||
if (stereo)
|
||||
sp [1].factor -= (sp [1].factor + 512) >> 10;
|
||||
}
|
||||
|
||||
((WavpackHeader *) wps->blockbuff)->crc = crc;
|
||||
|
@ -628,3 +664,5 @@ static int encode_buffer_high (WavpackStream *wps, int32_t *buffer, int num_samp
|
|||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif // ENABLE_DSD
|
||||
|
|
|
@ -202,7 +202,7 @@ int scan_float_data (WavpackStream *wps, f32 *values, int32_t num_values)
|
|||
// 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 appropiate flags in float_flags and max_exp.
|
||||
// the appropriate flags in float_flags and max_exp.
|
||||
|
||||
void send_float_data (WavpackStream *wps, f32 *values, int32_t num_values)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ WavpackContext *WavpackOpenFileOutput (WavpackBlockOutput blockout, void *wv_id,
|
|||
return NULL;
|
||||
|
||||
CLEAR (*wpc);
|
||||
wpc->total_samples = -1;
|
||||
wpc->stream_version = CUR_STREAM_VERS;
|
||||
wpc->blockout = blockout;
|
||||
wpc->wv_out = wv_id;
|
||||
|
@ -120,35 +121,94 @@ void WavpackSetFileInformation (WavpackContext *wpc, char *file_extension, unsig
|
|||
// 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.
|
||||
|
||||
static const uint32_t stereo_pairings [] = {
|
||||
(1 << 0) | (1 << 1), // FL, FR
|
||||
(1 << 4) | (1 << 5), // BL, BR
|
||||
(1 << 6) | (1 << 7), // FLC, FRC
|
||||
(1 << 9) | (1 << 10), // SL, SR
|
||||
(1 << 12) | (1 << 14), // TFL, TFR
|
||||
(1 << 15) | (1 << 17), // TBL, TBR
|
||||
(1 << 29) | (1 << 30) // stereo mix L,R (RF64)
|
||||
// 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_PAIRINGS (sizeof (stereo_pairings) / sizeof (stereo_pairings [0]))
|
||||
#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);
|
||||
return WavpackSetConfiguration64 (wpc, config, -1, NULL);
|
||||
else
|
||||
return WavpackSetConfiguration64 (wpc, config, total_samples);
|
||||
return WavpackSetConfiguration64 (wpc, config, total_samples, NULL);
|
||||
}
|
||||
|
||||
int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64_t total_samples)
|
||||
int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64_t total_samples, const unsigned char *chan_ids)
|
||||
{
|
||||
uint32_t flags, bps = 0, shift = 0;
|
||||
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;
|
||||
|
||||
|
@ -163,9 +223,19 @@ int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64
|
|||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
@ -188,18 +258,33 @@ int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64
|
|||
break;
|
||||
|
||||
flags |= i << SRATE_LSB;
|
||||
flags |= shift << SHIFT_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
|
||||
shift = (config->bytes_per_sample * 8) - config->bits_per_sample;
|
||||
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;
|
||||
|
@ -235,48 +320,95 @@ int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64
|
|||
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));
|
||||
uint32_t stereo_mask = 0, mono_mask = 0;
|
||||
int pos, chans = 0;
|
||||
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);
|
||||
|
||||
for (pos = 0; pos < 32; ++pos)
|
||||
if (chan_mask & (1 << pos)) {
|
||||
if (mono_mask) {
|
||||
stereo_mask = mono_mask | (1 << pos);
|
||||
break;
|
||||
}
|
||||
else
|
||||
mono_mask = 1 << pos;
|
||||
}
|
||||
|
||||
if (num_chans > 1 && stereo_mask) {
|
||||
for (i = 0; i < NUM_STEREO_PAIRINGS; ++i)
|
||||
if (stereo_mask == stereo_pairings [i]) {
|
||||
chan_mask &= ~stereo_mask;
|
||||
chans = 2;
|
||||
break;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == NUM_STEREO_PAIRINGS) {
|
||||
chan_mask &= ~mono_mask;
|
||||
chans = 1;
|
||||
}
|
||||
}
|
||||
else if (mono_mask) {
|
||||
chan_mask &= ~mono_mask;
|
||||
chans = 1;
|
||||
}
|
||||
|
||||
if (!chans) {
|
||||
if (config->flags & CONFIG_PAIR_UNDEF_CHANS)
|
||||
chans = num_chans > 1 ? 2 : 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
|
||||
chans = 1;
|
||||
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;
|
||||
|
@ -328,6 +460,11 @@ int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64
|
|||
// 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)
|
||||
{
|
||||
|
@ -372,28 +509,37 @@ 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)
|
||||
|
||||
if (wpc->config.flags & CONFIG_HIGH_FLAG)
|
||||
wpc->block_samples = wpc->config.sample_rate;
|
||||
else if (!(wpc->config.sample_rate % 2))
|
||||
wpc->block_samples = wpc->config.sample_rate / 2;
|
||||
else
|
||||
wpc->block_samples = wpc->config.sample_rate;
|
||||
// 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 = 22050;
|
||||
else
|
||||
wpc->block_samples = 44100;
|
||||
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->block_samples * wpc->config.num_channels > 150000)
|
||||
wpc->block_samples /= 2;
|
||||
while (wpc->config.sample_rate % divisor)
|
||||
divisor--;
|
||||
|
||||
while (wpc->block_samples * wpc->config.num_channels < 40000)
|
||||
wpc->block_samples *= 2;
|
||||
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) &&
|
||||
|
@ -414,9 +560,11 @@ int WavpackPackInit (WavpackContext *wpc)
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -715,24 +863,24 @@ static int create_riff_header (WavpackContext *wpc, int64_t total_samples, void
|
|||
wavhdr.GUID [13] = 0x71;
|
||||
}
|
||||
|
||||
strncpy (riffhdr.ckID, do_rf64 ? "RF64" : "RIFF", sizeof (riffhdr.ckID));
|
||||
strncpy (riffhdr.formType, "WAVE", sizeof (riffhdr.formType));
|
||||
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);
|
||||
strncpy (fmthdr.ckID, "fmt ", sizeof (fmthdr.ckID));
|
||||
strncpy (datahdr.ckID, "data", sizeof (datahdr.ckID));
|
||||
memcpy (fmthdr.ckID, "fmt ", sizeof (fmthdr.ckID));
|
||||
memcpy (datahdr.ckID, "data", sizeof (datahdr.ckID));
|
||||
fmthdr.ckSize = wavhdrsize;
|
||||
|
||||
if (write_junk) {
|
||||
CLEAR (junkchunk);
|
||||
strncpy (junkchunk.ckID, "junk", sizeof (junkchunk.ckID));
|
||||
memcpy (junkchunk.ckID, "junk", sizeof (junkchunk.ckID));
|
||||
junkchunk.ckSize = sizeof (junkchunk) - 8;
|
||||
WavpackNativeToLittleEndian (&junkchunk, ChunkHeaderFormat);
|
||||
}
|
||||
|
||||
if (do_rf64) {
|
||||
strncpy (ds64hdr.ckID, "ds64", sizeof (ds64hdr.ckID));
|
||||
memcpy (ds64hdr.ckID, "ds64", sizeof (ds64hdr.ckID));
|
||||
ds64hdr.ckSize = sizeof (ds64_chunk);
|
||||
CLEAR (ds64_chunk);
|
||||
ds64_chunk.riffSize64 = total_riff_bytes;
|
||||
|
@ -772,16 +920,35 @@ static int create_riff_header (WavpackContext *wpc, int64_t total_samples, void
|
|||
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, bcount;
|
||||
uint32_t max_blocksize, max_chans = 1, bcount;
|
||||
unsigned char *outbuff, *outend, *out2buff, *out2end;
|
||||
int result = TRUE;
|
||||
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 = block_samples * 16 + 4096;
|
||||
max_blocksize += max_blocksize; // 100% margin for lossless float data
|
||||
else
|
||||
max_blocksize = block_samples * 10 + 4096;
|
||||
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;
|
||||
|
@ -803,11 +970,20 @@ static int pack_streams (WavpackContext *wpc, uint32_t block_samples)
|
|||
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)
|
||||
|
@ -865,6 +1041,8 @@ static int pack_streams (WavpackContext *wpc, uint32_t block_samples)
|
|||
// 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;
|
||||
|
@ -879,6 +1057,7 @@ void WavpackUpdateNumSamples (WavpackContext *wpc, void *first_block)
|
|||
memcpy (WavpackGetWrapperLocation (first_block, NULL), riff_header, wrapper_size);
|
||||
}
|
||||
|
||||
block_update_checksum (first_block);
|
||||
WavpackNativeToLittleEndian (first_block, WavpackHeaderFormat);
|
||||
}
|
||||
|
||||
|
@ -1081,7 +1260,8 @@ static int write_metadata_block (WavpackContext *wpc)
|
|||
wpmdp++;
|
||||
}
|
||||
|
||||
wphdr = (WavpackHeader *) (block_buff = malloc (block_size));
|
||||
// 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);
|
||||
|
@ -1103,6 +1283,8 @@ static int write_metadata_block (WavpackContext *wpc)
|
|||
|
||||
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)) {
|
||||
|
@ -1124,3 +1306,140 @@ void free_metadata (WavpackMetadata *wpmd)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ static uint32_t __inline read_code (Bitstream *bs, uint32_t maxcode);
|
|||
|
||||
int32_t FASTCALL get_word (WavpackStream *wps, int chan, int32_t *correction)
|
||||
{
|
||||
register struct entropy_data *c = wps->w.c + chan;
|
||||
struct entropy_data *c = wps->w.c + chan;
|
||||
uint32_t ones_count, low, mid, high;
|
||||
int32_t value;
|
||||
int sign;
|
||||
|
@ -124,8 +124,8 @@ int32_t FASTCALL get_word (WavpackStream *wps, int chan, int32_t *correction)
|
|||
wps->wvbits.bc += sizeof (*(wps->wvbits.ptr)) * 8;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
_BitScanForward (&ones_count, ~wps->wvbits.sr);
|
||||
#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
|
||||
|
@ -288,6 +288,10 @@ int32_t FASTCALL get_word (WavpackStream *wps, int chan, int32_t *correction)
|
|||
|
||||
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)
|
||||
|
@ -399,8 +403,8 @@ int32_t get_words_lossless (WavpackStream *wps, int32_t *buffer, int32_t nsample
|
|||
bs->bc += sizeof (*(bs->ptr)) * 8;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
_BitScanForward (&ones_count, ~wps->wvbits.sr);
|
||||
#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
|
||||
|
|
|
@ -411,7 +411,7 @@ static int append_ape_tag_item (WavpackContext *wpc, const char *item, const cha
|
|||
int isize = (int) strlen (item);
|
||||
|
||||
if (!m_tag->ape_tag_hdr.ID [0]) {
|
||||
strncpy (m_tag->ape_tag_hdr.ID, "APETAGEX", sizeof (m_tag->ape_tag_hdr.ID));
|
||||
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;
|
||||
|
@ -429,7 +429,7 @@ static int append_ape_tag_item (WavpackContext *wpc, const char *item, const cha
|
|||
|
||||
m_tag->ape_tag_hdr.item_count++;
|
||||
m_tag->ape_tag_hdr.length += new_item_len;
|
||||
p = m_tag->ape_tag_data = realloc (m_tag->ape_tag_data, m_tag->ape_tag_hdr.length);
|
||||
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;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
// 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 accomodate the data, and this will need to be freed later. A return
|
||||
// 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.
|
||||
|
||||
|
@ -59,7 +59,7 @@ int load_tag (WavpackContext *wpc)
|
|||
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 = malloc (m_tag->ape_tag_hdr.length)) != NULL) {
|
||||
(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;
|
||||
|
@ -145,7 +145,7 @@ int load_tag (WavpackContext *wpc)
|
|||
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.
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#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__))
|
||||
#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
|
||||
|
@ -52,7 +52,7 @@ extern void DECORR_MONO_PASS_CONT (struct decorr_pass *dpp, int32_t *buffer, int
|
|||
///////////////////////////// executable code ////////////////////////////////
|
||||
|
||||
// This monster actually unpacks the WavPack bitstream(s) into the specified
|
||||
// buffer as 32-bit integers or floats (depending on orignal data). Lossy
|
||||
// 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
|
||||
|
@ -83,7 +83,7 @@ int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_co
|
|||
// 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 &&
|
||||
GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index < sample_count)
|
||||
(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)
|
||||
|
@ -148,6 +148,11 @@ int32_t unpack_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sample_co
|
|||
|
||||
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 ///////////////
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
// 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 documenation is provided in the version
|
||||
// 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -1172,11 +1174,11 @@ int32_t unpack_samples3 (WavpackContext *wpc, int32_t *buffer, uint32_t sample_c
|
|||
wpc->crc_errors++;
|
||||
|
||||
if (wpc->open_flags & OPEN_WRAPPER) {
|
||||
unsigned char *temp = malloc (1024);
|
||||
unsigned char *temp = (unsigned char *)malloc (1024);
|
||||
uint32_t bcount;
|
||||
|
||||
if (bs_unused_bytes (&wps->wvbits)) {
|
||||
wpc->wrapper_data = realloc (wpc->wrapper_data, wpc->wrapper_bytes + 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);
|
||||
}
|
||||
|
@ -1187,7 +1189,7 @@ int32_t unpack_samples3 (WavpackContext *wpc, int32_t *buffer, uint32_t sample_c
|
|||
if (!bcount)
|
||||
break;
|
||||
|
||||
wpc->wrapper_data = realloc (wpc->wrapper_data, wpc->wrapper_bytes + bcount);
|
||||
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;
|
||||
}
|
||||
|
@ -1697,3 +1699,5 @@ static unsigned char *bs_unused_data (Bitstream3 *bs)
|
|||
return bs->ptr;
|
||||
}
|
||||
|
||||
#endif // ENABLE_LEGACY
|
||||
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
// 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 documenation
|
||||
// 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -51,7 +53,7 @@ WavpackContext *open_file3 (WavpackContext *wpc, char *error)
|
|||
if (!strncmp (RiffChunkHeader.ckID, "RIFF", 4) && !strncmp (RiffChunkHeader.formType, "WAVE", 4)) {
|
||||
|
||||
if (wpc->open_flags & OPEN_WRAPPER) {
|
||||
wpc->wrapper_data = malloc (wpc->wrapper_bytes = sizeof (RiffChunkHeader));
|
||||
wpc->wrapper_data = (unsigned char *)malloc (wpc->wrapper_bytes = sizeof (RiffChunkHeader));
|
||||
memcpy (wpc->wrapper_data, &RiffChunkHeader, sizeof (RiffChunkHeader));
|
||||
}
|
||||
|
||||
|
@ -69,7 +71,7 @@ WavpackContext *open_file3 (WavpackContext *wpc, char *error)
|
|||
}
|
||||
else {
|
||||
if (wpc->open_flags & OPEN_WRAPPER) {
|
||||
wpc->wrapper_data = realloc (wpc->wrapper_data, wpc->wrapper_bytes + sizeof (ChunkHeader));
|
||||
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);
|
||||
}
|
||||
|
@ -84,7 +86,7 @@ WavpackContext *open_file3 (WavpackContext *wpc, char *error)
|
|||
return WavpackCloseFile (wpc);
|
||||
}
|
||||
else if (wpc->open_flags & OPEN_WRAPPER) {
|
||||
wpc->wrapper_data = realloc (wpc->wrapper_data, wpc->wrapper_bytes + sizeof (wavhdr));
|
||||
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);
|
||||
}
|
||||
|
@ -100,12 +102,12 @@ WavpackContext *open_file3 (WavpackContext *wpc, char *error)
|
|||
}
|
||||
|
||||
if (wpc->open_flags & OPEN_WRAPPER) {
|
||||
wpc->wrapper_data = realloc (wpc->wrapper_data, wpc->wrapper_bytes + bytes_to_skip);
|
||||
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 = malloc (bytes_to_skip);
|
||||
unsigned char *temp = (unsigned char *)malloc (bytes_to_skip);
|
||||
wpc->reader->read_bytes (wpc->wv_in, temp, bytes_to_skip);
|
||||
free (temp);
|
||||
}
|
||||
|
@ -122,12 +124,12 @@ WavpackContext *open_file3 (WavpackContext *wpc, char *error)
|
|||
}
|
||||
|
||||
if (wpc->open_flags & OPEN_WRAPPER) {
|
||||
wpc->wrapper_data = realloc (wpc->wrapper_data, wpc->wrapper_bytes + bytes_to_skip);
|
||||
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 = malloc (bytes_to_skip);
|
||||
unsigned char *temp = (unsigned char *)malloc (bytes_to_skip);
|
||||
wpc->reader->read_bytes (wpc->wv_in, temp, bytes_to_skip);
|
||||
free (temp);
|
||||
}
|
||||
|
@ -283,3 +285,5 @@ void free_stream3 (WavpackContext *wpc)
|
|||
free (wps);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ENABLE_LEGACY
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
// This module provides seeking support for WavPack files prior to version 4.0.
|
||||
|
||||
#ifdef ENABLE_LEGACY
|
||||
#ifndef NO_SEEKING
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -207,4 +208,5 @@ static void bs_restore3 (Bitstream3 *bs)
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // NO_SEEKING
|
||||
#endif // ENABLE_LEGACY
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
// This module actually handles the uncompression of the DSD audio data.
|
||||
|
||||
#ifdef ENABLE_DSD
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
@ -18,7 +20,7 @@
|
|||
|
||||
///////////////////////////// executable code ////////////////////////////////
|
||||
|
||||
// This function initialzes the main range-encoded data for DSD audio samples
|
||||
// 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);
|
||||
|
@ -32,7 +34,7 @@ int init_dsd_block (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
if (wpmd->byte_length < 2)
|
||||
return FALSE;
|
||||
|
||||
wps->dsd.byteptr = wpmd->data;
|
||||
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++;
|
||||
|
@ -48,7 +50,7 @@ int init_dsd_block (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
|
||||
if (wps->dsd.mode == 1)
|
||||
return init_dsd_block_fast (wps, wpmd);
|
||||
else if (wps->dsd.mode == 2)
|
||||
else if (wps->dsd.mode == 3)
|
||||
return init_dsd_block_high (wps, wpmd);
|
||||
else
|
||||
return FALSE;
|
||||
|
@ -57,12 +59,12 @@ int init_dsd_block (WavpackContext *wpc, WavpackMetadata *wpmd)
|
|||
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, crc = wps->crc;
|
||||
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 &&
|
||||
GET_BLOCK_INDEX (wps->wphdr) + wps->wphdr.block_samples - wps->sample_index < sample_count)
|
||||
(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)
|
||||
|
@ -122,12 +124,11 @@ int32_t unpack_dsd_samples (WavpackContext *wpc, int32_t *buffer, uint32_t sampl
|
|||
// #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_HISTORY_BITS 5
|
||||
|
||||
static int init_dsd_block_fast (WavpackStream *wps, WavpackMetadata *wpmd)
|
||||
{
|
||||
unsigned char history_bits, max_probability;
|
||||
int total_summed_probabilities = 0, i;
|
||||
unsigned char history_bits, max_probability, *lb_ptr;
|
||||
int total_summed_probabilities = 0, bi, i;
|
||||
|
||||
if (wps->dsd.byteptr == wps->dsd.endptr)
|
||||
return FALSE;
|
||||
|
@ -139,10 +140,12 @@ static int init_dsd_block_fast (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
|
||||
wps->dsd.history_bins = 1 << history_bits;
|
||||
|
||||
wps->dsd.value_lookup = malloc (sizeof (*wps->dsd.value_lookup) * wps->dsd.history_bins);
|
||||
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 = malloc (sizeof (*wps->dsd.summed_probabilities) * wps->dsd.history_bins);
|
||||
wps->dsd.probabilities = malloc (sizeof (*wps->dsd.probabilities) * 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++;
|
||||
|
||||
|
@ -175,27 +178,28 @@ static int init_dsd_block_fast (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
else
|
||||
return FALSE;
|
||||
|
||||
for (wps->dsd.p0 = 0; wps->dsd.p0 < wps->dsd.history_bins; ++wps->dsd.p0) {
|
||||
for (bi = 0; bi < wps->dsd.history_bins; ++bi) {
|
||||
int32_t sum_values;
|
||||
unsigned char *vp;
|
||||
|
||||
for (sum_values = i = 0; i < 256; ++i)
|
||||
wps->dsd.summed_probabilities [wps->dsd.p0] [i] = sum_values += wps->dsd.probabilities [wps->dsd.p0] [i];
|
||||
wps->dsd.summed_probabilities [bi] [i] = sum_values += wps->dsd.probabilities [bi] [i];
|
||||
|
||||
if (sum_values) {
|
||||
total_summed_probabilities += sum_values;
|
||||
vp = wps->dsd.value_lookup [wps->dsd.p0] = malloc (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 [wps->dsd.p0] [i];
|
||||
int c = wps->dsd.probabilities [bi] [i];
|
||||
|
||||
while (c--)
|
||||
*vp++ = i;
|
||||
*lb_ptr++ = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wps->dsd.endptr - wps->dsd.byteptr < 4 || total_summed_probabilities > wps->dsd.history_bins * 1280)
|
||||
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--;)
|
||||
|
@ -274,7 +278,7 @@ static int decode_fast (WavpackStream *wps, int32_t *output, int sample_count)
|
|||
#define DOWN 0x00010000
|
||||
#define DECAY 8
|
||||
|
||||
#define PRECISION 24
|
||||
#define PRECISION 20
|
||||
#define VALUE_ONE (1 << PRECISION)
|
||||
#define PRECISION_USE 12
|
||||
|
||||
|
@ -314,17 +318,19 @@ static int init_dsd_block_high (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
if (rate_s != RATE_S)
|
||||
return FALSE;
|
||||
|
||||
wps->dsd.ptable = malloc (PTABLE_BINS * sizeof (*wps->dsd.ptable));
|
||||
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++ << 16;
|
||||
sp->filter2 = *wps->dsd.byteptr++ << 16;
|
||||
sp->filter3 = *wps->dsd.byteptr++ << 16;
|
||||
sp->filter4 = *wps->dsd.byteptr++ << 16;
|
||||
sp->filter5 = *wps->dsd.byteptr++ << 16;
|
||||
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;
|
||||
|
@ -344,43 +350,30 @@ static int init_dsd_block_high (WavpackStream *wps, WavpackMetadata *wpmd)
|
|||
|
||||
static int decode_high (WavpackStream *wps, int32_t *output, int sample_count)
|
||||
{
|
||||
int total_samples = sample_count, channel = 0;
|
||||
|
||||
if (!(wps->wphdr.flags & MONO_DATA))
|
||||
total_samples *= 2;
|
||||
int total_samples = sample_count, stereo = (wps->wphdr.flags & MONO_DATA) ? 0 : 1;
|
||||
DSDfilters *sp = wps->dsd.filters;
|
||||
|
||||
while (total_samples--) {
|
||||
DSDfilters *sp = wps->dsd.filters + channel;
|
||||
int byte = 0, bitcount = 8;
|
||||
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--) {
|
||||
int value = sp->filter1 - sp->filter5 + sp->filter6 * (sp->factor >> 2);
|
||||
int index = (value >> (PRECISION - PRECISION_USE)) & PTABLE_MASK;
|
||||
unsigned int range = wps->dsd.high - wps->dsd.low, split;
|
||||
int *val = wps->dsd.ptable + index;
|
||||
|
||||
split = wps->dsd.low + ((range & 0xff000000) ? (range >> 8) * (*val >> 16) : ((range * (*val >> 16)) >> 8));
|
||||
value += sp->filter6 << 3;
|
||||
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;
|
||||
byte = (byte << 1) | 1;
|
||||
*val += (UP - *val) >> DECAY;
|
||||
sp->filter1 += (VALUE_ONE - sp->filter1) >> 6;
|
||||
sp->filter2 += (VALUE_ONE - sp->filter2) >> 4;
|
||||
|
||||
if ((value ^ (value - (sp->filter6 << 4))) < 0)
|
||||
sp->factor -= (value >> 31) | 1;
|
||||
*pp += (UP - *pp) >> DECAY;
|
||||
sp [0].filter0 = -1;
|
||||
}
|
||||
else {
|
||||
wps->dsd.low = split + 1;
|
||||
byte <<= 1;
|
||||
*val += (DOWN - *val) >> DECAY;
|
||||
sp->filter1 -= sp->filter1 >> 6;
|
||||
sp->filter2 -= sp->filter2 >> 4;
|
||||
|
||||
if ((value ^ (value - (sp->filter6 << 4))) < 0)
|
||||
sp->factor += (value >> 31) | 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) {
|
||||
|
@ -389,16 +382,61 @@ static int decode_high (WavpackStream *wps, int32_t *output, int sample_count)
|
|||
wps->dsd.low <<= 8;
|
||||
}
|
||||
|
||||
sp->filter3 += (sp->filter2 - sp->filter3) >> 4;
|
||||
sp->filter4 += (sp->filter3 - sp->filter4) >> 4;
|
||||
sp->filter5 += value = (sp->filter4 - sp->filter5) >> 4;
|
||||
sp->filter6 += (value - sp->filter6) >> 3;
|
||||
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++ = byte);
|
||||
wps->crc += (wps->crc << 1) + (*output++ = sp [0].byte & 0xff);
|
||||
sp [0].factor -= (sp [0].factor + 512) >> 10;
|
||||
|
||||
if (!(wps->wphdr.flags & MONO_DATA))
|
||||
channel ^= 1;
|
||||
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;
|
||||
|
@ -406,9 +444,11 @@ static int decode_high (WavpackStream *wps, int32_t *output, int sample_count)
|
|||
|
||||
/*------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#if 0
|
||||
|
||||
// 80 term DSD decimation filter
|
||||
// < 1 dB down at 20 kHz
|
||||
// > 108 dB stopband attenuation
|
||||
// > 108 dB stopband attenuation (fs/16)
|
||||
|
||||
static const int32_t decm_filter [] = {
|
||||
4, 17, 56, 147, 336, 693, 1320, 2359,
|
||||
|
@ -423,7 +463,28 @@ static const int32_t decm_filter [] = {
|
|||
2359, 1320, 693, 336, 147, 56, 17, 4,
|
||||
};
|
||||
|
||||
#define NUM_FILTER_TERMS ((int)(sizeof (decm_filter) / sizeof (decm_filter [0])))
|
||||
#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 {
|
||||
|
@ -438,7 +499,7 @@ typedef struct {
|
|||
|
||||
void *decimate_dsd_init (int num_channels)
|
||||
{
|
||||
DecimationContext *context = malloc (sizeof (DecimationContext));
|
||||
DecimationContext *context = (DecimationContext *)malloc (sizeof (DecimationContext));
|
||||
double filter_sum = 0, filter_scale;
|
||||
int skipped_terms, i, j;
|
||||
|
||||
|
@ -447,7 +508,7 @@ void *decimate_dsd_init (int num_channels)
|
|||
|
||||
memset (context, 0, sizeof (*context));
|
||||
context->num_channels = num_channels;
|
||||
context->chans = malloc (num_channels * sizeof (DecimationChannel));
|
||||
context->chans = (DecimationChannel *)malloc (num_channels * sizeof (DecimationChannel));
|
||||
|
||||
if (!context->chans) {
|
||||
free (context);
|
||||
|
@ -506,6 +567,7 @@ void decimate_dsd_run (void *decimate_context, int32_t *samples, int 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]];
|
||||
|
@ -516,6 +578,23 @@ void decimate_dsd_run (void *decimate_context, int32_t *samples, int num_samples
|
|||
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) {
|
||||
|
@ -537,3 +616,5 @@ void decimate_dsd_destroy (void *decimate_context)
|
|||
|
||||
free (context);
|
||||
}
|
||||
|
||||
#endif // ENABLE_DSD
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
static int64_t find_sample (WavpackContext *wpc, void *infile, int64_t header_pos, int64_t sample);
|
||||
|
||||
// Seek to the specifed sample index, returning TRUE on success. Note that
|
||||
// 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
|
||||
|
@ -38,7 +38,7 @@ int WavpackSeekSample (WavpackContext *wpc, uint32_t 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;
|
||||
uint32_t bcount, samples_to_skip, samples_to_decode = 0;
|
||||
int32_t *buffer;
|
||||
|
||||
if (wpc->total_samples == -1 || sample >= wpc->total_samples ||
|
||||
|
@ -46,11 +46,24 @@ int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample)
|
|||
(wpc->wvc_flag && !wpc->reader->can_seek (wpc->wvc_in)))
|
||||
return FALSE;
|
||||
|
||||
#ifndef VER4_ONLY
|
||||
#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) {
|
||||
|
||||
|
@ -72,8 +85,13 @@ int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample)
|
|||
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);
|
||||
SET_BLOCK_INDEX (wps->wphdr, GET_BLOCK_INDEX (wps->wphdr) - wpc->initial_index);
|
||||
wps->blockbuff = malloc (wps->wphdr.ckSize + 8);
|
||||
|
||||
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) !=
|
||||
|
@ -82,14 +100,28 @@ int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample)
|
|||
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);
|
||||
SET_BLOCK_INDEX (wps->wphdr, GET_BLOCK_INDEX (wps->wphdr) - wpc->initial_index);
|
||||
wps->block2buff = malloc (wps->wphdr.ckSize + 8);
|
||||
|
||||
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) !=
|
||||
|
@ -97,6 +129,16 @@ int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample)
|
|||
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)) {
|
||||
|
@ -115,8 +157,8 @@ int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
wpc->streams = realloc (wpc->streams, (wpc->num_streams + 1) * sizeof (wpc->streams [0]));
|
||||
wps = wpc->streams [wpc->num_streams++] = malloc (sizeof (WavpackStream));
|
||||
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);
|
||||
|
||||
|
@ -125,7 +167,7 @@ int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
wps->blockbuff = malloc (wps->wphdr.ckSize + 8);
|
||||
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) !=
|
||||
|
@ -134,6 +176,13 @@ int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample)
|
|||
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)) {
|
||||
|
@ -168,12 +217,14 @@ int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample)
|
|||
}
|
||||
|
||||
if (samples_to_skip) {
|
||||
buffer = malloc (samples_to_skip * 8);
|
||||
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);
|
||||
|
@ -181,9 +232,20 @@ int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -198,7 +260,7 @@ int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample)
|
|||
|
||||
static int64_t find_header (WavpackStreamReader64 *reader, void *id, int64_t filepos, WavpackHeader *wphdr)
|
||||
{
|
||||
unsigned char *buffer = malloc (BUFSIZE), *sp = buffer, *ep = buffer;
|
||||
unsigned char *buffer = (unsigned char *)malloc (BUFSIZE), *sp = buffer, *ep = buffer;
|
||||
|
||||
if (filepos != (uint32_t) -1 && reader->set_pos_abs (id, filepos)) {
|
||||
free (buffer);
|
||||
|
@ -210,7 +272,7 @@ static int64_t find_header (WavpackStreamReader64 *reader, void *id, int64_t fil
|
|||
|
||||
if (sp < ep) {
|
||||
bleft = (int)(ep - sp);
|
||||
memcpy (buffer, sp, bleft);
|
||||
memmove (buffer, sp, bleft);
|
||||
ep -= (sp - buffer);
|
||||
sp = buffer;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t sa
|
|||
uint32_t bcount, samples_unpacked = 0, samples_to_unpack;
|
||||
int32_t *bptr = buffer;
|
||||
|
||||
#ifndef VER4_ONLY
|
||||
#ifdef ENABLE_LEGACY
|
||||
if (wpc->stream3)
|
||||
return unpack_samples3 (wpc, buffer, samples);
|
||||
#endif
|
||||
|
@ -69,14 +69,9 @@ uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t sa
|
|||
|
||||
wpc->filepos = nexthdrpos + bcount;
|
||||
|
||||
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);
|
||||
|
||||
// allocate the memory for the entire raw block and read it in
|
||||
|
||||
wps->blockbuff = malloc (wps->wphdr.ckSize + 8);
|
||||
wps->blockbuff = (unsigned char *)malloc (wps->wphdr.ckSize + 8);
|
||||
|
||||
if (!wps->blockbuff)
|
||||
break;
|
||||
|
@ -91,6 +86,21 @@ uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t sa
|
|||
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
|
||||
|
@ -168,7 +178,7 @@ uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t sa
|
|||
// 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 = malloc (samples_to_unpack * 8), *src, *dst;
|
||||
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;
|
||||
|
||||
|
@ -185,12 +195,12 @@ uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t sa
|
|||
// if the stream has not been allocated and corresponding block read, do that here...
|
||||
|
||||
if (wpc->current_stream == wpc->num_streams) {
|
||||
wpc->streams = realloc (wpc->streams, (wpc->num_streams + 1) * sizeof (wpc->streams [0]));
|
||||
wpc->streams = (WavpackStream **)realloc (wpc->streams, (wpc->num_streams + 1) * sizeof (wpc->streams [0]));
|
||||
|
||||
if (!wpc->streams)
|
||||
break;
|
||||
|
||||
wps = wpc->streams [wpc->num_streams++] = malloc (sizeof (WavpackStream));
|
||||
wps = wpc->streams [wpc->num_streams++] = (WavpackStream *)malloc (sizeof (WavpackStream));
|
||||
|
||||
if (!wps)
|
||||
break;
|
||||
|
@ -205,12 +215,7 @@ uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t sa
|
|||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
wps->blockbuff = malloc (wps->wphdr.ckSize + 8);
|
||||
wps->blockbuff = (unsigned char *)malloc (wps->wphdr.ckSize + 8);
|
||||
|
||||
if (!wps->blockbuff)
|
||||
break;
|
||||
|
@ -225,6 +230,22 @@ uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t sa
|
|||
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)
|
||||
|
@ -242,9 +263,11 @@ uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t sa
|
|||
|
||||
// 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;
|
||||
|
@ -325,8 +348,10 @@ uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t sa
|
|||
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);
|
||||
|
||||
|
@ -377,8 +402,10 @@ uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t sa
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_DSD
|
||||
if (wpc->decimation_context)
|
||||
decimate_dsd_run (wpc->decimation_context, buffer, samples_unpacked);
|
||||
#endif
|
||||
|
||||
return samples_unpacked;
|
||||
}
|
||||
|
|
|
@ -691,7 +691,7 @@ int64_t DoGetFileSize (FILE *hFile)
|
|||
{
|
||||
struct stat statbuf;
|
||||
|
||||
if (!hFile || fstat (fileno (hFile), &statbuf) || !(statbuf.st_mode & S_IFREG))
|
||||
if (!hFile || fstat (fileno (hFile), &statbuf) || !S_ISREG(statbuf.st_mode))
|
||||
return 0;
|
||||
|
||||
return (int64_t) statbuf.st_size;
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#else
|
||||
#define VERSION_OS "Win32"
|
||||
#endif
|
||||
#define PACKAGE_VERSION "5.0.0-alpha4"
|
||||
#define PACKAGE_VERSION "5.2.0"
|
||||
#endif
|
||||
|
||||
#define FALSE 0
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2016 David Bryant. //
|
||||
// Copyright (c) 1998 - 2019 David Bryant. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -132,14 +132,17 @@ typedef struct {
|
|||
#define SRATE_MASK (0xfL << SRATE_LSB)
|
||||
|
||||
#define FALSE_STEREO 0x40000000 // block is stereo, but data is mono
|
||||
|
||||
#define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered
|
||||
#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping
|
||||
#define UNKNOWN_FLAGS 0x80000000 // also reserved, but refuse decode if
|
||||
// encountered
|
||||
|
||||
#define MONO_DATA (MONO_FLAG | FALSE_STEREO)
|
||||
|
||||
// Introduced in WavPack 5.0:
|
||||
#define HAS_CHECKSUM 0x10000000 // block contains a trailing checksum
|
||||
#define DSD_FLAG 0x80000000 // block is encoded DSD (1-bit PCM)
|
||||
|
||||
#define IGNORED_FLAGS 0x08000000 // reserved, but ignore if encountered
|
||||
#define UNKNOWN_FLAGS 0x00000000 // we no longer have any of these spares
|
||||
|
||||
#define MIN_STREAM_VERS 0x402 // lowest stream version we'll decode
|
||||
#define MAX_STREAM_VERS 0x410 // highest stream version we'll decode or encode
|
||||
|
||||
|
@ -175,6 +178,7 @@ 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_BLOCK_CHECKSUM (ID_OPTIONAL_DATA | 0xf)
|
||||
|
||||
///////////////////////// WavPack Configuration ///////////////////////////////
|
||||
|
||||
|
@ -206,6 +210,7 @@ typedef struct {
|
|||
#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_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
|
||||
#define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints
|
||||
|
@ -275,7 +280,7 @@ typedef int (*WavpackBlockOutput)(void *id, void *data, int32_t bcount);
|
|||
|
||||
//////////////////////////// function prototypes /////////////////////////////
|
||||
|
||||
typedef void WavpackContext;
|
||||
typedef struct WavpackContext WavpackContext;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -283,6 +288,11 @@ extern "C" {
|
|||
|
||||
#define MAX_WAVPACK_SAMPLES ((1LL << 40) - 257)
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
@ -304,6 +314,7 @@ WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int f
|
|||
#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);
|
||||
|
||||
|
@ -322,6 +333,7 @@ int WavpackGetMode (WavpackContext *wpc);
|
|||
#define MODE_XMODE 0x7000 // mask for extra level (1-6, 0=unknown)
|
||||
#define MODE_DNS 0x8000
|
||||
|
||||
int WavpackVerifySingleBlock (unsigned char *buffer, int verify_checksum);
|
||||
int WavpackGetQualifyMode (WavpackContext *wpc);
|
||||
char *WavpackGetErrorMessage (WavpackContext *wpc);
|
||||
int WavpackGetVersion (WavpackContext *wpc);
|
||||
|
@ -330,6 +342,7 @@ unsigned char WavpackGetFileFormat (WavpackContext *wpc);
|
|||
uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples);
|
||||
uint32_t WavpackGetNumSamples (WavpackContext *wpc);
|
||||
int64_t WavpackGetNumSamples64 (WavpackContext *wpc);
|
||||
uint32_t WavpackGetNumSamplesInFrame (WavpackContext *wpc);
|
||||
uint32_t WavpackGetSampleIndex (WavpackContext *wpc);
|
||||
int64_t WavpackGetSampleIndex64 (WavpackContext *wpc);
|
||||
int WavpackGetNumErrors (WavpackContext *wpc);
|
||||
|
@ -338,6 +351,7 @@ int WavpackSeekSample (WavpackContext *wpc, uint32_t sample);
|
|||
int WavpackSeekSample64 (WavpackContext *wpc, int64_t sample);
|
||||
WavpackContext *WavpackCloseFile (WavpackContext *wpc);
|
||||
uint32_t WavpackGetSampleRate (WavpackContext *wpc);
|
||||
uint32_t WavpackGetNativeSampleRate (WavpackContext *wpc);
|
||||
int WavpackGetBitsPerSample (WavpackContext *wpc);
|
||||
int WavpackGetBytesPerSample (WavpackContext *wpc);
|
||||
int WavpackGetNumChannels (WavpackContext *wpc);
|
||||
|
@ -345,6 +359,7 @@ int WavpackGetChannelMask (WavpackContext *wpc);
|
|||
int WavpackGetReducedChannels (WavpackContext *wpc);
|
||||
int WavpackGetFloatNormExp (WavpackContext *wpc);
|
||||
int WavpackGetMD5Sum (WavpackContext *wpc, unsigned char data [16]);
|
||||
void WavpackGetChannelIdentities (WavpackContext *wpc, unsigned char *identities);
|
||||
uint32_t WavpackGetChannelLayout (WavpackContext *wpc, unsigned char *reorder);
|
||||
uint32_t WavpackGetWrapperBytes (WavpackContext *wpc);
|
||||
unsigned char *WavpackGetWrapperData (WavpackContext *wpc);
|
||||
|
@ -377,7 +392,7 @@ void WavpackSetFileInformation (WavpackContext *wpc, char *file_extension, unsig
|
|||
#define WP_FORMAT_DSF 4 // Sony DSD Format
|
||||
|
||||
int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples);
|
||||
int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64_t total_samples);
|
||||
int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64_t total_samples, const unsigned char *chan_ids);
|
||||
int WavpackSetChannelLayout (WavpackContext *wpc, uint32_t layout_tag, const unsigned char *reorder);
|
||||
int WavpackAddWrapper (WavpackContext *wpc, void *data, uint32_t bcount);
|
||||
int WavpackStoreMD5Sum (WavpackContext *wpc, unsigned char data [16]);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2013 Conifer Software. //
|
||||
// Copyright (c) 1998 - 2019 David Bryant. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -11,7 +11,10 @@
|
|||
#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
|
||||
|
@ -96,120 +99,9 @@ typedef struct {
|
|||
unsigned char *ape_tag_data;
|
||||
} M_Tag;
|
||||
|
||||
// RIFF / wav header formats (these occur at the beginning of both wav files
|
||||
// and pre-4.0 WavPack files that are not in the "raw" mode)
|
||||
|
||||
typedef struct {
|
||||
char ckID [4];
|
||||
uint32_t ckSize;
|
||||
char formType [4];
|
||||
} RiffChunkHeader;
|
||||
|
||||
typedef struct {
|
||||
char ckID [4];
|
||||
uint32_t ckSize;
|
||||
} ChunkHeader;
|
||||
|
||||
#define ChunkHeaderFormat "4L"
|
||||
|
||||
typedef struct {
|
||||
uint16_t FormatTag, NumChannels;
|
||||
uint32_t SampleRate, BytesPerSecond;
|
||||
uint16_t BlockAlign, BitsPerSample;
|
||||
uint16_t cbSize, ValidBitsPerSample;
|
||||
int32_t ChannelMask;
|
||||
uint16_t SubFormat;
|
||||
char GUID [14];
|
||||
} WaveHeader;
|
||||
|
||||
#define WaveHeaderFormat "SSLLSSSSLS"
|
||||
|
||||
////////////////////////////// WavPack Header /////////////////////////////////
|
||||
|
||||
// Note that this is the ONLY structure that is written to (or read from)
|
||||
// WavPack 4.0 files, and is the preamble to every block in both the .wv
|
||||
// and .wvc files.
|
||||
|
||||
typedef struct {
|
||||
char ckID [4];
|
||||
uint32_t ckSize;
|
||||
int16_t version;
|
||||
unsigned char block_index_u8;
|
||||
unsigned char total_samples_u8;
|
||||
uint32_t total_samples, block_index, block_samples, flags, crc;
|
||||
} WavpackHeader;
|
||||
|
||||
#define WavpackHeaderFormat "4LS2LLLLL"
|
||||
|
||||
// Macros to access the 40-bit block_index field
|
||||
|
||||
#define GET_BLOCK_INDEX(hdr) ( (int64_t) (hdr).block_index + ((int64_t) (hdr).block_index_u8 << 32) )
|
||||
|
||||
#define SET_BLOCK_INDEX(hdr,value) do { \
|
||||
int64_t tmp = (value); \
|
||||
(hdr).block_index = (uint32_t) tmp; \
|
||||
(hdr).block_index_u8 = \
|
||||
(unsigned char) (tmp >> 32); \
|
||||
} while (0)
|
||||
|
||||
// Macros to access the 40-bit total_samples field, which is complicated by the fact that
|
||||
// all 1's in the lower 32 bits indicates "unknown" (regardless of upper 8 bits)
|
||||
|
||||
#define GET_TOTAL_SAMPLES(hdr) ( ((hdr).total_samples == (uint32_t) -1) ? -1 : \
|
||||
(int64_t) (hdr).total_samples + ((int64_t) (hdr).total_samples_u8 << 32) - (hdr).total_samples_u8 )
|
||||
|
||||
#define SET_TOTAL_SAMPLES(hdr,value) do { \
|
||||
int64_t tmp = (value); \
|
||||
if (tmp < 0) \
|
||||
(hdr).total_samples = (uint32_t) -1; \
|
||||
else { \
|
||||
tmp += (tmp / 0xffffffffLL); \
|
||||
(hdr).total_samples = (uint32_t) tmp; \
|
||||
(hdr).total_samples_u8 = \
|
||||
(unsigned char) (tmp >> 32); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
// or-values for "flags"
|
||||
|
||||
#define BYTES_STORED 3 // 1-4 bytes/sample
|
||||
#define MONO_FLAG 4 // not stereo
|
||||
#define HYBRID_FLAG 8 // hybrid mode
|
||||
#define JOINT_STEREO 0x10 // joint stereo
|
||||
#define CROSS_DECORR 0x20 // no-delay cross decorrelation
|
||||
#define HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
|
||||
#define FLOAT_DATA 0x80 // ieee 32-bit floating point data
|
||||
|
||||
#define INT32_DATA 0x100 // special extended int handling
|
||||
#define HYBRID_BITRATE 0x200 // bitrate noise (hybrid mode only)
|
||||
#define HYBRID_BALANCE 0x400 // balance noise (hybrid stereo mode only)
|
||||
|
||||
#define INITIAL_BLOCK 0x800 // initial block of multichannel segment
|
||||
#define FINAL_BLOCK 0x1000 // final block of multichannel segment
|
||||
|
||||
#define SHIFT_LSB 13
|
||||
#define SHIFT_MASK (0x1fL << SHIFT_LSB)
|
||||
|
||||
#define MAG_LSB 18
|
||||
#define MAG_MASK (0x1fL << MAG_LSB)
|
||||
|
||||
#define SRATE_LSB 23
|
||||
#define SRATE_MASK (0xfL << SRATE_LSB)
|
||||
|
||||
#define FALSE_STEREO 0x40000000 // block is stereo, but data is mono
|
||||
|
||||
#define IGNORED_FLAGS 0x18000000 // reserved, but ignore if encountered
|
||||
#define NEW_SHAPING 0x20000000 // use IIR filter for negative shaping
|
||||
#define DSD_FLAG 0x80000000 // block is DSD encoded (introduced in
|
||||
// WavPack 5.0)
|
||||
|
||||
#define UNKNOWN_FLAGS 0x00000000 // we no longer have any of these spares
|
||||
|
||||
#define MONO_DATA (MONO_FLAG | FALSE_STEREO)
|
||||
|
||||
#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 CUR_STREAM_VERS 0x410 // stream version we are writing now
|
||||
#define CUR_STREAM_VERS 0x407 // universally compatible stream version
|
||||
|
||||
|
||||
//////////////////////////// WavPack Metadata /////////////////////////////////
|
||||
|
@ -253,52 +145,15 @@ 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)
|
||||
|
||||
///////////////////////// WavPack Configuration ///////////////////////////////
|
||||
|
||||
// This internal structure is used during encode to provide configuration to
|
||||
// the encoding engine and during decoding to provide fle information back to
|
||||
// the higher level functions. Not all fields are used in both modes.
|
||||
|
||||
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;
|
||||
unsigned char md5_checksum [16], md5_read;
|
||||
int num_tag_strings;
|
||||
char **tag_strings;
|
||||
} WavpackConfig;
|
||||
#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_HYBRID_FLAG 8 // hybrid mode
|
||||
#define CONFIG_JOINT_STEREO 0x10 // joint stereo
|
||||
#define CONFIG_CROSS_DECORR 0x20 // no-delay cross decorrelation
|
||||
#define CONFIG_HYBRID_SHAPE 0x40 // noise shape (hybrid mode only)
|
||||
#define CONFIG_FLOAT_DATA 0x80 // ieee 32-bit floating point data
|
||||
|
||||
#define CONFIG_FAST_FLAG 0x200 // fast mode
|
||||
#define CONFIG_HIGH_FLAG 0x800 // high quality mode
|
||||
#define CONFIG_VERY_HIGH_FLAG 0x1000 // very high
|
||||
#define CONFIG_BITRATE_KBPS 0x2000 // bitrate is kbps, not bits / sample
|
||||
#define CONFIG_AUTO_SHAPING 0x4000 // automatic noise shaping
|
||||
#define CONFIG_SHAPE_OVERRIDE 0x8000 // shaping mode specified
|
||||
#define CONFIG_JOINT_OVERRIDE 0x10000 // joint-stereo mode specified
|
||||
#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_CALC_NOISE 0x800000 // calc noise in hybrid mode
|
||||
#define CONFIG_LOSSY_MODE 0x1000000 // obsolete (for information)
|
||||
#define CONFIG_EXTRA_MODE 0x2000000 // extra processing mode
|
||||
#define CONFIG_SKIP_WVX 0x4000000 // no wvx stream w/ floats & big ints
|
||||
#define CONFIG_MD5_CHECKSUM 0x8000000 // compute & 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_MONO 0x80000000 // optimize for mono streams posing as stereo
|
||||
|
||||
#define QMODE_DSD_AUDIO 0x30 // if either of these is set in qmode (version 5.0)
|
||||
|
||||
/*
|
||||
* These config flags were never actually used, or are no longer used, or are
|
||||
|
@ -356,6 +211,14 @@ typedef struct bs {
|
|||
#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 {
|
||||
|
@ -381,7 +244,7 @@ struct words_data {
|
|||
};
|
||||
|
||||
typedef struct {
|
||||
int32_t filter1, filter2, filter3, filter4, filter5, filter6, factor;
|
||||
int32_t value, filter0, filter1, filter2, filter3, filter4, filter5, filter6, factor, byte;
|
||||
} DSDfilters;
|
||||
|
||||
typedef struct {
|
||||
|
@ -414,7 +277,7 @@ typedef struct {
|
|||
const WavpackDecorrSpec *decorr_specs;
|
||||
|
||||
struct {
|
||||
unsigned char *byteptr, *endptr, (*probabilities) [256], **value_lookup, mode, ready;
|
||||
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;
|
||||
|
@ -439,38 +302,7 @@ typedef struct {
|
|||
// files. It is recommended that direct access to this structure be minimized
|
||||
// and the provided utilities used instead.
|
||||
|
||||
typedef struct {
|
||||
int32_t (*read_bytes)(void *id, void *data, int32_t bcount);
|
||||
uint32_t (*get_pos)(void *id);
|
||||
int (*set_pos_abs)(void *id, uint32_t pos);
|
||||
int (*set_pos_rel)(void *id, int32_t delta, int mode);
|
||||
int (*push_back_byte)(void *id, int c);
|
||||
uint32_t (*get_length)(void *id);
|
||||
int (*can_seek)(void *id);
|
||||
|
||||
// this callback is for writing edited tags only
|
||||
int32_t (*write_bytes)(void *id, void *data, int32_t bcount);
|
||||
} WavpackStreamReader;
|
||||
|
||||
// Extended version of structure for handling large files and added
|
||||
// functionality for truncating and closing files
|
||||
|
||||
typedef struct {
|
||||
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
|
||||
} WavpackStreamReader64;
|
||||
|
||||
typedef int (*WavpackBlockOutput)(void *id, void *data, int32_t bcount);
|
||||
|
||||
typedef struct {
|
||||
struct WavpackContext {
|
||||
WavpackConfig config;
|
||||
|
||||
WavpackMetadata *metadata;
|
||||
|
@ -498,13 +330,14 @@ typedef struct {
|
|||
void *stream3;
|
||||
|
||||
// these items were added in 5.0 to support alternate file types (especially CAF & DSD)
|
||||
unsigned char file_format, *channel_reordering;
|
||||
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];
|
||||
} WavpackContext;
|
||||
};
|
||||
|
||||
//////////////////////// function prototypes and macros //////////////////////
|
||||
|
||||
|
@ -554,9 +387,6 @@ typedef struct {
|
|||
if (source && result) (source ^ result) < 0 ? (weight -= delta) : (weight += delta);
|
||||
#endif
|
||||
|
||||
#define update_weight_d2(weight, delta, source, result) \
|
||||
if (source && result) weight -= (((source ^ result) >> 29) & 4) - 2;
|
||||
|
||||
#define update_weight_clip(weight, delta, source, result) \
|
||||
if (source && result) { \
|
||||
const int32_t s = (source ^ result) >> 31; \
|
||||
|
@ -564,13 +394,6 @@ typedef struct {
|
|||
weight = (weight ^ s) - s; \
|
||||
}
|
||||
|
||||
#define update_weight_clip_d2(weight, delta, source, result) \
|
||||
if (source && result) { \
|
||||
const int32_t s = (source ^ result) >> 31; \
|
||||
if ((weight = (weight ^ s) + (2 - 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);
|
||||
|
@ -752,7 +575,7 @@ 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__))
|
||||
#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
|
||||
|
@ -793,24 +616,10 @@ WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int f
|
|||
#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);
|
||||
|
||||
#define MODE_WVC 0x1
|
||||
#define MODE_LOSSLESS 0x2
|
||||
#define MODE_HYBRID 0x4
|
||||
#define MODE_FLOAT 0x8
|
||||
#define MODE_VALID_TAG 0x10
|
||||
#define MODE_HIGH 0x20
|
||||
#define MODE_FAST 0x40
|
||||
#define MODE_EXTRA 0x80 // extra mode used, see MODE_XMODE for possible level
|
||||
#define MODE_APETAG 0x100
|
||||
#define MODE_SFX 0x200
|
||||
#define MODE_VERY_HIGH 0x400
|
||||
#define MODE_MD5 0x800
|
||||
#define MODE_XMODE 0x7000 // mask for extra level (1-6, 0=unknown)
|
||||
#define MODE_DNS 0x8000
|
||||
|
||||
int WavpackGetQualifyMode (WavpackContext *wpc);
|
||||
int WavpackGetVersion (WavpackContext *wpc);
|
||||
uint32_t WavpackUnpackSamples (WavpackContext *wpc, int32_t *buffer, uint32_t samples);
|
||||
|
@ -818,6 +627,7 @@ 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);
|
||||
|
||||
|
@ -826,7 +636,7 @@ int read_wvc_block (WavpackContext *wpc);
|
|||
|
||||
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);
|
||||
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);
|
||||
|
@ -871,6 +681,8 @@ 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 ////////////////////////////////////
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
// **** WAVPACK **** //
|
||||
// Hybrid Lossless Wavefile Compressor //
|
||||
// Copyright (c) 1998 - 2006 Conifer Software. //
|
||||
// Copyright (c) 1998 - 2019 David Bryant. //
|
||||
// All Rights Reserved. //
|
||||
// Distributed under the BSD Software License (see license.txt) //
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -12,8 +12,8 @@
|
|||
#define WAVPACK_VERSION_H
|
||||
|
||||
#define LIBWAVPACK_MAJOR 5
|
||||
#define LIBWAVPACK_MINOR 0
|
||||
#define LIBWAVPACK_MINOR 2
|
||||
#define LIBWAVPACK_MICRO 0
|
||||
#define LIBWAVPACK_VERSION_STRING "5.0.0-alpha4"
|
||||
#define LIBWAVPACK_VERSION_STRING "5.2.0"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -569,21 +569,19 @@ int32_t nosend_word (WavpackStream *wps, int32_t value, int chan)
|
|||
}
|
||||
|
||||
// This function is used to scan some number of samples to set the variables
|
||||
// "slow_level" and the "median" array. In pure symetrical encoding mode this
|
||||
// "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.
|
||||
|
||||
void scan_word (WavpackStream *wps, int32_t *samples, uint32_t num_samples, int dir)
|
||||
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;
|
||||
|
||||
init_words (wps);
|
||||
|
||||
if (flags & MONO_DATA) {
|
||||
if (dir < 0) {
|
||||
samples += (num_samples - 1);
|
||||
|
@ -672,3 +670,19 @@ void scan_word (WavpackStream *wps, int32_t *samples, uint32_t num_samples, int
|
|||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -348,6 +348,8 @@
|
|||
GCC_PREFIX_HEADER = "";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
ENABLE_DSD,
|
||||
ENABLE_LEGACY,
|
||||
PACK,
|
||||
UNPACK,
|
||||
USE_FSTREAMS,
|
||||
|
@ -356,8 +358,8 @@
|
|||
VER3,
|
||||
"PACKAGE_NAME='\"wavpack\"'",
|
||||
"PACKAGE_TARNAME='\"wavpack\"'",
|
||||
"PACKAGE_VERSION='\"4.70.0\"'",
|
||||
"PACKAGE_STRING='\"wavpack 4.70.0\"'",
|
||||
"PACKAGE_VERSION='\"5.2.0\"'",
|
||||
"PACKAGE_STRING='\"wavpack 5.2.0\"'",
|
||||
"PACKAGE_BUGREPORT='\"bryant@wavpack.com\"'",
|
||||
"VERSION_OS='\"Darwin\"'",
|
||||
);
|
||||
|
@ -383,6 +385,8 @@
|
|||
GCC_PRECOMPILE_PREFIX_HEADER = NO;
|
||||
GCC_PREFIX_HEADER = "";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
ENABLE_DSD,
|
||||
ENABLE_LEGACY,
|
||||
PACK,
|
||||
UNPACK,
|
||||
USE_FSTREAMS,
|
||||
|
|
|
@ -124,13 +124,20 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
|
|||
|
||||
wv = [[WavPackReader alloc] initWithSource:s];
|
||||
|
||||
id audioSourceClass = NSClassFromString(@"AudioSource");
|
||||
NSURL *wvcurl = [[s url] URLByDeletingPathExtension];
|
||||
wvcurl = [wvcurl URLByAppendingPathExtension:@"wvc"];
|
||||
id<CogSource> wvcsrc = [audioSourceClass audioSourceForURL:wvcurl];
|
||||
if ([wvcsrc open:wvcurl])
|
||||
if ([s seekable])
|
||||
{
|
||||
wvc = [[WavPackReader alloc] initWithSource:wvcsrc];
|
||||
id audioSourceClass = NSClassFromString(@"AudioSource");
|
||||
NSURL *wvcurl = [[s url] URLByDeletingPathExtension];
|
||||
wvcurl = [wvcurl URLByAppendingPathExtension:@"wvc"];
|
||||
id<CogSource> wvcsrc = [audioSourceClass audioSourceForURL:wvcurl];
|
||||
if ([wvcsrc open:wvcurl])
|
||||
{
|
||||
wvc = [[WavPackReader alloc] initWithSource:wvcsrc];
|
||||
}
|
||||
else
|
||||
{
|
||||
wvc = nil;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -147,6 +154,9 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
|
|||
reader.write_bytes = WriteBytesProc;
|
||||
|
||||
open_flags |= OPEN_DSD_AS_PCM | OPEN_ALT_TYPES;
|
||||
|
||||
if (![s seekable])
|
||||
open_flags |= OPEN_STREAMING;
|
||||
|
||||
wpc = WavpackOpenFileInputEx(&reader, (__bridge void *)(wv), (__bridge void *)(wvc), error, open_flags, 0);
|
||||
if (!wpc) {
|
||||
|
|
Loading…
Reference in New Issue