/* SPDX-License-Identifier: BSD-3-Clause */ /* SPDX-FileCopyrightText: OpenMPT Project Developers and Contributors */ #pragma once #include "openmpt/all/BuildSettings.hpp" #include "mpt/audio/span.hpp" #include "mpt/base/macros.hpp" #include "openmpt/soundbase/SampleClip.hpp" #include "openmpt/soundbase/SampleClipFixedPoint.hpp" #include "openmpt/soundbase/SampleConvert.hpp" #include "openmpt/soundbase/SampleConvertFixedPoint.hpp" #include "openmpt/soundbase/SampleFormat.hpp" #include #include #include OPENMPT_NAMESPACE_BEGIN template void ConvertBufferMixInternalFixedToBuffer(TOutBuf outBuf, TInBuf inBuf, Tdither &dither, std::size_t channels, std::size_t count) { using TOutSample = typename std::remove_const::type; using TInSample = typename std::remove_const::type; assert(inBuf.size_channels() >= channels); assert(outBuf.size_channels() >= channels); assert(inBuf.size_frames() >= count); assert(outBuf.size_frames() >= count); constexpr int ditherBits = SampleFormat(SampleFormatTraits::sampleFormat()).IsInt() ? SampleFormat(SampleFormatTraits::sampleFormat()).GetBitsPerSample() : 0; SC::ClipFixed clip; SC::ConvertFixedPoint conv; for(std::size_t i = 0; i < count; ++i) { for(std::size_t channel = 0; channel < channels; ++channel) { outBuf(channel, i) = conv(clip(dither.template process(channel, inBuf(channel, i)))); } } } template void ConvertBufferToBufferMixInternalFixed(TOutBuf outBuf, TInBuf inBuf, std::size_t channels, std::size_t count) { using TOutSample = typename std::remove_const::type; using TInSample = typename std::remove_const::type; assert(inBuf.size_channels() >= channels); assert(outBuf.size_channels() >= channels); assert(inBuf.size_frames() >= count); assert(outBuf.size_frames() >= count); SC::ConvertToFixedPoint conv; for(std::size_t i = 0; i < count; ++i) { for(std::size_t channel = 0; channel < channels; ++channel) { outBuf(channel, i) = conv(inBuf(channel, i)); } } } template void ConvertBufferMixInternalToBuffer(TOutBuf outBuf, TInBuf inBuf, Tdither &dither, std::size_t channels, std::size_t count) { using TOutSample = typename std::remove_const::type; using TInSample = typename std::remove_const::type; assert(inBuf.size_channels() >= channels); assert(outBuf.size_channels() >= channels); assert(inBuf.size_frames() >= count); assert(outBuf.size_frames() >= count); constexpr int ditherBits = SampleFormat(SampleFormatTraits::sampleFormat()).IsInt() ? SampleFormat(SampleFormatTraits::sampleFormat()).GetBitsPerSample() : 0; SC::Clip clip; SC::Convert conv; for(std::size_t i = 0; i < count; ++i) { for(std::size_t channel = 0; channel < channels; ++channel) { outBuf(channel, i) = conv(clip(dither.template process(channel, inBuf(channel, i)))); } } } template void ConvertBufferToBufferMixInternal(TOutBuf outBuf, TInBuf inBuf, std::size_t channels, std::size_t count) { using TOutSample = typename std::remove_const::type; using TInSample = typename std::remove_const::type; assert(inBuf.size_channels() >= channels); assert(outBuf.size_channels() >= channels); assert(inBuf.size_frames() >= count); assert(outBuf.size_frames() >= count); SC::Convert conv; for(std::size_t i = 0; i < count; ++i) { for(std::size_t channel = 0; channel < channels; ++channel) { outBuf(channel, i) = conv(inBuf(channel, i)); } } } OPENMPT_NAMESPACE_END