Working on wt

This commit is contained in:
Roland Rabien 2020-05-21 21:39:47 -07:00
commit d858a10fc9
8 changed files with 89 additions and 14 deletions

@ -1 +1 @@
Subproject commit 2aa9e9fb9208a7e49eef07fe9a65365351b8481a Subproject commit d8ead26e5775c0b11bd5067399d3a38beb7602b2

Binary file not shown.

View file

@ -59,6 +59,7 @@ public:
addPage ("WT " + String (i + 1), 3, 4); addPage ("WT " + String (i + 1), 3, 4);
addPageEnable (i * 2, wt.enable); addPageEnable (i * 2, wt.enable);
addControl (i * 2, new gin::Knob (wt.table), 0, 0);
addControl (i * 2, new gin::Knob (wt.tune, true), 1, 0); addControl (i * 2, new gin::Knob (wt.tune, true), 1, 0);
addControl (i * 2, new gin::Knob (wt.finetune, true), 2, 0); addControl (i * 2, new gin::Knob (wt.finetune, true), 2, 0);
addControl (i * 2, new gin::Knob (wt.pan, true), 0, 1); addControl (i * 2, new gin::Knob (wt.pan, true), 0, 1);
@ -78,7 +79,7 @@ public:
auto& osc = proc.oscParams[i]; auto& osc = proc.oscParams[i];
addPage ("OSC " + String (i + 1), 3, 4); addPage ("OSC " + String (i + 1), 3, 4);
addPageEnable (i * 2, osc.enable); addPageEnable (Cfg::numWTs * 2 + i * 2, osc.enable);
addControl (Cfg::numWTs * 2 + i * 2, new gin::Select (osc.wave), 0, 0); addControl (Cfg::numWTs * 2 + i * 2, new gin::Select (osc.wave), 0, 0);
addControl (Cfg::numWTs * 2 + i * 2, new gin::Knob (osc.tune, true), 1, 0); addControl (Cfg::numWTs * 2 + i * 2, new gin::Knob (osc.tune, true), 1, 0);

View file

@ -107,6 +107,7 @@ void WavetableAudioProcessor::WTParams::setup (WavetableAudioProcessor& p, int i
String nm = "WT" + String (idx + 1) + " "; String nm = "WT" + String (idx + 1) + " ";
enable = p.addIntParam (id + "enable", nm + "Enable", "Enable", "", { 0.0, 1.0, 1.0, 1.0 }, idx == 0 ? 1.0f : 0.0f, 0.0f); enable = p.addIntParam (id + "enable", nm + "Enable", "Enable", "", { 0.0, 1.0, 1.0, 1.0 }, idx == 0 ? 1.0f : 0.0f, 0.0f);
table = p.addExtParam (id + "table", nm + "Table", "Table", "", { 0.0, 1.0, 0.0, 1.0 }, 0.0f, 0.0f);
voices = p.addIntParam (id + "unison", nm + "Unison", "Unison", "", { 1.0, 8.0, 1.0, 1.0 }, 1.0, 0.0f); voices = p.addIntParam (id + "unison", nm + "Unison", "Unison", "", { 1.0, 8.0, 1.0, 1.0 }, 1.0, 0.0f);
voicesTrns = p.addExtParam (id + "unisontrns", nm + "Unison Trns", "LTrans", "st", { -36.0, 36.0, 1.0, 1.0 }, 0.0, 0.0f); voicesTrns = p.addExtParam (id + "unisontrns", nm + "Unison Trns", "LTrans", "st", { -36.0, 36.0, 1.0, 1.0 }, 0.0, 0.0f);
tune = p.addExtParam (id + "tune", nm + "Tune", "Tune", "st", { -36.0, 36.0, 1.0, 1.0 }, 0.0, 0.0f); tune = p.addExtParam (id + "tune", nm + "Tune", "Tune", "st", { -36.0, 36.0, 1.0, 1.0 }, 0.0, 0.0f);
@ -125,7 +126,7 @@ void WavetableAudioProcessor::OSCParams::setup (WavetableAudioProcessor& p, int
String id = "osc" + String (idx + 1); String id = "osc" + String (idx + 1);
String nm = "OSC" + String (idx + 1) + " "; String nm = "OSC" + String (idx + 1) + " ";
enable = p.addIntParam (id + "enable", nm + "Enable", "Enable", "", { 0.0, 1.0, 1.0, 1.0 }, idx == 0 ? 1.0f : 0.0f, 0.0f); enable = p.addIntParam (id + "enable", nm + "Enable", "Enable", "", { 0.0, 1.0, 1.0, 1.0 }, 0.0f, 0.0f);
wave = p.addIntParam (id + "wave", nm + "Wave", "Wave", "", { 1.0, 7.0, 1.0, 1.0 }, 1.0, 0.0f, waveTextFunction); wave = p.addIntParam (id + "wave", nm + "Wave", "Wave", "", { 1.0, 7.0, 1.0, 1.0 }, 1.0, 0.0f, waveTextFunction);
voices = p.addIntParam (id + "unison", nm + "Unison", "Unison", "", { 1.0, 8.0, 1.0, 1.0 }, 1.0, 0.0f); voices = p.addIntParam (id + "unison", nm + "Unison", "Unison", "", { 1.0, 8.0, 1.0, 1.0 }, 1.0, 0.0f);
voicesTrns = p.addExtParam (id + "unisontrns", nm + "Unison Trns", "LTrans", "st", { -36.0, 36.0, 1.0, 1.0 }, 0.0, 0.0f); voicesTrns = p.addExtParam (id + "unisontrns", nm + "Unison Trns", "LTrans", "st", { -36.0, 36.0, 1.0, 1.0 }, 0.0, 0.0f);
@ -397,6 +398,8 @@ void WavetableAudioProcessor::LimiterParams::setup (WavetableAudioProcessor& p)
//============================================================================== //==============================================================================
WavetableAudioProcessor::WavetableAudioProcessor() WavetableAudioProcessor::WavetableAudioProcessor()
{ {
formatManager->registerBasicFormats();
enableLegacyMode(); enableLegacyMode();
setVoiceStealingEnabled (true); setVoiceStealingEnabled (true);
@ -440,6 +443,9 @@ WavetableAudioProcessor::WavetableAudioProcessor()
} }
setupModMatrix(); setupModMatrix();
MemoryBlock mb (BinaryData::WINDOW_S_WAV, BinaryData::WINDOW_S_WAVSize);
updateWavetable (0, mb, 256);
} }
WavetableAudioProcessor::~WavetableAudioProcessor() WavetableAudioProcessor::~WavetableAudioProcessor()
@ -850,6 +856,22 @@ void WavetableAudioProcessor::handleController ([[maybe_unused]] int ch, int num
modMatrix.setMonoValue (modSrcCC[num], val / 127.0f); modMatrix.setMonoValue (modSrcCC[num], val / 127.0f);
} }
void WavetableAudioProcessor::updateWavetable (int idx, MemoryBlock& src, int tableSize)
{
if (auto reader = std::unique_ptr<AudioFormatReader> (formatManager->createReaderFor (std::make_unique<MemoryInputStream> (src, false))))
{
AudioSampleBuffer buffer;
buffer.setSize (1, int (reader->lengthInSamples));
reader->read (&buffer, 0, int (reader->lengthInSamples), 0, true, false);
loadWavetables (waveTables[idx], buffer, reader->sampleRate, tableSize);
for (auto v : voices)
if (auto wtv = dynamic_cast<WavetableVoice*>(v))
wtv->setWavetable (idx, waveTables[idx]);
}
}
//============================================================================== //==============================================================================
bool WavetableAudioProcessor::hasEditor() const bool WavetableAudioProcessor::hasEditor() const
{ {

View file

@ -45,7 +45,7 @@ public:
{ {
WTParams() = default; WTParams() = default;
gin::Parameter::Ptr enable, voices, voicesTrns, tune, finetune, gin::Parameter::Ptr enable, table, voices, voicesTrns, tune, finetune,
level, detune, spread, pan; level, detune, spread, pan;
void setup (WavetableAudioProcessor& p, int idx); void setup (WavetableAudioProcessor& p, int idx);
@ -230,6 +230,9 @@ public:
JUCE_DECLARE_NON_COPYABLE (LimiterParams) JUCE_DECLARE_NON_COPYABLE (LimiterParams)
}; };
//==============================================================================
void updateWavetable (int idx, MemoryBlock& src, int tableSize);
//============================================================================== //==============================================================================
gin::ModSrcId modSrcPressure, modSrcTimbre, modScrPitchBend, gin::ModSrcId modSrcPressure, modSrcTimbre, modScrPitchBend,
modSrcNote, modSrcVelocity, modSrcStep, modSrcMonoStep; modSrcNote, modSrcVelocity, modSrcStep, modSrcMonoStep;
@ -237,6 +240,7 @@ public:
Array<gin::ModSrcId> modSrcCC, modSrcMonoLFO, modSrcLFO, modSrcFilter, modSrcEnv; Array<gin::ModSrcId> modSrcCC, modSrcMonoLFO, modSrcLFO, modSrcFilter, modSrcEnv;
//============================================================================== //==============================================================================
SharedResourcePointer<AudioFormatManager> formatManager;
WTParams wtParams[Cfg::numWTs]; WTParams wtParams[Cfg::numWTs];
OSCParams oscParams[Cfg::numOSCs]; OSCParams oscParams[Cfg::numOSCs];
@ -277,6 +281,8 @@ public:
AudioPlayHead* playhead = nullptr; AudioPlayHead* playhead = nullptr;
OwnedArray<gin::BandLimitedLookupTable> waveTables[Cfg::numWTs];
//============================================================================== //==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WavetableAudioProcessor) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WavetableAudioProcessor)
}; };

View file

@ -12,6 +12,11 @@ WavetableVoice::WavetableVoice (WavetableAudioProcessor& p, BandLimitedLookupTab
f.setNumChannels (2); f.setNumChannels (2);
} }
void WavetableVoice::setWavetable (int idx, OwnedArray<BandLimitedLookupTable>& table)
{
wtOscillators[idx].setWavetable (table);
}
void WavetableVoice::noteStarted() void WavetableVoice::noteStarted()
{ {
fastKill = false; fastKill = false;
@ -51,7 +56,10 @@ void WavetableVoice::noteStarted()
snapParams(); snapParams();
updateParams (0); updateParams (0);
snapParams(); snapParams();
for (auto& osc : wtOscillators)
osc.noteOn();
for (auto& osc : oscillators) for (auto& osc : oscillators)
osc.noteOn(); osc.noteOn();
@ -91,6 +99,9 @@ void WavetableVoice::noteRetriggered()
updateParams (0); updateParams (0);
for (auto& osc : wtOscillators)
osc.noteOn();
for (auto& osc : oscillators) for (auto& osc : oscillators)
osc.noteOn(); osc.noteOn();
@ -137,6 +148,9 @@ void WavetableVoice::setCurrentSampleRate (double newRate)
{ {
MPESynthesiserVoice::setCurrentSampleRate (newRate); MPESynthesiserVoice::setCurrentSampleRate (newRate);
for (auto& osc : wtOscillators)
osc.setSampleRate (newRate);
for (auto& osc : oscillators) for (auto& osc : oscillators)
osc.setSampleRate (newRate); osc.setSampleRate (newRate);
@ -161,9 +175,13 @@ void WavetableVoice::renderNextBlock (AudioBuffer<float>& outputBuffer, int star
// Run OSC // Run OSC
ScratchBuffer buffer (2, numSamples); ScratchBuffer buffer (2, numSamples);
for (int i = 0; i < Cfg::numWTs; i++)
if (proc.wtParams[i].enable->isOn())
wtOscillators[i].processAdding (currentMidiNotes[i], wtParams[i], buffer);
for (int i = 0; i < Cfg::numOSCs; i++) for (int i = 0; i < Cfg::numOSCs; i++)
if (proc.oscParams[i].enable->isOn()) if (proc.oscParams[i].enable->isOn())
oscillators[i].processAdding (currentMidiNotes[i], oscParams[i], buffer); oscillators[i].processAdding (currentMidiNotes[Cfg::numWTs + i], oscParams[i], buffer);
// Apply velocity // Apply velocity
float velocity = currentlyPlayingNote.noteOnVelocity.asUnsignedFloat(); float velocity = currentlyPlayingNote.noteOnVelocity.asUnsignedFloat();
@ -196,14 +214,32 @@ void WavetableVoice::updateParams (int blockSize)
proc.modMatrix.setPolyValue (*this, proc.modSrcNote, note.initialNote / 127.0f); proc.modMatrix.setPolyValue (*this, proc.modSrcNote, note.initialNote / 127.0f);
for (int i = 0; i < Cfg::numWTs; i++)
{
if (! proc.wtParams[i].enable->isOn()) continue;
currentMidiNotes[i] = noteSmoother.getCurrentValue() * 127.0f;
if (glideInfo.glissando) currentMidiNotes[i] = roundToInt (currentMidiNotes[i]);
currentMidiNotes[i] += float (note.totalPitchbendInSemitones);
currentMidiNotes[i] += getValue (proc.wtParams[i].tune) + getValue (proc.wtParams[i].finetune) / 100.0f;
wtParams[i].voices = int (proc.wtParams[i].voices->getProcValue());
wtParams[i].vcTrns = int (proc.wtParams[i].voicesTrns->getProcValue());
wtParams[i].pw = getValue (proc.wtParams[i].table);
wtParams[i].pan = getValue (proc.wtParams[i].pan);
wtParams[i].spread = getValue (proc.wtParams[i].spread) / 100.0f;
wtParams[i].detune = getValue (proc.wtParams[i].detune);
wtParams[i].gain = getValue (proc.wtParams[i].level);
}
for (int i = 0; i < Cfg::numOSCs; i++) for (int i = 0; i < Cfg::numOSCs; i++)
{ {
if (! proc.oscParams[i].enable->isOn()) continue; if (! proc.oscParams[i].enable->isOn()) continue;
currentMidiNotes[i] = noteSmoother.getCurrentValue() * 127.0f; currentMidiNotes[Cfg::numWTs + i] = noteSmoother.getCurrentValue() * 127.0f;
if (glideInfo.glissando) currentMidiNotes[i] = roundToInt (currentMidiNotes[i]); if (glideInfo.glissando) currentMidiNotes[Cfg::numWTs + i] = roundToInt (currentMidiNotes[Cfg::numWTs + i]);
currentMidiNotes[i] += float (note.totalPitchbendInSemitones); currentMidiNotes[Cfg::numWTs + i] += float (note.totalPitchbendInSemitones);
currentMidiNotes[i] += getValue (proc.oscParams[i].tune) + getValue (proc.oscParams[i].finetune) / 100.0f; currentMidiNotes[Cfg::numWTs + i] += getValue (proc.oscParams[i].tune) + getValue (proc.oscParams[i].finetune) / 100.0f;
oscParams[i].wave = (Wave) int (proc.oscParams[i].wave->getProcValue()); oscParams[i].wave = (Wave) int (proc.oscParams[i].wave->getProcValue());
oscParams[i].voices = int (proc.oscParams[i].voices->getProcValue()); oscParams[i].voices = int (proc.oscParams[i].voices->getProcValue());

View file

@ -11,7 +11,9 @@ class WavetableVoice : public gin::SynthesiserVoice,
{ {
public: public:
WavetableVoice (WavetableAudioProcessor& p, gin::BandLimitedLookupTables& bandLimitedLookupTables); WavetableVoice (WavetableAudioProcessor& p, gin::BandLimitedLookupTables& bandLimitedLookupTables);
void setWavetable (int idx, OwnedArray<gin::BandLimitedLookupTable>& table);
void noteStarted() override; void noteStarted() override;
void noteRetriggered() override; void noteRetriggered() override;
void noteStopped (bool allowTailOff) override; void noteStopped (bool allowTailOff) override;
@ -35,7 +37,8 @@ private:
WavetableAudioProcessor& proc; WavetableAudioProcessor& proc;
gin::BandLimitedLookupTables& bandLimitedLookupTables; gin::BandLimitedLookupTables& bandLimitedLookupTables;
gin::VoicedStereoOscillator oscillators[Cfg::numOSCs] = gin::WTVoicedStereoOscillator wtOscillators[Cfg::numWTs];
gin::BLLTVoicedStereoOscillator oscillators[Cfg::numOSCs] =
{ {
bandLimitedLookupTables, bandLimitedLookupTables,
}; };
@ -49,8 +52,10 @@ private:
gin::AnalogADSR adsr; gin::AnalogADSR adsr;
float currentMidiNotes[Cfg::numOSCs]; float currentMidiNotes[Cfg::numWTs + Cfg::numOSCs];
gin::VoicedStereoOscillator::Params oscParams[Cfg::numOSCs];
gin::WTVoicedStereoOscillator::Params wtParams[Cfg::numWTs];
gin::BLLTVoicedStereoOscillator::Params oscParams[Cfg::numOSCs];
gin::EasedValueSmoother<float> noteSmoother; gin::EasedValueSmoother<float> noteSmoother;

View file

@ -6,6 +6,11 @@
pluginManufacturerCode="Soca" pluginCode="SLwt" pluginAUMainType="'aumu'" pluginManufacturerCode="Soca" pluginCode="SLwt" pluginAUMainType="'aumu'"
cppLanguageStandard="latest" pluginChannelConfigs="{0,2}" version="0.0.2"> cppLanguageStandard="latest" pluginChannelConfigs="{0,2}" version="0.0.2">
<MAINGROUP id="Hs1HPA" name="Wavetable"> <MAINGROUP id="Hs1HPA" name="Wavetable">
<GROUP id="{64226C5F-B1F9-A1D8-F7EC-41424754AED6}" name="Resources">
<GROUP id="{46E1199A-9569-4016-DF2F-8CD2BDD4DB92}" name="Wavetables">
<FILE id="a6e9bN" name="WINDOW_S.WAV" compile="0" resource="1" file="Resources/Wavetables/WINDOW_S.WAV"/>
</GROUP>
</GROUP>
<GROUP id="{0CE63D98-F319-7656-21CD-D7A21B4A4B6C}" name="Source"> <GROUP id="{0CE63D98-F319-7656-21CD-D7A21B4A4B6C}" name="Source">
<FILE id="Ma3e0n" name="Cfg.h" compile="0" resource="0" file="Source/Cfg.h"/> <FILE id="Ma3e0n" name="Cfg.h" compile="0" resource="0" file="Source/Cfg.h"/>
<FILE id="f12Jxy" name="Boxes.h" compile="0" resource="0" file="Source/Boxes.h"/> <FILE id="f12Jxy" name="Boxes.h" compile="0" resource="0" file="Source/Boxes.h"/>