Skip to content

Commit

Permalink
Add SemiTones control to Wave Synth (#579)
Browse files Browse the repository at this point in the history
* Add SemiTones to Wave Synth based on Sine Synth implementation.

* Rearrange controls in Waveform Generator to fit new SemiTones control.

* Undo whitespace changes.

* Revert "Undo whitespace changes."

This reverts commit 017e3a0.

* Undo whitespace changes.

* Move new SemiTones params to end of enum for backwards compatibility.

* Align controls

---------

Co-authored-by: weavermedia <[email protected]>
  • Loading branch information
weavermedia and weavermedia authored Sep 30, 2024
1 parent c1bc03f commit c74fc71
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 38 deletions.
71 changes: 57 additions & 14 deletions hi_core/hi_modules/synthesisers/editors/WaveSynthBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,17 @@ WaveSynthBody::WaveSynthBody (ProcessorEditor *p)
pulseSlider2->setTextBoxStyle (Slider::TextBoxRight, false, 40, 20);
pulseSlider2->addListener (this);

addAndMakeVisible (semiToneSlider1 = new HiSlider ("SemiTones 1"));
semiToneSlider1->setRange (-12, 12, 1);
semiToneSlider1->setSliderStyle (Slider::RotaryHorizontalVerticalDrag);
semiToneSlider1->setTextBoxStyle (Slider::TextBoxRight, false, 40, 20);
semiToneSlider1->addListener (this);

addAndMakeVisible (semiToneSlider2 = new HiSlider ("SemiTones 2"));
semiToneSlider2->setRange (-12, 12, 1);
semiToneSlider2->setSliderStyle (Slider::RotaryHorizontalVerticalDrag);
semiToneSlider2->setTextBoxStyle (Slider::TextBoxRight, false, 40, 20);
semiToneSlider2->addListener (this);

//[UserPreSize]

Expand Down Expand Up @@ -219,6 +230,14 @@ WaveSynthBody::WaveSynthBody (ProcessorEditor *p)
pulseSlider2->setup(getProcessor(), WaveSynth::SpecialParameters::PulseWidth2, "Pulse Width 2");
pulseSlider2->setMode(HiSlider::Mode::NormalizedPercentage);

semiToneSlider1->setup(getProcessor(), WaveSynth::SpecialParameters::SemiTones1, "SemiTones 1");
semiToneSlider1->setMode(HiSlider::Discrete, -12.0, 12.0);
semiToneSlider1->setRange(-12.0, 12.0, 1.0);

semiToneSlider2->setup(getProcessor(), WaveSynth::SpecialParameters::SemiTones2, "SemiTones 2");
semiToneSlider2->setMode(HiSlider::Discrete, -12.0, 12.0);
semiToneSlider2->setRange(-12.0, 12.0, 1.0);

voiceAmountEditor->setFont(GLOBAL_FONT());
voiceAmountLabel->setFont(GLOBAL_FONT());
fadeTimeEditor->setFont(GLOBAL_FONT());
Expand Down Expand Up @@ -258,6 +277,8 @@ WaveSynthBody::~WaveSynthBody()
enableSecondButton = nullptr;
pulseSlider1 = nullptr;
pulseSlider2 = nullptr;
semiToneSlider1 = nullptr;
semiToneSlider2 = nullptr;


//[Destructor]. You can add your own custom destruction code here..
Expand Down Expand Up @@ -297,26 +318,28 @@ void WaveSynthBody::resized()
//[UserPreResize] Add your own custom resize code here..
//[/UserPreResize]

octaveSlider->setBounds (158, 15, 128, 48);
waveFormSelector->setBounds (26, 65, 128, 24);
waveformDisplay->setBounds (26, 15, 128, 48);
octaveSlider->setBounds (160, 17, 128, 48);
waveFormSelector->setBounds (25, 42, 128, 24);
waveformDisplay->setBounds (25, 15, 128, 24);
fadeTimeLabel->setBounds ((getWidth() / 2) + 7, 61, 79, 24);
voiceAmountLabel->setBounds ((getWidth() / 2) + -69, 62, 79, 24);
voiceAmountEditor->setBounds ((getWidth() / 2) + -30 - (68 / 2), 80, 68, 16);
fadeTimeEditor->setBounds ((getWidth() / 2) + 12, 80, 51, 16);
octaveSlider2->setBounds (getWidth() - 161 - 128, 15, 128, 48);
waveFormSelector2->setBounds (getWidth() - 26 - 128, 65, 128, 24);
waveformDisplay2->setBounds (getWidth() - 26 - 128, 15, 128, 48);
octaveSlider2->setBounds (getWidth() - 161 - 128, 17, 128, 48);
waveFormSelector2->setBounds (getWidth() - 26 - 128, 42, 128, 24);
waveformDisplay2->setBounds (getWidth() - 26 - 128, 15, 128, 24);
mixSlider->setBounds ((getWidth() / 2) - (128 / 2), 13, 128, 48);

panSlider->setBounds (160, 73, 128, 48);
panSlider2->setBounds (getWidth() - 161 - 128, 73, 128, 48);
detuneSlider2->setBounds (getWidth() - 26 - 128, 94, 128, 48);
detuneSlider->setBounds (25, 96, 128, 48);
panSlider->setBounds (25, 134, 128, 48);
panSlider2->setBounds (getWidth() - 26 - 128, 134, 128, 48);
detuneSlider2->setBounds (getWidth() - 161 - 128, 134, 128, 48);
detuneSlider->setBounds (160, 134, 128, 48);
enableSecondButton->setBounds ((getWidth() / 2) + -64, 136, 128, 28);
enableSyncButton->setBounds((getWidth() / 2) + -64, 166, 128, 28);
pulseSlider1->setBounds (160, 132, 128, 48);
pulseSlider2->setBounds (getWidth() - 161 - 128, 132, 128, 48);
pulseSlider1->setBounds (25, 77, 128, 48);
pulseSlider2->setBounds (getWidth() - 26 - 128, 77, 128, 48);
semiToneSlider1->setBounds (160, 77, 128, 48);
semiToneSlider2->setBounds (getWidth() - 161 - 128, 77, 128, 48);
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
}
Expand Down Expand Up @@ -371,6 +394,16 @@ void WaveSynthBody::sliderValueChanged (Slider* sliderThatWasMoved)
//[UserSliderCode_pulseSlider2] -- add your slider handling code here..
//[/UserSliderCode_pulseSlider2]
}
else if (sliderThatWasMoved == semiToneSlider1)
{
//[UserSliderCode_semiToneSlider1] -- add your slider handling code here..
//[/UserSliderCode_semiToneSlider1]
}
else if (sliderThatWasMoved == semiToneSlider2)
{
//[UserSliderCode_semiToneSlider2] -- add your slider handling code here..
//[/UserSliderCode_semiToneSlider2]
}

//[UsersliderValueChanged_Post]
//[/UsersliderValueChanged_Post]
Expand All @@ -384,13 +417,13 @@ void WaveSynthBody::comboBoxChanged (ComboBox* comboBoxThatHasChanged)
if (comboBoxThatHasChanged == waveFormSelector)
{
//[UserComboBoxCode_waveFormSelector] -- add your combo box handling code here..
//[/UserComboBoxCode_waveFormSelector]
}
else if (comboBoxThatHasChanged == waveFormSelector2)
{
//[UserComboBoxCode_waveFormSelector2] -- add your combo box handling code here..
//[/UserComboBoxCode_waveFormSelector2]
}

Expand Down Expand Up @@ -566,6 +599,16 @@ BEGIN_JUCER_METADATA
int="0.010000000000000000208" style="RotaryHorizontalVerticalDrag"
textBoxPos="TextBoxRight" textBoxEditable="1" textBoxWidth="40"
textBoxHeight="20" skewFactor="1" needsCallback="1"/>
<SLIDER name="SemiTones 1" id="c990fe6c1167b9cb" memberName="semiToneSlider1"
virtualName="HiSlider" explicitFocusOrder="0" pos="158 73 128 48"
tooltip="The semitone detune for oscillator 1" min="-12" max="12" int="1" style="RotaryHorizontalVerticalDrag"
textBoxPos="TextBoxRight" textBoxEditable="1" textBoxWidth="40"
textBoxHeight="20" skewFactor="1"/>
<SLIDER name="SemiTones 2" id="321ac674521d8e28" memberName="semiToneSlider2"
virtualName="HiSlider" explicitFocusOrder="0" pos="161Rr 73 128 48"
tooltip="The semitone detune for oscillator 2" min="-12" max="12" int="1"
style="RotaryHorizontalVerticalDrag" textBoxPos="TextBoxRight"
textBoxEditable="1" textBoxWidth="40" textBoxHeight="20" skewFactor="1"/>
</JUCER_COMPONENT>

END_JUCER_METADATA
Expand Down
11 changes: 8 additions & 3 deletions hi_core/hi_modules/synthesisers/editors/WaveSynthBody.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class WaveSynthBody : public ProcessorEditorBody,
octaveSlider->updateValue();
octaveSlider2->updateValue();

semiToneSlider1->updateValue();
semiToneSlider2->updateValue();

detuneSlider->updateValue();
detuneSlider2->updateValue();

Expand Down Expand Up @@ -87,7 +90,7 @@ class WaveSynthBody : public ProcessorEditorBody,
octaveSlider2->setEnabled(false);
detuneSlider2->setEnabled(false);
panSlider2->setEnabled(false);
}
};

Expand All @@ -105,8 +108,8 @@ class WaveSynthBody : public ProcessorEditorBody,
{
return h;
}

//[/UserMethods]

Expand Down Expand Up @@ -144,6 +147,8 @@ class WaveSynthBody : public ProcessorEditorBody,
ScopedPointer<HiToggleButton> enableSyncButton;
ScopedPointer<HiSlider> pulseSlider1;
ScopedPointer<HiSlider> pulseSlider2;
ScopedPointer<HiSlider> semiToneSlider1;
ScopedPointer<HiSlider> semiToneSlider2;


//==============================================================================
Expand Down
52 changes: 35 additions & 17 deletions hi_core/hi_modules/synthesisers/synths/WaveSynth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ WaveSynth::WaveSynth(MainController *mc, const String &id, int numVoices) :
ModulatorSynth(mc, id, numVoices),
octaveTranspose1((int)getDefaultValue(OctaveTranspose1)),
octaveTranspose2((int)getDefaultValue(OctaveTranspose2)),
semiTones1((int)getDefaultValue(SemiTones1)),
semiTones2((int)getDefaultValue(SemiTones2)),
detune1(getDefaultValue(Detune1)),
detune2(getDefaultValue(Detune2)),
pan1(getDefaultValue(Pan1)),
Expand Down Expand Up @@ -68,10 +70,12 @@ WaveSynth::WaveSynth(MainController *mc, const String &id, int numVoices) :
scaleFunction = [](float input) { return input * 2.0f - 1.0f; };

parameterNames.add("OctaveTranspose1");
parameterNames.add("SemiTones1");
parameterNames.add("WaveForm1");
parameterNames.add("Detune1");
parameterNames.add("Pan1");
parameterNames.add("OctaveTranspose2");
parameterNames.add("SemiTones2");
parameterNames.add("WaveForm2");
parameterNames.add("Detune2");
parameterNames.add("Pan2");
Expand All @@ -91,7 +95,7 @@ WaveSynth::WaveSynth(MainController *mc, const String &id, int numVoices) :

for (int i = 0; i < numVoices; i++)
addVoice(new WaveSynthVoice(this));
addSound(new WaveSound());
}

Expand All @@ -100,7 +104,9 @@ void WaveSynth::restoreFromValueTree(const ValueTree &v)
ModulatorSynth::restoreFromValueTree(v);

loadAttribute(OctaveTranspose1, "OctaveTranspose1");
loadAttribute(SemiTones1, "SemiTones1");
loadAttribute(OctaveTranspose2, "OctaveTranspose2");
loadAttribute(SemiTones2, "SemiTones2");
loadAttribute(Detune1, "Detune1");
loadAttribute(Detune2, "Detune2");
loadAttribute(WaveForm1, "WaveForm1");
Expand All @@ -119,7 +125,9 @@ ValueTree WaveSynth::exportAsValueTree() const
ValueTree v = ModulatorSynth::exportAsValueTree();

saveAttribute(OctaveTranspose1, "OctaveTranspose1");
saveAttribute(SemiTones1, "SemiTones1");
saveAttribute(OctaveTranspose2, "OctaveTranspose2");
saveAttribute(SemiTones2, "SemiTones2");
saveAttribute(Detune1, "Detune1");
saveAttribute(Detune2, "Detune2");
saveAttribute(WaveForm1, "WaveForm1");
Expand Down Expand Up @@ -174,10 +182,12 @@ float WaveSynth::getDefaultValue(int parameterIndex) const
switch (parameterIndex)
{
case OctaveTranspose1: return 0.0f;
case SemiTones1: return 0.0f;
case WaveForm1: return (float)WaveformComponent::WaveformType::Saw;
case Detune1: return 0.0f;
case Pan1: return 0.0f;
case OctaveTranspose2: return 0.0f;
case SemiTones2: return 0.0f;
case WaveForm2: return (float)WaveformComponent::WaveformType::Saw;
case Detune2: return 0.0f;
case Pan2: return 0.0f;
Expand Down Expand Up @@ -229,10 +239,12 @@ float WaveSynth::getAttribute(int parameterIndex) const
switch (parameterIndex)
{
case OctaveTranspose1: return (float)octaveTranspose1;
case SemiTones1: return (float)semiTones1;
case WaveForm1: return (float)waveForm1;
case Detune1: return detune1;
case Pan1: return pan1;
case OctaveTranspose2: return (float)octaveTranspose2;
case SemiTones2: return (float)semiTones2;
case WaveForm2: return (float)waveForm2;
case Detune2: return detune2;
case Pan2: return pan2;
Expand All @@ -258,9 +270,15 @@ void WaveSynth::setInternalAttribute(int parameterIndex, float newValue)
case OctaveTranspose1: octaveTranspose1 = (int)newValue;
refreshPitchValues(true);
break;
case SemiTones1: semiTones1 = (int)newValue;
refreshPitchValues(true);
break;
case OctaveTranspose2: octaveTranspose2 = (int)newValue;
refreshPitchValues(false);
break;
case SemiTones2: semiTones2 = (int)newValue;
refreshPitchValues(false);
break;
case Detune1: detune1 = newValue;
refreshPitchValues(true);
break;
Expand Down Expand Up @@ -331,11 +349,11 @@ void WaveSynth::refreshPulseWidth(bool left)

double WaveSynth::getPitchValue(bool getLeftValue)
{
const double octaveValue = pow(2.0, (double)getLeftValue ? octaveTranspose1 : octaveTranspose2);

const double octaveValue = pow(2.0, (double)(getLeftValue ? octaveTranspose1 : octaveTranspose2));
const double semiToneValue = pow(2.0, (double)(getLeftValue ? semiTones1 : semiTones2) / 12.0);
const double detuneValue = pow(2.0, (getLeftValue ? detune1 : detune2) / 1200.0);

return octaveValue * detuneValue;
return octaveValue * semiToneValue * detuneValue;
}


Expand All @@ -358,7 +376,7 @@ WaveSynthVoice::WaveSynthVoice(ModulatorSynth *ownerSynth) :
#else
octaveTransposeFactor2(1.0)
#endif
{
setWaveForm(WaveformComponent::Saw, true);
setWaveForm(WaveformComponent::Saw, false);
Expand Down Expand Up @@ -388,7 +406,7 @@ void WaveSynthVoice::startNote(int midiNoteNumber, float /*velocity*/, Synthesis
rightGenerator.setFrequency(cyclesPerSecond * octaveTransposeFactor2);

leftGenerator.setStartOffset((double)getCurrentHiseEvent().getStartOffset());
if(enableSecondOsc)
rightGenerator.setStartOffset((double)getCurrentHiseEvent().getStartOffset());

Expand Down Expand Up @@ -464,18 +482,18 @@ void WaveSynthVoice::calculateBlock(int startSample, int numSamples)
while (--numSamples >= 0)
{
auto leftDelta = (float)uptimeDelta;
if (voicePitchValues != nullptr)
leftDelta *= *voicePitchValues;

leftGenerator.setFreqModulationValue(leftDelta);

auto rightDelta = (float)uptimeDelta;
if (voicePitchValues != nullptr)
rightDelta *= *voicePitchValues;
if (secondPitchValues != nullptr)
rightDelta *= *secondPitchValues;

Expand Down Expand Up @@ -511,7 +529,7 @@ void WaveSynthVoice::calculateBlock(int startSample, int numSamples)

leftGenerator.setFreqModulationValue(leftDelta);

voicePitchValues++;

*outL = leftGenerator.getAndInc();
Expand All @@ -520,9 +538,9 @@ void WaveSynthVoice::calculateBlock(int startSample, int numSamples)
}
}



#else

Expand Down Expand Up @@ -559,7 +577,7 @@ void WaveSynthVoice::calculateBlock(int startSample, int numSamples)

#endif


#if HISE_USE_WRONG_VOICE_RENDERING_ORDER
getOwnerSynth()->effectChain->renderVoice(voiceIndex, voiceBuffer, startIndex, samplesToCopy);
Expand All @@ -572,7 +590,7 @@ void WaveSynthVoice::calculateBlock(int startSample, int numSamples)
auto leftSamples = voiceBuffer.getWritePointer(0, startIndex);
auto rightSamples = voiceBuffer.getWritePointer(1, startIndex);


auto& tBuffer = wavesynth->getTempBufferForMixCalculation();

Expand Down Expand Up @@ -641,7 +659,7 @@ void WaveSynthVoice::setWaveForm(WaveformComponent::WaveformType type, bool left
{
switch ((int)type)
{
case hise::WaveformComponent::Sine:
case hise::WaveformComponent::Sine:
left ? leftGenerator.setWaveform(mf::PolyBLEP::SINE) : rightGenerator.setWaveform(mf::PolyBLEP::SINE); break;
case hise::WaveformComponent::Triangle:
left ? leftGenerator.setWaveform(mf::PolyBLEP::TRIANGLE) : rightGenerator.setWaveform(mf::PolyBLEP::TRIANGLE); break;
Expand All @@ -663,7 +681,7 @@ void WaveSynthVoice::setWaveForm(WaveformComponent::WaveformType type, bool left
break;
}


}

Expand Down
Loading

0 comments on commit c74fc71

Please sign in to comment.