aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/soundlib/SampleIO.h
diff options
context:
space:
mode:
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/SampleIO.h')
-rw-r--r--Src/external_dependencies/openmpt-trunk/soundlib/SampleIO.h256
1 files changed, 256 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/soundlib/SampleIO.h b/Src/external_dependencies/openmpt-trunk/soundlib/SampleIO.h
new file mode 100644
index 00000000..416a6035
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/soundlib/SampleIO.h
@@ -0,0 +1,256 @@
+/*
+ * SampleIO.h
+ * ----------
+ * Purpose: Central code for reading and writing samples. Create your SampleIO object and have a go at the ReadSample and WriteSample functions!
+ * Notes : Not all combinations of possible sample format combinations are implemented, especially for WriteSample.
+ * Using the existing generic sample conversion functors in SampleFormatConverters.h, it should be quite easy to extend the code, though.
+ * Authors: Olivier Lapicque
+ * OpenMPT Devs
+ * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
+ */
+
+
+#pragma once
+
+#include "openmpt/all/BuildSettings.hpp"
+
+
+#include "../common/FileReaderFwd.h"
+
+
+OPENMPT_NAMESPACE_BEGIN
+
+
+struct ModSample;
+
+// Sample import / export formats
+class SampleIO
+{
+public:
+ // Bits per sample
+ enum Bitdepth : uint8
+ {
+ _8bit = 8,
+ _16bit = 16,
+ _24bit = 24,
+ _32bit = 32,
+ _64bit = 64,
+ };
+
+ // Number of channels + channel format
+ enum Channels : uint8
+ {
+ mono = 1,
+ stereoInterleaved, // LRLRLR...
+ stereoSplit, // LLL...RRR...
+ };
+
+ // Sample byte order
+ enum Endianness : uint8
+ {
+ littleEndian = 0,
+ bigEndian = 1,
+ };
+
+ // Sample encoding
+ enum Encoding : uint8
+ {
+ signedPCM = 0, // Integer PCM, signed
+ unsignedPCM, // Integer PCM, unsigned
+ deltaPCM, // Integer PCM, delta-encoded
+ floatPCM, // Floating point PCM
+ IT214, // Impulse Tracker 2.14 compressed
+ IT215, // Impulse Tracker 2.15 compressed
+ AMS, // AMS / Velvet Studio packed
+ DMF, // DMF Huffman compression
+ MDL, // MDL Huffman compression
+ PTM8Dto16, // PTM 8-Bit delta value -> 16-Bit sample
+ ADPCM, // 4-Bit ADPCM-packed
+ MT2, // MadTracker 2 stereo delta encoding
+ floatPCM15, // Floating point PCM with 2^15 full scale
+ floatPCM23, // Floating point PCM with 2^23 full scale
+ floatPCMnormalize, // Floating point PCM and data will be normalized while reading
+ signedPCMnormalize, // Integer PCM and data will be normalized while reading
+ uLaw, // 8-to-16 bit G.711 u-law compression
+ aLaw, // 8-to-16 bit G.711 a-law compression
+ };
+
+protected:
+ Bitdepth m_bitdepth;
+ Channels m_channels;
+ Endianness m_endianness;
+ Encoding m_encoding;
+
+public:
+ constexpr SampleIO(Bitdepth bits = _8bit, Channels channels = mono, Endianness endianness = littleEndian, Encoding encoding = signedPCM)
+ : m_bitdepth(bits), m_channels(channels), m_endianness(endianness), m_encoding(encoding)
+ { }
+
+ bool operator== (const SampleIO &other) const
+ {
+ return memcmp(this, &other, sizeof(*this)) == 0;
+ }
+
+ bool operator!= (const SampleIO &other) const
+ {
+ return memcmp(this, &other, sizeof(*this)) != 0;
+ }
+
+ void operator|= (Bitdepth bits)
+ {
+ m_bitdepth = bits;
+ }
+
+ void operator|= (Channels channels)
+ {
+ m_channels = channels;
+ }
+
+ void operator|= (Endianness endianness)
+ {
+ m_endianness = endianness;
+ }
+
+ void operator|= (Encoding encoding)
+ {
+ m_encoding = encoding;
+ }
+
+ void MayNormalize()
+ {
+ if(GetBitDepth() >= 24)
+ {
+ if(GetEncoding() == SampleIO::signedPCM)
+ {
+ m_encoding = SampleIO::signedPCMnormalize;
+ } else if(GetEncoding() == SampleIO::floatPCM)
+ {
+ m_encoding = SampleIO::floatPCMnormalize;
+ }
+ }
+ }
+
+ // Return 0 in case of variable-length encoded samples.
+ MPT_CONSTEXPRINLINE uint8 GetEncodedBitsPerSample() const
+ {
+ switch(GetEncoding())
+ {
+ case signedPCM: // Integer PCM, signed
+ case unsignedPCM: //Integer PCM, unsigned
+ case deltaPCM: // Integer PCM, delta-encoded
+ case floatPCM: // Floating point PCM
+ case MT2: // MadTracker 2 stereo delta encoding
+ case floatPCM15: // Floating point PCM with 2^15 full scale
+ case floatPCM23: // Floating point PCM with 2^23 full scale
+ case floatPCMnormalize: // Floating point PCM and data will be normalized while reading
+ case signedPCMnormalize: // Integer PCM and data will be normalized while reading
+ return GetBitDepth();
+
+ case IT214: // Impulse Tracker 2.14 compressed
+ case IT215: // Impulse Tracker 2.15 compressed
+ case AMS: // AMS / Velvet Studio packed
+ case DMF: // DMF Huffman compression
+ case MDL: // MDL Huffman compression
+ return 0; // variable-length compressed
+
+ case PTM8Dto16: // PTM 8-Bit delta value -> 16-Bit sample
+ return 16;
+ case ADPCM: // 4-Bit ADPCM-packed
+ return 4;
+ case uLaw: // G.711 u-law
+ return 8;
+ case aLaw: // G.711 a-law
+ return 8;
+
+ default:
+ return 0;
+ }
+ }
+
+ // Return the static header size additional to the raw encoded sample data.
+ MPT_CONSTEXPRINLINE std::size_t GetEncodedHeaderSize() const
+ {
+ switch(GetEncoding())
+ {
+ case ADPCM:
+ return 16;
+ default:
+ return 0;
+ }
+ }
+
+ // Returns true if the encoded size cannot be calculated apriori from the encoding format and the sample length.
+ MPT_CONSTEXPRINLINE bool IsVariableLengthEncoded() const
+ {
+ return GetEncodedBitsPerSample() == 0;
+ }
+
+ // Returns true if the decoder for a given format uses FileReader interface and thus do not need to call GetPinnedView()
+ MPT_CONSTEXPRINLINE bool UsesFileReaderForDecoding() const
+ {
+ switch(GetEncoding())
+ {
+ case IT214:
+ case IT215:
+ case AMS:
+ case DMF:
+ case MDL:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ // Get bits per sample
+ constexpr uint8 GetBitDepth() const
+ {
+ return static_cast<uint8>(m_bitdepth);
+ }
+ // Get channel layout
+ constexpr Channels GetChannelFormat() const
+ {
+ return m_channels;
+ }
+ // Get number of channels
+ constexpr uint8 GetNumChannels() const
+ {
+ return GetChannelFormat() == mono ? 1u : 2u;
+ }
+ // Get sample byte order
+ constexpr Endianness GetEndianness() const
+ {
+ return m_endianness;
+ }
+ // Get sample format / encoding
+ constexpr Encoding GetEncoding() const
+ {
+ return m_encoding;
+ }
+
+ // Returns the encoded size of the sample. In case of variable-length encoding returns 0.
+ std::size_t CalculateEncodedSize(SmpLength length) const
+ {
+ if(IsVariableLengthEncoded())
+ {
+ return 0;
+ }
+ uint8 bps = GetEncodedBitsPerSample();
+ if(bps % 8u != 0)
+ {
+ MPT_ASSERT(GetEncoding() == ADPCM && bps == 4);
+ return GetEncodedHeaderSize() + (((length + 1) / 2) * GetNumChannels()); // round up
+ }
+ return GetEncodedHeaderSize() + (length * (bps / 8) * GetNumChannels());
+ }
+
+ // Read a sample from memory
+ size_t ReadSample(ModSample &sample, FileReader &file) const;
+
+#ifndef MODPLUG_NO_FILESAVE
+ // Write a sample to file
+ size_t WriteSample(std::ostream &f, const ModSample &sample, SmpLength maxSamples = 0) const;
+#endif // MODPLUG_NO_FILESAVE
+};
+
+
+OPENMPT_NAMESPACE_END