1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/*
* PluginMixBuffer.h
* -----------------
* Purpose: Helper class for managing plugin audio input and output buffers.
* 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 <algorithm>
#include <array>
#if defined(MPT_ENABLE_ARCH_INTRINSICS) || defined(MPT_WITH_VST)
#include "mpt/base/aligned_array.hpp"
#endif // MPT_ENABLE_ARCH_INTRINSICS || MPT_WITH_VST
OPENMPT_NAMESPACE_BEGIN
// At least this part of the code is ready for double-precision rendering... :>
// buffer_t: Sample buffer type (float, double, ...)
// bufferSize: Buffer size in samples
template<typename buffer_t, uint32 bufferSize>
class PluginMixBuffer
{
private:
#if defined(MPT_ENABLE_ARCH_INTRINSICS) || defined(MPT_WITH_VST)
static constexpr std::align_val_t alignment = std::align_val_t{16};
static_assert(sizeof(mpt::aligned_array<buffer_t, bufferSize, alignment>) == sizeof(std::array<buffer_t, bufferSize>));
static_assert(alignof(mpt::aligned_array<buffer_t, bufferSize, alignment>) == static_cast<std::size_t>(alignment));
#endif // MPT_ENABLE_ARCH_INTRINSICS || MPT_WITH_VST
protected:
#if defined(MPT_ENABLE_ARCH_INTRINSICS) || defined(MPT_WITH_VST)
std::vector<mpt::aligned_array<buffer_t, bufferSize, alignment>> inputs;
std::vector<mpt::aligned_array<buffer_t, bufferSize, alignment>> outputs;
#else // !(MPT_ENABLE_ARCH_INTRINSICS || MPT_WITH_VST)
std::vector<std::array<buffer_t, bufferSize>> inputs;
std::vector<std::array<buffer_t, bufferSize>> outputs;
#endif // MPT_ENABLE_ARCH_INTRINSICS || MPT_WITH_VST
std::vector<buffer_t*> inputsarray;
std::vector<buffer_t*> outputsarray;
public:
// Allocate input and output buffers
bool Initialize(uint32 numInputs, uint32 numOutputs)
{
// Short cut - we do not need to recreate the buffers.
if(inputs.size() == numInputs && outputs.size() == numOutputs)
{
return true;
}
try
{
inputs.resize(numInputs);
outputs.resize(numOutputs);
inputsarray.resize(numInputs);
outputsarray.resize(numOutputs);
} catch(mpt::out_of_memory e)
{
mpt::delete_out_of_memory(e);
inputs.clear();
inputs.shrink_to_fit();
outputs.clear();
outputs.shrink_to_fit();
inputsarray.clear();
inputsarray.shrink_to_fit();
outputsarray.clear();
outputsarray.shrink_to_fit();
return false;
}
for(uint32 i = 0; i < numInputs; i++)
{
inputsarray[i] = inputs[i].data();
}
for(uint32 i = 0; i < numOutputs; i++)
{
outputsarray[i] = outputs[i].data();
}
return true;
}
// Silence all input buffers.
void ClearInputBuffers(uint32 numSamples)
{
MPT_ASSERT(numSamples <= bufferSize);
for(size_t i = 0; i < inputs.size(); i++)
{
std::fill(inputs[i].data(), inputs[i].data() + numSamples, buffer_t{0});
}
}
// Silence all output buffers.
void ClearOutputBuffers(uint32 numSamples)
{
MPT_ASSERT(numSamples <= bufferSize);
for(size_t i = 0; i < outputs.size(); i++)
{
std::fill(outputs[i].data(), outputs[i].data() + numSamples, buffer_t{0});
}
}
PluginMixBuffer()
{
Initialize(2, 0);
}
// Return pointer to a given input or output buffer
const buffer_t *GetInputBuffer(uint32 index) const { return inputs[index].data(); }
const buffer_t *GetOutputBuffer(uint32 index) const { return outputs[index].data(); }
buffer_t *GetInputBuffer(uint32 index) { return inputs[index].data(); }
buffer_t *GetOutputBuffer(uint32 index) { return outputs[index].data(); }
// Return pointer array to all input or output buffers
buffer_t **GetInputBufferArray() { return inputs.empty() ? nullptr : inputsarray.data(); }
buffer_t **GetOutputBufferArray() { return outputs.empty() ? nullptr : outputsarray.data(); }
bool Ok() const { return (inputs.size() + outputs.size()) > 0; }
};
OPENMPT_NAMESPACE_END
|