@@ -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
16541644template 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
19952013class 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
20672086template <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
22082228template <int NV> class smoother : public mothernode ,
0 commit comments