Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
175
Src/external_dependencies/openmpt-trunk/soundlib/ModSample.h
Normal file
175
Src/external_dependencies/openmpt-trunk/soundlib/ModSample.h
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* ModSample.h
|
||||
* -----------
|
||||
* Purpose: Module Sample header class and helpers
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "openmpt/all/BuildSettings.hpp"
|
||||
|
||||
OPENMPT_NAMESPACE_BEGIN
|
||||
|
||||
class CSoundFile;
|
||||
|
||||
// Sample Struct
|
||||
struct ModSample
|
||||
{
|
||||
SmpLength nLength; // In frames
|
||||
SmpLength nLoopStart, nLoopEnd; // Ditto
|
||||
SmpLength nSustainStart, nSustainEnd; // Ditto
|
||||
union
|
||||
{
|
||||
void *pSample; // Pointer to sample data
|
||||
int8 *pSample8; // Pointer to 8-bit sample data
|
||||
int16 *pSample16; // Pointer to 16-bit sample data
|
||||
} pData;
|
||||
uint32 nC5Speed; // Frequency of middle-C, in Hz (for IT/S3M/MPTM)
|
||||
uint16 nPan; // Default sample panning (if pan flag is set), 0...256
|
||||
uint16 nVolume; // Default volume, 0...256 (ignored if uFlags[SMP_NODEFAULTVOLUME] is set)
|
||||
uint16 nGlobalVol; // Global volume (sample volume is multiplied by this), 0...64
|
||||
SampleFlags uFlags; // Sample flags (see ChannelFlags enum)
|
||||
int8 RelativeTone; // Relative note to middle c (for MOD/XM)
|
||||
int8 nFineTune; // Finetune period (for MOD/XM), -128...127, unit is 1/128th of a semitone
|
||||
VibratoType nVibType; // Auto vibrato type
|
||||
uint8 nVibSweep; // Auto vibrato sweep (i.e. how long it takes until the vibrato effect reaches its full depth)
|
||||
uint8 nVibDepth; // Auto vibrato depth
|
||||
uint8 nVibRate; // Auto vibrato rate (speed)
|
||||
uint8 rootNote; // For multisample import
|
||||
|
||||
//char name[MAX_SAMPLENAME]; // Maybe it would be nicer to have sample names here, but that would require some refactoring.
|
||||
mpt::charbuf<MAX_SAMPLEFILENAME> filename;
|
||||
std::string GetFilename() const { return filename; }
|
||||
|
||||
union
|
||||
{
|
||||
std::array<SmpLength, 9> cues;
|
||||
OPLPatch adlib;
|
||||
};
|
||||
|
||||
ModSample(MODTYPE type = MOD_TYPE_NONE)
|
||||
{
|
||||
pData.pSample = nullptr;
|
||||
Initialize(type);
|
||||
}
|
||||
|
||||
bool HasSampleData() const noexcept
|
||||
{
|
||||
MPT_ASSERT(!pData.pSample || (pData.pSample && nLength > 0)); // having sample pointer implies non-zero sample length
|
||||
return pData.pSample != nullptr && nLength != 0;
|
||||
}
|
||||
|
||||
MPT_FORCEINLINE const void *samplev() const noexcept
|
||||
{
|
||||
return pData.pSample;
|
||||
}
|
||||
MPT_FORCEINLINE void *samplev() noexcept
|
||||
{
|
||||
return pData.pSample;
|
||||
}
|
||||
MPT_FORCEINLINE const std::byte *sampleb() const noexcept
|
||||
{
|
||||
return mpt::void_cast<const std::byte*>(pData.pSample);
|
||||
}
|
||||
MPT_FORCEINLINE std::byte *sampleb() noexcept
|
||||
{
|
||||
return mpt::void_cast<std::byte*>(pData.pSample);
|
||||
}
|
||||
MPT_FORCEINLINE const int8 *sample8() const noexcept
|
||||
{
|
||||
MPT_ASSERT(GetElementarySampleSize() == sizeof(int8));
|
||||
return pData.pSample8;
|
||||
}
|
||||
MPT_FORCEINLINE int8 *sample8() noexcept
|
||||
{
|
||||
MPT_ASSERT(GetElementarySampleSize() == sizeof(int8));
|
||||
return pData.pSample8;
|
||||
}
|
||||
MPT_FORCEINLINE const int16 *sample16() const noexcept
|
||||
{
|
||||
MPT_ASSERT(GetElementarySampleSize() == sizeof(int16));
|
||||
return pData.pSample16;
|
||||
}
|
||||
MPT_FORCEINLINE int16 *sample16() noexcept
|
||||
{
|
||||
MPT_ASSERT(GetElementarySampleSize() == sizeof(int16));
|
||||
return pData.pSample16;
|
||||
}
|
||||
|
||||
// Return the size of one (elementary) sample in bytes.
|
||||
uint8 GetElementarySampleSize() const noexcept { return (uFlags & CHN_16BIT) ? 2 : 1; }
|
||||
|
||||
// Return the number of channels in the sample.
|
||||
uint8 GetNumChannels() const noexcept { return (uFlags & CHN_STEREO) ? 2 : 1; }
|
||||
|
||||
// Return the number of bytes per frame (Channels * Elementary Sample Size)
|
||||
uint8 GetBytesPerSample() const noexcept { return GetElementarySampleSize() * GetNumChannels(); }
|
||||
|
||||
// Return the size which pSample is at least.
|
||||
SmpLength GetSampleSizeInBytes() const noexcept { return nLength * GetBytesPerSample(); }
|
||||
|
||||
// Returns sample rate of the sample. The argument is needed because
|
||||
// the sample rate is obtained differently for different module types.
|
||||
uint32 GetSampleRate(const MODTYPE type) const;
|
||||
|
||||
// Translate sample properties between two given formats.
|
||||
void Convert(MODTYPE fromType, MODTYPE toType);
|
||||
|
||||
// Initialize sample slot with default values.
|
||||
void Initialize(MODTYPE type = MOD_TYPE_NONE);
|
||||
|
||||
// Copies sample data from another sample slot and ensures that the 16-bit/stereo flags are set accordingly.
|
||||
bool CopyWaveform(const ModSample &smpFrom);
|
||||
|
||||
// Allocate sample based on a ModSample's properties.
|
||||
// Returns number of bytes allocated, 0 on failure.
|
||||
size_t AllocateSample();
|
||||
// Allocate sample memory. On sucess, a pointer to the silenced sample buffer is returned. On failure, nullptr is returned.
|
||||
static void *AllocateSample(SmpLength numFrames, size_t bytesPerSample);
|
||||
// Compute sample buffer size in bytes, including any overhead introduced by pre-computed loops and such. Returns 0 if sample is too big.
|
||||
static size_t GetRealSampleBufferSize(SmpLength numSamples, size_t bytesPerSample);
|
||||
|
||||
void FreeSample();
|
||||
static void FreeSample(void *samplePtr);
|
||||
|
||||
// Set loop points and update loop wrap-around buffer
|
||||
void SetLoop(SmpLength start, SmpLength end, bool enable, bool pingpong, CSoundFile &sndFile);
|
||||
// Set sustain loop points and update loop wrap-around buffer
|
||||
void SetSustainLoop(SmpLength start, SmpLength end, bool enable, bool pingpong, CSoundFile &sndFile);
|
||||
// Update loop wrap-around buffer
|
||||
void PrecomputeLoops(CSoundFile &sndFile, bool updateChannels = true);
|
||||
|
||||
constexpr bool HasLoop() const noexcept { return uFlags[CHN_LOOP] && nLoopEnd > nLoopStart; }
|
||||
constexpr bool HasSustainLoop() const noexcept { return uFlags[CHN_SUSTAINLOOP] && nSustainEnd > nSustainStart; }
|
||||
constexpr bool HasPingPongLoop() const noexcept { return uFlags.test_all(CHN_LOOP | CHN_PINGPONGLOOP) && nLoopEnd > nLoopStart; }
|
||||
constexpr bool HasPingPongSustainLoop() const noexcept { return uFlags.test_all(CHN_SUSTAINLOOP | CHN_PINGPONGSUSTAIN) && nSustainEnd > nSustainStart; }
|
||||
|
||||
// Remove loop points if they're invalid.
|
||||
void SanitizeLoops();
|
||||
|
||||
// Transpose <-> Frequency conversions
|
||||
static uint32 TransposeToFrequency(int transpose, int finetune = 0);
|
||||
void TransposeToFrequency();
|
||||
static std::pair<int8, int8> FrequencyToTranspose(uint32 freq);
|
||||
void FrequencyToTranspose();
|
||||
|
||||
// Transpose the sample by amount specified in octaves (i.e. amount=1 transposes one octave up)
|
||||
void Transpose(double amount);
|
||||
|
||||
// Check if the sample has any valid cue points
|
||||
bool HasAnyCuePoints() const;
|
||||
// Check if the sample's cue points are the default cue point set.
|
||||
bool HasCustomCuePoints() const;
|
||||
void SetDefaultCuePoints();
|
||||
// Set cue points so that they are suitable for regular offset command extension
|
||||
void Set16BitCuePoints();
|
||||
void RemoveAllCuePoints();
|
||||
|
||||
void SetAdlib(bool enable, OPLPatch patch = OPLPatch{{}});
|
||||
};
|
||||
|
||||
OPENMPT_NAMESPACE_END
|
Loading…
Add table
Add a link
Reference in a new issue