diff --git a/Assets/web/src/App.js b/Assets/web/src/App.js
index 8269b1a..fc5b5d4 100644
--- a/Assets/web/src/App.js
+++ b/Assets/web/src/App.js
@@ -48,6 +48,7 @@ function App() {
return (
+
diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp
index 99f5e77..f8b278e 100644
--- a/Source/PluginProcessor.cpp
+++ b/Source/PluginProcessor.cpp
@@ -66,6 +66,7 @@ void WebViewPluginAudioProcessor::processBlock(juce::AudioBuffer& buffer,
shifter.SetAutoTuneSpeed(state.getParameterAsValue("autoTuneSpeed").getValue());
shifter.SetAutoTuneDepth(state.getParameterAsValue("autoTuneDepth").getValue());
shifter.SetPortamentoTime(state.getParameterAsValue("portTime").getValue());
+ shifter.SetHarmonyMix(state.getParameterAsValue("harmonyMix").getValue());
juce::AudioBuffer const_buff;
const_buff.makeCopyOf(buffer);
shifter.Process(const_buff.getArrayOfReadPointers(), (float**)buffer.getArrayOfWritePointers(), buffer.getNumSamples());
diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h
index e31a8ae..825b81c 100644
--- a/Source/PluginProcessor.h
+++ b/Source/PluginProcessor.h
@@ -72,6 +72,14 @@ public:
"AutoTune Speed",
NormalisableRange {0.001f, 0.1f, .001f},
.5f);
+
+ sliderIds.push_back("harmonyMix");
+ addToLayout(layout,
+ ParameterID("harmonyMix"),
+ "Harmony Mix",
+ NormalisableRange {0.0f, 1.0f, .01f},
+ .01f);
+
sliderIds.push_back("portTime");
addToLayout(layout,
ParameterID("portTime"),
diff --git a/Source/Shifter.cpp b/Source/Shifter.cpp
index f8139c9..8b9d287 100644
--- a/Source/Shifter.cpp
+++ b/Source/Shifter.cpp
@@ -205,12 +205,12 @@ void Shifter::AddInterpolatedFrame(int voice, int max_index, float resampling_pe
float value = ((1 - interp) * in_buffer[(int)f_index] + (interp)*in_buffer[(int)(f_index + 1) % 8192]) * mult;
if(voice >= MAX_VOICES) {
//value *= volume;
- out_buffer[0][out_index] += value;
- out_buffer[1][out_index] += value;
+ out_buffer[0][out_index] += value * melody_mix;
+ out_buffer[1][out_index] += value * melody_mix;
} else {
value *= voices[voice].CurrentAmplitude() * volume;
- out_buffer[0][out_index] += value * voices[voice].GetPanning(0);
- out_buffer[1][out_index] += value * voices[voice].GetPanning(1);
+ out_buffer[0][out_index] += value * voices[voice].GetPanning(0) * harmony_mix;
+ out_buffer[1][out_index] += value * voices[voice].GetPanning(1) * harmony_mix;
}
@@ -307,4 +307,15 @@ void Shifter::RemoveMidiNote(int note) {
voices[i].Release();
}
}
+}
+
+void Shifter::SetHarmonyMix(float mix) {
+ if (mix < .5) {
+ melody_mix = 1.0f;
+ harmony_mix = mix * 2.0f;
+ }
+ else {
+ harmony_mix = 1.0f;
+ melody_mix = (1.0f - mix) * 2.0f;
+ }
}
\ No newline at end of file
diff --git a/Source/Shifter.h b/Source/Shifter.h
index a2eb829..243f8fc 100644
--- a/Source/Shifter.h
+++ b/Source/Shifter.h
@@ -156,6 +156,7 @@ public:
}
float getInputPitch() const { return sample_rate_ / in_period; }
float getOutputPitch() const { return sample_rate_ / out_period; }
+ void SetHarmonyMix(float mix);
float out_midi = 40;
ShifterVoice voices[MAX_VOICES];
@@ -185,6 +186,8 @@ private:
double smear_step = 0.003;
bool onset_trigger = false;
bool pitch_trigger = false;
+ float harmony_mix = 0.0f;
+ float melody_mix = 0.0f;
int trigger_bank;