Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
256
Src/external_dependencies/openmpt-trunk/soundlib/SampleIO.h
Normal file
256
Src/external_dependencies/openmpt-trunk/soundlib/SampleIO.h
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue