aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/soundlib/ModSample.h
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/soundlib/ModSample.h
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/ModSample.h')
-rw-r--r--Src/external_dependencies/openmpt-trunk/soundlib/ModSample.h175
1 files changed, 175 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/soundlib/ModSample.h b/Src/external_dependencies/openmpt-trunk/soundlib/ModSample.h
new file mode 100644
index 00000000..07a2e1f4
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/soundlib/ModSample.h
@@ -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