Skip to content
This repository has been archived by the owner on Jul 27, 2023. It is now read-only.

Commit

Permalink
Added Synthesizer example
Browse files Browse the repository at this point in the history
  • Loading branch information
ffAudio committed Nov 22, 2019
1 parent 9a87c0c commit fe6deca
Show file tree
Hide file tree
Showing 9 changed files with 368 additions and 5 deletions.
3 changes: 2 additions & 1 deletion examples/EqualizerExample/EqualizerExample.jucer
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>

<JUCERPROJECT id="WYEC4E" name="EqualizerExample" projectType="audioplug" jucerVersion="5.4.5"
projectLineFeed="&#10;">
projectLineFeed="&#10;" companyName="Foleys Finest Audio" companyWebsite="https://foleysfinest.com"
bundleIdentifier="com.foleysfinest.equalizerexample" pluginManufacturerCode="FFAU">
<MAINGROUP id="FaWUds" name="EqualizerExample">
<GROUP id="{2FE48CA4-8183-CD45-E26D-AA245FA268D6}" name="Source">
<FILE id="x4GqF2" name="PluginProcessor.cpp" compile="1" resource="0"
Expand Down
2 changes: 1 addition & 1 deletion examples/EqualizerExample/Source/PluginProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class EqualizerExampleAudioProcessor : public AudioProcessor,

foleys::MagicFilterPlot* plotSum = nullptr;

// define that as last member of your AudioProcessor
// GUI MAGIC: define that as last member of your AudioProcessor
foleys::MagicProcessorState magicState { *this, treeState };

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EqualizerExampleAudioProcessor)
Expand Down
91 changes: 91 additions & 0 deletions examples/FoleysSynth/FoleysSynth.jucer
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>

<JUCERPROJECT id="JeItQC" name="FoleysSynth" projectType="audioplug" jucerVersion="5.4.5"
companyName="Foleys Finest Audio" projectLineFeed="&#10;" companyWebsite="https://foleysfinest.com"
pluginCharacteristicsValue="pluginIsSynth,pluginWantsMidiIn"
pluginManufacturerCode="FFAU">
<MAINGROUP id="LGWoY5" name="FoleysSynth">
<GROUP id="{0F03A121-FE7D-F4DB-7A0D-D90E378AACC7}" name="Source">
<FILE id="mHBU5k" name="PluginProcessor.cpp" compile="1" resource="0"
file="Source/PluginProcessor.cpp"/>
<FILE id="w20MsF" name="PluginProcessor.h" compile="0" resource="0"
file="Source/PluginProcessor.h"/>
</GROUP>
<GROUP id="{99A1E16A-8343-0C77-9D5B-A3401E80CB20}" name="Resources">
<FILE id="YQH7jG" name="magic.xml" compile="0" resource="1" file="Resources/magic.xml"/>
</GROUP>
</MAINGROUP>
<EXPORTFORMATS>
<XCODE_MAC targetFolder="Builds/MacOSX">
<CONFIGURATIONS>
<CONFIGURATION isDebug="1" name="Debug"/>
<CONFIGURATION isDebug="0" name="Release"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_audio_basics" path="../../JUCE/modules"/>
<MODULEPATH id="juce_audio_devices" path="../../JUCE/modules"/>
<MODULEPATH id="juce_audio_formats" path="../../JUCE/modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="../../JUCE/modules"/>
<MODULEPATH id="juce_audio_processors" path="../../JUCE/modules"/>
<MODULEPATH id="juce_audio_utils" path="../../JUCE/modules"/>
<MODULEPATH id="juce_core" path="../../JUCE/modules"/>
<MODULEPATH id="juce_cryptography" path="../../JUCE/modules"/>
<MODULEPATH id="juce_data_structures" path="../../JUCE/modules"/>
<MODULEPATH id="juce_events" path="../../JUCE/modules"/>
<MODULEPATH id="juce_graphics" path="../../JUCE/modules"/>
<MODULEPATH id="juce_gui_basics" path="../../JUCE/modules"/>
<MODULEPATH id="juce_gui_extra" path="../../JUCE/modules"/>
<MODULEPATH id="juce_opengl" path="../../JUCE/modules"/>
<MODULEPATH id="foleys_gui_magic" path="../../modules"/>
<MODULEPATH id="juce_dsp" path="../../JUCE/modules"/>
</MODULEPATHS>
</XCODE_MAC>
<VS2019 targetFolder="Builds/VisualStudio2019">
<CONFIGURATIONS>
<CONFIGURATION isDebug="1" name="Debug"/>
<CONFIGURATION isDebug="0" name="Release"/>
</CONFIGURATIONS>
<MODULEPATHS>
<MODULEPATH id="juce_audio_basics" path="../../JUCE/modules"/>
<MODULEPATH id="juce_audio_devices" path="../../JUCE/modules"/>
<MODULEPATH id="juce_audio_formats" path="../../JUCE/modules"/>
<MODULEPATH id="juce_audio_plugin_client" path="../../JUCE/modules"/>
<MODULEPATH id="juce_audio_processors" path="../../JUCE/modules"/>
<MODULEPATH id="juce_audio_utils" path="../../JUCE/modules"/>
<MODULEPATH id="juce_core" path="../../JUCE/modules"/>
<MODULEPATH id="juce_cryptography" path="../../JUCE/modules"/>
<MODULEPATH id="juce_data_structures" path="../../JUCE/modules"/>
<MODULEPATH id="juce_events" path="../../JUCE/modules"/>
<MODULEPATH id="juce_graphics" path="../../JUCE/modules"/>
<MODULEPATH id="juce_gui_basics" path="../../JUCE/modules"/>
<MODULEPATH id="juce_gui_extra" path="../../JUCE/modules"/>
<MODULEPATH id="juce_opengl" path="../../JUCE/modules"/>
<MODULEPATH id="foleys_gui_magic" path="../../modules"/>
<MODULEPATH id="juce_dsp" path="../../JUCE/modules"/>
</MODULEPATHS>
</VS2019>
</EXPORTFORMATS>
<MODULES>
<MODULE id="foleys_gui_magic" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_audio_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_audio_devices" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_audio_formats" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_audio_plugin_client" showAllCode="1" useLocalCopy="0"
useGlobalPath="0"/>
<MODULE id="juce_audio_processors" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_audio_utils" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_core" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_cryptography" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_data_structures" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_dsp" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_events" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_graphics" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_gui_basics" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_gui_extra" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
<MODULE id="juce_opengl" showAllCode="1" useLocalCopy="0" useGlobalPath="0"/>
</MODULES>
<LIVE_SETTINGS>
<OSX/>
</LIVE_SETTINGS>
<JUCEOPTIONS JUCE_VST3_CAN_REPLACE_VST2="0" JUCE_STRICT_REFCOUNTEDPOINTER="1"/>
</JUCERPROJECT>
9 changes: 9 additions & 0 deletions examples/FoleysSynth/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FoleysSynth example
===================

This example shows, how to write a synthesizer plugin using the
WYSWYG GUI using foleys_gui_magic.

The example is work in progress, the MidiKeyboardComponent is
already present, but no sound yet.

Binary file added examples/FoleysSynth/Resources/magic.xml
Binary file not shown.
195 changes: 195 additions & 0 deletions examples/FoleysSynth/Source/PluginProcessor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/*
==============================================================================
This file was auto-generated!
It contains the basic framework code for a JUCE plugin processor.
==============================================================================
*/

#include "PluginProcessor.h"

//==============================================================================
FoleysSynthAudioProcessor::FoleysSynthAudioProcessor()
#ifndef JucePlugin_PreferredChannelConfigurations
: AudioProcessor (BusesProperties()
#if ! JucePlugin_IsMidiEffect
#if ! JucePlugin_IsSynth
.withInput ("Input", AudioChannelSet::stereo(), true)
#endif
.withOutput ("Output", AudioChannelSet::stereo(), true)
#endif
)
#endif
{
}

FoleysSynthAudioProcessor::~FoleysSynthAudioProcessor()
{
}

//==============================================================================
void FoleysSynthAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
// Use this method as the place to do any pre-playback
// initialisation that you need..
}

void FoleysSynthAudioProcessor::releaseResources()
{
// When playback stops, you can use this as an opportunity to free up any
// spare memory, etc.
}

#ifndef JucePlugin_PreferredChannelConfigurations
bool FoleysSynthAudioProcessor::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 FoleysSynthAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer& midiMessages)
{
ScopedNoDenormals noDenormals;
auto totalNumInputChannels = getTotalNumInputChannels();
auto totalNumOutputChannels = getTotalNumOutputChannels();

// MAGIC GUI: send midi messages to the keyboard state
magicState.processMidiBuffer (midiMessages, buffer.getNumSamples());

// In case we have more outputs than inputs, this code clears any output
// channels that didn't contain input data, (because these aren't
// guaranteed to be empty - they may contain garbage).
// This is here to avoid people getting screaming feedback
// when they first compile a plugin, but obviously you don't need to keep
// this code if your algorithm always overwrites all the output channels.
for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
buffer.clear (i, 0, buffer.getNumSamples());

// This is the place where you'd normally do the guts of your plugin's
// audio processing...
// Make sure to reset the state if your inner loop is processing
// the samples and the outer loop is handling the channels.
// Alternatively, you can process the samples with the channels
// interleaved by keeping the same state.
for (int channel = 0; channel < totalNumInputChannels; ++channel)
{
auto* channelData = buffer.getWritePointer (channel);

// ..do something to the data...
}
}

//==============================================================================
bool FoleysSynthAudioProcessor::hasEditor() const
{
return true; // (change this to false if you choose to not supply an editor)
}

AudioProcessorEditor* FoleysSynthAudioProcessor::createEditor()
{
// MAGIC GUI: create the generated editor
return new foleys::MagicPluginEditor (magicState, BinaryData::magic_xml, BinaryData::magic_xmlSize);
}

//==============================================================================
void FoleysSynthAudioProcessor::getStateInformation (MemoryBlock& destData)
{
// MAGIC GUI: let the magicState conveniently handle save and restore the state.
// You don't need to use that, but it also takes care of restoring the last editor size
magicState.getStateInformation (destData);
}

void FoleysSynthAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
{
// MAGIC GUI: let the magicState conveniently handle save and restore the state.
// You don't need to use that, but it also takes care of restoring the last editor size
magicState.setStateInformation (data, sizeInBytes, getActiveEditor());
}

//==============================================================================
const String FoleysSynthAudioProcessor::getName() const
{
return JucePlugin_Name;
}

bool FoleysSynthAudioProcessor::acceptsMidi() const
{
#if JucePlugin_WantsMidiInput
return true;
#else
return false;
#endif
}

bool FoleysSynthAudioProcessor::producesMidi() const
{
#if JucePlugin_ProducesMidiOutput
return true;
#else
return false;
#endif
}

bool FoleysSynthAudioProcessor::isMidiEffect() const
{
#if JucePlugin_IsMidiEffect
return true;
#else
return false;
#endif
}

double FoleysSynthAudioProcessor::getTailLengthSeconds() const
{
return 0.0;
}

int FoleysSynthAudioProcessor::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 FoleysSynthAudioProcessor::getCurrentProgram()
{
return 0;
}

void FoleysSynthAudioProcessor::setCurrentProgram (int index)
{
}

const String FoleysSynthAudioProcessor::getProgramName (int index)
{
return {};
}

void FoleysSynthAudioProcessor::changeProgramName (int index, const String& newName)
{
}

//==============================================================================
// This creates new instances of the plugin..
AudioProcessor* JUCE_CALLTYPE createPluginFilter()
{
return new FoleysSynthAudioProcessor();
}
66 changes: 66 additions & 0 deletions examples/FoleysSynth/Source/PluginProcessor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
==============================================================================
This file was auto-generated!
It contains the basic framework code for a JUCE plugin processor.
==============================================================================
*/

#pragma once

#include "../JuceLibraryCode/JuceHeader.h"

//==============================================================================
/**
*/
class FoleysSynthAudioProcessor : public AudioProcessor
{
public:
//==============================================================================
FoleysSynthAudioProcessor();
~FoleysSynthAudioProcessor();

//==============================================================================
void prepareToPlay (double sampleRate, int samplesPerBlock) override;
void releaseResources() override;

#ifndef JucePlugin_PreferredChannelConfigurations
bool isBusesLayoutSupported (const BusesLayout& layouts) const override;
#endif

void processBlock (AudioBuffer<float>&, MidiBuffer&) override;

//==============================================================================
AudioProcessorEditor* createEditor() override;
bool hasEditor() const override;

//==============================================================================
void getStateInformation (MemoryBlock& destData) override;
void setStateInformation (const void* data, int sizeInBytes) override;

//==============================================================================
const String getName() const override;

bool acceptsMidi() const override;
bool producesMidi() const override;
bool isMidiEffect() const override;
double getTailLengthSeconds() const override;

//==============================================================================
int getNumPrograms() override;
int getCurrentProgram() override;
void setCurrentProgram (int index) override;
const String getProgramName (int index) override;
void changeProgramName (int index, const String& newName) override;

private:
//==============================================================================
AudioProcessorValueTreeState treeState { *this, nullptr };

// GUI MAGIC: define that as last member of your AudioProcessor
foleys::MagicProcessorState magicState { *this, treeState };

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FoleysSynthAudioProcessor)
};
5 changes: 3 additions & 2 deletions examples/SignalGenerator/SignalGenerator.jucer
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>

<JUCERPROJECT id="T33gqD" name="SignalGenerator" projectType="audioplug" jucerVersion="5.4.4"
<JUCERPROJECT id="T33gqD" name="SignalGenerator" projectType="audioplug" jucerVersion="5.4.5"
pluginAUMainType="'aufx'" pluginVST3Category="Generator" pluginRTASCategory="2048"
pluginAAXCategory="2048" pluginVSTCategory="kPlugCategGenerator"
projectLineFeed="&#10;">
projectLineFeed="&#10;" companyName="Foleys Finest Audio" companyWebsite="https://foleysfinest.com"
bundleIdentifier="com.foleysfinest.signalgenerator" pluginManufacturerCode="FFAU">
<MAINGROUP id="KtcAG2" name="SignalGenerator">
<GROUP id="{C9FD3DD7-E1DA-CA2D-54CB-B4D603FF3A7D}" name="Source">
<FILE id="GPUQn8" name="PluginProcessor.cpp" compile="1" resource="0"
Expand Down

0 comments on commit fe6deca

Please sign in to comment.