Files
harmonizer_plugin/Source/PluginProcessor.cpp
michalcourson b3429f03cb closes #8
some ui work
2025-11-11 17:28:45 -05:00

105 lines
3.8 KiB
C++

/*
==============================================================================
PluginProcessor.cpp
Created: 4 Nov 2025 6:20:37pm
Author: mickl
==============================================================================
*/
#include "PluginProcessor.h"
//==============================================================================
WebViewPluginAudioProcessor::WebViewPluginAudioProcessor(AudioProcessorValueTreeState::ParameterLayout layout)
: AudioProcessor(BusesProperties()
.withInput("Input", juce::AudioChannelSet::stereo(), true)
.withOutput("Output", juce::AudioChannelSet::stereo(), true)
),
parameters(layout),
state(*this, nullptr, "STATE", std::move(layout))
{
shifter.Init(48000.0f, 48);
shifter.SetFormantPreserve(state.getParameterAsValue("formantPreserve").getValue());
shifter.SetAutoTuneSpeed(state.getParameterAsValue("autoTuneSpeed").getValue());
shifter.SetAutoTuneDepth(state.getParameterAsValue("autoTuneDepth").getValue());
shifter.SetPortamentoTime(state.getParameterAsValue("portTime").getValue());
}
//==============================================================================
void WebViewPluginAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock)
{
const auto channels = std::max(getTotalNumInputChannels(), getTotalNumOutputChannels());
shifter.Init((float)sampleRate, samplesPerBlock);
if (channels == 0)
return;
filter.prepare({ sampleRate, (uint32_t)samplesPerBlock, (uint32_t)channels });
filter.reset();
}
bool WebViewPluginAudioProcessor::isBusesLayoutSupported(const BusesLayout& layouts) const
{
if (layouts.getMainOutputChannelSet() != juce::AudioChannelSet::mono()
&& layouts.getMainOutputChannelSet() != juce::AudioChannelSet::stereo())
return false;
if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())
return false;
return true;
}
void WebViewPluginAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer,
juce::MidiBuffer& midi)
{
juce::ScopedNoDenormals noDenormals;
const auto totalNumInputChannels = getTotalNumInputChannels();
const auto totalNumOutputChannels = getTotalNumOutputChannels();
for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
buffer.clear(i, 0, buffer.getNumSamples());
shifter.SetFormantPreserve(state.getParameterAsValue("formantPreserve").getValue());
shifter.SetAutoTuneSpeed(state.getParameterAsValue("autoTuneSpeed").getValue());
shifter.SetAutoTuneDepth(state.getParameterAsValue("autoTuneDepth").getValue());
shifter.SetPortamentoTime(state.getParameterAsValue("portTime").getValue());
shifter.SetHarmonyMix(state.getParameterAsValue("harmonyMix").getValue());
shifter.SetAutoTuneEnable(state.getParameterAsValue("autoTuneEnabled").getValue());
shifter.SetFreeze(state.getParameterAsValue("freezeEnabled").getValue());
shifter.SetFreezePitchAdjust(state.getParameterAsValue("freezePitch").getValue());
shifter.SetFreezeVolume(state.getParameterAsValue("freezeVolume").getValue());
shifter.SetPanWidth(state.getParameterAsValue("panWidth").getValue());
juce::AudioBuffer<float> const_buff;
const_buff.makeCopyOf(buffer);
shifter.Process(const_buff.getArrayOfReadPointers(), (float**)buffer.getArrayOfWritePointers(), buffer.getNumSamples());
for (const auto metadata : midi)
{
const auto msg = metadata.getMessage();
if (msg.isNoteOn()) {
shifter.AddMidiNote(msg.getNoteNumber());
new_midi = true;
}
else if (msg.isNoteOff()) {
shifter.RemoveMidiNote(msg.getNoteNumber());
new_midi = true;
}
}
}
//==============================================================================
void WebViewPluginAudioProcessor::getStateInformation(juce::MemoryBlock& destData)
{
juce::ignoreUnused(destData);
}
void WebViewPluginAudioProcessor::setStateInformation(const void* data, int sizeInBytes)
{
juce::ignoreUnused(data, sizeInBytes);
}