123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- /*
- * 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 <typename SampleConversion, typename Tbyte>
- 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<std::size_t>(sample.nLength));
- size_t numFrames = countFrames;
- SampleConversion sampleConv(conv);
- const std::byte * MPT_RESTRICT inBuf = mpt::byte_cast<const std::byte*>(sourceBuffer);
- typename SampleConversion::output_t * MPT_RESTRICT outBuf = static_cast<typename SampleConversion::output_t *>(sample.samplev());
- while(numFrames--)
- {
- *outBuf = sampleConv(inBuf);
- inBuf += SampleConversion::input_inc;
- outBuf++;
- }
- return frameSize * countFrames;
- }
- // Copy a stereo interleaved sample data buffer.
- template <typename SampleConversion, typename Tbyte>
- 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<std::size_t>(sample.nLength));
- size_t numFrames = countFrames;
- SampleConversion sampleConvLeft(conv);
- SampleConversion sampleConvRight(conv);
- const std::byte * MPT_RESTRICT inBuf = mpt::byte_cast<const std::byte*>(sourceBuffer);
- typename SampleConversion::output_t * MPT_RESTRICT outBuf = static_cast<typename SampleConversion::output_t *>(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 <typename SampleConversion, typename Tbyte>
- 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<std::size_t>(sample.nLength) * SampleConversion::input_inc, sourceSize);
- const size_t sourceSizeRight = std::min(static_cast<std::size_t>(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<const std::byte*>(sourceBuffer);
- typename SampleConversion::output_t * MPT_RESTRICT outBufLeft = static_cast<typename SampleConversion::output_t *>(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<const std::byte*>(sourceBuffer) + sample.nLength * SampleConversion::input_inc;
- typename SampleConversion::output_t * MPT_RESTRICT outBufRight = static_cast<typename SampleConversion::output_t *>(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 <typename SampleConversion, typename Tbyte>
- 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<const std::byte*>(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<typename SampleConversion::output_t *>(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
|