1
0

PluginMixBuffer.h 3.8 KB

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