Skip to content

Commit

Permalink
use std::span for audio buffers passed to DfxPluginCore::process
Browse files Browse the repository at this point in the history
  • Loading branch information
sophiapoirier committed Oct 28, 2022
1 parent d5b479f commit 79195f6
Show file tree
Hide file tree
Showing 20 changed files with 104 additions and 96 deletions.
10 changes: 5 additions & 5 deletions dfx-library/dfxplugin-rtas.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ UInt32 DfxPlugin::ProcessAudio(bool inIsGlobalBypassed)
else // no input connection; use default value of zero
{
// (re)allocate the zero audio buffer if it is not currently large enough for this rendering slice
if (static_cast<long>(mZeroAudioBuffer.size()) < totalInputSamples)
if (std::ssize(mZeroAudioBuffer) < totalInputSamples)
{
mZeroAudioBuffer.assign(totalInputSamples, 0.0f);
}
Expand Down Expand Up @@ -541,7 +541,7 @@ void DfxPlugin::RenderAudio(float** inAudioStreams, float** outAudioStreams, lon
// RTAS clip monitoring
for (SInt32 channel = 0; (channel < GetNumInputs()) && !fClipped; channel++)
{
mInputAudioStreams[[channel]] = nullptr;
mInputAudioStreams[channel] = nullptr;
if (!inAudioStreams[channel]) // XXX possible in AudioSuite
{
continue;
Expand Down Expand Up @@ -584,16 +584,16 @@ void DfxPlugin::RenderAudio(float** inAudioStreams, float** outAudioStreams, lon
#if TARGET_PLUGIN_USES_DSPCORE
if (mDSPCores[channel])
{
auto inputAudio = mInputAudioStreams[channel];
std::span inputAudio(mInputAudioStreams[channel], dfx::math::ToUnsigned(inNumFramesToProcess));
if (asymmetricalchannels())
{
if (channel == 0)
{
std::copy_n(mInputAudioStreams[channel], sampleFrames, mAsymmetricalInputAudioBuffer.data());
}
inputAudio = mAsymmetricalInputAudioBuffer.data();
inputAudio = std::span(mAsymmetricalInputAudioBuffer).subspan(0, dfx::math::ToUnsigned(inNumFramesToProcess));
}
mDSPCores[channel]->process(inputAudio, outAudioStreams[channel], dfx::math::ToUnsigned(inNumFramesToProcess));
mDSPCores[channel]->process(inputAudio, {outAudioStreams[channel], dfx::math::ToUnsigned(inNumFramesToProcess)});
}
#endif
}
Expand Down
6 changes: 3 additions & 3 deletions dfx-library/dfxplugin-vst.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -543,17 +543,17 @@ void DfxPlugin::processReplacing(float** inputs, float** outputs, VstInt32 sampl
{
if (mDSPCores[ch])
{
auto inputAudio = mInputAudioStreams[ch];
std::span inputAudio(mInputAudioStreams[ch], dfx::math::ToUnsigned(sampleFrames));
if (asymmetricalchannels())
{
if (ch == 0)
{
assert(mAsymmetricalInputAudioBuffer.size() >= static_cast<size_t>(sampleFrames));
std::copy_n(mInputAudioStreams[ch], dfx::math::ToUnsigned(sampleFrames), mAsymmetricalInputAudioBuffer.data());
}
inputAudio = mAsymmetricalInputAudioBuffer.data();
inputAudio = std::span(mAsymmetricalInputAudioBuffer).subspan(0, dfx::math::ToUnsigned(sampleFrames));
}
mDSPCores[ch]->process(inputAudio, outputs[ch], dfx::math::ToUnsigned(sampleFrames));
mDSPCores[ch]->process(inputAudio, {outputs[ch], dfx::math::ToUnsigned(sampleFrames)});
}
}
#else
Expand Down
43 changes: 22 additions & 21 deletions dfx-library/dfxplugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ VST_NUM_CHANNELS
#include <mutex>
#include <optional>
#include <set>
#include <span>
#include <string>
#include <string_view>
#include <thread>
Expand Down Expand Up @@ -1110,20 +1111,20 @@ class DfxPluginCore
#endif
{
public:
explicit DfxPluginCore(DfxPlugin* inDfxPlugin)
explicit DfxPluginCore(DfxPlugin& inDfxPlugin)
:
#ifdef TARGET_API_DSPCORE_CLASS
TARGET_API_DSPCORE_CLASS(*inDfxPlugin),
TARGET_API_DSPCORE_CLASS(inDfxPlugin),
#endif
mDfxPlugin(inDfxPlugin),
mSampleRate(inDfxPlugin->getsamplerate())
mSampleRate(inDfxPlugin.getsamplerate())
{
assert(mSampleRate > 0.);
}

virtual ~DfxPluginCore()
{
mDfxPlugin->unregisterAllSmoothedAudioValues(this);
mDfxPlugin.unregisterAllSmoothedAudioValues(this);
}

DfxPluginCore(DfxPluginCore const&) = delete;
Expand All @@ -1136,14 +1137,14 @@ class DfxPluginCore
reset();
}

virtual void process(float const* inStream, float* outStream, size_t inNumFrames) = 0;
virtual void process(std::span<float const> inStream, std::span<float> outStream) = 0;
virtual void reset() {}
// NOTE: a weakness of the processparameters design, and then subsequent snapping of
// all smoothed values if it is the first audio render since audio reset, is that you
// initially miss that snap if you getValue a smoothed value within processparameters
virtual void processparameters() {}

auto getplugin() const noexcept
DfxPlugin& getplugin() const noexcept
{
return mDfxPlugin;
}
Expand All @@ -1157,23 +1158,23 @@ class DfxPluginCore
}
double getparameter_f(dfx::ParameterID inParameterID) const
{
return mDfxPlugin->getdspcoreparameter_f(inParameterID);
return mDfxPlugin.getdspcoreparameter_f(inParameterID);
}
int64_t getparameter_i(dfx::ParameterID inParameterID) const
{
return mDfxPlugin->getdspcoreparameter_i(inParameterID);
return mDfxPlugin.getdspcoreparameter_i(inParameterID);
}
bool getparameter_b(dfx::ParameterID inParameterID) const
{
return mDfxPlugin->getdspcoreparameter_b(inParameterID);
return mDfxPlugin.getdspcoreparameter_b(inParameterID);
}
double getparameter_scalar(dfx::ParameterID inParameterID) const
{
return mDfxPlugin->getdspcoreparameter_scalar(inParameterID);
return mDfxPlugin.getdspcoreparameter_scalar(inParameterID);
}
double getparameter_gen(dfx::ParameterID inParameterID) const
{
return mDfxPlugin->getdspcoreparameter_gen(inParameterID);
return mDfxPlugin.getdspcoreparameter_gen(inParameterID);
}
std::optional<double> getparameterifchanged_f(dfx::ParameterID inParameterID) const
{
Expand All @@ -1197,38 +1198,38 @@ class DfxPluginCore
}
double getparametermin_f(dfx::ParameterID inParameterID) const
{
return mDfxPlugin->getparametermin_f(inParameterID);
return mDfxPlugin.getparametermin_f(inParameterID);
}
int64_t getparametermin_i(dfx::ParameterID inParameterID) const
{
return mDfxPlugin->getparametermin_i(inParameterID);
return mDfxPlugin.getparametermin_i(inParameterID);
}
double getparametermax_f(dfx::ParameterID inParameterID) const
{
return mDfxPlugin->getparametermax_f(inParameterID);
return mDfxPlugin.getparametermax_f(inParameterID);
}
int64_t getparametermax_i(dfx::ParameterID inParameterID) const
{
return mDfxPlugin->getparametermax_i(inParameterID);
return mDfxPlugin.getparametermax_i(inParameterID);
}
bool getparameterchanged(dfx::ParameterID inParameterID) const
{
return mDfxPlugin->getparameterchanged(inParameterID);
return mDfxPlugin.getparameterchanged(inParameterID);
}
void registerSmoothedAudioValue(dfx::ISmoothedValue* smoothedValue)
{
mDfxPlugin->registerSmoothedAudioValue(smoothedValue, this);
mDfxPlugin.registerSmoothedAudioValue(smoothedValue, this);
smoothedValue->setSampleRate(getsamplerate());
}
void incrementSmoothedAudioValues()
{
mDfxPlugin->incrementSmoothedAudioValues(this);
mDfxPlugin.incrementSmoothedAudioValues(this);
}

#ifdef TARGET_API_AUDIOUNIT
void Process(Float32 const* inStream, Float32* outStream, UInt32 inNumFrames, bool& ioSilence) final
{
process(inStream, outStream, inNumFrames);
process({inStream, inNumFrames}, {outStream, inNumFrames});
ioSilence = false; // TODO: allow DSP cores to communicate their output silence status
}
void Reset() final
Expand All @@ -1244,7 +1245,7 @@ class DfxPluginCore


private:
DfxPlugin* const mDfxPlugin;
DfxPlugin& mDfxPlugin;
double const mSampleRate; // fixed for the lifespan of a DSP core

#ifndef TARGET_API_AUDIOUNIT
Expand Down Expand Up @@ -1434,7 +1435,7 @@ template <class DSPCoreClass>
[[nodiscard]] std::unique_ptr<DSPCoreClass> DfxPlugin::dspCoreFactory()
{
static_assert(std::is_base_of_v<DfxPluginCore, DSPCoreClass>);
auto core = std::make_unique<DSPCoreClass>(this);
auto core = std::make_unique<DSPCoreClass>(*this);
core->dfxplugincore_postconstructor();
return core;
}
Expand Down
6 changes: 3 additions & 3 deletions exemplar/exemplar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ PLUGIN::PLUGIN(TARGET_API_BASE_INSTANCE_TYPE inInstance)
#endif
}

PLUGINCORE::PLUGINCORE(DfxPlugin * inInstance)
PLUGINCORE::PLUGINCORE(DfxPlugin& inInstance)
: DfxPluginCore(inInstance) {
/* determine the size of the largest window size */
constexpr auto maxframe = *std::max_element(std::cbegin(buffersizes), std::cend(buffersizes));
Expand Down Expand Up @@ -557,10 +557,10 @@ void PLUGINCORE::classify(float const * in, float & scale,
*/


void PLUGINCORE::process(const float *tin, float *tout, size_t samples) {
void PLUGINCORE::process(std::span<float const> tin, std::span<float> tout) {
int z = 0;

for (size_t ii = 0; ii < samples; ii++) {
for (size_t ii = 0; ii < tout.size(); ii++) {

/* copy sample in */
in0[insize] = tin[ii];
Expand Down
8 changes: 4 additions & 4 deletions exemplar/exemplar.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ enum : dfx::ParameterID { P_BUFSIZE, P_SHAPE,
};


class PLUGIN : public DfxPlugin {
class PLUGIN final : public DfxPlugin {
public:
explicit PLUGIN(TARGET_API_BASE_INSTANCE_TYPE inInstance);

Expand All @@ -81,13 +81,13 @@ class PLUGIN : public DfxPlugin {
void makepresets();
};

class PLUGINCORE : public DfxPluginCore {
class PLUGINCORE final : public DfxPluginCore {
public:
explicit PLUGINCORE(DfxPlugin * inInstance);
explicit PLUGINCORE(DfxPlugin& inInstance);

void reset() override;
void processparameters() override;
void process(const float *in, float *out, size_t inNumFrames) override;
void process(std::span<float const> in, std::span<float> out) override;

long getwindowsize() const noexcept { return third; }

Expand Down
20 changes: 10 additions & 10 deletions geometer/geometer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,14 +301,14 @@ void PLUGIN::updatewindowcache(PLUGINCORE * geometercore)
void PLUGINCORE::clearwindowcache()
{
if (iswaveformsource()) {
geometer->clearwindowcache();
geometer.clearwindowcache();
}
}

void PLUGINCORE::updatewindowcache()
{
if (iswaveformsource()) {
geometer->updatewindowcache(this);
geometer.updatewindowcache(this);
}
}

Expand Down Expand Up @@ -343,9 +343,9 @@ std::optional<dfx::ParameterAssignment> PLUGIN::settings_getLearningAssignData(d
}
}

PLUGINCORE::PLUGINCORE(DfxPlugin* inDfxPlugin)
PLUGINCORE::PLUGINCORE(DfxPlugin& inDfxPlugin)
: DfxPluginCore(inDfxPlugin),
geometer(dynamic_cast<PLUGIN*>(inDfxPlugin))
geometer(dynamic_cast<PLUGIN&>(inDfxPlugin))
{
/* determine the size of the largest window size */
constexpr auto maxframe = *std::max_element(PLUGIN::buffersizes.cbegin(), PLUGIN::buffersizes.cend());
Expand All @@ -369,8 +369,8 @@ PLUGINCORE::PLUGINCORE(DfxPlugin* inDfxPlugin)

if (iswaveformsource()) { // does not matter which DSP core, but this just should happen only once
auto const delay_samples = dfx::math::ToUnsigned(PLUGIN::buffersizes.at(getparameter_i(P_BUFSIZE)));
getplugin()->setlatency_samples(delay_samples);
getplugin()->settailsize_samples(delay_samples);
getplugin().setlatency_samples(delay_samples);
getplugin().settailsize_samples(delay_samples);
}
}

Expand Down Expand Up @@ -1185,8 +1185,8 @@ XXX Sophia's ideas:
- it would also be nice to make this windowing stuff into a reusable class so that we don't find ourselves maintaining the same code accross so many different plugins
*/

void PLUGINCORE::process(float const* tin, float* tout, size_t samples) {
for (size_t ii = 0; ii < samples; ii++) {
void PLUGINCORE::process(std::span<float const> tin, std::span<float> tout) {
for (size_t ii = 0; ii < tout.size(); ii++) {

/* copy sample in */
in0[insize] = tin[ii];
Expand Down Expand Up @@ -1259,9 +1259,9 @@ void PLUGINCORE::updatewindowsize()
outstart = 0;
outsize = framesize;

getplugin()->setlatency_samples(dfx::math::ToUnsigned(framesize));
getplugin().setlatency_samples(dfx::math::ToUnsigned(framesize));
/* tail is the same as delay, of course */
getplugin()->settailsize_samples(dfx::math::ToUnsigned(framesize));
getplugin().settailsize_samples(dfx::math::ToUnsigned(framesize));
}


Expand Down
6 changes: 3 additions & 3 deletions geometer/geometer.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ class PLUGIN final : public DfxPlugin {

class PLUGINCORE final : public DfxPluginCore {
public:
explicit PLUGINCORE(DfxPlugin* inDfxPlugin);
explicit PLUGINCORE(DfxPlugin& inDfxPlugin);

void reset() override;
void processparameters() override;
void process(float const* inAudio, float* outAudio, size_t inNumFrames) override;
void process(std::span<float const> inAudio, std::span<float> outAudio) override;

/* several of these are needed by geometerview. */
int processw(float const * in, float * out, int samples,
Expand All @@ -106,7 +106,7 @@ class PLUGINCORE final : public DfxPluginCore {
void clearwindowcache();
void updatewindowcache();

PLUGIN* const geometer;
PLUGIN& geometer;

/* input and output buffers. out is framesize*2 samples long, in is framesize
samples long. (for maximum framesize)
Expand Down
23 changes: 14 additions & 9 deletions polarizer/polarizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Polarizer. If not, see <https://www.gnu.org/licenses/>.
To contact the author, use the contact form at https://destroyfx.org/
To contact the author, use the contact form at https://destroyfx.org
------------------------------------------------------------------------*/

#include "polarizer.h"

#include <algorithm>


// these are macros that do boring entry point stuff for us
DFX_EFFECT_ENTRY(Polarizer)
Expand All @@ -40,7 +42,7 @@ Polarizer::Polarizer(TARGET_API_BASE_INSTANCE_TYPE inInstance)
}

//-----------------------------------------------------------------------------------------
PolarizerDSP::PolarizerDSP(DfxPlugin* inDfxPlugin)
PolarizerDSP::PolarizerDSP(DfxPlugin& inDfxPlugin)
: DfxPluginCore(inDfxPlugin)
{
registerSmoothedAudioValue(&mPolarizedAmp);
Expand All @@ -62,15 +64,18 @@ void PolarizerDSP::processparameters()
}

//-----------------------------------------------------------------------------------------
void PolarizerDSP::process(float const* inAudio, float* outAudio, size_t inNumFrames)
void PolarizerDSP::process(std::span<float const> inAudio, std::span<float> outAudio)
{
// fetch the current parameter values
auto const leapSize = getparameter_i(kSkip);
auto const leapSize = static_cast<decltype(mUnaffectedSamples)>(getparameter_i(kSkip));
auto const implode = getparameter_b(kImplode);

for (size_t sampleIndex = 0; sampleIndex < inNumFrames; sampleIndex++)
// catch up if leap size decreased
mUnaffectedSamples = std::min(mUnaffectedSamples, leapSize);

std::transform(inAudio.begin(), inAudio.end(), outAudio.begin(), [this, leapSize, implode](auto const inputValue)
{
auto outputValue = inAudio[sampleIndex];
auto outputValue = inputValue;
mUnaffectedSamples--;
if (mUnaffectedSamples < 0) // go to polarized when the leap is done
{
Expand All @@ -93,8 +98,8 @@ void PolarizerDSP::process(float const* inAudio, float* outAudio, size_t inNumFr
}
}

outAudio[sampleIndex] = outputValue;

incrementSmoothedAudioValues();
}

return outputValue;
});
}
Loading

0 comments on commit 79195f6

Please sign in to comment.