Skip to content

Commit 7d27031

Browse files
committed
Merge branch 'develop'
2 parents f863c02 + 073a6ff commit 7d27031

30 files changed

Lines changed: 10729 additions & 7832 deletions

hi_core/hi_modules/hardcoded/HardcodedModuleBase.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ void HardcodedSwappableEffect::setHardcodedAttribute(int parameterIndex, float n
864864
}
865865
else
866866
{
867+
PolyHandler::ScopedAllVoiceSetter avs(polyHandler);
867868
p->callback.call((double)newValue);
868869
}
869870
}

hi_core/hi_modules/modulators/mods/FlexAhdsrEnvelope.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,8 @@ void FlexAhdsrEnvelope::setInternalAttribute(int parameterIndex, float newValue)
425425
parameterIndex -= getParameterOffset();
426426
parameters[parameterIndex] = newValue;
427427

428+
PolyHandler::ScopedAllVoiceSetter avs(polyHandler);
429+
428430
switch(parameterIndex)
429431
{
430432
case 0: obj.template setParameter<0>(newValue); break;

hi_dsp_library/dsp_nodes/CoreNodes.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ template <int NV> void oscillator<NV>::prepare(PrepareSpecs ps)
4545
voiceData.prepare(ps);
4646
sr = ps.sampleRate;
4747

48-
VoiceSetter sv(*this, true);
49-
5048
setFrequency(freqValue);
5149
setPitchMultiplier(uiData.multiplier);
5250
}

hi_dsp_library/dsp_nodes/CoreNodes.h

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,10 +1564,8 @@ template <int NV> class oscillator: public OscillatorDisplayProvider,
15641564

15651565
uiData.uptimeDelta = newUptimeDelta;
15661566

1567-
voiceData.forEachCurrentVoice([newUptimeDelta](OscData& d)
1568-
{
1567+
for (auto& d : voiceData)
15691568
d.uptimeDelta = newUptimeDelta;
1570-
});
15711569
}
15721570
}
15731571

@@ -1592,10 +1590,8 @@ template <int NV> class oscillator: public OscillatorDisplayProvider,
15921590

15931591
uiData.phase = v;
15941592

1595-
voiceData.forEachCurrentVoice([v](OscData& d)
1596-
{
1593+
for (auto& d : voiceData)
15971594
d.phase = v;
1598-
});
15991595

16001596
sendDisplayUpdateMessage(0.0f);
16011597
}
@@ -1604,10 +1600,8 @@ template <int NV> class oscillator: public OscillatorDisplayProvider,
16041600
{
16051601
uiData.gain = gain;
16061602

1607-
voiceData.forEachCurrentVoice([gain](OscData& d)
1608-
{
1603+
for (auto& d : voiceData)
16091604
d.gain = gain;
1610-
});
16111605

16121606
sendDisplayUpdateMessage(0.0, true);
16131607
}
@@ -1616,10 +1610,8 @@ template <int NV> class oscillator: public OscillatorDisplayProvider,
16161610
{
16171611
auto pitchMultiplier = newMultiplier;
16181612

1619-
voiceData.forEachCurrentVoice([pitchMultiplier](OscData& d)
1620-
{
1613+
for (auto& d : voiceData)
16211614
d.multiplier = pitchMultiplier;
1622-
});
16231615

16241616
uiData.multiplier = pitchMultiplier;
16251617

@@ -1647,8 +1639,6 @@ template <int NV> class oscillator: public OscillatorDisplayProvider,
16471639

16481640
float currentNyquistGain = 1.0f;
16491641

1650-
SN_VOICE_SETTER(oscillator, voiceData);
1651-
16521642
};
16531643

16541644
template class oscillator<1>;
@@ -1716,15 +1706,18 @@ template <int NV> struct file_player : public data::base,
17161706
{
17171707
if (mode != PlaybackModes::MidiFreq)
17181708
{
1719-
auto& cd = *currentXYZSample.begin();
1720-
1721-
HiseEvent e(HiseEvent::Type::NoteOn, 64, 1, 1);
1722-
1723-
if (this->externalData.getStereoSample(cd, e))
1724-
s.uptimeDelta = cd.getPitchFactor();
1709+
// Manual lock required here because reset() is called directly
1710+
// from prepare(), startVoice(), and setPlaybackMode().
1711+
if (auto dt = DataTryReadLock(this))
1712+
{
1713+
auto& cd = currentXYZSample.get();
1714+
HiseEvent e(HiseEvent::Type::NoteOn, 64, 1, 1);
17251715

1726-
1716+
if (this->externalData.getStereoSample(cd, e))
1717+
s.uptimeDelta = cd.getPitchFactor();
1718+
}
17271719

1720+
// Always reset playback position, regardless of lock status
17281721
s.uptime = 0.0;
17291722
}
17301723
}
@@ -1755,6 +1748,8 @@ template <int NV> struct file_player : public data::base,
17551748

17561749
template <int C> void processFix(ProcessData<C>& data)
17571750
{
1751+
// Acquire read lock for external audio data access.
1752+
// If lock fails (data being updated), skip this buffer.
17581753
if (auto dt = DataTryReadLock(this))
17591754
{
17601755
auto& s = getCurrentAudioSample();
@@ -1763,7 +1758,6 @@ template <int NV> struct file_player : public data::base,
17631758
{
17641759
auto fd = data.toFrameData();
17651760

1766-
17671761
auto maxIndex = (double)s.data[0].size();
17681762

17691763
if (mode == PlaybackModes::SignalInput)
@@ -1776,7 +1770,6 @@ template <int NV> struct file_player : public data::base,
17761770
}
17771771
else
17781772
{
1779-
17801773
using IndexType = index::unscaled<double, index::looped<0>>;
17811774

17821775
IndexType i(state.get().uptime);
@@ -1793,9 +1786,18 @@ template <int NV> struct file_player : public data::base,
17931786
for (auto& ch : data)
17941787
{
17951788
auto b = data.toChannelData(ch);
1796-
FloatVectorOperations::clear(b.begin(), b.size());
1789+
FloatVectorOperations::clear(b.begin(), b.size());
17971790
}
1798-
};
1791+
}
1792+
}
1793+
else if (mode == PlaybackModes::SignalInput)
1794+
{
1795+
// Lock not acquired, still clear output to avoid garbage
1796+
for (auto& ch : data)
1797+
{
1798+
auto b = data.toChannelData(ch);
1799+
FloatVectorOperations::clear(b.begin(), b.size());
1800+
}
17991801
}
18001802
}
18011803

@@ -1853,6 +1855,7 @@ template <int NV> struct file_player : public data::base,
18531855

18541856
template <typename FrameDataType> void processFrame(FrameDataType& data) noexcept
18551857
{
1858+
// Acquire read lock for external audio data access.
18561859
if (auto dt = DataTryReadLock(this))
18571860
{
18581861
auto& cd = getCurrentAudioSample().data;
@@ -1892,6 +1895,11 @@ template <int NV> struct file_player : public data::base,
18921895
}
18931896
}
18941897
}
1898+
else
1899+
{
1900+
// Lock not acquired, output silence
1901+
data = 0.0f;
1902+
}
18951903
}
18961904

18971905
void handleHiseEvent(HiseEvent& e)
@@ -1902,12 +1910,21 @@ template <int NV> struct file_player : public data::base,
19021910

19031911
if (e.isNoteOn())
19041912
{
1905-
auto& cd = getCurrentAudioSample();
1913+
// Acquire read lock for external audio data access.
1914+
if (auto dt = DataTryReadLock(this))
1915+
{
1916+
auto& cd = getCurrentAudioSample();
19061917

1907-
if (this->externalData.getStereoSample(cd, e))
1908-
s.uptimeDelta = cd.getPitchFactor();
1918+
if (this->externalData.getStereoSample(cd, e))
1919+
s.uptimeDelta = cd.getPitchFactor();
1920+
else
1921+
s.uptimeDelta = e.getFrequency() / rootFreq;
1922+
}
19091923
else
1924+
{
1925+
// Lock not acquired, use frequency-based pitch
19101926
s.uptimeDelta = e.getFrequency() / rootFreq;
1927+
}
19111928

19121929
s.uptime = 0.0;
19131930
}
@@ -1990,6 +2007,7 @@ template <int NV> struct file_player : public data::base,
19902007

19912008
PolyData<OscData, NumVoices> state;
19922009
PrepareSpecs lastSpecs;
2010+
19932011
};
19942012

19952013
class fm : public HiseDspBase
@@ -2062,6 +2080,7 @@ class fm : public HiseDspBase
20622080
PolyData<double, NUM_POLYPHONIC_VOICES> modGain;
20632081

20642082
SharedResourcePointer<SineLookupTable<2048>> sinTable;
2083+
20652084
};
20662085

20672086
template <int V> class gain : public HiseDspBase,
@@ -2203,6 +2222,7 @@ template <int V> class gain : public HiseDspBase,
22032222
double resetValue = 0.0;
22042223

22052224
PolyData<sfloat, NumVoices> gainer;
2225+
22062226
};
22072227

22082228
template <int NV> class smoother: public mothernode,

hi_dsp_library/dsp_nodes/EnvelopeNodes.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -666,8 +666,6 @@ template <int NV, typename ParameterType> struct simple_ar: public pimpl::envelo
666666
}
667667
}
668668

669-
670-
671669
PolyData<State, NumVoices> states;
672670
};
673671

@@ -1890,6 +1888,9 @@ template <int NV, typename IndexClass, runtime_target::RuntimeTarget TargetType>
18901888
check();
18911889
}
18921890

1891+
// note: never use this directly outside of the usual HISE callback system
1892+
// use the isPlaying() function instead, this gets you the state for the currently
1893+
// rendered voice
18931894
bool handleModulation(double& v)
18941895
{
18951896
return mv.getChangedValue(v);
@@ -1900,10 +1901,14 @@ template <int NV, typename IndexClass, runtime_target::RuntimeTarget TargetType>
19001901
check();
19011902
}
19021903

1903-
void check()
1904+
bool check()
19041905
{
1905-
if(!state.get().isPlaying())
1906+
auto isPlaying = state.get().isPlaying();
1907+
1908+
if(!isPlaying)
19061909
mv.setModValue(0.0);
1910+
1911+
return isPlaying;
19071912
}
19081913

19091914
virtual void prepare(PrepareSpecs ps)
@@ -1959,7 +1964,6 @@ template <int NV, typename IndexClass, runtime_target::RuntimeTarget TargetType>
19591964

19601965
public:
19611966

1962-
SN_VOICE_SETTER(mod_voice_checker_base, state);
19631967
};
19641968

19651969
template <int NV, typename IndexClass=runtime_target::indexers::fix_hash<1>> struct global_mod_gate :

hi_dsp_library/dsp_nodes/EventNodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ template <int NV, typename TimerType> class timer : public timer_base<TimerType>
280280

281281
bool handleModulation(double& value)
282282
{
283-
return t.begin()->getChangedValue(value);
283+
return t.get().getChangedValue(value);
284284
}
285285

286286
void createParameters(ParameterDataList& data)

hi_dsp_library/dsp_nodes/FilterNode.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,6 @@ class FilterNodeBase : public data::filter_base,
139139

140140
PolyData<FilterObject, NumVoices> filter;
141141

142-
SN_VOICE_SETTER(FilterNodeBase, filter);
143-
144142
double sr = -1.0;
145143
bool enabled = true;
146144

hi_dsp_library/dsp_nodes/JuceNodes.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ template <typename T, int NV> struct jwrapper
112112

113113
public:
114114

115-
SN_VOICE_SETTER(jwrapper, objects);
116115
};
117116

118117
/** This template can be used in order to implement a modulation source node from a JUCE processor.
@@ -268,13 +267,13 @@ template <int NV> struct jpanner : public base::jwrapper<juce::dsp::Panner<float
268267

269268
template <int P> void setParameter(double v)
270269
{
271-
this->objects.forEachCurrentVoice([v](juce::dsp::Panner<float>& obj)
270+
for (auto& obj : this->objects)
272271
{
273272
if (P == 0)
274273
obj.setPan(v);
275274
if (P == 1)
276275
obj.setRule((juce::dsp::Panner<float>::Rule)(int)v);
277-
});
276+
}
278277
}
279278

280279
void createParameters(ParameterDataList& d) override

hi_dsp_library/dsp_nodes/MathNodes.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,9 +1050,7 @@ public polyphonic_base
10501050

10511051
void clearFilterState()
10521052
{
1053-
typename decltype(filterState)::ScopedVoiceSetter scope(filterState, true);
1054-
1055-
for(auto& voiceState : filterState)
1053+
for (auto& voiceState : filterState.all())
10561054
voiceState.fill(0.0f);
10571055
}
10581056

hi_dsp_library/dsp_nodes/ModulationNodes.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,6 @@ struct mod_base: public data::display_buffer_base<ConfigClass::shouldEnableDispl
539539

540540
public:
541541

542-
SN_VOICE_SETTER(mod_base, state);
543542
};
544543

545544
}

0 commit comments

Comments
 (0)