#include "PluginProcessor.h" #include "PluginEditor.h" //============================================================================== SpectrogramPluginAudioProcessor::SpectrogramPluginAudioProcessor() #ifndef JucePlugin_PreferredChannelConfigurations : AudioProcessor(BusesProperties() #if ! JucePlugin_IsMidiEffect #if ! JucePlugin_IsSynth .withInput("Input", AudioChannelSet::stereo(), true) #endif .withOutput("Output", AudioChannelSet::stereo(), true) #endif ), lowPassFilter(dsp::IIR::Coefficients::makeLowPass(44100, 20000.0f, 0.1f)) #endif { addParameter(gain = new AudioParameterFloat("gain", // parameter ID "Gain", // parameter name NormalisableRange(0.0f, 1.0f), // parameter range 0.5f)); // default value addParameter(freq = new AudioParameterFloat("freq", "Freq", NormalisableRange(20.0f, 20000.0f), 20.0f)); addParameter(res = new AudioParameterFloat("res", "Res", NormalisableRange(0.0f, 1.0f), 0.5f)); } SpectrogramPluginAudioProcessor::~SpectrogramPluginAudioProcessor() { } //============================================================================== const String SpectrogramPluginAudioProcessor::getName() const { return JucePlugin_Name; } bool SpectrogramPluginAudioProcessor::acceptsMidi() const { #if JucePlugin_WantsMidiInput return true; #else return false; #endif } bool SpectrogramPluginAudioProcessor::producesMidi() const { #if JucePlugin_ProducesMidiOutput return true; #else return false; #endif } double SpectrogramPluginAudioProcessor::getTailLengthSeconds() const { return 0.0; } int SpectrogramPluginAudioProcessor::getNumPrograms() { return 1; // NB: some hosts don’t cope very well if you tell them there are 0 programs, // so this should be at least 1, even if you’re not really implementing programs. } int SpectrogramPluginAudioProcessor::getCurrentProgram() { return 0; } void SpectrogramPluginAudioProcessor::setCurrentProgram(int index) { } const String SpectrogramPluginAudioProcessor::getProgramName(int index) { return {}; } void SpectrogramPluginAudioProcessor::changeProgramName(int index, const String& newName) { } //============================================================================== void SpectrogramPluginAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBlock) { // Use this method as the place to do any pre-playback // initialisation that you need… previousGain = *gain; dsp::ProcessSpec spec; spec.sampleRate = sampleRate; spec.maximumBlockSize = samplesPerBlock; spec.numChannels = getTotalNumOutputChannels(); lowPassFilter.prepare(spec); lowPassFilter.reset(); } void SpectrogramPluginAudioProcessor::releaseResources() { // When playback stops, you can use this as an opportunity to free up any // spare memory, etc. } #ifndef JucePlugin_PreferredChannelConfigurations bool SpectrogramPluginAudioProcessor::isBusesLayoutSupported(const BusesLayout& layouts) const { #if JucePlugin_IsMidiEffect ignoreUnused(layouts); return true; #else // This is the place where you check if the layout is supported. // In this template code we only support mono or stereo. if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono() && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo()) return false; // This checks if the input layout matches the output layout #if ! JucePlugin_IsSynth if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet()) return false; #endif return true; #endif } #endif void SpectrogramPluginAudioProcessor::updateFilter() { float cutoff = freq->get(); float resonance = res->get(); *lowPassFilter.state = *dsp::IIR::Coefficients::makeLowPass(44100, cutoff, resonance); } void SpectrogramPluginAudioProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { const int totalNumInputChannels = getTotalNumInputChannels(); const int totalNumOutputChannels = getTotalNumOutputChannels(); for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i) buffer.clear(i, 0, buffer.getNumSamples()); dsp::AudioBlock block(buffer); updateFilter(); lowPassFilter.process(dsp::ProcessContextReplacing(block)); //============================Gain Adjust======================= double currentGain = gain->get(); if (currentGain == previousGain) { buffer.applyGain(currentGain); } else { buffer.applyGainRamp(0, buffer.getNumSamples(), previousGain, currentGain); previousGain = currentGain; } //=================================FFT============================================ auto myeditor = dynamic_cast(getActiveEditor()); if (myeditor != nullptr) { myeditor->m_SpectroGramComp.processAudioBlock(buffer); } } //============================================================================== bool SpectrogramPluginAudioProcessor::hasEditor() const { return true; // (change this to false if you choose to not supply an editor) } AudioProcessorEditor* SpectrogramPluginAudioProcessor::createEditor() { return new SpectrogramPluginAudioProcessorEditor(*this); } //============================================================================== void SpectrogramPluginAudioProcessor::getStateInformation(MemoryBlock& destData) { // You should use this method to store your parameters in the memory block. // You could do that either as raw data, or use the XML or ValueTree classes // as intermediaries to make it easy to save and load complex data. MemoryOutputStream(destData, true).writeFloat(*gain); } void SpectrogramPluginAudioProcessor::setStateInformation(const void* data, int sizeInBytes) { // You should use this method to restore your parameters from this memory block, // whose contents will have been created by the getStateInformation() call. *gain = MemoryInputStream(data, static_cast (sizeInBytes), false).readFloat(); } //============================================================================== // This creates new instances of the plugin… AudioProcessor* JUCE_CALLTYPE createPluginFilter() { return new SpectrogramPluginAudioProcessor(); }