From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- .../openmpt-trunk/soundlib/ModSampleCopy.h | 157 +++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 Src/external_dependencies/openmpt-trunk/soundlib/ModSampleCopy.h (limited to 'Src/external_dependencies/openmpt-trunk/soundlib/ModSampleCopy.h') diff --git a/Src/external_dependencies/openmpt-trunk/soundlib/ModSampleCopy.h b/Src/external_dependencies/openmpt-trunk/soundlib/ModSampleCopy.h new file mode 100644 index 00000000..0eda92e5 --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/soundlib/ModSampleCopy.h @@ -0,0 +1,157 @@ +/* + * ModSampleCopy.h + * --------------- + * Purpose: Functions for copying ModSample data. + * 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" + + +#include "openmpt/soundbase/SampleDecode.hpp" + + +OPENMPT_NAMESPACE_BEGIN + + +struct ModSample; + +// Copy a mono sample data buffer. +template +size_t CopyMonoSample(ModSample &sample, const Tbyte *sourceBuffer, size_t sourceSize, SampleConversion conv = SampleConversion()) +{ + MPT_ASSERT(sample.GetNumChannels() == 1); + MPT_ASSERT(sample.GetElementarySampleSize() == sizeof(typename SampleConversion::output_t)); + + const size_t frameSize = SampleConversion::input_inc; + const size_t countFrames = std::min(sourceSize / frameSize, static_cast(sample.nLength)); + size_t numFrames = countFrames; + SampleConversion sampleConv(conv); + const std::byte * MPT_RESTRICT inBuf = mpt::byte_cast(sourceBuffer); + typename SampleConversion::output_t * MPT_RESTRICT outBuf = static_cast(sample.samplev()); + while(numFrames--) + { + *outBuf = sampleConv(inBuf); + inBuf += SampleConversion::input_inc; + outBuf++; + } + return frameSize * countFrames; +} + + +// Copy a stereo interleaved sample data buffer. +template +size_t CopyStereoInterleavedSample(ModSample &sample, const Tbyte *sourceBuffer, size_t sourceSize, SampleConversion conv = SampleConversion()) +{ + MPT_ASSERT(sample.GetNumChannels() == 2); + MPT_ASSERT(sample.GetElementarySampleSize() == sizeof(typename SampleConversion::output_t)); + + const size_t frameSize = 2 * SampleConversion::input_inc; + const size_t countFrames = std::min(sourceSize / frameSize, static_cast(sample.nLength)); + size_t numFrames = countFrames; + SampleConversion sampleConvLeft(conv); + SampleConversion sampleConvRight(conv); + const std::byte * MPT_RESTRICT inBuf = mpt::byte_cast(sourceBuffer); + typename SampleConversion::output_t * MPT_RESTRICT outBuf = static_cast(sample.samplev()); + while(numFrames--) + { + *outBuf = sampleConvLeft(inBuf); + inBuf += SampleConversion::input_inc; + outBuf++; + *outBuf = sampleConvRight(inBuf); + inBuf += SampleConversion::input_inc; + outBuf++; + } + return frameSize * countFrames; +} + + +// Copy a stereo split sample data buffer. +template +size_t CopyStereoSplitSample(ModSample &sample, const Tbyte *sourceBuffer, size_t sourceSize, SampleConversion conv = SampleConversion()) +{ + MPT_ASSERT(sample.GetNumChannels() == 2); + MPT_ASSERT(sample.GetElementarySampleSize() == sizeof(typename SampleConversion::output_t)); + + const size_t sampleSize = SampleConversion::input_inc; + const size_t sourceSizeLeft = std::min(static_cast(sample.nLength) * SampleConversion::input_inc, sourceSize); + const size_t sourceSizeRight = std::min(static_cast(sample.nLength) * SampleConversion::input_inc, sourceSize - sourceSizeLeft); + const size_t countSamplesLeft = sourceSizeLeft / sampleSize; + const size_t countSamplesRight = sourceSizeRight / sampleSize; + + size_t numSamplesLeft = countSamplesLeft; + SampleConversion sampleConvLeft(conv); + const std::byte * MPT_RESTRICT inBufLeft = mpt::byte_cast(sourceBuffer); + typename SampleConversion::output_t * MPT_RESTRICT outBufLeft = static_cast(sample.samplev()); + while(numSamplesLeft--) + { + *outBufLeft = sampleConvLeft(inBufLeft); + inBufLeft += SampleConversion::input_inc; + outBufLeft += 2; + } + + size_t numSamplesRight = countSamplesRight; + SampleConversion sampleConvRight(conv); + const std::byte * MPT_RESTRICT inBufRight = mpt::byte_cast(sourceBuffer) + sample.nLength * SampleConversion::input_inc; + typename SampleConversion::output_t * MPT_RESTRICT outBufRight = static_cast(sample.samplev()) + 1; + while(numSamplesRight--) + { + *outBufRight = sampleConvRight(inBufRight); + inBufRight += SampleConversion::input_inc; + outBufRight += 2; + } + + return (countSamplesLeft + countSamplesRight) * sampleSize; +} + + +// Copy a sample data buffer and normalize it. Requires slightly advanced sample conversion functor. +template +size_t CopyAndNormalizeSample(ModSample &sample, const Tbyte *sourceBuffer, size_t sourceSize, typename SampleConversion::peak_t *srcPeak = nullptr, SampleConversion conv = SampleConversion()) +{ + const size_t sampleSize = SampleConversion::input_inc; + + MPT_ASSERT(sample.GetElementarySampleSize() == sizeof(typename SampleConversion::output_t)); + + size_t numSamples = sample.nLength * sample.GetNumChannels(); + LimitMax(numSamples, sourceSize / sampleSize); + + const std::byte * inBuf = mpt::byte_cast(sourceBuffer); + // Finding max value + SampleConversion sampleConv(conv); + for(size_t i = numSamples; i != 0; i--) + { + sampleConv.FindMax(inBuf); + inBuf += SampleConversion::input_inc; + } + + // If buffer is silent (maximum is 0), don't bother normalizing the sample - just keep the already silent buffer. + if(!sampleConv.IsSilent()) + { + inBuf = sourceBuffer; + // Copying buffer. + typename SampleConversion::output_t *outBuf = static_cast(sample.samplev()); + + for(size_t i = numSamples; i != 0; i--) + { + *outBuf = sampleConv(inBuf); + outBuf++; + inBuf += SampleConversion::input_inc; + } + } + + if(srcPeak) + { + *srcPeak = sampleConv.GetSrcPeak(); + } + + return numSamples * sampleSize; +} + + +OPENMPT_NAMESPACE_END -- cgit