Skip to content

Commit

Permalink
Remove some locks from the audio thread (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
vberthiaume authored Jul 9, 2024
1 parent c217297 commit 8b0e2d3
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 22 deletions.
32 changes: 17 additions & 15 deletions source/DSP/GainedOscillator.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class GainedOscillator
osc.setFrequency (newValue, force);
}

void setOscShape (int newShape);
void setOscShape (OscShape::Values newShape) { nextOsc.store (newShape); }

/**
* @brief Sets the gain for the oscillator in the processorChain.
Expand All @@ -69,9 +69,7 @@ class GainedOscillator
template <typename ProcessContext>
void process (const ProcessContext& context) noexcept
{
//TODO: lock in audio thread!!! This should/could be a try lock and the other one a lock,
// so we only lock in the other place. But are these actuallty different threads though?
std::lock_guard<std::mutex> lock (processMutex);
updateOscillators();

processorChain.process (context);
}
Expand All @@ -85,7 +83,9 @@ class GainedOscillator
gainIndex
};

std::mutex processMutex;
std::atomic<OscShape::Values> currentOsc { OscShape::none }, nextOsc { { OscShape::saw } };

void updateOscillators();

bool isActive = true;

Expand All @@ -99,23 +99,28 @@ class GainedOscillator

//====================================================================================================

template<std::floating_point T>
void GainedOscillator<T>::setOscShape (int newShape)
template <std::floating_point T>
void GainedOscillator<T>::updateOscillators()
{
auto& osc = processorChain.template get<oscIndex> ();
//compare the current osc type with the (buffered next osc type). Get outta here if they the same
const auto nextOscBuf { nextOsc.load() };
if (currentOsc == nextOscBuf)
return;

//this is to make sure we preserve the same gain after we re-init, right?
bool wasActive = isActive;
isActive = true;

switch (newShape)
auto& osc = processorChain.template get<oscIndex>();
switch (nextOscBuf)
{
case OscShape::none:
osc.initialise ([&] (T /*x*/) { return T (0); });
isActive = false;
break;

case OscShape::saw:
{
std::lock_guard<std::mutex> lock (processMutex);
osc.initialise ([](T x)
{
//this is a sawtooth wave; as x goes from -pi to pi, y goes from -1 to 1
Expand All @@ -126,7 +131,6 @@ void GainedOscillator<T>::setOscShape (int newShape)

case OscShape::sawTri:
{
std::lock_guard<std::mutex> lock (processMutex);
osc.initialise ([](T x)
{
T y = juce::jmap (x, T (-juce::MathConstants<double>::pi), T (juce::MathConstants<double>::pi), T (-1), T (1)) / 2;
Expand All @@ -142,7 +146,6 @@ void GainedOscillator<T>::setOscShape (int newShape)

case OscShape::triangle:
{
std::lock_guard<std::mutex> lock (processMutex);
osc.initialise ([](T x)
{
if (x < 0)
Expand All @@ -156,7 +159,6 @@ void GainedOscillator<T>::setOscShape (int newShape)

case OscShape::pulse:
{
std::lock_guard<std::mutex> lock (processMutex);
osc.initialise ([](T x)
{
if (x < 0)
Expand All @@ -169,8 +171,6 @@ void GainedOscillator<T>::setOscShape (int newShape)

case OscShape::noise:
{
std::lock_guard<std::mutex> lock (processMutex);

osc.initialise ([&](T /*x*/)
{
return distribution (generator);
Expand All @@ -190,4 +190,6 @@ void GainedOscillator<T>::setOscShape (int newShape)
else
setGain (0);
}

currentOsc.store (nextOscBuf);
}
8 changes: 4 additions & 4 deletions source/DSP/PhatOscillators.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class PhatOscillators : public juce::AudioProcessorValueTreeState::Listener
}

void setOscFreq (OscId oscNum, int newMidiNote);
void setOscShape (OscId oscNum, int newShape);
void setOscShape (OscId oscNum, OscShape::Values newShape);
void setOscTuning (OscId oscNum, float newTuning);

void setOscSub (float newSub)
Expand Down Expand Up @@ -203,9 +203,9 @@ void PhatOscillators<T>::parameterChanged (const juce::String& parameterID, floa
else if (parameterID == osc2TuningID.getParamID ())
setOscTuning (OscId::osc2Index, newValue);
else if (parameterID == osc1ShapeID.getParamID ())
setOscShape (OscId::osc1Index, (int) newValue);
setOscShape (OscId::osc1Index, static_cast<OscShape::Values> (newValue));
else if (parameterID == osc2ShapeID.getParamID ())
setOscShape (OscId::osc2Index, (int) newValue);
setOscShape (OscId::osc2Index, static_cast<OscShape::Values> (newValue));
else if (parameterID == oscSubID.getParamID ())
setOscSub (newValue);
else if (parameterID == oscMixID.getParamID ())
Expand Down Expand Up @@ -318,7 +318,7 @@ void PhatOscillators<T>::setOscFreq (OscId oscNum, int newMidiNote)
}

template <std::floating_point T>
void PhatOscillators<T>::setOscShape (OscId oscNum, int newShape)
void PhatOscillators<T>::setOscShape (OscId oscNum, OscShape::Values newShape)
{
switch (oscNum)
{
Expand Down
6 changes: 4 additions & 2 deletions source/DSP/ProPhatVoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,10 @@ void ProPhatVoice<T>::updateLfo()
{
T lfoOut;
{
//TODO: LOCK IN AUDIO THREAD
std::lock_guard<std::mutex> lock (lfoMutex);
std::unique_lock<std::mutex> lck (lfoMutex, std::defer_lock);
if (! lck.try_lock())
return;

lfoOut = lfo.processSample (T (0)) * lfoAmount;
}

Expand Down
2 changes: 1 addition & 1 deletion source/Utility/Helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ struct Selection

struct OscShape : public Selection
{
enum
enum Values
{
none = 0,
saw,
Expand Down

0 comments on commit 8b0e2d3

Please sign in to comment.