@@ -71,6 +71,7 @@ else | |||
$(MAKE) -C tal-reverb-2/LV2 | |||
$(MAKE) -C tal-reverb-3/LV2 | |||
$(MAKE) -C tal-vocoder-2/LV2 | |||
$(MAKE) -C temper/LV2 | |||
$(MAKE) -C vex/LV2 | |||
$(MAKE) -C wolpertinger/LV2 | |||
endif | |||
@@ -111,6 +112,7 @@ vst: libs | |||
$(MAKE) -C tal-reverb-2/VST | |||
$(MAKE) -C tal-reverb-3/VST | |||
$(MAKE) -C tal-vocoder-2/VST | |||
$(MAKE) -C temper/VST | |||
$(MAKE) -C vex/VST | |||
$(MAKE) -C wolpertinger/VST | |||
@@ -150,6 +152,7 @@ clean: | |||
$(MAKE) clean -C tal-reverb-2/LV2 | |||
$(MAKE) clean -C tal-reverb-3/LV2 | |||
$(MAKE) clean -C tal-vocoder-2/LV2 | |||
$(MAKE) clean -C temper/LV2 | |||
$(MAKE) clean -C vex/LV2 | |||
$(MAKE) clean -C wolpertinger/LV2 | |||
@@ -185,6 +188,7 @@ clean: | |||
$(MAKE) clean -C tal-reverb-2/VST | |||
$(MAKE) clean -C tal-reverb-3/VST | |||
$(MAKE) clean -C tal-vocoder-2/VST | |||
$(MAKE) clean -C temper/VST | |||
$(MAKE) clean -C vex/VST | |||
$(MAKE) clean -C wolpertinger/VST | |||
@@ -0,0 +1,19 @@ | |||
dofile("../../../scripts/make-project.lua") | |||
package = make_juce_lv2_project("Temper") | |||
if (windows) then | |||
-- TODO | |||
elseif (macosx) then | |||
-- TODO | |||
else | |||
package.linkoptions = { package.linkoptions, "`pkg-config --libs gl`" } | |||
end | |||
package.files = { | |||
matchfiles ( | |||
"../source/*.cpp", | |||
"../../../libs/juce-plugin/JucePluginMain.cpp" | |||
) | |||
} |
@@ -0,0 +1,19 @@ | |||
dofile("../../../scripts/make-project.lua") | |||
package = make_juce_vst_project("Temper") | |||
if (windows) then | |||
-- TODO | |||
elseif (macosx) then | |||
-- TODO | |||
else | |||
package.linkoptions = { package.linkoptions, "`pkg-config --libs gl`" } | |||
end | |||
package.files = { | |||
matchfiles ( | |||
"../source/*.cpp", | |||
"../../../libs/juce-plugin/JucePluginMain.cpp" | |||
) | |||
} |
@@ -0,0 +1,44 @@ | |||
/* ========================================================================================= | |||
This is an auto-generated file: Any edits you make may be overwritten! | |||
*/ | |||
#pragma once | |||
namespace BinaryData | |||
{ | |||
extern const char* Background_png; | |||
const int Background_pngSize = 1105568; | |||
extern const char* BeeStingPreset_xml; | |||
const int BeeStingPreset_xmlSize = 250; | |||
extern const char* DefaultPreset_xml; | |||
const int DefaultPreset_xmlSize = 249; | |||
extern const char* FlyingUnitedPreset_xml; | |||
const int FlyingUnitedPreset_xmlSize = 252; | |||
extern const char* GraphBackground_png; | |||
const int GraphBackground_pngSize = 179814; | |||
extern const char* MontserratLight_otf; | |||
const int MontserratLight_otfSize = 91496; | |||
extern const char* MorningAtTheDMVPreset_xml; | |||
const int MorningAtTheDMVPreset_xmlSize = 254; | |||
extern const char* StubbedToePreset_xml; | |||
const int StubbedToePreset_xmlSize = 252; | |||
// Points to the start of a list of resource names. | |||
extern const char* namedResourceList[]; | |||
// Number of elements in the namedResourceList array. | |||
const int namedResourceListSize = 8; | |||
// If you provide the name of one of the binary resource variables above, this function will | |||
// return the corresponding data and its size (or a null pointer if the name isn't found). | |||
const char* getNamedResource (const char* resourceNameUTF8, int& dataSizeInBytes) throw(); | |||
} |
@@ -0,0 +1,43 @@ | |||
/* | |||
============================================================================== | |||
FaustUIBridge.cpp | |||
Created: 9 Feb 2017 5:59:55pm | |||
Author: Nick Thompson | |||
============================================================================== | |||
*/ | |||
#include "FaustUIBridge.h" | |||
FaustUIBridge::FaustUIBridge(AudioProcessorValueTreeState& vts) | |||
: valueTreeState(vts) | |||
{ | |||
} | |||
FaustUIBridge::~FaustUIBridge() | |||
{ | |||
for (int i = 0; i < listenerAssignments.size(); ++i) | |||
{ | |||
ParameterListenerPair p = listenerAssignments.getUnchecked(i); | |||
String paramId = p.paramId; | |||
FaustUIBridgeListener* listener = p.listener; | |||
valueTreeState.removeParameterListener(paramId, listener); | |||
} | |||
listenerAssignments.clear(); | |||
} | |||
void FaustUIBridge::addHorizontalSlider(const char *label, float *zone, float init, float min, float max, float step) | |||
{ | |||
// Create the AudioProcessor parameter if not exists | |||
if (!valueTreeState.getParameter(label)) | |||
valueTreeState.createAndAddParameter(label, label, String(), | |||
NormalisableRange<float>(min, max), init, nullptr, nullptr); | |||
// Attach the listener to keep the internal dsp values up to date | |||
FaustUIBridgeListener* l = new FaustUIBridgeListener(zone); | |||
listeners.add(l); | |||
listenerAssignments.add(ParameterListenerPair(String(label), l)); | |||
valueTreeState.addParameterListener(label, l); | |||
} |
@@ -0,0 +1,132 @@ | |||
/* | |||
============================================================================== | |||
FaustUIBridge.h | |||
Created: 9 Feb 2017 5:59:55pm | |||
Author: Nick Thompson | |||
============================================================================== | |||
*/ | |||
#ifndef FAUSTUIBRIDGE_H_INCLUDED | |||
#define FAUSTUIBRIDGE_H_INCLUDED | |||
#include "JuceHeader.h" | |||
#include "faust/gui/UI.h" | |||
//============================================================================== | |||
/** | |||
This class interfaces with the Faust UI paradigm, mapping control parameters | |||
into AudioProcessorParameters on a provided AudioProcessorValueTreeState. | |||
*/ | |||
class FaustUIBridge : public UI | |||
{ | |||
public: | |||
/** Construct a FaustUIBridge instance with the associated AudioProcessorValueTreeState. */ | |||
FaustUIBridge(AudioProcessorValueTreeState& vts); | |||
/** Destructor. */ | |||
virtual ~FaustUIBridge() override; | |||
//============================================================================== | |||
/** Widget Layout | |||
The following methods implement the widget layout functions. | |||
Because we intend for an AudioProcessorEditor to manage the | |||
visual aspect of the plugin, these methods are no-ops. | |||
*/ | |||
virtual void openTabBox(const char* label) override {}; | |||
virtual void openHorizontalBox(const char* label) override {}; | |||
virtual void openVerticalBox(const char* label) override {}; | |||
virtual void closeBox() override {}; | |||
//============================================================================== | |||
/** Active Widgets | |||
The following methods implement the active widget functions | |||
by constructing an AudioProcessorParameter and installing a | |||
FaustUIBridgeListener to propagate changes back to the corresponding | |||
zone. | |||
*/ | |||
virtual void addButton(const char* label, FAUSTFLOAT* zone) override {}; | |||
virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) override {}; | |||
virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) override {}; | |||
virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) override; | |||
virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) override {}; | |||
//============================================================================== | |||
/** Passive Widgets | |||
The following methods implement the passive widget functions. | |||
Again, because we intend for an AudioProcessorEditor to manage the | |||
visual aspect of the plugin, these methods are no-ops. | |||
*/ | |||
virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) override {}; | |||
virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) override {}; | |||
//============================================================================== | |||
/** Metadata declarations | |||
An additional no-op to implement the last piece of the Faust UI interface. | |||
*/ | |||
virtual void declare(FAUSTFLOAT*, const char*, const char*) override {}; | |||
//============================================================================== | |||
/** This class implements a simple callback which reacts to a value change on a | |||
given AudioProcessorParameter. | |||
We construct an instance of this class for each Faust zone declared via the | |||
active widget methods above. | |||
*/ | |||
class FaustUIBridgeListener : public AudioProcessorValueTreeState::Listener | |||
{ | |||
public: | |||
FaustUIBridgeListener(float* zone) : m_zone(zone) {}; | |||
virtual ~FaustUIBridgeListener() override {}; | |||
virtual void parameterChanged (const String& parameterID, float newValue) override | |||
{ | |||
*m_zone = newValue; | |||
}; | |||
private: | |||
float* m_zone; | |||
}; | |||
private: | |||
//============================================================================== | |||
/** | |||
This struct associates an AudioProcessorParameter id with a FaustUIBridgeListener | |||
object which as been attached to the valueTreeState. | |||
*/ | |||
struct ParameterListenerPair | |||
{ | |||
//============================================================================== | |||
/** Constructor. | |||
@param paramId The String Id of the AudioProcessorParameter. | |||
@param listener The attached FaustUIBridgeListener. | |||
*/ | |||
ParameterListenerPair(String paramId, FaustUIBridgeListener* listener) | |||
: paramId(paramId), listener(listener) {}; | |||
String paramId; | |||
FaustUIBridgeListener* listener; | |||
}; | |||
// A reference to the AudioProcessor's value tree so that we can map the faust | |||
// UI parameters to AudioProcessor parameters. | |||
AudioProcessorValueTreeState& valueTreeState; | |||
// Maintain an array associating AudioProcessorParameters to the Listeners that have been | |||
// installed on those parameters. | |||
Array<ParameterListenerPair> listenerAssignments; | |||
// And an array of listeners to ensure the mapping between internal value tree values | |||
// match the float* zone members of the faust implementation. | |||
OwnedArray<AudioProcessorValueTreeState::Listener> listeners; | |||
}; | |||
#endif // FAUSTUIBRIDGE_H_INCLUDED |
@@ -0,0 +1,34 @@ | |||
/* | |||
IMPORTANT! This file is auto-generated each time you save your | |||
project - if you alter its contents, your changes may be overwritten! | |||
This is the header file that your files should include in order to get all the | |||
JUCE library headers. You should avoid including the JUCE headers directly in | |||
your own source files, because that wouldn't pick up the correct configuration | |||
options for your app. | |||
*/ | |||
#ifndef __APPHEADERFILE_JH7QDM__ | |||
#define __APPHEADERFILE_JH7QDM__ | |||
#include "JucePluginMain.h" | |||
#include "BinaryData.h" | |||
#if ! DONT_SET_USING_JUCE_NAMESPACE | |||
// If your code uses a lot of JUCE classes, then this will obviously save you | |||
// a lot of typing, but can be disabled by setting DONT_SET_USING_JUCE_NAMESPACE. | |||
using namespace juce; | |||
#endif | |||
#if ! JUCE_DONT_DECLARE_PROJECTINFO | |||
namespace ProjectInfo | |||
{ | |||
const char* const projectName = "Temper"; | |||
const char* const versionString = "1.0.3"; | |||
const int versionNumber = 0x10003; | |||
} | |||
#endif | |||
#endif // __APPHEADERFILE_JH7QDM__ |
@@ -0,0 +1,139 @@ | |||
/* | |||
IMPORTANT! This file is auto-generated each time you save your | |||
project - if you alter its contents, your changes may be overwritten! | |||
There's a section below where you can add your own custom code safely, and the | |||
Projucer will preserve the contents of that block, but the best way to change | |||
any of these definitions is by using the Projucer's project settings. | |||
Any commented-out settings will assume their default values. | |||
*/ | |||
#pragma once | |||
//============================================================================== | |||
#ifndef JucePlugin_Enable_IAA | |||
#define JucePlugin_Enable_IAA 0 | |||
#endif | |||
#ifndef JucePlugin_Name | |||
#define JucePlugin_Name "Temper" | |||
#endif | |||
#ifndef JucePlugin_Desc | |||
#define JucePlugin_Desc "Modern digital distortion." | |||
#endif | |||
#ifndef JucePlugin_Manufacturer | |||
#define JucePlugin_Manufacturer "Creative Intent" | |||
#endif | |||
#ifndef JucePlugin_ManufacturerWebsite | |||
#define JucePlugin_ManufacturerWebsite "http://www.creativeintent.co" | |||
#endif | |||
#ifndef JucePlugin_ManufacturerEmail | |||
#define JucePlugin_ManufacturerEmail "" | |||
#endif | |||
#ifndef JucePlugin_ManufacturerCode | |||
#define JucePlugin_ManufacturerCode 0x4376696e // 'Cvin' | |||
#endif | |||
#ifndef JucePlugin_PluginCode | |||
#define JucePlugin_PluginCode 0x546d7072 // 'Tmpr' | |||
#endif | |||
#ifndef JucePlugin_IsSynth | |||
#define JucePlugin_IsSynth 0 | |||
#endif | |||
#ifndef JucePlugin_WantsMidiInput | |||
#define JucePlugin_WantsMidiInput 0 | |||
#endif | |||
#ifndef JucePlugin_ProducesMidiOutput | |||
#define JucePlugin_ProducesMidiOutput 0 | |||
#endif | |||
#ifndef JucePlugin_IsMidiEffect | |||
#define JucePlugin_IsMidiEffect 0 | |||
#endif | |||
#ifndef JucePlugin_EditorRequiresKeyboardFocus | |||
#define JucePlugin_EditorRequiresKeyboardFocus 0 | |||
#endif | |||
#ifndef JucePlugin_Version | |||
#define JucePlugin_Version 1.0.3 | |||
#endif | |||
#ifndef JucePlugin_VersionCode | |||
#define JucePlugin_VersionCode 0x10003 | |||
#endif | |||
#ifndef JucePlugin_VersionString | |||
#define JucePlugin_VersionString "1.0.3" | |||
#endif | |||
#ifndef JucePlugin_VSTUniqueID | |||
#define JucePlugin_VSTUniqueID JucePlugin_PluginCode | |||
#endif | |||
#ifndef JucePlugin_VSTCategory | |||
#define JucePlugin_VSTCategory kPlugCategEffect | |||
#endif | |||
#ifndef JucePlugin_AUMainType | |||
#define JucePlugin_AUMainType kAudioUnitType_Effect | |||
#endif | |||
#ifndef JucePlugin_AUSubType | |||
#define JucePlugin_AUSubType JucePlugin_PluginCode | |||
#endif | |||
#ifndef JucePlugin_AUExportPrefix | |||
#define JucePlugin_AUExportPrefix TemperAU | |||
#endif | |||
#ifndef JucePlugin_AUExportPrefixQuoted | |||
#define JucePlugin_AUExportPrefixQuoted "TemperAU" | |||
#endif | |||
#ifndef JucePlugin_AUManufacturerCode | |||
#define JucePlugin_AUManufacturerCode JucePlugin_ManufacturerCode | |||
#endif | |||
#ifndef JucePlugin_CFBundleIdentifier | |||
#define JucePlugin_CFBundleIdentifier com.creativeintent.temper | |||
#endif | |||
#ifndef JucePlugin_RTASCategory | |||
#define JucePlugin_RTASCategory ePlugInCategory_None | |||
#endif | |||
#ifndef JucePlugin_RTASManufacturerCode | |||
#define JucePlugin_RTASManufacturerCode JucePlugin_ManufacturerCode | |||
#endif | |||
#ifndef JucePlugin_RTASProductId | |||
#define JucePlugin_RTASProductId JucePlugin_PluginCode | |||
#endif | |||
#ifndef JucePlugin_RTASDisableBypass | |||
#define JucePlugin_RTASDisableBypass 0 | |||
#endif | |||
#ifndef JucePlugin_RTASDisableMultiMono | |||
#define JucePlugin_RTASDisableMultiMono 0 | |||
#endif | |||
#ifndef JucePlugin_AAXIdentifier | |||
#define JucePlugin_AAXIdentifier com.creativeintent.temper | |||
#endif | |||
#ifndef JucePlugin_AAXManufacturerCode | |||
#define JucePlugin_AAXManufacturerCode JucePlugin_ManufacturerCode | |||
#endif | |||
#ifndef JucePlugin_AAXProductId | |||
#define JucePlugin_AAXProductId JucePlugin_PluginCode | |||
#endif | |||
#ifndef JucePlugin_AAXCategory | |||
#define JucePlugin_AAXCategory AAX_ePlugInCategory_Dynamics | |||
#endif | |||
#ifndef JucePlugin_AAXDisableBypass | |||
#define JucePlugin_AAXDisableBypass 0 | |||
#endif | |||
#ifndef JucePlugin_AAXDisableMultiMono | |||
#define JucePlugin_AAXDisableMultiMono 0 | |||
#endif | |||
#ifndef JucePlugin_IAAType | |||
#define JucePlugin_IAAType 0x61757278 // 'aurx' | |||
#endif | |||
#ifndef JucePlugin_IAASubType | |||
#define JucePlugin_IAASubType JucePlugin_PluginCode | |||
#endif | |||
#ifndef JucePlugin_IAAName | |||
#define JucePlugin_IAAName "Creative Intent: Temper" | |||
#endif | |||
#define JucePlugin_LV2URI "https://github.com/creativeintent/temper" | |||
#define JucePlugin_LV2Category "DistortionPlugin" | |||
#define JucePlugin_WantsLV2Latency 0 | |||
#define JucePlugin_WantsLV2State 0 | |||
#define JucePlugin_WantsLV2StateString 0 | |||
#define JucePlugin_WantsLV2Presets 1 | |||
#define JucePlugin_WantsLV2TimePos 0 |
@@ -0,0 +1,337 @@ | |||
/* | |||
============================================================================== | |||
This is an automatically generated GUI class created by the Projucer! | |||
Be careful when adding custom code to these files, as only the code within | |||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded | |||
and re-saved. | |||
Created with Projucer version: 4.3.0 | |||
------------------------------------------------------------------------------ | |||
The Projucer is part of the JUCE library - "Jules' Utility Class Extensions" | |||
Copyright (c) 2015 - ROLI Ltd. | |||
============================================================================== | |||
*/ | |||
//[Headers] You can add your own extra header files here... | |||
//[/Headers] | |||
#include "MainComponent.h" | |||
//[MiscUserDefs] You can add your own user definitions and misc code here... | |||
typedef AudioProcessorValueTreeState::SliderAttachment SliderAttachment; | |||
//[/MiscUserDefs] | |||
//============================================================================== | |||
MainComponent::MainComponent (AudioProcessorValueTreeState& vts) | |||
: m_vts(vts) | |||
{ | |||
//[Constructor_pre] You can add your own custom stuff here.. | |||
//[/Constructor_pre] | |||
addAndMakeVisible (m_cutoffSlider = new Slider ("Cutoff")); | |||
m_cutoffSlider->setRange (100, 20000, 0); | |||
m_cutoffSlider->setSliderStyle (Slider::RotaryHorizontalVerticalDrag); | |||
m_cutoffSlider->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); | |||
addAndMakeVisible (m_resoSlider = new Slider ("Resonance")); | |||
m_resoSlider->setRange (1, 8, 0); | |||
m_resoSlider->setSliderStyle (Slider::RotaryHorizontalVerticalDrag); | |||
m_resoSlider->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); | |||
addAndMakeVisible (m_driveSlider = new Slider ("Drive")); | |||
m_driveSlider->setRange (-10, 10, 0); | |||
m_driveSlider->setSliderStyle (Slider::RotaryHorizontalVerticalDrag); | |||
m_driveSlider->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); | |||
addAndMakeVisible (m_curveSlider = new Slider ("Curve")); | |||
m_curveSlider->setRange (0.1, 4, 0); | |||
m_curveSlider->setSliderStyle (Slider::RotaryHorizontalVerticalDrag); | |||
m_curveSlider->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); | |||
addAndMakeVisible (m_satSlider = new Slider ("Saturation")); | |||
m_satSlider->setRange (0, 1, 0); | |||
m_satSlider->setSliderStyle (Slider::RotaryHorizontalVerticalDrag); | |||
m_satSlider->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); | |||
addAndMakeVisible (m_feedbackSlider = new Slider ("Feedback")); | |||
m_feedbackSlider->setRange (-60, -24, 0); | |||
m_feedbackSlider->setSliderStyle (Slider::RotaryHorizontalVerticalDrag); | |||
m_feedbackSlider->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); | |||
addAndMakeVisible (m_gainSlider = new Slider ("Level")); | |||
m_gainSlider->setRange (-24, 24, 0); | |||
m_gainSlider->setSliderStyle (Slider::RotaryHorizontalVerticalDrag); | |||
m_gainSlider->setTextBoxStyle (Slider::NoTextBox, true, 80, 20); | |||
addAndMakeVisible (m_cutoffLabel = new Label ("Cutoff Label", | |||
TRANS("CUTOFF"))); | |||
m_cutoffLabel->setFont (Font (15.00f, Font::plain)); | |||
m_cutoffLabel->setJustificationType (Justification::centred); | |||
m_cutoffLabel->setEditable (false, false, false); | |||
m_cutoffLabel->setColour (Label::textColourId, Colour (0xffff8917)); | |||
m_cutoffLabel->setColour (TextEditor::textColourId, Colours::black); | |||
m_cutoffLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
addAndMakeVisible (m_resoLabel = new Label ("Resonance Label", | |||
TRANS("RESONANCE"))); | |||
m_resoLabel->setFont (Font (15.00f, Font::plain)); | |||
m_resoLabel->setJustificationType (Justification::centred); | |||
m_resoLabel->setEditable (false, false, false); | |||
m_resoLabel->setColour (Label::textColourId, Colour (0xffff8917)); | |||
m_resoLabel->setColour (TextEditor::textColourId, Colours::black); | |||
m_resoLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
addAndMakeVisible (m_driveLabel = new Label ("Drive Label", | |||
TRANS("DRIVE"))); | |||
m_driveLabel->setFont (Font (15.00f, Font::plain)); | |||
m_driveLabel->setJustificationType (Justification::centred); | |||
m_driveLabel->setEditable (false, false, false); | |||
m_driveLabel->setColour (Label::textColourId, Colour (0xffff8917)); | |||
m_driveLabel->setColour (TextEditor::textColourId, Colours::black); | |||
m_driveLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
addAndMakeVisible (m_curveLabel = new Label ("Curve Label", | |||
TRANS("CURVE"))); | |||
m_curveLabel->setFont (Font (15.00f, Font::plain)); | |||
m_curveLabel->setJustificationType (Justification::centred); | |||
m_curveLabel->setEditable (false, false, false); | |||
m_curveLabel->setColour (Label::textColourId, Colour (0xffff8917)); | |||
m_curveLabel->setColour (TextEditor::textColourId, Colours::black); | |||
m_curveLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
addAndMakeVisible (m_satLabel = new Label ("Saturation Label", | |||
TRANS("SATURATION"))); | |||
m_satLabel->setFont (Font (15.00f, Font::plain)); | |||
m_satLabel->setJustificationType (Justification::centred); | |||
m_satLabel->setEditable (false, false, false); | |||
m_satLabel->setColour (Label::textColourId, Colour (0xffff8917)); | |||
m_satLabel->setColour (TextEditor::textColourId, Colours::black); | |||
m_satLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
addAndMakeVisible (m_feedbackLabel = new Label ("Feedback Label", | |||
TRANS("FEEDBACK"))); | |||
m_feedbackLabel->setFont (Font (15.00f, Font::plain)); | |||
m_feedbackLabel->setJustificationType (Justification::centred); | |||
m_feedbackLabel->setEditable (false, false, false); | |||
m_feedbackLabel->setColour (Label::textColourId, Colour (0xffff8917)); | |||
m_feedbackLabel->setColour (TextEditor::textColourId, Colours::black); | |||
m_feedbackLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
addAndMakeVisible (m_gainLabel = new Label ("Gain Label", | |||
TRANS("LEVEL"))); | |||
m_gainLabel->setFont (Font (15.00f, Font::plain)); | |||
m_gainLabel->setJustificationType (Justification::centred); | |||
m_gainLabel->setEditable (false, false, false); | |||
m_gainLabel->setColour (Label::textColourId, Colour (0xffff8917)); | |||
m_gainLabel->setColour (TextEditor::textColourId, Colours::black); | |||
m_gainLabel->setColour (TextEditor::backgroundColourId, Colour (0x00000000)); | |||
drawable1 = Drawable::createFromImageData (BinaryData::Background_png, BinaryData::Background_pngSize); | |||
//[UserPreSize] | |||
//[/UserPreSize] | |||
setSize (744, 476); | |||
//[Constructor] You can add your own custom stuff here.. | |||
filterFreqAttachment = new SliderAttachment(m_vts, "Cutoff", *m_cutoffSlider); | |||
filterResoAttachment = new SliderAttachment(m_vts, "Resonance", *m_resoSlider); | |||
driveAttachment = new SliderAttachment(m_vts, "Drive", *m_driveSlider); | |||
curveAttachment = new SliderAttachment(m_vts, "Curve", *m_curveSlider); | |||
satAttachment = new SliderAttachment(m_vts, "Saturation", *m_satSlider); | |||
feedbackAttachment = new SliderAttachment(m_vts, "Feedback", *m_feedbackSlider); | |||
levelAttachment = new SliderAttachment(m_vts, "Level", *m_gainSlider); | |||
m_cutoffSlider->setTextValueSuffix("Hz"); | |||
m_cutoffSlider->setSkewFactorFromMidPoint(800.0); | |||
m_feedbackSlider->setTextValueSuffix("dB"); | |||
m_gainSlider->setTextValueSuffix("dB"); | |||
//[/Constructor] | |||
} | |||
MainComponent::~MainComponent() | |||
{ | |||
//[Destructor_pre]. You can add your own custom destruction code here.. | |||
// This has to happen before we null out the Sliders themselves because | |||
// when the ScopedPointer<> delete policy tries to remove Listeners from | |||
// the SliderAttachment it refers to the Sliders themselves. If the Sliders | |||
// have already been deleted at that point then we get a null pointer error. | |||
filterFreqAttachment = nullptr; | |||
filterResoAttachment = nullptr; | |||
driveAttachment = nullptr; | |||
curveAttachment = nullptr; | |||
satAttachment = nullptr; | |||
feedbackAttachment = nullptr; | |||
levelAttachment = nullptr; | |||
//[/Destructor_pre] | |||
m_cutoffSlider = nullptr; | |||
m_resoSlider = nullptr; | |||
m_driveSlider = nullptr; | |||
m_curveSlider = nullptr; | |||
m_satSlider = nullptr; | |||
m_feedbackSlider = nullptr; | |||
m_gainSlider = nullptr; | |||
m_cutoffLabel = nullptr; | |||
m_resoLabel = nullptr; | |||
m_driveLabel = nullptr; | |||
m_curveLabel = nullptr; | |||
m_satLabel = nullptr; | |||
m_feedbackLabel = nullptr; | |||
m_gainLabel = nullptr; | |||
drawable1 = nullptr; | |||
//[Destructor]. You can add your own custom destruction code here.. | |||
//[/Destructor] | |||
} | |||
//============================================================================== | |||
void MainComponent::paint (Graphics& g) | |||
{ | |||
//[UserPrePaint] Add your own custom painting code here.. | |||
//[/UserPrePaint] | |||
g.setColour (Colours::black); | |||
jassert (drawable1 != 0); | |||
if (drawable1 != 0) | |||
drawable1->drawWithin (g, Rectangle<float> (0, 0, 744, 476), | |||
RectanglePlacement::stretchToFit, 1.000f); | |||
//[UserPaint] Add your own custom painting code here.. | |||
//[/UserPaint] | |||
} | |||
void MainComponent::resized() | |||
{ | |||
//[UserPreResize] Add your own custom resize code here.. | |||
//[/UserPreResize] | |||
m_cutoffSlider->setBounds (28, 149, 72, 72); | |||
m_resoSlider->setBounds (28, 277, 72, 72); | |||
m_driveSlider->setBounds (336, 357, 72, 72); | |||
m_curveSlider->setBounds (219, 370, 50, 50); | |||
m_satSlider->setBounds (475, 370, 50, 50); | |||
m_feedbackSlider->setBounds (640, 148, 72, 72); | |||
m_gainSlider->setBounds (640, 277, 72, 72); | |||
m_cutoffLabel->setBounds (24, 111, 80, 20); | |||
m_resoLabel->setBounds (24, 369, 80, 20); | |||
m_driveLabel->setBounds (332, 450, 80, 20); | |||
m_curveLabel->setBounds (204, 440, 80, 20); | |||
m_satLabel->setBounds (462, 440, 80, 20); | |||
m_feedbackLabel->setBounds (637, 111, 80, 20); | |||
m_gainLabel->setBounds (639, 369, 80, 20); | |||
//[UserResized] Add your own custom resize handling here.. | |||
//[/UserResized] | |||
} | |||
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here... | |||
//[/MiscUserCode] | |||
//============================================================================== | |||
#if 0 | |||
/* -- Projucer information section -- | |||
This is where the Projucer stores the metadata that describe this GUI layout, so | |||
make changes in here at your peril! | |||
BEGIN_JUCER_METADATA | |||
<JUCER_COMPONENT documentType="Component" className="MainComponent" componentName="" | |||
parentClasses="public Component" constructorParams="AudioProcessorValueTreeState& vts" | |||
variableInitialisers="m_vts(vts)" snapPixels="8" snapActive="1" | |||
snapShown="1" overlayOpacity="0.330" fixedSize="1" initialWidth="744" | |||
initialHeight="476"> | |||
<BACKGROUND backgroundColour="ffffff"> | |||
<IMAGE pos="0 0 744 476" resource="BinaryData::Background_png" opacity="1" | |||
mode="0"/> | |||
</BACKGROUND> | |||
<SLIDER name="Cutoff" id="80edd5c38c704dd5" memberName="m_cutoffSlider" | |||
virtualName="" explicitFocusOrder="0" pos="28 149 72 72" min="100" | |||
max="20000" int="0" style="RotaryHorizontalVerticalDrag" textBoxPos="NoTextBox" | |||
textBoxEditable="0" textBoxWidth="80" textBoxHeight="20" skewFactor="1" | |||
needsCallback="0"/> | |||
<SLIDER name="Resonance" id="3bb5cf0ab68e9733" memberName="m_resoSlider" | |||
virtualName="" explicitFocusOrder="0" pos="28 277 72 72" min="1" | |||
max="8" int="0" style="RotaryHorizontalVerticalDrag" textBoxPos="NoTextBox" | |||
textBoxEditable="0" textBoxWidth="80" textBoxHeight="20" skewFactor="1" | |||
needsCallback="0"/> | |||
<SLIDER name="Drive" id="9909e31099819864" memberName="m_driveSlider" | |||
virtualName="" explicitFocusOrder="0" pos="336 357 72 72" min="-10" | |||
max="10" int="0" style="RotaryHorizontalVerticalDrag" textBoxPos="NoTextBox" | |||
textBoxEditable="0" textBoxWidth="80" textBoxHeight="20" skewFactor="1" | |||
needsCallback="0"/> | |||
<SLIDER name="Curve" id="a56ea73f883bdf8f" memberName="m_curveSlider" | |||
virtualName="" explicitFocusOrder="0" pos="219 370 50 50" min="0.10000000000000000555" | |||
max="4" int="0" style="RotaryHorizontalVerticalDrag" textBoxPos="NoTextBox" | |||
textBoxEditable="0" textBoxWidth="80" textBoxHeight="20" skewFactor="1" | |||
needsCallback="0"/> | |||
<SLIDER name="Saturation" id="a1e434d9a7eda8a0" memberName="m_satSlider" | |||
virtualName="" explicitFocusOrder="0" pos="475 370 50 50" min="0" | |||
max="1" int="0" style="RotaryHorizontalVerticalDrag" textBoxPos="NoTextBox" | |||
textBoxEditable="0" textBoxWidth="80" textBoxHeight="20" skewFactor="1" | |||
needsCallback="0"/> | |||
<SLIDER name="Feedback" id="ecd475fce33f4b83" memberName="m_feedbackSlider" | |||
virtualName="" explicitFocusOrder="0" pos="640 148 72 72" min="-60" | |||
max="-24" int="0" style="RotaryHorizontalVerticalDrag" textBoxPos="NoTextBox" | |||
textBoxEditable="0" textBoxWidth="80" textBoxHeight="20" skewFactor="1" | |||
needsCallback="0"/> | |||
<SLIDER name="Level" id="bf47d1ef820213ea" memberName="m_gainSlider" | |||
virtualName="" explicitFocusOrder="0" pos="640 277 72 72" min="-24" | |||
max="24" int="0" style="RotaryHorizontalVerticalDrag" textBoxPos="NoTextBox" | |||
textBoxEditable="0" textBoxWidth="80" textBoxHeight="20" skewFactor="1" | |||
needsCallback="0"/> | |||
<LABEL name="Cutoff Label" id="8c36484c7dd57b99" memberName="m_cutoffLabel" | |||
virtualName="" explicitFocusOrder="0" pos="24 111 80 20" textCol="ffff8917" | |||
edTextCol="ff000000" edBkgCol="0" labelText="CUTOFF" editableSingleClick="0" | |||
editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" | |||
fontsize="15" bold="0" italic="0" justification="36"/> | |||
<LABEL name="Resonance Label" id="cc33e12b86f2a86a" memberName="m_resoLabel" | |||
virtualName="" explicitFocusOrder="0" pos="24 369 80 20" textCol="ffff8917" | |||
edTextCol="ff000000" edBkgCol="0" labelText="RESONANCE" editableSingleClick="0" | |||
editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" | |||
fontsize="15" bold="0" italic="0" justification="36"/> | |||
<LABEL name="Drive Label" id="195ded46976233cb" memberName="m_driveLabel" | |||
virtualName="" explicitFocusOrder="0" pos="332 450 80 20" textCol="ffff8917" | |||
edTextCol="ff000000" edBkgCol="0" labelText="DRIVE" editableSingleClick="0" | |||
editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" | |||
fontsize="15" bold="0" italic="0" justification="36"/> | |||
<LABEL name="Curve Label" id="30073a37efa500cc" memberName="m_curveLabel" | |||
virtualName="" explicitFocusOrder="0" pos="204 440 80 20" textCol="ffff8917" | |||
edTextCol="ff000000" edBkgCol="0" labelText="CURVE" editableSingleClick="0" | |||
editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" | |||
fontsize="15" bold="0" italic="0" justification="36"/> | |||
<LABEL name="Saturation Label" id="e8a8527f3f6976cf" memberName="m_satLabel" | |||
virtualName="" explicitFocusOrder="0" pos="462 440 80 20" textCol="ffff8917" | |||
edTextCol="ff000000" edBkgCol="0" labelText="SATURATION" editableSingleClick="0" | |||
editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" | |||
fontsize="15" bold="0" italic="0" justification="36"/> | |||
<LABEL name="Feedback Label" id="5547950683b7ca1f" memberName="m_feedbackLabel" | |||
virtualName="" explicitFocusOrder="0" pos="637 111 80 20" textCol="ffff8917" | |||
edTextCol="ff000000" edBkgCol="0" labelText="FEEDBACK" editableSingleClick="0" | |||
editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" | |||
fontsize="15" bold="0" italic="0" justification="36"/> | |||
<LABEL name="Gain Label" id="719d91e31d43fa34" memberName="m_gainLabel" | |||
virtualName="" explicitFocusOrder="0" pos="639 369 80 20" textCol="ffff8917" | |||
edTextCol="ff000000" edBkgCol="0" labelText="LEVEL" editableSingleClick="0" | |||
editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font" | |||
fontsize="15" bold="0" italic="0" justification="36"/> | |||
</JUCER_COMPONENT> | |||
END_JUCER_METADATA | |||
*/ | |||
#endif | |||
//[EndFile] You can add extra defines here... | |||
//[/EndFile] |
@@ -0,0 +1,90 @@ | |||
/* | |||
============================================================================== | |||
This is an automatically generated GUI class created by the Projucer! | |||
Be careful when adding custom code to these files, as only the code within | |||
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded | |||
and re-saved. | |||
Created with Projucer version: 4.3.0 | |||
------------------------------------------------------------------------------ | |||
The Projucer is part of the JUCE library - "Jules' Utility Class Extensions" | |||
Copyright (c) 2015 - ROLI Ltd. | |||
============================================================================== | |||
*/ | |||
#ifndef __JUCE_HEADER_9002020A4DD09B20__ | |||
#define __JUCE_HEADER_9002020A4DD09B20__ | |||
//[Headers] -- You can add your own extra header files here -- | |||
#include "JuceHeader.h" | |||
//[/Headers] | |||
//============================================================================== | |||
/** | |||
//[Comments] | |||
An auto-generated component, created by the Projucer. | |||
Describe your class and how it works here! | |||
//[/Comments] | |||
*/ | |||
class MainComponent : public Component | |||
{ | |||
public: | |||
//============================================================================== | |||
MainComponent (AudioProcessorValueTreeState& vts); | |||
~MainComponent(); | |||
//============================================================================== | |||
//[UserMethods] -- You can add your own custom methods in this section. | |||
//[/UserMethods] | |||
void paint (Graphics& g) override; | |||
void resized() override; | |||
private: | |||
//[UserVariables] -- You can add your own custom variables in this section. | |||
AudioProcessorValueTreeState& m_vts; | |||
ScopedPointer<AudioProcessorValueTreeState::SliderAttachment> filterFreqAttachment; | |||
ScopedPointer<AudioProcessorValueTreeState::SliderAttachment> filterResoAttachment; | |||
ScopedPointer<AudioProcessorValueTreeState::SliderAttachment> driveAttachment; | |||
ScopedPointer<AudioProcessorValueTreeState::SliderAttachment> satAttachment; | |||
ScopedPointer<AudioProcessorValueTreeState::SliderAttachment> curveAttachment; | |||
ScopedPointer<AudioProcessorValueTreeState::SliderAttachment> feedbackAttachment; | |||
ScopedPointer<AudioProcessorValueTreeState::SliderAttachment> levelAttachment; | |||
//[/UserVariables] | |||
//============================================================================== | |||
ScopedPointer<Slider> m_cutoffSlider; | |||
ScopedPointer<Slider> m_resoSlider; | |||
ScopedPointer<Slider> m_driveSlider; | |||
ScopedPointer<Slider> m_curveSlider; | |||
ScopedPointer<Slider> m_satSlider; | |||
ScopedPointer<Slider> m_feedbackSlider; | |||
ScopedPointer<Slider> m_gainSlider; | |||
ScopedPointer<Label> m_cutoffLabel; | |||
ScopedPointer<Label> m_resoLabel; | |||
ScopedPointer<Label> m_driveLabel; | |||
ScopedPointer<Label> m_curveLabel; | |||
ScopedPointer<Label> m_satLabel; | |||
ScopedPointer<Label> m_feedbackLabel; | |||
ScopedPointer<Label> m_gainLabel; | |||
ScopedPointer<Drawable> drawable1; | |||
//============================================================================== | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent) | |||
}; | |||
//[EndFile] You can add extra defines here... | |||
//[/EndFile] | |||
#endif // __JUCE_HEADER_9002020A4DD09B20__ |
@@ -0,0 +1,60 @@ | |||
/* | |||
============================================================================== | |||
This file was auto-generated! | |||
It contains the basic framework code for a JUCE plugin editor. | |||
============================================================================== | |||
*/ | |||
#include "PluginProcessor.h" | |||
#include "PluginEditor.h" | |||
//============================================================================== | |||
TemperAudioProcessorEditor::TemperAudioProcessorEditor (TemperAudioProcessor& p, AudioProcessorValueTreeState& vts) | |||
: AudioProcessorEditor (&p), processor (p), m_vts(vts) | |||
{ | |||
addAndMakeVisible(m_main = new MainComponent(m_vts)); | |||
addAndMakeVisible(m_vizPre = new SpectroscopeComponent()); | |||
addAndMakeVisible(m_vizPost = new SpectroscopeComponent()); | |||
m_main->setAlwaysOnTop(true); | |||
m_vizPre->setColours(Colour::fromRGBA(255, 51, 34, 255), | |||
Colour::fromRGBA(223, 19, 19, 255).withAlpha(0.7f), | |||
Colour::fromRGBA(123, 0, 0, 255).withAlpha(0.7f)); | |||
m_vizPost->setColours(Colour::fromRGBA(255, 186, 34, 255), | |||
Colour::fromRGBA(253, 174, 25, 255).withAlpha(0.7f), | |||
Colour::fromRGBA(255, 126, 0, 255).withAlpha(0.7f)); | |||
m_vizPre->toBehind(m_vizPost); | |||
m_glContext.setComponentPaintingEnabled(true); | |||
m_glContext.attachTo(*this); | |||
setSize (744, 476); | |||
setLookAndFeel(&laf); | |||
} | |||
TemperAudioProcessorEditor::~TemperAudioProcessorEditor() | |||
{ | |||
m_glContext.detach(); | |||
setLookAndFeel(nullptr); | |||
} | |||
//============================================================================== | |||
void TemperAudioProcessorEditor::paint (Graphics& g) | |||
{ | |||
Image graphBackground = ImageCache::getFromMemory(BinaryData::GraphBackground_png, | |||
BinaryData::GraphBackground_pngSize); | |||
g.drawImageAt(graphBackground.rescaled(396, 134), 194, 181); | |||
} | |||
void TemperAudioProcessorEditor::resized() | |||
{ | |||
m_main->setBounds(0, 0, 744, 476); | |||
m_vizPre->setBounds(194, 181, 396, 134); | |||
m_vizPost->setBounds(194, 181, 396, 134); | |||
} |
@@ -0,0 +1,54 @@ | |||
/* | |||
============================================================================== | |||
This file was auto-generated! | |||
It contains the basic framework code for a JUCE plugin editor. | |||
============================================================================== | |||
*/ | |||
#ifndef PLUGINEDITOR_H_INCLUDED | |||
#define PLUGINEDITOR_H_INCLUDED | |||
#include "JuceHeader.h" | |||
#include "TemperLookAndFeel.h" | |||
#include "PluginProcessor.h" | |||
#include "MainComponent.h" | |||
#include "SpectroscopeComponent.h" | |||
typedef AudioProcessorValueTreeState::SliderAttachment SliderAttachment; | |||
//============================================================================== | |||
/** | |||
*/ | |||
class TemperAudioProcessorEditor : public AudioProcessorEditor | |||
{ | |||
public: | |||
TemperAudioProcessorEditor (TemperAudioProcessor&, AudioProcessorValueTreeState&); | |||
~TemperAudioProcessorEditor(); | |||
//============================================================================== | |||
void paint (Graphics&) override; | |||
void resized() override; | |||
//============================================================================== | |||
ScopedPointer<SpectroscopeComponent> m_vizPre; | |||
ScopedPointer<SpectroscopeComponent> m_vizPost; | |||
private: | |||
// This reference is provided as a quick way for your editor to | |||
// access the processor object that created it. | |||
TemperAudioProcessor& processor; | |||
TemperLookAndFeel laf; | |||
OpenGLContext m_glContext; | |||
AudioProcessorValueTreeState& m_vts; | |||
ScopedPointer<MainComponent> m_main; | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemperAudioProcessorEditor) | |||
}; | |||
#endif // PLUGINEDITOR_H_INCLUDED |
@@ -0,0 +1,283 @@ | |||
/* | |||
============================================================================== | |||
This file was auto-generated! | |||
It contains the basic framework code for a JUCE plugin processor. | |||
============================================================================== | |||
*/ | |||
#include "PluginProcessor.h" | |||
#include "PluginEditor.h" | |||
#include "TemperDsp.hpp" | |||
const int kOversampleFactor = 3; | |||
//============================================================================== | |||
TemperAudioProcessor::TemperAudioProcessor() | |||
#ifndef JucePlugin_PreferredChannelConfigurations | |||
: AudioProcessor (BusesProperties() | |||
#if ! JucePlugin_IsMidiEffect | |||
#if ! JucePlugin_IsSynth | |||
.withInput ("Input", AudioChannelSet::stereo(), true) | |||
#endif | |||
.withOutput ("Output", AudioChannelSet::stereo(), true) | |||
#endif | |||
), | |||
m_params (*this, nullptr) | |||
#else | |||
: m_params (*this, nullptr) | |||
#endif | |||
{ | |||
m_restriction = new RestrictionProcessor(); | |||
m_bridge = new FaustUIBridge(m_params); | |||
m_lastKnownSampleRate = 0.0; | |||
m_currentProgram = -1; | |||
// Initialize the dsp units | |||
for (int i = 0; i < getTotalNumInputChannels(); ++i) | |||
{ | |||
TemperDsp* dsp = new TemperDsp(); | |||
dsp->buildUserInterface(m_bridge); | |||
m_dsps.add(dsp); | |||
} | |||
// Initialize the AudioProcessorValueTreeState root | |||
ValueTree root (Identifier("TEMPER")); | |||
m_params.state = root; | |||
} | |||
TemperAudioProcessor::~TemperAudioProcessor() | |||
{ | |||
} | |||
//============================================================================== | |||
const String TemperAudioProcessor::getName() const | |||
{ | |||
return JucePlugin_Name; | |||
} | |||
bool TemperAudioProcessor::acceptsMidi() const | |||
{ | |||
#if JucePlugin_WantsMidiInput | |||
return true; | |||
#else | |||
return false; | |||
#endif | |||
} | |||
bool TemperAudioProcessor::producesMidi() const | |||
{ | |||
#if JucePlugin_ProducesMidiOutput | |||
return true; | |||
#else | |||
return false; | |||
#endif | |||
} | |||
double TemperAudioProcessor::getTailLengthSeconds() const | |||
{ | |||
return 0.0; | |||
} | |||
int TemperAudioProcessor::getNumPrograms() | |||
{ | |||
return 5; // 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 TemperAudioProcessor::getCurrentProgram() | |||
{ | |||
return m_currentProgram; | |||
} | |||
void TemperAudioProcessor::setCurrentProgram (int index) | |||
{ | |||
switch (index) { | |||
case 0: | |||
setStateInformation(BinaryData::DefaultPreset_xml, | |||
BinaryData::DefaultPreset_xmlSize); | |||
break; | |||
case 1: | |||
setStateInformation(BinaryData::StubbedToePreset_xml, | |||
BinaryData::StubbedToePreset_xmlSize); | |||
break; | |||
case 2: | |||
setStateInformation(BinaryData::BeeStingPreset_xml, | |||
BinaryData::BeeStingPreset_xmlSize); | |||
break; | |||
case 3: | |||
setStateInformation(BinaryData::MorningAtTheDMVPreset_xml, | |||
BinaryData::MorningAtTheDMVPreset_xmlSize); | |||
break; | |||
case 4: | |||
setStateInformation(BinaryData::FlyingUnitedPreset_xml, | |||
BinaryData::FlyingUnitedPreset_xmlSize); | |||
break; | |||
default: | |||
break; | |||
} | |||
m_currentProgram = index; | |||
} | |||
const String TemperAudioProcessor::getProgramName (int index) | |||
{ | |||
switch (index) { | |||
case 0: | |||
return String("Default"); | |||
case 1: | |||
return String("Stubbed Toe"); | |||
case 2: | |||
return String("Bee Sting"); | |||
case 3: | |||
return String("Morning at the DMV"); | |||
case 4: | |||
return String("Flying United"); | |||
default: | |||
return String(); | |||
} | |||
} | |||
void TemperAudioProcessor::changeProgramName (int index, const String& newName) | |||
{ | |||
} | |||
//============================================================================== | |||
void TemperAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock) | |||
{ | |||
auto filterType = juce::dsp::Oversampling<float>::filterHalfBandPolyphaseIIR; | |||
m_oversampler = std::unique_ptr<juce::dsp::Oversampling<float>>(new juce::dsp::Oversampling<float>(getTotalNumInputChannels(), | |||
kOversampleFactor, filterType, false)); | |||
// Re-initialize the dsp modules at the upsampled rate. | |||
if (m_lastKnownSampleRate == 0.0) | |||
for (int i = 0; i < m_dsps.size(); ++i) | |||
m_dsps.getUnchecked(i)->init(sampleRate * pow(2, kOversampleFactor)); | |||
else | |||
for (int i = 0; i < m_dsps.size(); ++i) | |||
m_dsps.getUnchecked(i)->instanceConstants(sampleRate * pow(2, kOversampleFactor)); | |||
m_oversampler->initProcessing(static_cast<size_t> (samplesPerBlock)); | |||
m_restriction->prepareToPlay(samplesPerBlock, sampleRate); | |||
m_lastKnownSampleRate = sampleRate; | |||
setLatencySamples(static_cast<int>(m_oversampler->getLatencyInSamples())); | |||
} | |||
void TemperAudioProcessor::releaseResources() | |||
{ | |||
// When playback stops, you can use this as an opportunity to free up any | |||
// spare memory, etc. | |||
} | |||
#ifndef JucePlugin_PreferredChannelConfigurations | |||
bool TemperAudioProcessor::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 TemperAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) | |||
{ | |||
const int totalNumInputChannels = getTotalNumInputChannels(); | |||
const int totalNumOutputChannels = getTotalNumOutputChannels(); | |||
TemperAudioProcessorEditor* editor = static_cast<TemperAudioProcessorEditor*>(getActiveEditor()); | |||
// 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 (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i) | |||
buffer.clear (i, 0, buffer.getNumSamples()); | |||
// Push input buffer into the Pre spectroscope component. | |||
if (editor) | |||
editor->m_vizPre->pushBuffer(buffer); | |||
// Now the guts of the processing; oversampling and applying the Faust dsp module. | |||
const int numInputChannels = buffer.getNumChannels(); | |||
const int numInputSamples = buffer.getNumSamples(); | |||
juce::dsp::AudioBlock<float> block (buffer.getArrayOfWritePointers(), | |||
numInputChannels, | |||
numInputSamples); | |||
juce::dsp::AudioBlock<float> oversampledBlock = m_oversampler->processSamplesUp(block); | |||
// Run the faust processors on each channel of the oversampled block. | |||
for (int i = 0; i < numInputChannels; ++i) | |||
{ | |||
auto* processor = m_dsps.getUnchecked(i); | |||
auto* data = oversampledBlock.getChannelPointer(i); | |||
int len = static_cast<int>(oversampledBlock.getNumSamples()); | |||
processor->compute(len, &data, &data); | |||
} | |||
m_oversampler->processSamplesDown(block); | |||
#ifdef TEMPER_DEMO_BUILD | |||
// After the Faust processing, add the demo restriction to the output stream | |||
m_restriction->processBlock(buffer); | |||
#endif | |||
// Push resulting buffer into the Post spectroscope component. | |||
if (editor) | |||
editor->m_vizPost->pushBuffer(buffer); | |||
} | |||
//============================================================================== | |||
bool TemperAudioProcessor::hasEditor() const | |||
{ | |||
return true; // (change this to false if you choose to not supply an editor) | |||
} | |||
AudioProcessorEditor* TemperAudioProcessor::createEditor() | |||
{ | |||
return new TemperAudioProcessorEditor (*this, m_params); | |||
} | |||
//============================================================================== | |||
void TemperAudioProcessor::getStateInformation (MemoryBlock& destData) | |||
{ | |||
ScopedPointer<XmlElement> xml (m_params.state.createXml()); | |||
copyXmlToBinary(*xml, destData); | |||
} | |||
void TemperAudioProcessor::setStateInformation (const void* data, int sizeInBytes) | |||
{ | |||
ScopedPointer<XmlElement> xmlState (getXmlFromBinary (data, sizeInBytes)); | |||
if (xmlState != nullptr) | |||
if (xmlState->hasTagName (m_params.state.getType())) | |||
m_params.state = ValueTree::fromXml (*xmlState); | |||
} | |||
//============================================================================== | |||
// This creates new instances of the plugin.. | |||
AudioProcessor* JUCE_CALLTYPE createPluginFilter() | |||
{ | |||
return new TemperAudioProcessor(); | |||
} |
@@ -0,0 +1,79 @@ | |||
/* | |||
============================================================================== | |||
This file was auto-generated! | |||
It contains the basic framework code for a JUCE plugin processor. | |||
============================================================================== | |||
*/ | |||
#ifndef PLUGINPROCESSOR_H_INCLUDED | |||
#define PLUGINPROCESSOR_H_INCLUDED | |||
#include "JuceHeader.h" | |||
#include "FaustUIBridge.h" | |||
#include "RestrictionProcessor.h" | |||
#include "faust/dsp/dsp.h" | |||
//============================================================================== | |||
/** | |||
*/ | |||
class TemperAudioProcessor : public AudioProcessor | |||
{ | |||
public: | |||
//============================================================================== | |||
TemperAudioProcessor(); | |||
~TemperAudioProcessor(); | |||
//============================================================================== | |||
void prepareToPlay (double sampleRate, int samplesPerBlock) override; | |||
void releaseResources() override; | |||
#ifndef JucePlugin_PreferredChannelConfigurations | |||
bool isBusesLayoutSupported (const BusesLayout& layouts) const override; | |||
#endif | |||
void processBlock (AudioSampleBuffer&, MidiBuffer&) override; | |||
//============================================================================== | |||
AudioProcessorEditor* createEditor() override; | |||
bool hasEditor() const override; | |||
//============================================================================== | |||
const String getName() const override; | |||
bool acceptsMidi() const override; | |||
bool producesMidi() 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; | |||
//============================================================================== | |||
void getStateInformation (MemoryBlock& destData) override; | |||
void setStateInformation (const void* data, int sizeInBytes) override; | |||
private: | |||
AudioProcessorValueTreeState m_params; | |||
OwnedArray<::dsp> m_dsps; | |||
ScopedPointer<FaustUIBridge> m_bridge; | |||
ScopedPointer<RestrictionProcessor> m_restriction; | |||
std::unique_ptr<juce::dsp::Oversampling<float>> m_oversampler; | |||
double m_lastKnownSampleRate; | |||
int m_currentProgram; | |||
//============================================================================== | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TemperAudioProcessor) | |||
}; | |||
#endif // PLUGINPROCESSOR_H_INCLUDED |
@@ -0,0 +1,55 @@ | |||
/* | |||
============================================================================== | |||
RestrictionProcessor.cpp | |||
Created: 15 Feb 2017 10:03:51pm | |||
Author: Nick Thompson | |||
============================================================================== | |||
*/ | |||
#include "RestrictionProcessor.h" | |||
const double kFreq = 0.05; // Twenty second period. | |||
const double kDuty = 0.75; // Fifteen seconds of audio, five seconds of silence. | |||
//============================================================================== | |||
RestrictionProcessor::RestrictionProcessor() | |||
{ | |||
m_smoothing = new LinearSmoothedValue<float>(); | |||
} | |||
//============================================================================== | |||
void RestrictionProcessor::prepareToPlay(int samplesPerBlockExpected, double sampleRate) | |||
{ | |||
m_sampleRate = sampleRate; | |||
m_delta = kFreq / m_sampleRate; | |||
m_currentAngle = 0.0; | |||
m_smoothing->reset(sampleRate, 1.0); | |||
} | |||
void RestrictionProcessor::releaseResources() {} | |||
void RestrictionProcessor::processBlock(AudioSampleBuffer &buffer) | |||
{ | |||
const int numChannels = buffer.getNumChannels(); | |||
const int numSamples = buffer.getNumSamples(); | |||
float** channelData = buffer.getArrayOfWritePointers(); | |||
for (int j = 0; j < numSamples; ++j) | |||
{ | |||
const float targetGain = static_cast<float>(m_currentAngle <= kDuty); | |||
m_smoothing->setValue(targetGain); | |||
const float gain = m_smoothing->getNextValue(); | |||
for (int i = 0; i < numChannels; ++i) | |||
{ | |||
const float in = channelData[i][j]; | |||
channelData[i][j] = gain * in; | |||
} | |||
m_currentAngle = fmod(m_currentAngle + m_delta, 1.0); | |||
} | |||
} |
@@ -0,0 +1,66 @@ | |||
/* | |||
============================================================================== | |||
RestrictionProcessor.h | |||
Created: 15 Feb 2017 10:03:51pm | |||
Author: Nick Thompson | |||
============================================================================== | |||
*/ | |||
#ifndef RESTRICTIONPROCESSOR_H_INCLUDED | |||
#define RESTRICTIONPROCESSOR_H_INCLUDED | |||
#include "JuceHeader.h" | |||
//============================================================================== | |||
/** | |||
A simple variant on the JUCE AudioSource for managing the trial version | |||
restrictions and plugin validation. | |||
When a source needs to be played, it is first put into a 'prepared' state by a call to | |||
prepareToPlay(), and then repeated calls will be made to its processBlock() method to | |||
process the audio data. | |||
*/ | |||
class RestrictionProcessor | |||
{ | |||
public: | |||
//============================================================================== | |||
/** Creates an AudioSource. */ | |||
RestrictionProcessor(); | |||
/** Destructor. */ | |||
virtual ~RestrictionProcessor() {} | |||
//============================================================================== | |||
/** Tells the processor to prepare for playing. | |||
*/ | |||
void prepareToPlay (int samplesPerBlockExpected, double sampleRate); | |||
/** Allows the source to release anything it no longer needs after playback has stopped. | |||
This will be called when the source is no longer going to have its processBlock() | |||
method called, so it should release any spare memory, etc. that it might have | |||
allocated during the prepareToPlay() call. | |||
*/ | |||
void releaseResources(); | |||
/** Called repeatedly to fetch subsequent blocks of audio data. | |||
After calling the prepareToPlay() method, this callback will be made each | |||
time the audio playback hardware (or whatever other destination the audio | |||
data is going to) needs another block of data. | |||
*/ | |||
void processBlock (AudioSampleBuffer& buffer); | |||
private: | |||
//============================================================================== | |||
ScopedPointer<LinearSmoothedValue<float>> m_smoothing; | |||
//============================================================================== | |||
double m_sampleRate; | |||
double m_delta; | |||
double m_currentAngle; | |||
}; | |||
#endif // RESTRICTIONPROCESSOR_H_INCLUDED |
@@ -0,0 +1,131 @@ | |||
/* | |||
============================================================================== | |||
SpectroscopeComponent.cpp | |||
Created: 8 Apr 2017 12:46:51pm | |||
Author: Nick Thompson | |||
============================================================================== | |||
*/ | |||
#include "JuceHeader.h" | |||
#include "SpectroscopeComponent.h" | |||
//============================================================================== | |||
SpectroscopeComponent::SpectroscopeComponent() | |||
: m_fifoIndex(0), | |||
m_fftBlockReady(false), | |||
m_forwardFFT(kFFTOrder), | |||
m_window(kFFTSize, juce::dsp::WindowingFunction<float>::hann), | |||
m_strokeColour(Colours::white), | |||
m_fillStartColour(Colours::white.withAlpha(0.2f)), | |||
m_fillStopColour(Colours::white.withAlpha(0.8f)) | |||
{ | |||
zeromem(m_outputData, sizeof(m_outputData)); | |||
setSize(700, 200); | |||
startTimerHz(30); | |||
} | |||
SpectroscopeComponent::~SpectroscopeComponent() | |||
{ | |||
stopTimer(); | |||
} | |||
void SpectroscopeComponent::paint (Graphics& g) | |||
{ | |||
const float width = (float) getWidth(); | |||
const float height = (float) getHeight(); | |||
// Clear the drawing target | |||
g.setColour(Colours::transparentBlack); | |||
g.fillAll(); | |||
// The values in the output bins after the FFT have a range that I don't understand | |||
// and isn't explained in the docs. It seems that if I scale down by the size of the | |||
// fft buffer, I get somewhat reasonable results on the graph. But in examples I've | |||
// seen, we would just divide here by the maximum value in the bins at the time of | |||
// drawing. Seeing as that would be inconsistent between frames, I'm defaulting to the | |||
// size of the fft here unless the max value in the bins is larger. | |||
Range<float> maxBin = FloatVectorOperations::findMinAndMax(m_outputData, kOutputSize); | |||
const float scale = 1.0f / jmax((float) kFFTSize, maxBin.getEnd()); | |||
g.setColour(m_fillStartColour); | |||
for (int i = 0; i < kOutputSize; ++i) | |||
{ | |||
float x = std::log10 (1 + 39 * ((i + 1.0f) / kOutputSize)) / std::log10 (40.0f) * width; | |||
const float yMag = scale * m_outputData[i]; | |||
const float yDecibel = Decibels::gainToDecibels(yMag); | |||
const float y = jmap(yDecibel, -90.0f, -12.0f, height, 0.0f); | |||
g.drawVerticalLine((int) x, y, height); | |||
} | |||
} | |||
void SpectroscopeComponent::resized() | |||
{ | |||
} | |||
void SpectroscopeComponent::timerCallback() | |||
{ | |||
if (m_fftBlockReady) | |||
{ | |||
// Compute the frequency transform | |||
m_window.multiplyWithWindowingTable(m_fftData, kFFTSize); | |||
m_forwardFFT.performFrequencyOnlyForwardTransform(m_fftData); | |||
// Copy the frequency bins into the output data buffer, taking | |||
// max(output[i], fftData[i]) for each bin. Note that after computing the | |||
// FrequencyOnlyForwardTransform on an array A of size N, A[N/2, N) is full | |||
// of zeros, and A[0, N/4) is a mirror of A[N/4, N/2). Therefore we only copy | |||
// kFFTSize / 2 samples into the output data buffer here. | |||
FloatVectorOperations::max(m_outputData, m_outputData, m_fftData, kOutputSize); | |||
m_fftBlockReady = false; | |||
} | |||
// Decay the output bin magnitudes | |||
for (int i = 0; i < kOutputSize; ++i) | |||
m_outputData[i] *= 0.707f; | |||
repaint(); | |||
} | |||
void SpectroscopeComponent::pushBuffer(AudioSampleBuffer &buffer) | |||
{ | |||
if (buffer.getNumChannels() > 0) | |||
{ | |||
const int numSamples = buffer.getNumSamples(); | |||
const float* channelData = buffer.getReadPointer(0); | |||
for (int i = 0; i < numSamples; ++i) | |||
pushSample(channelData[i]); | |||
} | |||
} | |||
inline void SpectroscopeComponent::pushSample(float sample) | |||
{ | |||
// When we wrap around the fifo table, we copy the data into the | |||
// FFT buffer and prepare to perform the transform. | |||
if (m_fifoIndex == kFFTSize) | |||
{ | |||
if (!m_fftBlockReady) | |||
{ | |||
zeromem(m_fftData, sizeof(m_fftData)); | |||
memcpy(m_fftData, m_fifo, sizeof(m_fifo)); | |||
m_fftBlockReady = true; | |||
} | |||
m_fifoIndex = 0; | |||
} | |||
m_fifo[m_fifoIndex++] = sample; | |||
} | |||
void SpectroscopeComponent::setColours(Colour strokeColour, Colour fillStartColour, Colour fillStopColour) | |||
{ | |||
m_strokeColour = strokeColour; | |||
m_fillStartColour = fillStartColour; | |||
m_fillStopColour = fillStopColour; | |||
} |
@@ -0,0 +1,60 @@ | |||
/* | |||
============================================================================== | |||
SpectroscopeComponent.h | |||
Created: 8 Apr 2017 12:46:51pm | |||
Author: Nick Thompson | |||
============================================================================== | |||
*/ | |||
#ifndef SPECTROSCOPECOMPONENT_H_INCLUDED | |||
#define SPECTROSCOPECOMPONENT_H_INCLUDED | |||
#include "JuceHeader.h" | |||
//============================================================================== | |||
/* | |||
*/ | |||
class SpectroscopeComponent : public Component, | |||
private Timer | |||
{ | |||
public: | |||
SpectroscopeComponent(); | |||
~SpectroscopeComponent(); | |||
void paint (Graphics&) override; | |||
void resized() override; | |||
void timerCallback() override; | |||
void pushBuffer (AudioSampleBuffer& buffer); | |||
inline void pushSample (float sample); | |||
void setColours (Colour strokeColour, Colour fillStartColour, Colour fillStopColour); | |||
enum { | |||
kFFTOrder = 11, | |||
kFFTSize = 2048, // 2^11 | |||
kOutputSize = 1024, // 2048 / 2 | |||
}; | |||
private: | |||
float m_fifo [kFFTSize]; | |||
float m_fftData [2 * kFFTSize]; | |||
float m_outputData [kOutputSize]; | |||
unsigned int m_fifoIndex; | |||
bool m_fftBlockReady; | |||
juce::dsp::FFT m_forwardFFT; | |||
juce::dsp::WindowingFunction<float> m_window; | |||
Colour m_strokeColour; | |||
Colour m_fillStartColour; | |||
Colour m_fillStopColour; | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SpectroscopeComponent) | |||
}; | |||
#endif // SPECTROSCOPECOMPONENT_H_INCLUDED |
@@ -0,0 +1,339 @@ | |||
/* ------------------------------------------------------------ | |||
name: "temper" | |||
Code generated with Faust 2.5.32 (https://faust.grame.fr) | |||
Compilation options: cpp, -scal -ftz 0 | |||
------------------------------------------------------------ */ | |||
#ifndef __TemperDsp_H__ | |||
#define __TemperDsp_H__ | |||
/************************************************************************ | |||
************************************************************************ | |||
FAUST Architecture File | |||
Copyright (C) 2003-2011 GRAME, Centre National de Creation Musicale | |||
--------------------------------------------------------------------- | |||
This is sample code. This file is provided as an example of minimal | |||
FAUST architecture file. Redistribution and use in source and binary | |||
forms, with or without modification, in part or in full are permitted. | |||
In particular you can create a derived work of this FAUST architecture | |||
and distribute that work under terms of your choice. | |||
This sample code is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |||
************************************************************************ | |||
************************************************************************/ | |||
#include <math.h> | |||
#include <algorithm> | |||
#include "faust/gui/UI.h" | |||
#include "faust/gui/meta.h" | |||
#include "faust/dsp/dsp.h" | |||
using std::max; | |||
using std::min; | |||
/****************************************************************************** | |||
******************************************************************************* | |||
VECTOR INTRINSICS | |||
******************************************************************************* | |||
*******************************************************************************/ | |||
/****************************************************************************** | |||
******************************************************************************* | |||
ABSTRACT USER INTERFACE | |||
******************************************************************************* | |||
*******************************************************************************/ | |||
//---------------------------------------------------------------------------- | |||
// FAUST generated signal processor | |||
//---------------------------------------------------------------------------- | |||
#ifndef FAUSTFLOAT | |||
#define FAUSTFLOAT float | |||
#endif | |||
#include <cmath> | |||
#include <math.h> | |||
float TemperDsp_faustpower2_f(float value) { | |||
return (value * value); | |||
} | |||
#ifndef FAUSTCLASS | |||
#define FAUSTCLASS TemperDsp | |||
#endif | |||
#ifdef __APPLE__ | |||
#define exp10f __exp10f | |||
#define exp10 __exp10 | |||
#endif | |||
class TemperDsp : public ::dsp { | |||
private: | |||
FAUSTFLOAT fHslider0; | |||
float fRec3[2]; | |||
FAUSTFLOAT fHslider1; | |||
float fRec4[2]; | |||
int fSamplingFreq; | |||
float fConst0; | |||
float fConst1; | |||
FAUSTFLOAT fHslider2; | |||
float fRec6[2]; | |||
FAUSTFLOAT fHslider3; | |||
float fRec7[2]; | |||
float fRec5[3]; | |||
float fConst2; | |||
float fConst3; | |||
float fRec8[2]; | |||
FAUSTFLOAT fHslider4; | |||
float fRec9[2]; | |||
FAUSTFLOAT fHslider5; | |||
float fRec10[2]; | |||
float fVec0[2]; | |||
float fRec2[2]; | |||
float fRec1[2]; | |||
float fRec0[2]; | |||
FAUSTFLOAT fHslider6; | |||
float fRec11[2]; | |||
public: | |||
void metadata(Meta* m) { | |||
m->declare("analyzers.lib/name", "Faust Analyzer Library"); | |||
m->declare("analyzers.lib/version", "0.0"); | |||
m->declare("basics.lib/name", "Faust Basic Element Library"); | |||
m->declare("basics.lib/version", "0.0"); | |||
m->declare("filename", "temper"); | |||
m->declare("filters.lib/name", "Faust Filters Library"); | |||
m->declare("filters.lib/version", "0.0"); | |||
m->declare("maths.lib/author", "GRAME"); | |||
m->declare("maths.lib/copyright", "GRAME"); | |||
m->declare("maths.lib/license", "LGPL with exception"); | |||
m->declare("maths.lib/name", "Faust Math Library"); | |||
m->declare("maths.lib/version", "2.1"); | |||
m->declare("name", "temper"); | |||
m->declare("signals.lib/name", "Faust Signal Routing Library"); | |||
m->declare("signals.lib/version", "0.0"); | |||
} | |||
virtual int getNumInputs() { | |||
return 1; | |||
} | |||
virtual int getNumOutputs() { | |||
return 1; | |||
} | |||
virtual int getInputRate(int channel) { | |||
int rate; | |||
switch (channel) { | |||
case 0: { | |||
rate = 1; | |||
break; | |||
} | |||
default: { | |||
rate = -1; | |||
break; | |||
} | |||
} | |||
return rate; | |||
} | |||
virtual int getOutputRate(int channel) { | |||
int rate; | |||
switch (channel) { | |||
case 0: { | |||
rate = 1; | |||
break; | |||
} | |||
default: { | |||
rate = -1; | |||
break; | |||
} | |||
} | |||
return rate; | |||
} | |||
static void classInit(int samplingFreq) { | |||
} | |||
virtual void instanceConstants(int samplingFreq) { | |||
fSamplingFreq = samplingFreq; | |||
fConst0 = min(192000.0f, max(1.0f, float(fSamplingFreq))); | |||
fConst1 = (3.14159274f / fConst0); | |||
fConst2 = expf((0.0f - (25.0f / fConst0))); | |||
fConst3 = (1.0f - fConst2); | |||
} | |||
virtual void instanceResetUserInterface() { | |||
fHslider0 = FAUSTFLOAT(1.0f); | |||
fHslider1 = FAUSTFLOAT(-60.0f); | |||
fHslider2 = FAUSTFLOAT(20000.0f); | |||
fHslider3 = FAUSTFLOAT(1.0f); | |||
fHslider4 = FAUSTFLOAT(4.0f); | |||
fHslider5 = FAUSTFLOAT(1.0f); | |||
fHslider6 = FAUSTFLOAT(-3.0f); | |||
} | |||
virtual void instanceClear() { | |||
for (int l0 = 0; (l0 < 2); l0 = (l0 + 1)) { | |||
fRec3[l0] = 0.0f; | |||
} | |||
for (int l1 = 0; (l1 < 2); l1 = (l1 + 1)) { | |||
fRec4[l1] = 0.0f; | |||
} | |||
for (int l2 = 0; (l2 < 2); l2 = (l2 + 1)) { | |||
fRec6[l2] = 0.0f; | |||
} | |||
for (int l3 = 0; (l3 < 2); l3 = (l3 + 1)) { | |||
fRec7[l3] = 0.0f; | |||
} | |||
for (int l4 = 0; (l4 < 3); l4 = (l4 + 1)) { | |||
fRec5[l4] = 0.0f; | |||
} | |||
for (int l5 = 0; (l5 < 2); l5 = (l5 + 1)) { | |||
fRec8[l5] = 0.0f; | |||
} | |||
for (int l6 = 0; (l6 < 2); l6 = (l6 + 1)) { | |||
fRec9[l6] = 0.0f; | |||
} | |||
for (int l7 = 0; (l7 < 2); l7 = (l7 + 1)) { | |||
fRec10[l7] = 0.0f; | |||
} | |||
for (int l8 = 0; (l8 < 2); l8 = (l8 + 1)) { | |||
fVec0[l8] = 0.0f; | |||
} | |||
for (int l9 = 0; (l9 < 2); l9 = (l9 + 1)) { | |||
fRec2[l9] = 0.0f; | |||
} | |||
for (int l10 = 0; (l10 < 2); l10 = (l10 + 1)) { | |||
fRec1[l10] = 0.0f; | |||
} | |||
for (int l11 = 0; (l11 < 2); l11 = (l11 + 1)) { | |||
fRec0[l11] = 0.0f; | |||
} | |||
for (int l12 = 0; (l12 < 2); l12 = (l12 + 1)) { | |||
fRec11[l12] = 0.0f; | |||
} | |||
} | |||
virtual void init(int samplingFreq) { | |||
classInit(samplingFreq); | |||
instanceInit(samplingFreq); | |||
} | |||
virtual void instanceInit(int samplingFreq) { | |||
instanceConstants(samplingFreq); | |||
instanceResetUserInterface(); | |||
instanceClear(); | |||
} | |||
virtual TemperDsp* clone() { | |||
return new TemperDsp(); | |||
} | |||
virtual int getSampleRate() { | |||
return fSamplingFreq; | |||
} | |||
virtual void buildUserInterface(UI* ui_interface) { | |||
ui_interface->openVerticalBox("temper"); | |||
ui_interface->addHorizontalSlider("Curve", &fHslider5, 1.0f, 0.100000001f, 4.0f, 0.00100000005f); | |||
ui_interface->addHorizontalSlider("Cutoff", &fHslider2, 20000.0f, 100.0f, 20000.0f, 1.0f); | |||
ui_interface->addHorizontalSlider("Drive", &fHslider4, 4.0f, -10.0f, 10.0f, 0.00100000005f); | |||
ui_interface->addHorizontalSlider("Feedback", &fHslider1, -60.0f, -60.0f, -24.0f, 1.0f); | |||
ui_interface->addHorizontalSlider("Level", &fHslider6, -3.0f, -24.0f, 24.0f, 1.0f); | |||
ui_interface->addHorizontalSlider("Resonance", &fHslider3, 1.0f, 1.0f, 8.0f, 0.00100000005f); | |||
ui_interface->addHorizontalSlider("Saturation", &fHslider0, 1.0f, 0.0f, 1.0f, 0.00100000005f); | |||
ui_interface->closeBox(); | |||
} | |||
virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { | |||
FAUSTFLOAT* input0 = inputs[0]; | |||
FAUSTFLOAT* output0 = outputs[0]; | |||
float fSlow0 = (0.00499999989f * float(fHslider0)); | |||
float fSlow1 = (0.00499999989f * powf(10.0f, (0.0500000007f * float(fHslider1)))); | |||
float fSlow2 = (0.00499999989f / tanf((fConst1 * float(fHslider2)))); | |||
float fSlow3 = (0.00499999989f * float(fHslider3)); | |||
float fSlow4 = (0.00499999989f * float(fHslider4)); | |||
float fSlow5 = (0.00499999989f * float(fHslider5)); | |||
float fSlow6 = (0.00499999989f * powf(10.0f, (0.0500000007f * float(fHslider6)))); | |||
for (int i = 0; (i < count); i = (i + 1)) { | |||
fRec3[0] = (fSlow0 + (0.995000005f * fRec3[1])); | |||
fRec4[0] = (fSlow1 + (0.995000005f * fRec4[1])); | |||
fRec6[0] = (fSlow2 + (0.995000005f * fRec6[1])); | |||
fRec7[0] = (fSlow3 + (0.995000005f * fRec7[1])); | |||
float fTemp0 = (1.0f / fRec7[0]); | |||
float fTemp1 = ((fRec6[0] * (fRec6[0] + fTemp0)) + 1.0f); | |||
fRec5[0] = (float(input0[i]) - (((((fRec6[0] * (fRec6[0] - fTemp0)) + 1.0f) * fRec5[2]) + (2.0f * (fRec5[1] * (1.0f - TemperDsp_faustpower2_f(fRec6[0]))))) / fTemp1)); | |||
float fTemp2 = ((fRec4[0] * fRec0[1]) + (((fRec5[0] + (2.0f * fRec5[1])) + fRec5[2]) / fTemp1)); | |||
float fTemp3 = fabsf(fTemp2); | |||
fRec8[0] = max(fTemp3, ((fConst3 * fTemp3) + (fConst2 * fRec8[1]))); | |||
fRec9[0] = (fSlow4 + (0.995000005f * fRec9[1])); | |||
float fTemp4 = min(3.0f, max(-3.0f, (fRec8[0] + (fRec9[0] * fTemp2)))); | |||
fRec10[0] = (fSlow5 + (0.995000005f * fRec10[1])); | |||
float fTemp5 = TemperDsp_faustpower2_f(fRec10[0]); | |||
float fTemp6 = (TemperDsp_faustpower2_f(fTemp4) * fTemp5); | |||
float fTemp7 = ((fTemp4 * (fTemp6 + 27.0f)) * ((9.0f * fTemp5) + 27.0f)); | |||
float fTemp8 = (((9.0f * fTemp6) + 27.0f) * (fTemp5 + 27.0f)); | |||
float fTemp9 = (((1.0f - fRec3[0]) * fTemp2) + (0.239999995f * ((fTemp7 * fRec3[0]) / fTemp8))); | |||
fVec0[0] = fTemp9; | |||
fRec2[0] = (fVec0[1] + (((0.0f - (0.239999995f * (fTemp7 / fTemp8))) * fRec2[1]) + (0.239999995f * ((fTemp7 * fTemp9) / fTemp8)))); | |||
fRec1[0] = ((fRec2[0] + (0.995000005f * fRec1[1])) - fRec2[1]); | |||
fRec0[0] = fRec1[0]; | |||
fRec11[0] = (fSlow6 + (0.995000005f * fRec11[1])); | |||
output0[i] = FAUSTFLOAT((4.0f * (fRec0[0] * fRec11[0]))); | |||
fRec3[1] = fRec3[0]; | |||
fRec4[1] = fRec4[0]; | |||
fRec6[1] = fRec6[0]; | |||
fRec7[1] = fRec7[0]; | |||
fRec5[2] = fRec5[1]; | |||
fRec5[1] = fRec5[0]; | |||
fRec8[1] = fRec8[0]; | |||
fRec9[1] = fRec9[0]; | |||