Skip to content

Commit 9c8d520

Browse files
committed
#38 Update pipes on tuning change.
1 parent 37e9c2e commit 9c8d520

File tree

4 files changed

+82
-28
lines changed

4 files changed

+82
-28
lines changed

Source/PluginEditor.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,8 @@ AeolusAudioProcessorEditor::AeolusAudioProcessorEditor (AeolusAudioProcessor& p)
149149

150150
const bool scaleChanged = (g->getTuningFrequency() != freq) || (g->getScale().getType() != scaleType);
151151

152-
if (mtsChanged) {
152+
if (mtsChanged || scaleChanged) {
153153
g->setMTSEnabled(contentPtr->isMTSTuningEnabled());
154-
}
155-
156-
if (scaleChanged) {
157154
g->setTuningFrequency(freq);
158155
g->setScaleType(scaleType);
159156
g->rebuildRankwaves();

Source/aeolus/engine.cpp

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ EngineGlobal::EngineGlobal()
7979

8080
loadRankwaves();
8181
loadIRs();
82+
83+
startTimer(100);
8284
}
8385

8486
EngineGlobal::~EngineGlobal()
@@ -190,14 +192,14 @@ String EngineGlobal::getMTSScaleName()
190192
return String(MTS_GetScaleName(_mtsClient));
191193
}
192194

193-
double EngineGlobal::getMTSNoteToFrequency(int midiNote, int midiChannel)
195+
float EngineGlobal::getMTSNoteToFrequency(int midiNote, int midiChannel)
194196
{
195197
if (_mtsClient == nullptr || !isConnectedToMTSMaster())
196198
{
197199
return _scale.getFrequencyForMidoNote(midiNote);
198200
}
199201

200-
return MTS_NoteToFrequency(_mtsClient, (char)midiNote, (char)midiChannel);
202+
return (float)MTS_NoteToFrequency(_mtsClient, (char)midiNote, (char)midiChannel);
201203
}
202204

203205

@@ -211,22 +213,22 @@ void EngineGlobal::rebuildRankwaves()
211213
// Kill all the active voices
212214
int numActiveVoices = 0;
213215

214-
for (auto* processor : _processors) {
215-
processor->killAllVoices();
216-
numActiveVoices += processor->getNumberOfActiveVoices();
217-
}
216+
do {
217+
for (auto* processor : _processors) {
218+
const auto numVoices{ processor->getNumberOfActiveVoices() };
218219

219-
Thread::sleep(100);
220+
if (numVoices > 0) {
221+
processor->killAllVoices();
222+
numActiveVoices += numVoices;
223+
}
224+
}
220225

221-
// Wait for the voices to release
222-
while (numActiveVoices > 0) {
223-
numActiveVoices = 0;
224-
for (auto* processor : _processors) {
225-
processor->killAllVoices();
226-
numActiveVoices += processor->getNumberOfActiveVoices();
227-
Thread::sleep(100);
226+
// Wait for the voices to release
227+
if (numActiveVoices > 0) {
228+
Thread::sleep(10);
228229
}
229-
}
230+
231+
} while (numActiveVoices > 0);
230232

231233
updateStops(_sampleRate);
232234
}
@@ -361,6 +363,33 @@ void EngineGlobal::loadIRs()
361363

362364
}
363365

366+
bool EngineGlobal::updateMTSTuningCache()
367+
{
368+
bool changed{};
369+
370+
for (int midiNote = 0; midiNote < _mtsTuningCache.size(); ++midiNote) {
371+
const float f{ getMTSNoteToFrequency(midiNote, 0) };
372+
if (_mtsTuningCache[midiNote] != f) {
373+
_mtsTuningCache[midiNote] = f;
374+
changed = true;
375+
}
376+
}
377+
378+
return changed;
379+
}
380+
381+
void EngineGlobal::timerCallback()
382+
{
383+
if (!_mtsEnabled) return;
384+
385+
auto changed{ updateMTSTuningCache() };
386+
387+
if (changed) {
388+
rebuildRankwaves();
389+
}
390+
}
391+
392+
364393
JUCE_IMPLEMENT_SINGLETON(EngineGlobal)
365394

366395
//==============================================================================

Source/aeolus/engine.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ class Engine;
4646
*
4747
* This class in a singleton which is shared among all the plugin instances.
4848
*/
49-
class EngineGlobal : public juce::DeletedAtShutdown
49+
class EngineGlobal : public juce::DeletedAtShutdown,
50+
private juce::Timer
5051
{
5152
public:
5253

@@ -100,7 +101,7 @@ class EngineGlobal : public juce::DeletedAtShutdown
100101

101102
bool isConnectedToMTSMaster();
102103
juce::String getMTSScaleName();
103-
double getMTSNoteToFrequency(int midiNote, int midiChannel);
104+
float getMTSNoteToFrequency(int midiNote, int midiChannel);
104105

105106
bool isMTSEnabled() const { return _mtsEnabled; }
106107
void setMTSEnabled(bool shouldBeEnabled) { _mtsEnabled = shouldBeEnabled; }
@@ -116,6 +117,15 @@ class EngineGlobal : public juce::DeletedAtShutdown
116117
void loadRankwaves();
117118
void loadIRs();
118119

120+
/**
121+
* Refresh MTS tuning table for all MIDI notes.
122+
* Returns true if there was a change to the tuning.
123+
*/
124+
bool updateMTSTuningCache();
125+
126+
// juce::Timer
127+
void timerCallback() override;
128+
119129
juce::Array<ProcessorProxy*> _processors;
120130

121131
juce::OwnedArray<Rankwave> _rankwaves;
@@ -130,6 +140,7 @@ class EngineGlobal : public juce::DeletedAtShutdown
130140

131141
MTSClient* _mtsClient{};
132142
bool _mtsEnabled{};
143+
std::array<float, 128> _mtsTuningCache{};
133144

134145
juce::ApplicationProperties _globalProperties;
135146
};

Source/aeolus/rankwave.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -426,15 +426,32 @@ void Rankwave::createPipes(const Scale& scale, float tuningFrequency)
426426

427427
void Rankwave::retunePipes(const Scale& scale, float tuningFrequency)
428428
{
429-
const auto fn = _model.getFn();
430-
const auto fd = _model.getFd();
429+
auto* g = aeolus::EngineGlobal::getInstance();
431430

432-
float fbase = tuningFrequency * fn / fd;
431+
const float fnd = (float)_model.getFn() / (float)_model.getFd();
432+
jassert(fnd > 0.0f);
433433

434-
for (int i = _noteMin; i <= _noteMax; ++i) {
435-
Pipewave* pipe = _pipes[i - _noteMin];
436-
pipe->setFrequency(scale.getFrequencyForMidoNote(i, fbase));
437-
pipe->setNeedsToBeRebuilt(true);
434+
if (g->isMTSEnabled()) {
435+
// Use MTS provided tuning
436+
for (int i = _noteMin; i <= _noteMax; ++i) {
437+
Pipewave* pipe = _pipes[i - _noteMin];
438+
const float f{ g->getMTSNoteToFrequency(i, 0) * fnd };
439+
440+
if (pipe->getPipeFrequency() != f) {
441+
pipe->setFrequency(f);
442+
pipe->setNeedsToBeRebuilt(true);
443+
}
444+
}
445+
446+
} else {
447+
// Use local scale
448+
float fbase = tuningFrequency * fnd;
449+
450+
for (int i = _noteMin; i <= _noteMax; ++i) {
451+
Pipewave* pipe = _pipes[i - _noteMin];
452+
pipe->setFrequency(scale.getFrequencyForMidoNote(i, fbase));
453+
pipe->setNeedsToBeRebuilt(true);
454+
}
438455
}
439456
}
440457

0 commit comments

Comments
 (0)