some app controls, format preserve, start of autotune speed

This commit is contained in:
michalcourson
2025-10-04 17:22:29 -04:00
parent 720a013ff3
commit 7ba141daed
6 changed files with 33 additions and 16 deletions

View File

@ -49,7 +49,7 @@ import PropTypes from "prop-types";
import * as Juce from "juce-framework-frontend"; import * as Juce from "juce-framework-frontend";
import "./App.css"; import "./App.css";
import { KnobPercentage } from "./Components/KnobPercentage"; // import { KnobPercentage } from "./Components/KnobPercentage";
// Custom attributes in React must be in all lower case // Custom attributes in React must be in all lower case
const controlParameterIndexAnnotation = "controlparameterindex"; const controlParameterIndexAnnotation = "controlparameterindex";
@ -107,10 +107,6 @@ function JuceSlider({ identifier, title }) {
<Typography sx={{ mt: 1.5 }}> <Typography sx={{ mt: 1.5 }}>
{properties.name}: {sliderState.getScaledValue()} {properties.label} {properties.name}: {sliderState.getScaledValue()} {properties.label}
</Typography> </Typography>
<KnobPercentage theme="stone" label={properties.name} />
<p>
{sliderState.getScaledValue()} {properties.label}
</p>
<Slider <Slider
aria-label={title} aria-label={title}
value={value} value={value}
@ -423,7 +419,7 @@ function App() {
<div> <div>
<Container> <Container>
<JuceSlider identifier="formantSlider" title="Formant" /> <JuceSlider identifier="formantSlider" title="Formant" />
<JuceSlider identifier="cutoffSlider" title="Cutoff" /> <JuceSlider identifier="autoTuneSpeedSlider" title="Auto Tune Speed" />
</Container> </Container>
<CardActions style={{ justifyContent: "center" }}> <CardActions style={{ justifyContent: "center" }}>
<Button <Button

Binary file not shown.

View File

@ -59,7 +59,8 @@ inline std::unique_ptr<InputStream> createAssetInputStream (const char* resource
[[maybe_unused]] AssertAssetExists assertExists = AssertAssetExists::yes) [[maybe_unused]] AssertAssetExists assertExists = AssertAssetExists::yes)
{ {
auto assetsDir = File::getCurrentWorkingDirectory().getChildFile("..\\..\\Assets"); // auto assetsDir = File::getCurrentWorkingDirectory().getChildFile("..\\..\\Assets");
File assetsDir("C:\\Users\\mickl\\Desktop\\Plugins\\Harmonizer\\Assets");
auto resourceFile = assetsDir.getChildFile (resourcePath); auto resourceFile = assetsDir.getChildFile (resourcePath);

View File

@ -100,11 +100,19 @@ void Shifter::DetectPitch(const float* const* in, float** out, size_t size)
float in_freq = 48000 / in_period; float in_freq = 48000 / in_period;
int midi = (int)(12 * log2f(in_freq / 440) + 69.5f); int midi = (int)(12 * log2f(in_freq / 440) + 69.5f);
out_midi[MAX_VOICES] = midi; float target_out_period = 48000.0f / mtof(midi);
static float out_period_filter_amount = 0.7f; // You can expose this as a parameter if (midi != last_autotune_midi) {
float target_out_period = 48000.0f / mtof(midi); last_autotune_midi = midi;
out_periods[MAX_VOICES] = out_periods[MAX_VOICES] * out_period_filter_amount + target_out_period * (1.0f - out_period_filter_amount); out_periods[MAX_VOICES] = in_period;
}
float error = target_out_period - out_periods[MAX_VOICES];
float adjustment = error * out_period_filter_amount;
//target_out_period = in_period * out_period_filter_amount + target_out_period * (1 - out_period_filter_amount);
out_midi[MAX_VOICES] = midi;
out_periods[MAX_VOICES] += adjustment;
} }
void Shifter::SetRates() {} void Shifter::SetRates() {}

View File

@ -82,6 +82,7 @@ public:
void AddMidiNote(int note); void AddMidiNote(int note);
void RemoveMidiNote(int note); void RemoveMidiNote(int note);
void SetFormantPreserve(float val) { formant_preserve = val; } void SetFormantPreserve(float val) { formant_preserve = val; }
void SetAutoTuneSpeed(float val) { out_period_filter_amount = 1 - val; }
int out_midi[MAX_VOICES + 1] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 }; int out_midi[MAX_VOICES + 1] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 };
@ -129,6 +130,9 @@ private:
float out_buffer[2][BUFFER_SIZE]; float out_buffer[2][BUFFER_SIZE];
int out_playhead = 0; int out_playhead = 0;
int in_playhead = 0; int in_playhead = 0;
int last_autotune_midi = -1;
float out_period_filter_amount = 0.7f; // You can expose this as a parameter
float out_periods[MAX_VOICES + 1] = { 0,0,0,0,0,0,0,0,0,0,0,0 }; //C3 float out_periods[MAX_VOICES + 1] = { 0,0,0,0,0,0,0,0,0,0,0,0 }; //C3
float out_panning[MAX_VOICES + 1] = { 0,0,0,0,0,0,0,0,0,0,0,.5 }; //C3 float out_panning[MAX_VOICES + 1] = { 0,0,0,0,0,0,0,0,0,0,0,.5 }; //C3

View File

@ -63,6 +63,7 @@ namespace ID
#define PARAMETER_ID(str) static const ParameterID str { #str, 1 }; #define PARAMETER_ID(str) static const ParameterID str { #str, 1 };
PARAMETER_ID(formantPreserve) PARAMETER_ID(formantPreserve)
PARAMETER_ID(autoTuneSpeed)
PARAMETER_ID(mute) PARAMETER_ID(mute)
PARAMETER_ID(filterType) PARAMETER_ID(filterType)
@ -210,8 +211,8 @@ public:
.5f)), .5f)),
autoTuneSpeed(addToLayout<AudioParameterFloat>(layout, autoTuneSpeed(addToLayout<AudioParameterFloat>(layout,
ID::formantPreserve, ID::autoTuneSpeed,
"AutoTuneSpeed", "AutoTune Speed",
NormalisableRange<float> {0.0f, 1.0f, .01f}, NormalisableRange<float> {0.0f, 1.0f, .01f},
.5f)), .5f)),
mute(addToLayout<AudioParameterBool>(layout, ID::mute, "Mute", false)), mute(addToLayout<AudioParameterBool>(layout, ID::mute, "Mute", false)),
@ -318,6 +319,7 @@ void WebViewPluginAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer,
for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i) for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
buffer.clear(i, 0, buffer.getNumSamples()); buffer.clear(i, 0, buffer.getNumSamples());
shifter.SetFormantPreserve(parameters.formantPreserve.get()); shifter.SetFormantPreserve(parameters.formantPreserve.get());
shifter.SetAutoTuneSpeed(parameters.autoTuneSpeed.get());
juce::AudioBuffer<float> const_buff; juce::AudioBuffer<float> const_buff;
const_buff.makeCopyOf(buffer); const_buff.makeCopyOf(buffer);
shifter.Process(const_buff.getArrayOfReadPointers(), (float**)buffer.getArrayOfWritePointers(), buffer.getNumSamples()); shifter.Process(const_buff.getArrayOfReadPointers(), (float**)buffer.getArrayOfWritePointers(), buffer.getNumSamples());
@ -463,6 +465,7 @@ private:
WebViewPluginAudioProcessor& processorRef; WebViewPluginAudioProcessor& processorRef;
WebSliderRelay formantSliderRelay{ "formantSlider" }; WebSliderRelay formantSliderRelay{ "formantSlider" };
WebSliderRelay autoTuneSpeedSliderRelay{ "autoTuneSpeedSlider" };
WebToggleButtonRelay muteToggleRelay{ "muteToggle" }; WebToggleButtonRelay muteToggleRelay{ "muteToggle" };
WebComboBoxRelay filterTypeComboRelay{ "filterTypeCombo" }; WebComboBoxRelay filterTypeComboRelay{ "filterTypeCombo" };
@ -474,6 +477,7 @@ private:
.withUserDataFolder(File::getSpecialLocation(File::SpecialLocationType::tempDirectory))) .withUserDataFolder(File::getSpecialLocation(File::SpecialLocationType::tempDirectory)))
.withNativeIntegrationEnabled() .withNativeIntegrationEnabled()
.withOptionsFrom(formantSliderRelay) .withOptionsFrom(formantSliderRelay)
.withOptionsFrom(autoTuneSpeedSliderRelay)
.withOptionsFrom(muteToggleRelay) .withOptionsFrom(muteToggleRelay)
.withOptionsFrom(filterTypeComboRelay) .withOptionsFrom(filterTypeComboRelay)
.withOptionsFrom(controlParameterIndexReceiver) .withOptionsFrom(controlParameterIndexReceiver)
@ -488,6 +492,7 @@ private:
URL { localDevServerAddress }.getOrigin()) }; URL { localDevServerAddress }.getOrigin()) };
WebSliderParameterAttachment formantAttachment; WebSliderParameterAttachment formantAttachment;
WebSliderParameterAttachment autoTuneSpeedAttachment;
WebToggleButtonParameterAttachment muteAttachment; WebToggleButtonParameterAttachment muteAttachment;
WebComboBoxParameterAttachment filterTypeAttachment; WebComboBoxParameterAttachment filterTypeAttachment;
@ -616,6 +621,9 @@ WebViewPluginAudioProcessorEditor::WebViewPluginAudioProcessorEditor(WebViewPlug
formantAttachment(*processorRef.state.getParameter(ID::formantPreserve.getParamID()), formantAttachment(*processorRef.state.getParameter(ID::formantPreserve.getParamID()),
formantSliderRelay, formantSliderRelay,
processorRef.state.undoManager), processorRef.state.undoManager),
autoTuneSpeedAttachment(*processorRef.state.getParameter(ID::autoTuneSpeed.getParamID()),
autoTuneSpeedSliderRelay,
processorRef.state.undoManager),
muteAttachment(*processorRef.state.getParameter(ID::mute.getParamID()), muteAttachment(*processorRef.state.getParameter(ID::mute.getParamID()),
muteToggleRelay, muteToggleRelay,
processorRef.state.undoManager), processorRef.state.undoManager),
@ -625,8 +633,8 @@ WebViewPluginAudioProcessorEditor::WebViewPluginAudioProcessorEditor(WebViewPlug
{ {
addAndMakeVisible(webComponent); addAndMakeVisible(webComponent);
webComponent.goToURL(localDevServerAddress); //webComponent.goToURL(localDevServerAddress);
//webComponent.goToURL (WebBrowserComponent::getResourceProviderRoot()); webComponent.goToURL (WebBrowserComponent::getResourceProviderRoot());
setSize(500, 500); setSize(500, 500);