merge with modulesio/master

pull/35/head
dimitri 8 years ago
commit 3857ab49e9

@ -70,11 +70,13 @@ int main(int argc, const char **argv) try
//loader.Load(fileData.get(), "test_data/ad_hoc/KittyPurr16_Stereo.flac");
//loader.Load(fileData.get(), "test_data/ad_hoc/KittyPurr16_Mono.flac");
//loader.Load(fileData.get(), "test_data/ad_hoc/KittyPurr24_Stereo.flac");
//auto memory = ReadFile("test_data/ad_hoc/KittyPurr24_Stereo.flac"); // broken
//loader.Load(fileData.get(), "flac", memory.buffer); // broken
// Single-channel opus
//loader.Load(fileData.get(), "test_data/ad_hoc/detodos.opus"); // "Firefox: From All, To All"
// 1 + 2 channel wavepack
// 1 + 2 channel wavpack
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Float32.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Float32_Mono.wv");
//loader.Load(fileData.get(), "test_data/ad_hoc/TestBeat_Int16.wv");
@ -110,7 +112,7 @@ int main(int argc, const char **argv) try
// Resample
std::vector<float> outputBuffer;
outputBuffer.reserve(fileData->samples.size());
linear_resample(44100.0 / 48000.0, fileData->samples, outputBuffer, fileData->samples.size());
linear_resample(44100.0 / 48000.0, fileData->samples, outputBuffer, (uint32_t) fileData->samples.size());
std::cout << "Input Samples: " << fileData->samples.size() << std::endl;
std::cout << "Output Samples: " << outputBuffer.size() << std::endl;

@ -68,7 +68,9 @@ class NyquistIO
void AddDecoderToTable(std::shared_ptr<nqr::BaseDecoder> decoder);
std::map<std::string, std::shared_ptr<BaseDecoder>> decoderTable;
NO_MOVE(NyquistIO);
public:
NyquistIO();
~NyquistIO();
void Load(AudioData * data, const std::string & path);

@ -201,6 +201,57 @@ inline std::array<uint8_t, 3> Unpack(uint32_t a)
return output;
}
//////////////////////////
// Resampling Utilities //
//////////////////////////
// This is a naieve implementation of a resampling filter where a lerp is used as a bad low-pass.
// It very far from the ideal case and should be used with caution (or not at all) on signals that matter.
// It is included here to upsample 44.1k to 48k for the purposes of microphone input => Opus, where the the
// nominal frequencies of speech are particularly far from Nyquist.
inline void linear_resample(const double rate, const std::vector<float> & input, std::vector<float> & output, const uint32_t samplesToProcess)
{
double virtualReadIndex = 0;
double a, b, i, sample;
uint32_t n = samplesToProcess - 1;
while (n--)
{
uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex);
i = virtualReadIndex - readIndex;
a = input[readIndex + 0];
b = input[readIndex + 1];
sample = (1.0 - i) * a + i * b; // linear interpolate
output.push_back(static_cast<float>(sample));
virtualReadIndex += rate;
}
}
inline double sample_hermite_4p_3o(double x, double * y)
{
static double c0, c1, c2, c3;
c0 = y[1];
c1 = (1.0 / 2.0)*(y[2] - y[0]);
c2 = (y[0] - (5.0 / 2.0)*y[1]) + (2.0*y[2] - (1.0 / 2.0)*y[3]);
c3 = (1.0 / 2.0)*(y[3] - y[0]) + (3.0 / 2.0)*(y[1] - y[2]);
return ((c3*x + c2)*x + c1)*x + c0;
}
inline void hermite_resample(const double rate, const std::vector<float> & input, std::vector<float> & output, const uint32_t samplesToProcess)
{
double virtualReadIndex = 1;
double i, sample;
uint32_t n = samplesToProcess - 1;
while (n--)
{
uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex);
i = virtualReadIndex - readIndex;
double samps[4] = { input[readIndex - 1], input[readIndex], input[readIndex + 1], input[readIndex + 2] };
sample = sample_hermite_4p_3o(i, samps); // cubic hermite interpolate over 4 samples
output.push_back(static_cast<float>(sample));
virtualReadIndex += rate;
}
}
//////////////////////////
// Conversion Utilities //
//////////////////////////

@ -100,7 +100,7 @@ namespace nqr
const uint8_t * data = state.inBuffer;
// Loop over the interleaved channels
for (int32_t ch = 0; ch < num_channels; ch++)
for (uint32_t ch = 0; ch < num_channels; ch++)
{
const int byteOffset = ch * 4;

@ -32,53 +32,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace nqr
{
// This is a naieve implementation of a resampling filter where a lerp is used as a bad low-pass.
// It very far from the ideal case and should be used with caution (or not at all) on signals that matter.
// It is included here to upsample 44.1k to 48k for the purposes of microphone input => Opus, where the the
// nominal frequencies of speech are particularly far from Nyquist.
static inline void linear_resample(const double rate, const std::vector<float> & input, std::vector<float> & output, size_t samplesToProcess)
{
double virtualReadIndex = 0;
double a, b, i, sample;
uint32_t n = samplesToProcess - 1;
while (n--)
{
uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex);
i = virtualReadIndex - readIndex;
a = input[readIndex + 0];
b = input[readIndex + 1];
sample = (1.0 - i) * a + i * b; // linear interpolate
output.push_back(sample);
virtualReadIndex += rate;
}
}
static inline double sample_hermite_4p_3o(double x, double * y)
{
static double c0, c1, c2, c3;
c0 = y[1];
c1 = (1.0/2.0)*(y[2]-y[0]);
c2 = (y[0] - (5.0/2.0)*y[1]) + (2.0*y[2] - (1.0/2.0)*y[3]);
c3 = (1.0/2.0)*(y[3]-y[0]) + (3.0/2.0)*(y[1]-y[2]);
return ((c3*x+c2)*x+c1)*x+c0;
}
static inline void hermite_resample(const double rate, const std::vector<float> & input, std::vector<float> & output, size_t samplesToProcess)
{
double virtualReadIndex = 1;
double i, sample;
uint32_t n = samplesToProcess - 1;
while (n--)
{
uint32_t readIndex = static_cast<uint32_t>(virtualReadIndex);
i = virtualReadIndex - readIndex;
double samps[4] = {input[readIndex - 1], input[readIndex], input[readIndex + 1], input[readIndex + 2]};
sample = sample_hermite_4p_3o(i, samps); // cubic hermite interpolate over 4 samples
output.push_back(sample);
virtualReadIndex += rate;
}
}
enum EncoderError
{
NoError,

@ -36,7 +36,6 @@
<ClCompile Include="..\..\src\ModplugDependencies.cpp" />
<ClCompile Include="..\..\src\MusepackDecoder.cpp" />
<ClCompile Include="..\..\src\MusepackDependencies.c" />
<ClCompile Include="..\..\src\WavPackDependencies.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\AudioDecoder.h" />

@ -46,9 +46,6 @@
<ClCompile Include="..\..\src\MusepackDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\WavPackDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ModplugDependencies.cpp">
<Filter>src\deps</Filter>
</ClCompile>

@ -35,7 +35,32 @@
<ClCompile Include="..\..\src\ModplugDependencies.cpp" />
<ClCompile Include="..\..\src\MusepackDecoder.cpp" />
<ClCompile Include="..\..\src\MusepackDependencies.c" />
<ClCompile Include="..\..\src\WavPackDependencies.c" />
<ClCompile Include="..\..\third_party\wavpack\src\common_utils.c" />
<ClCompile Include="..\..\third_party\wavpack\src\decorr_utils.c" />
<ClCompile Include="..\..\third_party\wavpack\src\entropy_utils.c" />
<ClCompile Include="..\..\third_party\wavpack\src\extra1.c" />
<ClCompile Include="..\..\third_party\wavpack\src\extra2.c" />
<ClCompile Include="..\..\third_party\wavpack\src\open_filename.c" />
<ClCompile Include="..\..\third_party\wavpack\src\open_legacy.c" />
<ClCompile Include="..\..\third_party\wavpack\src\open_raw.c" />
<ClCompile Include="..\..\third_party\wavpack\src\open_utils.c" />
<ClCompile Include="..\..\third_party\wavpack\src\pack.c" />
<ClCompile Include="..\..\third_party\wavpack\src\pack_dns.c" />
<ClCompile Include="..\..\third_party\wavpack\src\pack_dsd.c" />
<ClCompile Include="..\..\third_party\wavpack\src\pack_floats.c" />
<ClCompile Include="..\..\third_party\wavpack\src\pack_utils.c" />
<ClCompile Include="..\..\third_party\wavpack\src\read_words.c" />
<ClCompile Include="..\..\third_party\wavpack\src\tags.c" />
<ClCompile Include="..\..\third_party\wavpack\src\tag_utils.c" />
<ClCompile Include="..\..\third_party\wavpack\src\unpack.c" />
<ClCompile Include="..\..\third_party\wavpack\src\unpack3.c" />
<ClCompile Include="..\..\third_party\wavpack\src\unpack3_open.c" />
<ClCompile Include="..\..\third_party\wavpack\src\unpack3_seek.c" />
<ClCompile Include="..\..\third_party\wavpack\src\unpack_dsd.c" />
<ClCompile Include="..\..\third_party\wavpack\src\unpack_floats.c" />
<ClCompile Include="..\..\third_party\wavpack\src\unpack_seek.c" />
<ClCompile Include="..\..\third_party\wavpack\src\unpack_utils.c" />
<ClCompile Include="..\..\third_party\wavpack\src\write_words.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\AudioDecoder.h" />
@ -106,8 +131,9 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>DEBUG;_ITERATOR_DEBUG_LEVEL=0;_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -118,8 +144,9 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>DEBUG;_ITERATOR_DEBUG_LEVEL=0;_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -134,6 +161,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -150,6 +178,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_MBCS;D_SCL_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNING;WIN32;_WIN32;USE_ALLOCA;OPUS_BUILD;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\third_party\;$(ProjectDir)..\..\include\libnyquist\;$(ProjectDir)..\..\third_party\libvorbis\include;$(ProjectDir)..\..\third_party\libogg\include;$(ProjectDir)..\..\third_party\wavpack\include;$(ProjectDir)..\..\third_party\flac\src\include;$(ProjectDir)..\..\third_party\opus\celt;$(ProjectDir)..\..\third_party\opus\libopus\include;$(ProjectDir)..\..\third_party\opus\libopus\src;$(ProjectDir)..\..\third_party\opus\opusfile\include;$(ProjectDir)..\..\third_party\opus\opusfile\src;$(ProjectDir)..\..\third_party\opus\opusfile\src\include;$(ProjectDir)..\..\third_party\opus\silk;$(ProjectDir)..\..\third_party\opus\silk\float;$(ProjectDir)..\..\third_party\musepack\include;$(ProjectDir)..\..\third_party\musepack\libmpcenc;$(ProjectDir)..\..\third_party\musepack\libmpcdec;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>

@ -43,20 +43,92 @@
<ClCompile Include="..\..\src\MusepackDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\src\WavPackDependencies.c">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ModplugDependencies.cpp">
<Filter>src\deps</Filter>
</ClCompile>
<ClCompile Include="..\..\src\ModplugDecoder.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\entropy_utils.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\decorr_utils.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\open_legacy.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\open_filename.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\extra2.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\extra1.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\common_utils.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\open_utils.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\open_raw.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\pack.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\pack_dns.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\pack_floats.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\pack_dsd.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\pack_utils.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\read_words.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\tags.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\unpack.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\unpack_dsd.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\unpack_floats.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\tag_utils.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\unpack_seek.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\unpack_utils.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\unpack3.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\unpack3_open.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\unpack3_seek.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
<ClCompile Include="..\..\third_party\wavpack\src\write_words.c">
<Filter>src\deps\WavpackDependencies</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\OpusDecoder.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\AudioDecoder.h">
<Filter>include</Filter>
</ClInclude>
@ -93,6 +165,9 @@
<ClInclude Include="..\..\include\libnyquist\IMA4Util.h">
<Filter>include\util</Filter>
</ClInclude>
<ClInclude Include="$(ProjectDir)..\..\include\libnyquist\OpusDecoder.h">
<Filter>include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="include">
@ -107,5 +182,8 @@
<Filter Include="src\deps">
<UniqueIdentifier>{d839471f-71d1-471e-95e0-c33af9bb64bc}</UniqueIdentifier>
</Filter>
<Filter Include="src\deps\WavpackDependencies">
<UniqueIdentifier>{4ed41d64-0c09-4382-8ee9-70aad6043650}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

@ -22,7 +22,6 @@
08B91DA11AC73B8A00335131 /* OpusDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D971AC73B8A00335131 /* OpusDecoder.cpp */; };
08B91DA21AC73B8A00335131 /* WavDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D981AC73B8A00335131 /* WavDecoder.cpp */; };
08B91DA31AC73B8A00335131 /* WavPackDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08B91D991AC73B8A00335131 /* WavPackDecoder.cpp */; };
08D0EC751C6DA41300FCDA23 /* WavPackDependencies.c in Sources */ = {isa = PBXBuildFile; fileRef = 08D0EC741C6DA41300FCDA23 /* WavPackDependencies.c */; };
08FFC72D1CA702EC005812D6 /* ModplugDependencies.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08FFC72C1CA702EC005812D6 /* ModplugDependencies.cpp */; };
08FFC72F1CA7038D005812D6 /* ModplugDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08FFC72E1CA7038D005812D6 /* ModplugDecoder.cpp */; };
/* End PBXBuildFile section */
@ -72,7 +71,6 @@
08B91D981AC73B8A00335131 /* WavDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WavDecoder.cpp; path = src/WavDecoder.cpp; sourceTree = SOURCE_ROOT; };
08B91D991AC73B8A00335131 /* WavPackDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WavPackDecoder.cpp; path = src/WavPackDecoder.cpp; sourceTree = SOURCE_ROOT; };
08C83B7C1C25D7780071EED6 /* IMA4Util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = IMA4Util.h; path = include/libnyquist/IMA4Util.h; sourceTree = SOURCE_ROOT; };
08D0EC741C6DA41300FCDA23 /* WavPackDependencies.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = WavPackDependencies.c; path = src/WavPackDependencies.c; sourceTree = SOURCE_ROOT; };
08FFC72C1CA702EC005812D6 /* ModplugDependencies.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ModplugDependencies.cpp; path = src/ModplugDependencies.cpp; sourceTree = SOURCE_ROOT; };
08FFC72E1CA7038D005812D6 /* ModplugDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ModplugDecoder.cpp; path = src/ModplugDecoder.cpp; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
@ -92,7 +90,6 @@
isa = PBXGroup;
children = (
08FFC72C1CA702EC005812D6 /* ModplugDependencies.cpp */,
08D0EC741C6DA41300FCDA23 /* WavPackDependencies.c */,
081FFB181ADF803800673073 /* FlacDependencies.c */,
086DADAB1ADF9DF30031F793 /* VorbisDependencies.c */,
0804D13E1AE69F0100F4B1FD /* OpusDependencies.c */,
@ -264,7 +261,6 @@
08FFC72D1CA702EC005812D6 /* ModplugDependencies.cpp in Sources */,
08B91D9E1AC73B8A00335131 /* FlacDecoder.cpp in Sources */,
08FFC72F1CA7038D005812D6 /* ModplugDecoder.cpp in Sources */,
08D0EC751C6DA41300FCDA23 /* WavPackDependencies.c in Sources */,
086DADAD1AE029860031F793 /* VorbisDependencies.c in Sources */,
08B91DA31AC73B8A00335131 /* WavPackDecoder.cpp in Sources */,
08B91D9D1AC73B8A00335131 /* Common.cpp in Sources */,

@ -24,6 +24,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Common.h"
#include <cstring>
using namespace nqr;
@ -104,9 +105,10 @@ void nqr::ConvertToFloat32(float * dst, const uint8_t * src, const size_t N, PCM
else if (f == PCM_FLT)
{
const float * dataPtr = reinterpret_cast<const float *>(src);
memcpy(dst, src, N * sizeof(float));
/* const float * dataPtr = reinterpret_cast<const float *>(src);
for (size_t i = 0; i < N; ++i)
dst[i] = (float) Read32(dataPtr[i]);
dst[i] = (float) Read32(dataPtr[i]); */
}
else if (f == PCM_DBL)
{

@ -24,26 +24,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "FlacDecoder.h"
#include "flac/all.h"
#include "flac/stream_decoder.h"
#include "FLAC/all.h"
#include "FLAC/stream_decoder.h"
#include "AudioDecoder.h"
#include <cstring>
using namespace nqr;
// FLAC is a big-endian format. All values are unsigned.
class FlacDecoderInternal
{
public:
// FLAC is a big-endian format. All values are unsigned.
FlacDecoderInternal(AudioData * d, std::string filepath) : d(d)
FlacDecoderInternal(AudioData * d, const std::string & filepath) : d(d)
{
/////////////////////////////
// Initialize FLAC library //
/////////////////////////////
decoderInternal = FLAC__stream_decoder_new();
FLAC__stream_decoder_set_metadata_respond(decoderInternal, FLAC__METADATA_TYPE_STREAMINFO);
@ -58,10 +55,6 @@ public:
FLAC__stream_decoder_set_md5_checking(decoderInternal, true);
//////////////////////
// Read Stream Data //
/////////////////////
if (initialized)
{
// Find the size and allocate memory
@ -81,12 +74,50 @@ public:
// Next, process internal buffer into the user-visible samples array
ConvertToFloat32(d->samples.data(), internalBuffer.data(), totalSamples, d->sourceFormat);
}
else
{
throw std::runtime_error("Unable to initialize FLAC decoder");
else throw std::runtime_error("Unable to initialize FLAC decoder");
}
FlacDecoderInternal(AudioData * d, const std::vector<uint8_t> & memory) : d(d), data(std::move(memory)), dataPos(0)
{
decoderInternal = FLAC__stream_decoder_new();
FLAC__stream_decoder_set_metadata_respond(decoderInternal, FLAC__METADATA_TYPE_STREAMINFO);
bool initialized = FLAC__stream_decoder_init_stream(
decoderInternal,
read_callback,
seek_callback,
tell_callback,
length_callback,
eof_callback,
s_writeCallback,
s_metadataCallback,
s_errorCallback,
this
) == FLAC__STREAM_DECODER_INIT_STATUS_OK;
FLAC__stream_decoder_set_md5_checking(decoderInternal, true);
if (initialized)
{
// Find the size and allocate memory
FLAC__stream_decoder_process_until_end_of_metadata(decoderInternal);
// Read memory out into our temporary internalBuffer
FLAC__stream_decoder_process_until_end_of_stream(decoderInternal);
// Presently unneeded, but useful for reference
// FLAC__ChannelAssignment channelAssignment = FLAC__stream_decoder_get_channel_assignment(decoderInternal);
// Fill out remaining user data
d->lengthSeconds = (float) numSamples / (float) d->sampleRate;
auto totalSamples = numSamples * d->channelCount;
// Next, process internal buffer into the user-visible samples array
ConvertToFloat32(d->samples.data(), internalBuffer.data(), totalSamples, d->sourceFormat);
}
else throw std::runtime_error("Unable to initialize FLAC decoder");
}
~FlacDecoderInternal()
@ -121,16 +152,14 @@ public:
static FLAC__StreamDecoderWriteStatus s_writeCallback(const FLAC__StreamDecoder *, const FLAC__Frame* frame, const FLAC__int32 * const buffer[], void * userPtr)
{
FlacDecoderInternal * decoder = reinterpret_cast<FlacDecoderInternal *>(userPtr);
const size_t bytesPerSample = GetFormatBitsPerSample(decoder->d->sourceFormat) / 8;
auto dataPtr = decoder->internalBuffer.data();
for (uint32_t i = 0; i < frame->header.blocksize; i++)
{
for (int j = 0; j < decoder->d->channelCount; j++)
{
memcpy(dataPtr + decoder->bufferPosition, &buffer[j][i], bytesPerSample);
std::memcpy(dataPtr + decoder->bufferPosition, &buffer[j][i], bytesPerSample);
decoder->bufferPosition += bytesPerSample;
}
}
@ -145,7 +174,51 @@ public:
static void s_errorCallback (const FLAC__StreamDecoder *, FLAC__StreamDecoderErrorStatus status, void *)
{
std::cerr << "FLAC Decoder Error: " << FLAC__StreamDecoderErrorStatusString[status] << std::endl;
throw std::runtime_error("FLAC decode exception " + std::string(FLAC__StreamDecoderErrorStatusString[status]));
}
static FLAC__StreamDecoderReadStatus read_callback(const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
{
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
size_t readLength = std::min<size_t>(*bytes, decoderInternal->data.size() - decoderInternal->dataPos);
if (readLength > 0)
{
std::memcpy(buffer, decoderInternal->data.data(), readLength);
decoderInternal->dataPos += readLength;
*bytes = readLength;
if (decoderInternal->dataPos < decoderInternal->data.size()) return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
else return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
}
else return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
}
static FLAC__StreamDecoderSeekStatus seek_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
{
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
size_t newPos = std::min<size_t>(absolute_byte_offset, decoderInternal->data.size() - decoderInternal->dataPos);
decoderInternal->dataPos = newPos;
return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
}
static FLAC__StreamDecoderTellStatus tell_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
{
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
*absolute_byte_offset = decoderInternal->dataPos;
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
}
static FLAC__StreamDecoderLengthStatus length_callback(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
{
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
*stream_length = decoderInternal->data.size();
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
}
static FLAC__bool eof_callback(const FLAC__StreamDecoder *decoder, void *client_data)
{
FlacDecoderInternal *decoderInternal = (FlacDecoderInternal *)client_data;
return decoderInternal->dataPos == decoderInternal->data.size();
}
private:
@ -153,7 +226,8 @@ private:
NO_COPY(FlacDecoderInternal);
FLAC__StreamDecoder * decoderInternal;
std::vector<uint8_t> data;
size_t dataPos;
size_t bufferPosition = 0;
size_t numSamples = 0;
@ -173,7 +247,7 @@ void FlacDecoder::LoadFromPath(AudioData * data, const std::string & path)
void FlacDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
throw LoadBufferNotImplEx();
FlacDecoderInternal decoder(data, memory);
}
std::vector<std::string> FlacDecoder::GetSupportedFileExtensions()

@ -77,25 +77,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define HAVE_LROUND 1
#include "flac/all.h"
#include "FLAC/all.h"
#if defined(_MSC_VER)
#include "flac/src/win_utf8_io.c"
#include "FLAC/src/win_utf8_io.c"
#endif
#include "flac/src/bitmath.c"
#include "flac/src/bitreader.c"
#include "flac/src/bitwriter.c"
#include "flac/src/cpu.c"
#include "flac/src/crc.c"
#include "flac/src/fixed.c"
#include "flac/src/float.c"
#include "flac/src/format.c"
#include "flac/src/lpc.c"
#include "flac/src/md5.c"
#include "flac/src/memory.c"
#include "flac/src/stream_decoder.c"
#include "flac/src/window.c"
#include "FLAC/src/bitmath.c"
#include "FLAC/src/bitreader.c"
#include "FLAC/src/bitwriter.c"
#include "FLAC/src/cpu.c"
#include "FLAC/src/crc.c"
#include "FLAC/src/fixed.c"
#include "FLAC/src/float.c"
#include "FLAC/src/format.c"
#include "FLAC/src/lpc.c"
#include "FLAC/src/md5.c"
#include "FLAC/src/memory.c"
#include "FLAC/src/stream_decoder.c"
#include "FLAC/src/window.c"
#undef VERSION

@ -53,10 +53,7 @@ public:
ModPlug_SetSettings(&mps);
mpf = ModPlug_Load((const void*)fileData.data(), fileData.size());
if (!mpf)
{
throw std::runtime_error("could not load module");
}
if (!mpf) throw std::runtime_error("could not load module");
d->sampleRate = 44100;
d->channelCount = 2;
@ -68,21 +65,24 @@ public:
auto totalSamples = (44100LL * len_ms) / 1000;
d->samples.resize(totalSamples * d->channelCount);
auto readInternal = [&]()
auto read_func = [&]()
{
const float invf = 1 / (float)0x7fffffff;
float *ptr = d->samples.data();
float *end = d->samples.data() + d->samples.size();
while( ptr < end ) {
while (ptr < end)
{
int res = ModPlug_Read(mpf, (void*)ptr, (end - ptr) * sizeof(float));
int samples_read = res / (sizeof(float) * 2);
if( totalSamples < samples_read ) {
if (totalSamples < samples_read)
{
samples_read = totalSamples;
}
for( int i = 0; i < samples_read; ++i ) {
for (int i = 0; i < samples_read; ++i)
{
*ptr++ = *((int*)ptr) * invf;
*ptr++ = *((int*)ptr) * invf;
}
@ -93,8 +93,10 @@ public:
return ptr >= end;
};
if (!readInternal())
if (!read_func())
{
throw std::runtime_error("could not read any data");
}
ModPlug_Unload(mpf);
}
@ -102,9 +104,7 @@ public:
private:
ModPlugFile * mpf;
NO_MOVE(ModplugInternal);
AudioData * d;
};
@ -128,4 +128,3 @@ std::vector<std::string> ModplugDecoder::GetSupportedFileExtensions()
{
return {"pat","mid", "mod","s3m","xm","it","669","amf","ams","dbm","dmf","dsm","far","mdl","med","mtm","okt","ptm","stm","ult","umx","mt2","psm"};
}

@ -110,9 +110,7 @@ public:
reader.tell = tell_mem;
mpcDemux = mpc_demux_init(&reader);
if (!mpcDemux)
throw std::runtime_error("could not initialize mpc demuxer");
if (!mpcDemux) throw std::runtime_error("could not initialize mpc demuxer");
mpc_demux_get_info(mpcDemux, &streamInfo);

@ -26,6 +26,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "WavDecoder.h"
#include "RiffUtils.h"
#include "IMA4Util.h"
#include <cstring>
using namespace nqr;
@ -200,7 +201,7 @@ void WavDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & m
uint32_t frameOffset = 0;
uint32_t frameCount = DataChunkInfo.size / s.frame_size;
for (int i = 0; i < frameCount; ++i)
for (uint32_t i = 0; i < frameCount; ++i)
{
decode_ima_adpcm(s, adpcm_pcm16.data() + frameOffset, wavHeader.channel_count);
s.inBuffer += s.frame_size;

@ -83,7 +83,6 @@ int WavEncoder::WriteFile(const EncoderParams p, const AudioData * d, const std:
sampleData = sampleDataOptionalMix.data();
sampleDataSize = sampleDataOptionalMix.size();
}
// Stereo => Mono
else if (d->channelCount == 2 && p.channelCount == 1)
{
@ -95,12 +94,10 @@ int WavEncoder::WriteFile(const EncoderParams p, const AudioData * d, const std:
sampleDataSize = sampleDataOptionalMix.size();
}
else if (d->channelCount == p.channelCount)
{
// No op
}
else
{
return EncoderError::UnsupportedChannelMix;

@ -25,6 +25,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "WavPackDecoder.h"
#include "wavpack.h"
#include <string.h>
using namespace nqr;
@ -33,11 +34,67 @@ class WavPackInternal
public:
WavPackInternal(AudioData * d, const std::string path) : d(d)
WavPackInternal(AudioData * d, const std::string & path) : d(d)
{
char errorStr[128];
context = WavpackOpenFileInput(path.c_str(), errorStr, OPEN_WVC | OPEN_NORMALIZE, 0);
if (!context) throw std::runtime_error("Not a WavPack file");
auto bitdepth = WavpackGetBitsPerSample(context);
d->sampleRate = WavpackGetSampleRate(context);
d->channelCount = WavpackGetNumChannels(context);
d->lengthSeconds = double(getLengthInSeconds());
d->frameSize = d->channelCount * bitdepth;
//@todo support channel masks
// WavpackGetChannelMask
auto totalSamples = size_t(getTotalSamples());
int mode = WavpackGetMode(context);
bool isFloatingPoint = (MODE_FLOAT & mode);
d->sourceFormat = MakeFormatForBits(bitdepth, isFloatingPoint, false);
/// From the WavPack docs:
/// "... required memory at "buffer" is 4 * samples * num_channels bytes. The
/// audio data is returned right-justified in 32-bit longs in the endian
/// mode native to the executing processor."
d->samples.resize(totalSamples * d->channelCount);
if (!isFloatingPoint)
internalBuffer.resize(totalSamples * d->channelCount);
if (!readInternal(totalSamples))
throw std::runtime_error("could not read any data");
// Next, process internal buffer into the user-visible samples array
if (!isFloatingPoint)
ConvertToFloat32(d->samples.data(), internalBuffer.data(), totalSamples * d->channelCount, d->sourceFormat);
}
WavPackInternal(AudioData * d, const std::vector<uint8_t> & memory) : d(d), data(std::move(memory)), dataPos(0)
{
WavpackStreamReader64 reader =
{
read_bytes,
write_bytes,
get_pos,
set_pos_abs,
set_pos_rel,
push_back_byte,
get_length,
can_seek,
truncate_here,
close,
};
char errorStr[128];
context = WavpackOpenFileInputEx64(&reader, this, nullptr, errorStr, OPEN_WVC | OPEN_NORMALIZE, 0);
if (!context)
{
throw std::runtime_error("Not a WavPack file");
@ -60,11 +117,6 @@ public:
d->sourceFormat = MakeFormatForBits(bitdepth, isFloatingPoint, false);
/* From the docs:
"... required memory at "buffer" is 4 * samples * num_channels bytes. The
audio data is returned right-justified in 32-bit longs in the endian
mode native to the executing processor."
*/
d->samples.resize(totalSamples * d->channelCount);
if (!isFloatingPoint)
@ -89,8 +141,6 @@ public:
size_t framesRemaining = requestedFrameCount;
size_t totalFramesRead = 0;
// int frameSize = d->channelCount * WavpackGetBitsPerSample(context);
// The samples returned are handled differently based on the file's mode
int mode = WavpackGetMode(context);
@ -111,8 +161,7 @@ public:
}
// EOF
//if (framesRead == 0)
// break;
//if (framesRead == 0) break;
totalFramesRead += framesRead;
framesRemaining -= framesRead;
@ -121,6 +170,115 @@ public:
return totalFramesRead;
}
static int32_t read_bytes(void * id, void * data, int32_t byte_count)
{
if (id != nullptr)
{
WavPackInternal *decoder = (WavPackInternal *)id;
int32_t readLength = std::min<size_t>(byte_count, decoder->data.size() - decoder->dataPos);
if (readLength > 0)
{
std::memcpy(data, decoder->data.data(), readLength);
decoder->dataPos += readLength;
return readLength;
}
else return 0;
}
return 0;
}
static int32_t write_bytes(void * id, void * data, int32_t byte_count)
{
if (id != nullptr)
{
WavPackInternal *decoder = (WavPackInternal *)id;
int32_t writeLength = std::min<size_t>(byte_count, decoder->data.size() - decoder->dataPos);
if (writeLength > 0)
{
std::memcpy(decoder->data.data(), data, writeLength);
decoder->dataPos += writeLength;
return writeLength;
}
else return 0;
}
return 0;
}
static int64_t get_pos(void *id)
{
if (id != nullptr)
{
WavPackInternal *decoder = (WavPackInternal *)id;
return decoder->dataPos;
}
return 0;
}
static int set_pos_abs(void *id, int64_t pos)
{
if (id != nullptr)
{
WavPackInternal *decoder = (WavPackInternal *)id;
size_t newPos = std::min<size_t>(pos, decoder->data.size());
decoder->dataPos = newPos;
return newPos;
}
return 0;
}
static int set_pos_rel(void *id, int64_t delta, int mode)
{
if (id != nullptr)
{
WavPackInternal *decoder = (WavPackInternal *)id;
size_t newPos = 0;
if (mode == SEEK_SET) newPos = delta;
else if (mode == SEEK_CUR) newPos = decoder->dataPos + delta;
else if (mode == SEEK_END) newPos = decoder->data.size() + delta;
newPos = std::min<size_t>(newPos, decoder->data.size());
decoder->dataPos = newPos;
return newPos;
}
return 0;
}
static int push_back_byte(void *id, int c)
{
if (id != nullptr)
{
WavPackInternal *decoder = (WavPackInternal *)id;
decoder->dataPos--;
decoder->data[decoder->dataPos] = c;
return 1;
}
return 0;
}
static int64_t get_length(void *id)
{
if (id != nullptr)
{
WavPackInternal *decoder = (WavPackInternal *)id;
return decoder->data.size();
}
return 0;
}
static int can_seek(void *id)
{
if (id != nullptr) return 1;
return 0;
}
static int truncate_here(void *id)
{
if (id != nullptr)
{
WavPackInternal *decoder = (WavPackInternal *)id;
decoder->data.resize(decoder->dataPos);
return 1;
}
return 0;
}
static int close(void *id)
{
if (id != nullptr) return 1;
return 0;
}
private:
NO_MOVE(WavPackInternal);
@ -130,6 +288,8 @@ private:
WavpackContext * context; //@todo unique_ptr
AudioData * d;
std::vector<uint8_t> data;
size_t dataPos;
std::vector<int32_t> internalBuffer;
@ -149,7 +309,7 @@ void WavPackDecoder::LoadFromPath(AudioData * data, const std::string & path)
void WavPackDecoder::LoadFromBuffer(AudioData * data, const std::vector<uint8_t> & memory)
{
throw LoadBufferNotImplEx();
WavPackInternal decoder(data, memory);
}
std::vector<std::string> WavPackDecoder::GetSupportedFileExtensions()

@ -1,68 +0,0 @@
/*
Copyright (c) 2015, Dimitri Diakopoulos 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.
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 COPYRIGHT HOLDER 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.
*/
#if (_MSC_VER)
#pragma warning (push)
#pragma warning (disable: 181 111 4267 4996 4244 4701 4702 4133 4100 4127 4206 4312 4505 4365 4005 4013 4334 4703)
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wshadow"
#pragma clang diagnostic ignored "-Wdeprecated-register"
#endif
#ifdef _WIN32
#ifndef WIN32
#define WIN32
#endif
#endif
#include "wavpack/src/bits.c"
#include "wavpack/src/extra1.c"
#define WavpackExtraInfo WavpackExtraInfo_alt
#define log2overhead log2overhead_alt
#define xtable xtable_alt
#include "wavpack/src/extra2.c"
#include "wavpack/src/float.c"
#include "wavpack/src/metadata.c"
#define decorr_stereo_pass decorr_stereo_pass_alt
#include "wavpack/src/pack.c"
#include "wavpack/src/tags.c"
#undef decorr_stereo_pass
#define decorr_stereo_pass decorr_stereo_pass_alt_2
#include "wavpack/src/unpack.c"
#include "wavpack/src/unpack3.c"
#include "wavpack/src/words.c"
#include "wavpack/src/wputils.c"
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#if (_MSC_VER)
#pragma warning (pop)
#endif

@ -98,12 +98,10 @@ static LONG DolbyLoFilterDelay[XBASSBUFFERSIZE];
static LONG DolbyHiFilterBuffer[FILTERBUFFERSIZE];
static LONG SurroundBuffer[SURROUNDBUFFERSIZE];
/*
// Access the main temporary mix buffer directly: avoids an extra pointer
extern int MixSoundBuffer[MIXBUFFERSIZE*2];
extern int MixSoundBuffer[MIXBUFFERSIZE*4];
//cextern int MixReverbBuffer[MIXBUFFERSIZE*2];
extern int MixReverbBuffer[MIXBUFFERSIZE*2];
*/
static UINT GetMaskFromSize(UINT len)
//-----------------------------------

@ -140,7 +140,12 @@
#else
# include <ogg/config_types.h>
#include <inttypes.h>
typedef int16_t ogg_int16_t;
typedef uint16_t ogg_uint16_t;
typedef int32_t ogg_int32_t;
typedef uint32_t ogg_uint32_t;
typedef int64_t ogg_int64_t;
#endif

@ -0,0 +1,5 @@
wpinclude_HEADERS = wavpack.h
wpincludedir = $(prefix)/include/wavpack
MAINTAINERCLEANFILES = \
Makefile.in

@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////////////////////
// **** WAVPACK **** //
// Hybrid Lossless Wavefile Compressor //
// Copyright (c) 1998 - 2006 Conifer Software. //
// Copyright (c) 1998 - 2016 David Bryant. //
// All Rights Reserved. //
// Distributed under the BSD Software License (see license.txt) //
////////////////////////////////////////////////////////////////////////////
@ -16,10 +16,17 @@
#include <sys/types.h>
#if defined(_WIN32) && !defined(__MINGW32__)
#include <stdint.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
typedef unsigned __int64 uint64_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int8 uint8_t;
typedef __int64 int64_t;
typedef __int32 int32_t;
typedef __int16 int16_t;
typedef __int8 int8_t;
#else
#include <inttypes.h>
#include <stdint.h>
#endif
// RIFF / wav header formats (these occur at the beginning of both wav files
@ -41,12 +48,12 @@ typedef struct {
#define ChunkHeaderFormat "4L"
typedef struct {
unsigned short FormatTag, NumChannels;
uint16_t FormatTag, NumChannels;
uint32_t SampleRate, BytesPerSecond;
unsigned short BlockAlign, BitsPerSample;
unsigned short cbSize, ValidBitsPerSample;
uint16_t BlockAlign, BitsPerSample;
uint16_t cbSize, ValidBitsPerSample;
int32_t ChannelMask;
unsigned short SubFormat;
uint16_t SubFormat;
char GUID [14];
} WaveHeader;
@ -62,13 +69,43 @@ typedef struct {
typedef struct {
char ckID [4];
uint32_t ckSize;
short version;
unsigned char track_no, index_no;
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 WavpackHeader.flags
#define BYTES_STORED 3 // 1-4 bytes/sample
#define MONO_FLAG 4 // not stereo
@ -95,17 +132,19 @@ 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
#define CUR_STREAM_VERS 0x407 // stream version we are writing now
// These are the mask bit definitions for the metadata chunk id byte (see format.txt)
@ -131,11 +170,15 @@ typedef struct {
#define ID_RIFF_HEADER (ID_OPTIONAL_DATA | 0x1)
#define ID_RIFF_TRAILER (ID_OPTIONAL_DATA | 0x2)
#define ID_REPLAY_GAIN (ID_OPTIONAL_DATA | 0x3) // never used (APEv2)
#define ID_CUESHEET (ID_OPTIONAL_DATA | 0x4) // never used (APEv2)
#define ID_ALT_HEADER (ID_OPTIONAL_DATA | 0x3)
#define ID_ALT_TRAILER (ID_OPTIONAL_DATA | 0x4)
#define ID_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0x5)
#define ID_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x6)
#define ID_SAMPLE_RATE (ID_OPTIONAL_DATA | 0x7)
#define ID_ALT_EXTENSION (ID_OPTIONAL_DATA | 0x8)
#define ID_ALT_MD5_CHECKSUM (ID_OPTIONAL_DATA | 0x9)
#define ID_NEW_CONFIG_BLOCK (ID_OPTIONAL_DATA | 0xa)
#define ID_BLOCK_CHECKSUM (ID_OPTIONAL_DATA | 0xf)
///////////////////////// WavPack Configuration ///////////////////////////////
@ -149,12 +192,13 @@ typedef struct {
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;
int num_tag_strings; // this field is not used
char **tag_strings; // this field is not used
} WavpackConfig;
#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_FAST_FLAG 0x200 // fast mode
#define CONFIG_HIGH_FLAG 0x800 // high quality mode
@ -166,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
@ -174,6 +219,32 @@ typedef struct {
#define CONFIG_PAIR_UNDEF_CHANS 0x20000000 // encode undefined channels in stereo pairs
#define CONFIG_OPTIMIZE_MONO 0x80000000 // optimize for mono streams posing as stereo
// The lower 8 bits of qmode indicate the use of new features in version 5 that (presently)
// only apply to Core Audio Files (CAF) and DSD files, but could apply to other things too.
// These flags are stored in the file and can be retrieved by a decoder that is aware of
// them, but the individual bits are meaningless to the library. If ANY of these bits are
// set then the MD5 sum is written with a new ID so that old decoders will not see it
// (because these features will cause the MD5 sum to be different and fail).
#define QMODE_BIG_ENDIAN 0x1 // big-endian data format (opposite of WAV format)
#define QMODE_SIGNED_BYTES 0x2 // 8-bit audio data is signed (opposite of WAV format)
#define QMODE_UNSIGNED_WORDS 0x4 // audio data (other than 8-bit) is unsigned (opposite of WAV format)
#define QMODE_REORDERED_CHANS 0x8 // source channels were not Microsoft order, so they were reordered
#define QMODE_DSD_LSB_FIRST 0x10 // DSD bytes, LSB first (most Sony .dsf files)
#define QMODE_DSD_MSB_FIRST 0x20 // DSD bytes, MSB first (Philips .dff files)
#define QMODE_DSD_IN_BLOCKS 0x40 // DSD data is blocked by channels (Sony .dsf only)
#define QMODE_DSD_AUDIO (QMODE_DSD_LSB_FIRST | QMODE_DSD_MSB_FIRST)
// The rest of the qmode word is reserved for the private use of the command-line programs
// and are ignored by the library (and not stored either). They really should not be defined
// here, but I thought it would be a good idea to have all the definitions together.
#define QMODE_ADOBE_MODE 0x100 // user specified Adobe mode
#define QMODE_NO_STORE_WRAPPER 0x200 // user specified to not store audio file wrapper (RIFF, CAFF, etc.)
#define QMODE_CHANS_UNASSIGNED 0x400 // user specified "..." in --channel-order option
#define QMODE_IGNORE_LENGTH 0x800 // user specified to ignore length in file header
#define QMODE_RAW_PCM 0x1000 // user specified raw PCM format (no header present)
////////////// Callbacks used for reading & writing WavPack streams //////////
typedef struct {
@ -189,18 +260,40 @@ typedef struct {
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);
//////////////////////////// function prototypes /////////////////////////////
// Note: See wputils.c sourcecode for descriptions for using these functions.
typedef void WavpackContext;
#ifdef __cplusplus
extern "C" {
#endif
#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);
@ -212,6 +305,16 @@ WavpackContext *WavpackOpenFileInput (const char *infilename, char *error, int f
#define OPEN_STREAMING 0x20 // "streaming" mode blindly unpacks blocks
// w/o regard to header file position info
#define OPEN_EDIT_TAGS 0x40 // allow editing of tags
#define OPEN_FILE_UTF8 0x80 // assume filenames are UTF-8 encoded, not ANSI (Windows only)
// new for version 5
#define OPEN_DSD_NATIVE 0x100 // open DSD files as bitstreams
// (returned as 8-bit "samples" stored in 32-bit words)
#define OPEN_DSD_AS_PCM 0x200 // open DSD files as 24-bit PCM (decimated 8x)
#define OPEN_ALT_TYPES 0x400 // application is aware of alternate file types & qmode
// (just affects retrieving wrappers & MD5 checksums)
#define OPEN_NO_CHECKSUM 0x800 // don't verify block checksums before decoding
int WavpackGetMode (WavpackContext *wpc);
@ -230,16 +333,25 @@ 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);
char *WavpackGetFileExtension (WavpackContext *wpc);
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);
int WavpackLossyBlocks (WavpackContext *wpc);
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);
@ -247,12 +359,15 @@ 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);
void WavpackFreeWrapper (WavpackContext *wpc);
void WavpackSeekTrailingWrapper (WavpackContext *wpc);
double WavpackGetProgress (WavpackContext *wpc);
uint32_t WavpackGetFileSize (WavpackContext *wpc);
int64_t WavpackGetFileSize64 (WavpackContext *wpc);
double WavpackGetRatio (WavpackContext *wpc);
double WavpackGetAverageBitrate (WavpackContext *wpc, int count_wvc);
double WavpackGetInstantBitrate (WavpackContext *wpc);
@ -268,7 +383,17 @@ int WavpackDeleteTagItem (WavpackContext *wpc, const char *item);
int WavpackWriteTag (WavpackContext *wpc);
WavpackContext *WavpackOpenFileOutput (WavpackBlockOutput blockout, void *wv_id, void *wvc_id);
void WavpackSetFileInformation (WavpackContext *wpc, char *file_extension, unsigned char file_format);
#define WP_FORMAT_WAV 0 // Microsoft RIFF, including BWF and RF64 varients
#define WP_FORMAT_W64 1 // Sony Wave64
#define WP_FORMAT_CAF 2 // Apple CoreAudio
#define WP_FORMAT_DFF 3 // Philips DSDIFF
#define WP_FORMAT_DSF 4 // Sony DSD Format
int WavpackSetConfiguration (WavpackContext *wpc, WavpackConfig *config, uint32_t total_samples);
int WavpackSetConfiguration64 (WavpackContext *wpc, WavpackConfig *config, int64_t total_samples, const unsigned char *chan_ids);
int 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]);
int WavpackPackInit (WavpackContext *wpc);
@ -282,6 +407,8 @@ void WavpackFloatNormalize (int32_t *values, int32_t num_values, int delta_exp);
void WavpackLittleEndianToNative (void *data, char *format);
void WavpackNativeToLittleEndian (void *data, char *format);
void WavpackBigEndianToNative (void *data, char *format);
void WavpackNativeToBigEndian (void *data, char *format);
uint32_t WavpackGetLibraryVersion (void);
const char *WavpackGetLibraryVersionString (void);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save