#include "PluginProcessor.h" #include "PluginEditor.h" BeamgridAudioProcessor::BeamgridAudioProcessor() : AudioProcessor (BusesProperties() .withInput ("Input", juce::AudioChannelSet::stereo(), true) .withOutput ("Output", juce::AudioChannelSet::stereo(), true)), params (*this, nullptr, "Parameters", createParameterLayout()) { } BeamgridAudioProcessor::~BeamgridAudioProcessor() = default; juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter() { return new BeamgridAudioProcessor(); } juce::AudioProcessorValueTreeState::ParameterLayout BeamgridAudioProcessor::createParameterLayout() { std::vector> params; params.push_back (std::make_unique( "grace", "Peak Grace (ms)", juce::NormalisableRange (0.0f, 2000.0f, 1.0f), 800.0f, juce::AudioParameterFloatAttributes().withLabel ("ms"))); params.push_back (std::make_unique( "falloff", "Peak Falloff", juce::NormalisableRange (0.0f, 1.0f, 0.001f), 0.4f, juce::AudioParameterFloatAttributes().withLabel (""))); params.push_back (std::make_unique( "barfalloff", "Bar Falloff", juce::NormalisableRange (0.0f, 1.0f, 0.001f), 0.5f, juce::AudioParameterFloatAttributes().withLabel (""))); params.push_back (std::make_unique( "hue", "Hue", juce::NormalisableRange (0.0f, 1.0f, 0.001f), 0.5f, juce::AudioParameterFloatAttributes().withLabel (""))); params.push_back (std::make_unique( "smooth", "Smoothing", juce::NormalisableRange (0.0f, 1.0f, 0.001f), 0.35f, juce::AudioParameterFloatAttributes().withLabel (""))); params.push_back (std::make_unique( "grid", "Grid Visibility", juce::NormalisableRange (0.0f, 1.0f, 0.001f), 0.32f, juce::AudioParameterFloatAttributes().withLabel (""))); params.push_back (std::make_unique( "gridzoom", "Grid Zoom", juce::NormalisableRange (0.98f, 1.02f, 0.001f), 1.0f, juce::AudioParameterFloatAttributes().withLabel (""))); params.push_back (std::make_unique( "gridfade", "Grid Fade", juce::NormalisableRange (0.0f, 1.0f, 0.001f), 0.0f, juce::AudioParameterFloatAttributes().withLabel (""))); params.push_back (std::make_unique( "curving", "Curving", juce::NormalisableRange (0.0f, 1.0f, 0.001f), 0.0f, juce::AudioParameterFloatAttributes().withLabel (""))); params.push_back (std::make_unique( "tilt", "Tilt", juce::NormalisableRange (-1.0f, 1.0f, 0.001f), 0.0f, juce::AudioParameterFloatAttributes().withLabel (""))); juce::NormalisableRange barsRange (8.0f, 128.0f, [] (float start, float end, float v) { return start + v * (end - start); }, // convertFrom0To1 [] (float start, float end, float v) { return (v - start) / (end - start); }, // convertTo0To1 [] (float, float, float v) // snapToLegalValue { const float steps[] = { 8.0f, 16.0f, 24.0f, 32.0f, 40.0f, 48.0f, 56.0f, 64.0f, 72.0f, 80.0f, 88.0f, 96.0f, 104.0f, 112.0f, 120.0f, 128.0f }; float best = steps[0]; float bestDist = std::abs (v - best); for (float s : steps) { const float dist = std::abs (v - s); if (dist < bestDist) { bestDist = dist; best = s; } } return best; }); params.push_back (std::make_unique( "bars", "Bars", barsRange, 64.0f)); params.push_back (std::make_unique( "mode", "Mode", 1, 3, 1)); juce::NormalisableRange ledsRange (4.0f, 48.0f, [] (float start, float end, float v) { return start + v * (end - start); }, // convertFrom0To1 [] (float start, float end, float v) { return (v - start) / (end - start); }, // convertTo0To1 [] (float, float, float v) // snapToLegalValue { const float steps[] = { 4.0f, 8.0f, 12.0f, 16.0f, 20.0f, 24.0f, 28.0f, 32.0f, 36.0f, 40.0f, 44.0f, 48.0f }; float best = steps[0]; float bestDist = std::abs (v - best); for (float s : steps) { const float dist = std::abs (v - s); if (dist < bestDist) { bestDist = dist; best = s; } } return best; }); params.push_back (std::make_unique( "leds", "LEDs/Bar", ledsRange, 16.0f)); return { params.begin(), params.end() }; } void BeamgridAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock) { analyser.prepare (sampleRate, samplesPerBlock); } void BeamgridAudioProcessor::releaseResources() {} bool BeamgridAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const { if (layouts.getMainInputChannels() == 0 || layouts.getMainOutputChannels() == 0) return false; if (layouts.getMainInputChannels() != layouts.getMainOutputChannels()) return false; return true; } void BeamgridAudioProcessor::processBlock (juce::AudioBuffer& buffer, juce::MidiBuffer& /*midi*/) { juce::ScopedNoDenormals noDenormals; analyser.setTilt (*params.getRawParameterValue ("tilt")); // Analyse the first channel; pass the audio through unchanged. if (buffer.getNumChannels() > 0) analyser.push (buffer.getReadPointer (0), buffer.getNumSamples()); } juce::AudioProcessorEditor* BeamgridAudioProcessor::createEditor() { return new BeamgridAudioProcessorEditor (*this); } void BeamgridAudioProcessor::getStateInformation (juce::MemoryBlock& dest) { auto state = params.copyState(); std::unique_ptr xml (state.createXml()); copyXmlToBinary (*xml, dest); } void BeamgridAudioProcessor::setStateInformation (const void* data, int sizeInBytes) { std::unique_ptr xml (getXmlFromBinary (data, sizeInBytes)); if (xml && xml->hasTagName (params.state.getType())) params.replaceState (juce::ValueTree::fromXml (*xml)); }