Parameters names matches the DX7

pull/1/head
asb2m10 11 years ago
parent 0768632125
commit c6235fd409
  1. 8
      Builds/MacOSX/Dexed.xcodeproj/project.pbxproj
  2. BIN
      Builds/MacOSX/Dexed.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad/UserInterfaceState.xcuserstate
  3. 2
      Builds/VisualStudio2012/Dexed.vcxproj
  4. 6
      Builds/VisualStudio2012/Dexed.vcxproj.filters
  5. 2
      Dexed.jucer
  6. 17
      README.md
  7. 293
      Source/GlobalEditor.cpp
  8. 18
      Source/GlobalEditor.h
  9. 1
      Source/OperatorEditor.cpp
  10. 86
      Source/PluginFx.cpp
  11. 34
      Source/PluginFx.h
  12. 171
      Source/PluginParam.cpp
  13. 35
      Source/PluginParam.h
  14. 5
      Source/PluginProcessor.cpp
  15. 15
      Source/PluginProcessor.h

@ -32,6 +32,7 @@
1CBFE444B43C89E749602B7F = { isa = PBXBuildFile; fileRef = 45ADFD8885BE76C7F7D999AC; }; 1CBFE444B43C89E749602B7F = { isa = PBXBuildFile; fileRef = 45ADFD8885BE76C7F7D999AC; };
478699B4EF80A1A1C0D34C10 = { isa = PBXBuildFile; fileRef = 018D0FB9E97B68D2EB3E3F72; }; 478699B4EF80A1A1C0D34C10 = { isa = PBXBuildFile; fileRef = 018D0FB9E97B68D2EB3E3F72; };
623AFA9E78826CA0136251DF = { isa = PBXBuildFile; fileRef = 59D15F780D468B587F9C7E78; }; 623AFA9E78826CA0136251DF = { isa = PBXBuildFile; fileRef = 59D15F780D468B587F9C7E78; };
B18C192606DF6079E7B9AEB9 = { isa = PBXBuildFile; fileRef = 8BADEB7BF1A65E83A7A1736D; };
1C87DA0B69D67481FC6CF4FD = { isa = PBXBuildFile; fileRef = 54363D0B39B88D43447C0123; }; 1C87DA0B69D67481FC6CF4FD = { isa = PBXBuildFile; fileRef = 54363D0B39B88D43447C0123; };
E3FA856CA4DB2009BB0F13E7 = { isa = PBXBuildFile; fileRef = 505852570B48EB3F18076B03; }; E3FA856CA4DB2009BB0F13E7 = { isa = PBXBuildFile; fileRef = 505852570B48EB3F18076B03; };
7E6DF76EEA834AC1E96470CE = { isa = PBXBuildFile; fileRef = 3254CAE4C282C4432214B016; }; 7E6DF76EEA834AC1E96470CE = { isa = PBXBuildFile; fileRef = 3254CAE4C282C4432214B016; };
@ -487,6 +488,7 @@
8B160A62F6A6EF21379A8EA7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Direct2DGraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; }; 8B160A62F6A6EF21379A8EA7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_Direct2DGraphicsContext.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/native/juce_win32_Direct2DGraphicsContext.cpp"; sourceTree = "SOURCE_ROOT"; };
8B86ECF3351C9D029821C621 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ImageComponent.h"; sourceTree = "SOURCE_ROOT"; }; 8B86ECF3351C9D029821C621 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_ImageComponent.h"; sourceTree = "SOURCE_ROOT"; };
8B87D00DA619D83BA6926E28 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ScopedLock.h"; sourceTree = "SOURCE_ROOT"; }; 8B87D00DA619D83BA6926E28 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ScopedLock.h"; path = "../../JuceLibraryCode/modules/juce_core/threads/juce_ScopedLock.h"; sourceTree = "SOURCE_ROOT"; };
8BADEB7BF1A65E83A7A1736D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = PluginFx.cpp; path = ../../Source/PluginFx.cpp; sourceTree = "SOURCE_ROOT"; };
8BBE375590444CD57A311DD2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Time.h"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_Time.h"; sourceTree = "SOURCE_ROOT"; }; 8BBE375590444CD57A311DD2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Time.h"; path = "../../JuceLibraryCode/modules/juce_core/time/juce_Time.h"; sourceTree = "SOURCE_ROOT"; };
8C4A3CBB322357AF0CA3C2CD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileListComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h"; sourceTree = "SOURCE_ROOT"; }; 8C4A3CBB322357AF0CA3C2CD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileListComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_FileListComponent.h"; sourceTree = "SOURCE_ROOT"; };
8CA96F07FD8390BD5EEC909B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsDisplayComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h"; sourceTree = "SOURCE_ROOT"; }; 8CA96F07FD8390BD5EEC909B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DirectoryContentsDisplayComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.h"; sourceTree = "SOURCE_ROOT"; };
@ -733,6 +735,7 @@
DB3B5F6FE49267EE53089A05 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; }; DB3B5F6FE49267EE53089A05 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../JuceLibraryCode/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
DB9F89D1872247982F4D0913 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableHeaderComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h"; sourceTree = "SOURCE_ROOT"; }; DB9F89D1872247982F4D0913 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TableHeaderComponent.h"; path = "../../JuceLibraryCode/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h"; sourceTree = "SOURCE_ROOT"; };
DBEA78ADC148399D593D22A9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorEditor.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h"; sourceTree = "SOURCE_ROOT"; }; DBEA78ADC148399D593D22A9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AudioProcessorEditor.h"; path = "../../JuceLibraryCode/modules/juce_audio_processors/processors/juce_AudioProcessorEditor.h"; sourceTree = "SOURCE_ROOT"; };
DC75DFCDFCDB425927B11EC0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PluginFx.h; path = ../../Source/PluginFx.h; sourceTree = "SOURCE_ROOT"; };
DD1BF932ABF0CEC81A8B8A3A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicObject.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.h"; sourceTree = "SOURCE_ROOT"; }; DD1BF932ABF0CEC81A8B8A3A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DynamicObject.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_DynamicObject.h"; sourceTree = "SOURCE_ROOT"; };
DD683E5793B347EEB07FB199 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrayAllocationBase.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_ArrayAllocationBase.h"; sourceTree = "SOURCE_ROOT"; }; DD683E5793B347EEB07FB199 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ArrayAllocationBase.h"; path = "../../JuceLibraryCode/modules/juce_core/containers/juce_ArrayAllocationBase.h"; sourceTree = "SOURCE_ROOT"; };
DD9B0DAF1119ECB6FDC0A3AE = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Path.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.cpp"; sourceTree = "SOURCE_ROOT"; }; DD9B0DAF1119ECB6FDC0A3AE = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Path.cpp"; path = "../../JuceLibraryCode/modules/juce_graphics/geometry/juce_Path.cpp"; sourceTree = "SOURCE_ROOT"; };
@ -889,7 +892,9 @@
018D0FB9E97B68D2EB3E3F72, 018D0FB9E97B68D2EB3E3F72,
BD25F7AC4728A7875B6AE9D5, BD25F7AC4728A7875B6AE9D5,
59D15F780D468B587F9C7E78, 59D15F780D468B587F9C7E78,
EA6FC4F1F0D6EAE661569905 ); name = Source; sourceTree = "<group>"; }; EA6FC4F1F0D6EAE661569905,
8BADEB7BF1A65E83A7A1736D,
DC75DFCDFCDB425927B11EC0 ); name = Source; sourceTree = "<group>"; };
C21CEF3B473FDC99270B7623 = { isa = PBXGroup; children = ( C21CEF3B473FDC99270B7623 = { isa = PBXGroup; children = (
F472964B0FFEE5615B72CE3D, F472964B0FFEE5615B72CE3D,
29B923E6EB12F97B68585AFC ); name = Dexed; sourceTree = "<group>"; }; 29B923E6EB12F97B68585AFC ); name = Dexed; sourceTree = "<group>"; };
@ -1942,6 +1947,7 @@
1CBFE444B43C89E749602B7F, 1CBFE444B43C89E749602B7F,
478699B4EF80A1A1C0D34C10, 478699B4EF80A1A1C0D34C10,
623AFA9E78826CA0136251DF, 623AFA9E78826CA0136251DF,
B18C192606DF6079E7B9AEB9,
1C87DA0B69D67481FC6CF4FD, 1C87DA0B69D67481FC6CF4FD,
E3FA856CA4DB2009BB0F13E7, E3FA856CA4DB2009BB0F13E7,
7E6DF76EEA834AC1E96470CE, 7E6DF76EEA834AC1E96470CE,

@ -148,6 +148,7 @@
<ClCompile Include="..\..\Source\PluginProcessor.cpp"/> <ClCompile Include="..\..\Source\PluginProcessor.cpp"/>
<ClCompile Include="..\..\Source\PluginEditor.cpp"/> <ClCompile Include="..\..\Source\PluginEditor.cpp"/>
<ClCompile Include="..\..\Source\PluginParam.cpp"/> <ClCompile Include="..\..\Source\PluginParam.cpp"/>
<ClCompile Include="..\..\Source\PluginFx.cpp"/>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.cpp"> <ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild> <ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile> </ClCompile>
@ -1129,6 +1130,7 @@
<ClInclude Include="..\..\Source\PluginProcessor.h"/> <ClInclude Include="..\..\Source\PluginProcessor.h"/>
<ClInclude Include="..\..\Source\PluginEditor.h"/> <ClInclude Include="..\..\Source\PluginEditor.h"/>
<ClInclude Include="..\..\Source\PluginParam.h"/> <ClInclude Include="..\..\Source\PluginParam.h"/>
<ClInclude Include="..\..\Source\PluginFx.h"/>
<ClInclude Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.h"/> <ClInclude Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.h"/>
<ClInclude Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioSampleBuffer.h"/> <ClInclude Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioSampleBuffer.h"/>
<ClInclude Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_FloatVectorOperations.h"/> <ClInclude Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_FloatVectorOperations.h"/>

@ -313,6 +313,9 @@
<ClCompile Include="..\..\Source\PluginParam.cpp"> <ClCompile Include="..\..\Source\PluginParam.cpp">
<Filter>Dexed\Source</Filter> <Filter>Dexed\Source</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\Source\PluginFx.cpp">
<Filter>Dexed\Source</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.cpp"> <ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.cpp">
<Filter>Juce Modules\juce_audio_basics\buffers</Filter> <Filter>Juce Modules\juce_audio_basics\buffers</Filter>
</ClCompile> </ClCompile>
@ -1437,6 +1440,9 @@
<ClInclude Include="..\..\Source\PluginParam.h"> <ClInclude Include="..\..\Source\PluginParam.h">
<Filter>Dexed\Source</Filter> <Filter>Dexed\Source</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\Source\PluginFx.h">
<Filter>Dexed\Source</Filter>
</ClInclude>
<ClInclude Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.h"> <ClInclude Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.h">
<Filter>Juce Modules\juce_audio_basics\buffers</Filter> <Filter>Juce Modules\juce_audio_basics\buffers</Filter>
</ClInclude> </ClInclude>

@ -57,6 +57,8 @@
<FILE id="lZFsG0" name="PluginEditor.h" compile="0" resource="0" file="Source/PluginEditor.h"/> <FILE id="lZFsG0" name="PluginEditor.h" compile="0" resource="0" file="Source/PluginEditor.h"/>
<FILE id="ZRipB1" name="PluginParam.cpp" compile="1" resource="0" file="Source/PluginParam.cpp"/> <FILE id="ZRipB1" name="PluginParam.cpp" compile="1" resource="0" file="Source/PluginParam.cpp"/>
<FILE id="uqNUvy" name="PluginParam.h" compile="0" resource="0" file="Source/PluginParam.h"/> <FILE id="uqNUvy" name="PluginParam.h" compile="0" resource="0" file="Source/PluginParam.h"/>
<FILE id="bvvgdq" name="PluginFx.cpp" compile="1" resource="0" file="Source/PluginFx.cpp"/>
<FILE id="E4gace" name="PluginFx.h" compile="0" resource="0" file="Source/PluginFx.h"/>
</GROUP> </GROUP>
</MAINGROUP> </MAINGROUP>
<EXPORTFORMATS> <EXPORTFORMATS>

@ -1,7 +1,7 @@
Dexed DX7 Software Emulator Dexed DX7 Software Emulator
=========================== ===========================
Dexed is a multiplatform, multiformat plugin synth that is closely modeled on the Yamaha DX7. Dexed is a multi platform, multiformat plugin synth that is closely modeled on the Yamaha DX7.
Under the hood, it uses [music-synthesizer-for-android](https://code.google.com/p/music-synthesizer-for-android) Under the hood, it uses [music-synthesizer-for-android](https://code.google.com/p/music-synthesizer-for-android)
for the synth engine and [JUCE](http://wwww.juce.com) as a plugin wrapper. for the synth engine and [JUCE](http://wwww.juce.com) as a plugin wrapper.
@ -13,10 +13,21 @@ Binary downloads
It is far from finish but for those who want to try the "music-synthesizer-for-android" project It is far from finish but for those who want to try the "music-synthesizer-for-android" project
on a PC/Mac, you can download it [here](http://le-son666.com/software/dexed) on a PC/Mac, you can download it [here](http://le-son666.com/software/dexed)
(New) Features
--------------
* Multi platform (OS X, Windows, Linux) and multi format (VST, AU); by using JUCE.
* The sound engine [music-synthesizer-for-android](https://code.google.com/p/music-synthesizer-for-android) is closely modeled on the original DX7 characteristics
* All of the 144 DX7 parameters are available from one single panel
* Fully supports DX7 input and output Sysex messages; including controller change. This means that you can use this with a native DX7/TX7 as a patch editor
* Each operator have a realtime VU meter to know wich one is active
* Can load any DX7/TX7 sysex programs [see this](http://www.synprez.com/SynprezFM/) for great collection of DX7 patches (SynprezFM-II-builtins.tgz)
TODO - Dexed TODO - Dexed
------------ ------------
* Make all the knobs actually work * Implement a better DX look and feel
* Implement the DX look and feel * Better implementation of the LPF filter
* Better display of the amplitude envelope
* Implement a display of the algo
TODO - msfa TODO - msfa
----------- -----------

@ -50,7 +50,7 @@ GlobalEditor::GlobalEditor ()
addAndMakeVisible (lfoSpeed = new Slider ("lfoSpeed")); addAndMakeVisible (lfoSpeed = new Slider ("lfoSpeed"));
lfoSpeed->setRange (0, 99, 1); lfoSpeed->setRange (0, 99, 1);
lfoSpeed->setSliderStyle (Slider::LinearVertical); lfoSpeed->setSliderStyle (Slider::LinearHorizontal);
lfoSpeed->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); lfoSpeed->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
lfoSpeed->addListener (this); lfoSpeed->addListener (this);
@ -68,18 +68,18 @@ GlobalEditor::GlobalEditor ()
addAndMakeVisible (lfoDelay = new Slider ("lfoDelay")); addAndMakeVisible (lfoDelay = new Slider ("lfoDelay"));
lfoDelay->setRange (0, 99, 1); lfoDelay->setRange (0, 99, 1);
lfoDelay->setSliderStyle (Slider::LinearVertical); lfoDelay->setSliderStyle (Slider::Rotary);
lfoDelay->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); lfoDelay->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
lfoDelay->addListener (this); lfoDelay->addListener (this);
addAndMakeVisible (cutoff = new Slider ("cutoff")); addAndMakeVisible (cutoff = new Slider ("cutoff"));
cutoff->setRange (0, 10, 0); cutoff->setRange (0, 1, 0);
cutoff->setSliderStyle (Slider::Rotary); cutoff->setSliderStyle (Slider::Rotary);
cutoff->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); cutoff->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
cutoff->addListener (this); cutoff->addListener (this);
addAndMakeVisible (reso = new Slider ("reso")); addAndMakeVisible (reso = new Slider ("reso"));
reso->setRange (0, 10, 0); reso->setRange (0, 1, 0);
reso->setSliderStyle (Slider::Rotary); reso->setSliderStyle (Slider::Rotary);
reso->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); reso->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
reso->addListener (this); reso->addListener (this);
@ -87,6 +87,78 @@ GlobalEditor::GlobalEditor ()
addAndMakeVisible (algoDisplay = new AlgoDisplay()); addAndMakeVisible (algoDisplay = new AlgoDisplay());
algoDisplay->setName ("algoDisplay"); algoDisplay->setName ("algoDisplay");
addAndMakeVisible (pitchRate2 = new Slider ("pitchRate2"));
pitchRate2->setRange (0, 99, 1);
pitchRate2->setSliderStyle (Slider::Rotary);
pitchRate2->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
pitchRate2->addListener (this);
addAndMakeVisible (pitchRate3 = new Slider ("pitchRate3"));
pitchRate3->setRange (0, 99, 1);
pitchRate3->setSliderStyle (Slider::Rotary);
pitchRate3->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
pitchRate3->addListener (this);
addAndMakeVisible (pitchRate4 = new Slider ("pitchRate4"));
pitchRate4->setRange (0, 99, 1);
pitchRate4->setSliderStyle (Slider::Rotary);
pitchRate4->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
pitchRate4->addListener (this);
addAndMakeVisible (pitchRate1 = new Slider ("pitchRate1"));
pitchRate1->setRange (0, 99, 1);
pitchRate1->setSliderStyle (Slider::Rotary);
pitchRate1->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
pitchRate1->addListener (this);
addAndMakeVisible (pitchLevel2 = new Slider ("pitchLevel2"));
pitchLevel2->setRange (0, 99, 1);
pitchLevel2->setSliderStyle (Slider::Rotary);
pitchLevel2->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
pitchLevel2->addListener (this);
addAndMakeVisible (pitchLevel3 = new Slider ("pitchLevel3"));
pitchLevel3->setRange (0, 99, 1);
pitchLevel3->setSliderStyle (Slider::Rotary);
pitchLevel3->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
pitchLevel3->addListener (this);
addAndMakeVisible (pitchLevel4 = new Slider ("pitchLevel4"));
pitchLevel4->setRange (0, 99, 1);
pitchLevel4->setSliderStyle (Slider::Rotary);
pitchLevel4->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
pitchLevel4->addListener (this);
addAndMakeVisible (pitchLevel1 = new Slider ("pitchLevel1"));
pitchLevel1->setRange (0, 99, 1);
pitchLevel1->setSliderStyle (Slider::Rotary);
pitchLevel1->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
pitchLevel1->addListener (this);
addAndMakeVisible (feedback = new Slider ("feedback"));
feedback->setRange (0, 7, 1);
feedback->setSliderStyle (Slider::Rotary);
feedback->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
feedback->addListener (this);
addAndMakeVisible (transpose = new Slider ("transpose"));
transpose->setRange (0, 49, 0);
transpose->setSliderStyle (Slider::LinearVertical);
transpose->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
transpose->addListener (this);
addAndMakeVisible (oscSync = new ToggleButton ("oscSync"));
oscSync->setButtonText (String::empty);
addAndMakeVisible (pitchModSens = new Slider ("pitchModSens"));
pitchModSens->setRange (0, 7, 0);
pitchModSens->setSliderStyle (Slider::Rotary);
pitchModSens->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
pitchModSens->addListener (this);
addAndMakeVisible (lfoSync = new ToggleButton ("lfoSync"));
lfoSync->setButtonText (String::empty);
//[UserPreSize] //[UserPreSize]
//[/UserPreSize] //[/UserPreSize]
@ -95,6 +167,8 @@ GlobalEditor::GlobalEditor ()
//[Constructor] You can add your own custom stuff here.. //[Constructor] You can add your own custom stuff here..
systemMsg << "* DEXED DX synthesizer *";
//[/Constructor] //[/Constructor]
} }
@ -112,6 +186,19 @@ GlobalEditor::~GlobalEditor()
cutoff = nullptr; cutoff = nullptr;
reso = nullptr; reso = nullptr;
algoDisplay = nullptr; algoDisplay = nullptr;
pitchRate2 = nullptr;
pitchRate3 = nullptr;
pitchRate4 = nullptr;
pitchRate1 = nullptr;
pitchLevel2 = nullptr;
pitchLevel3 = nullptr;
pitchLevel4 = nullptr;
pitchLevel1 = nullptr;
feedback = nullptr;
transpose = nullptr;
oscSync = nullptr;
pitchModSens = nullptr;
lfoSync = nullptr;
//[Destructor]. You can add your own custom destruction code here.. //[Destructor]. You can add your own custom destruction code here..
@ -125,20 +212,44 @@ void GlobalEditor::paint (Graphics& g)
//[/UserPrePaint] //[/UserPrePaint]
//[UserPaint] Add your own custom painting code here.. //[UserPaint] Add your own custom painting code here..
g.setColour (Colours::black);
g.setFont (Font (Font::getDefaultMonospacedFontName(), 15.00f, Font::plain));
g.drawText (systemMsg,
11, 8, 300, 8,
Justification::centredLeft, true);
g.setColour (Colours::black);
g.setFont (Font (Font::getDefaultMonospacedFontName(), 15.00f, Font::plain));
g.drawText (paramMsg,
11, 24, 300, 8,
Justification::centredLeft, true);
//[/UserPaint] //[/UserPaint]
} }
void GlobalEditor::resized() void GlobalEditor::resized()
{ {
algo->setBounds (784, 48, 64, 24); algo->setBounds (480, 64, 80, 24);
lfoType->setBounds (768, 8, 80, 16); lfoType->setBounds (624, 40, 96, 16);
lfoSpeed->setBounds (712, 0, 23, 80); lfoSpeed->setBounds (624, 16, 96, 16);
lfoAmDepth->setBounds (816, 24, 32, 24); lfoAmDepth->setBounds (696, 64, 24, 24);
lfoPitchDepth->setBounds (792, 24, 32, 24); lfoPitchDepth->setBounds (648, 64, 24, 24);
lfoDelay->setBounds (736, 0, 23, 80); lfoDelay->setBounds (672, 64, 24, 24);
cutoff->setBounds (176, 40, 48, 48); cutoff->setBounds (8, 40, 48, 48);
reso->setBounds (232, 40, 48, 48); reso->setBounds (64, 40, 48, 48);
algoDisplay->setBounds (8, 8, 150, 72); algoDisplay->setBounds (480, 8, 126, 56);
pitchRate2->setBounds (776, 64, 32, 24);
pitchRate3->setBounds (800, 64, 32, 24);
pitchRate4->setBounds (824, 64, 32, 24);
pitchRate1->setBounds (752, 64, 32, 24);
pitchLevel2->setBounds (776, 40, 32, 24);
pitchLevel3->setBounds (800, 40, 32, 24);
pitchLevel4->setBounds (824, 40, 32, 24);
pitchLevel1->setBounds (752, 40, 32, 24);
feedback->setBounds (560, 64, 24, 24);
transpose->setBounds (728, 0, 24, 56);
oscSync->setBounds (584, 64, 24, 24);
pitchModSens->setBounds (728, 64, 24, 24);
lfoSync->setBounds (624, 64, 24, 24);
//[UserResized] Add your own custom resize handling here.. //[UserResized] Add your own custom resize handling here..
//[/UserResized] //[/UserResized]
} }
@ -183,6 +294,61 @@ void GlobalEditor::sliderValueChanged (Slider* sliderThatWasMoved)
//[UserSliderCode_reso] -- add your slider handling code here.. //[UserSliderCode_reso] -- add your slider handling code here..
//[/UserSliderCode_reso] //[/UserSliderCode_reso]
} }
else if (sliderThatWasMoved == pitchRate2)
{
//[UserSliderCode_pitchRate2] -- add your slider handling code here..
//[/UserSliderCode_pitchRate2]
}
else if (sliderThatWasMoved == pitchRate3)
{
//[UserSliderCode_pitchRate3] -- add your slider handling code here..
//[/UserSliderCode_pitchRate3]
}
else if (sliderThatWasMoved == pitchRate4)
{
//[UserSliderCode_pitchRate4] -- add your slider handling code here..
//[/UserSliderCode_pitchRate4]
}
else if (sliderThatWasMoved == pitchRate1)
{
//[UserSliderCode_pitchRate1] -- add your slider handling code here..
//[/UserSliderCode_pitchRate1]
}
else if (sliderThatWasMoved == pitchLevel2)
{
//[UserSliderCode_pitchLevel2] -- add your slider handling code here..
//[/UserSliderCode_pitchLevel2]
}
else if (sliderThatWasMoved == pitchLevel3)
{
//[UserSliderCode_pitchLevel3] -- add your slider handling code here..
//[/UserSliderCode_pitchLevel3]
}
else if (sliderThatWasMoved == pitchLevel4)
{
//[UserSliderCode_pitchLevel4] -- add your slider handling code here..
//[/UserSliderCode_pitchLevel4]
}
else if (sliderThatWasMoved == pitchLevel1)
{
//[UserSliderCode_pitchLevel1] -- add your slider handling code here..
//[/UserSliderCode_pitchLevel1]
}
else if (sliderThatWasMoved == feedback)
{
//[UserSliderCode_feedback] -- add your slider handling code here..
//[/UserSliderCode_feedback]
}
else if (sliderThatWasMoved == transpose)
{
//[UserSliderCode_transpose] -- add your slider handling code here..
//[/UserSliderCode_transpose]
}
else if (sliderThatWasMoved == pitchModSens)
{
//[UserSliderCode_pitchModSens] -- add your slider handling code here..
//[/UserSliderCode_pitchModSens]
}
//[UsersliderValueChanged_Post] //[UsersliderValueChanged_Post]
//[/UsersliderValueChanged_Post] //[/UsersliderValueChanged_Post]
@ -214,7 +380,32 @@ void GlobalEditor::bind(DexedAudioProcessor *parent) {
parent->lfoWaveform->bind(lfoType); parent->lfoWaveform->bind(lfoType);
parent->lfoAmpDepth->bind(lfoAmDepth); parent->lfoAmpDepth->bind(lfoAmDepth);
parent->lfoPitchDepth->bind(lfoPitchDepth); parent->lfoPitchDepth->bind(lfoPitchDepth);
processor = parent; parent->lfoSync->bind(lfoSync);
parent->oscSync->bind(oscSync);
parent->transpose->bind(transpose);
parent->feedback->bind(feedback);
parent->pitchModSens->bind(pitchModSens);
parent->pitchEgLevel[0]->bind(pitchLevel1);
parent->pitchEgLevel[1]->bind(pitchLevel2);
parent->pitchEgLevel[2]->bind(pitchLevel3);
parent->pitchEgLevel[3]->bind(pitchLevel4);
parent->pitchEgRate[0]->bind(pitchRate1);
parent->pitchEgRate[1]->bind(pitchRate2);
parent->pitchEgRate[2]->bind(pitchRate3);
parent->pitchEgRate[3]->bind(pitchRate4);
parent->fxCutoff->bind(cutoff);
parent->fxReso->bind(reso);
processor = parent;
}
void GlobalEditor::setSystemMessage(String msg) {
systemMsg = msg;
repaint();
}
void GlobalEditor::setParamMessage(String msg) {
paramMsg = msg;
repaint();
} }
//[/MiscUserCode] //[/MiscUserCode]
@ -235,40 +426,90 @@ BEGIN_JUCER_METADATA
fixedSize="1" initialWidth="855" initialHeight="90"> fixedSize="1" initialWidth="855" initialHeight="90">
<BACKGROUND backgroundColour="ffffff"/> <BACKGROUND backgroundColour="ffffff"/>
<SLIDER name="algo" id="8a226ddf9bbff752" memberName="algo" virtualName="" <SLIDER name="algo" id="8a226ddf9bbff752" memberName="algo" virtualName=""
explicitFocusOrder="0" pos="784 48 64 24" min="1" max="32" int="1" explicitFocusOrder="0" pos="480 64 80 24" min="1" max="32" int="1"
style="Rotary" textBoxPos="TextBoxLeft" textBoxEditable="0" textBoxWidth="80" style="Rotary" textBoxPos="TextBoxLeft" textBoxEditable="0" textBoxWidth="80"
textBoxHeight="20" skewFactor="1"/> textBoxHeight="20" skewFactor="1"/>
<COMBOBOX name="new combo box" id="31018596af3b34e9" memberName="lfoType" <COMBOBOX name="new combo box" id="31018596af3b34e9" memberName="lfoType"
virtualName="" explicitFocusOrder="0" pos="768 8 80 16" editable="0" virtualName="" explicitFocusOrder="0" pos="624 40 96 16" editable="0"
layout="33" items="TRIANGLE&#10;SAW DOWN&#10;SAW UP&#10;SQUARE&#10;SINE&#10;S&amp;HOLD" layout="33" items="TRIANGLE&#10;SAW DOWN&#10;SAW UP&#10;SQUARE&#10;SINE&#10;S&amp;HOLD"
textWhenNonSelected="" textWhenNoItems="(no choices)"/> textWhenNonSelected="" textWhenNoItems="(no choices)"/>
<SLIDER name="lfoSpeed" id="b10eaf327ab3bff5" memberName="lfoSpeed" virtualName="" <SLIDER name="lfoSpeed" id="b10eaf327ab3bff5" memberName="lfoSpeed" virtualName=""
explicitFocusOrder="0" pos="712 0 23 80" min="0" max="99" int="1" explicitFocusOrder="0" pos="624 16 96 16" min="0" max="99" int="1"
style="LinearVertical" textBoxPos="NoTextBox" textBoxEditable="1" style="LinearHorizontal" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="new slider" id="3e95a6206fa4a891" memberName="lfoAmDepth" <SLIDER name="new slider" id="3e95a6206fa4a891" memberName="lfoAmDepth"
virtualName="" explicitFocusOrder="0" pos="816 24 32 24" min="0" virtualName="" explicitFocusOrder="0" pos="696 64 24 24" min="0"
max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1" max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="new slider" id="6ead769ca786c813" memberName="lfoPitchDepth" <SLIDER name="new slider" id="6ead769ca786c813" memberName="lfoPitchDepth"
virtualName="" explicitFocusOrder="0" pos="792 24 32 24" min="0" virtualName="" explicitFocusOrder="0" pos="648 64 24 24" min="0"
max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1" max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="lfoDelay" id="1fce68dc81619ef5" memberName="lfoDelay" virtualName="" <SLIDER name="lfoDelay" id="1fce68dc81619ef5" memberName="lfoDelay" virtualName=""
explicitFocusOrder="0" pos="736 0 23 80" min="0" max="99" int="1" explicitFocusOrder="0" pos="672 64 24 24" min="0" max="99" int="1"
style="LinearVertical" textBoxPos="NoTextBox" textBoxEditable="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1" textBoxWidth="80"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/> textBoxHeight="20" skewFactor="1"/>
<SLIDER name="cutoff" id="40531f16bb0bd225" memberName="cutoff" virtualName="" <SLIDER name="cutoff" id="40531f16bb0bd225" memberName="cutoff" virtualName=""
explicitFocusOrder="0" pos="176 40 48 48" min="0" max="10" int="0" explicitFocusOrder="0" pos="8 40 48 48" min="0" max="1" int="0"
style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1" textBoxWidth="80" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1" textBoxWidth="80"
textBoxHeight="20" skewFactor="1"/> textBoxHeight="20" skewFactor="1"/>
<SLIDER name="reso" id="c8c13464e81a8d83" memberName="reso" virtualName="" <SLIDER name="reso" id="c8c13464e81a8d83" memberName="reso" virtualName=""
explicitFocusOrder="0" pos="232 40 48 48" min="0" max="10" int="0" explicitFocusOrder="0" pos="64 40 48 48" min="0" max="1" int="0"
style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1" textBoxWidth="80" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1" textBoxWidth="80"
textBoxHeight="20" skewFactor="1"/> textBoxHeight="20" skewFactor="1"/>
<GENERICCOMPONENT name="algoDisplay" id="b26fb9e3b5f0bc37" memberName="algoDisplay" <GENERICCOMPONENT name="algoDisplay" id="b26fb9e3b5f0bc37" memberName="algoDisplay"
virtualName="" explicitFocusOrder="0" pos="8 8 150 72" class="AlgoDisplay" virtualName="" explicitFocusOrder="0" pos="480 8 126 56" class="AlgoDisplay"
params=""/> params=""/>
<SLIDER name="pitchRate2" id="73f386b3c91d3de4" memberName="pitchRate2"
virtualName="" explicitFocusOrder="0" pos="776 64 32 24" min="0"
max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="pitchRate3" id="187c25b24413fccf" memberName="pitchRate3"
virtualName="" explicitFocusOrder="0" pos="800 64 32 24" min="0"
max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="pitchRate4" id="1aeb2a8fbbcbeaab" memberName="pitchRate4"
virtualName="" explicitFocusOrder="0" pos="824 64 32 24" min="0"
max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="pitchRate1" id="419d613b3fb9604e" memberName="pitchRate1"
virtualName="" explicitFocusOrder="0" pos="752 64 32 24" min="0"
max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="pitchLevel2" id="3a355ad2221887d9" memberName="pitchLevel2"
virtualName="" explicitFocusOrder="0" pos="776 40 32 24" min="0"
max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="pitchLevel3" id="5c5d782e8a7f3ad7" memberName="pitchLevel3"
virtualName="" explicitFocusOrder="0" pos="800 40 32 24" min="0"
max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="pitchLevel4" id="eb900b141fbad8ff" memberName="pitchLevel4"
virtualName="" explicitFocusOrder="0" pos="824 40 32 24" min="0"
max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="pitchLevel1" id="344cbe26ec9fa128" memberName="pitchLevel1"
virtualName="" explicitFocusOrder="0" pos="752 40 32 24" min="0"
max="99" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="feedback" id="4fac1940c29ab8c" memberName="feedback" virtualName=""
explicitFocusOrder="0" pos="560 64 24 24" min="0" max="7" int="1"
style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1" textBoxWidth="80"
textBoxHeight="20" skewFactor="1"/>
<SLIDER name="transpose" id="7d1266b1c1534947" memberName="transpose"
virtualName="" explicitFocusOrder="0" pos="728 0 24 56" min="0"
max="49" int="0" style="LinearVertical" textBoxPos="NoTextBox"
textBoxEditable="1" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<TOGGLEBUTTON name="oscSync" id="8f3fe641537cd00" memberName="oscSync" virtualName=""
explicitFocusOrder="0" pos="584 64 24 24" buttonText="" connectedEdges="0"
needsCallback="0" radioGroupId="0" state="0"/>
<SLIDER name="pitchModSens" id="904f73df85a9f886" memberName="pitchModSens"
virtualName="" explicitFocusOrder="0" pos="728 64 24 24" min="0"
max="7" int="0" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<TOGGLEBUTTON name="lfoSync" id="ff92bb0a5a4f7187" memberName="lfoSync" virtualName=""
explicitFocusOrder="0" pos="624 64 24 24" buttonText="" connectedEdges="0"
needsCallback="0" radioGroupId="0" state="0"/>
</JUCER_COMPONENT> </JUCER_COMPONENT>
END_JUCER_METADATA END_JUCER_METADATA

@ -47,8 +47,9 @@ public:
//============================================================================== //==============================================================================
//[UserMethods] -- You can add your own custom methods in this section. //[UserMethods] -- You can add your own custom methods in this section.
void bind(DexedAudioProcessor *processor); void bind(DexedAudioProcessor *processor);
void setSystemMessage(String msg);
void setParamMessage(String msg);
//[/UserMethods] //[/UserMethods]
void paint (Graphics& g); void paint (Graphics& g);
@ -61,6 +62,8 @@ public:
private: private:
//[UserVariables] -- You can add your own custom variables in this section. //[UserVariables] -- You can add your own custom variables in this section.
DexedAudioProcessor *processor; DexedAudioProcessor *processor;
String systemMsg;
String paramMsg;
//[/UserVariables] //[/UserVariables]
//============================================================================== //==============================================================================
@ -73,6 +76,19 @@ private:
ScopedPointer<Slider> cutoff; ScopedPointer<Slider> cutoff;
ScopedPointer<Slider> reso; ScopedPointer<Slider> reso;
ScopedPointer<AlgoDisplay> algoDisplay; ScopedPointer<AlgoDisplay> algoDisplay;
ScopedPointer<Slider> pitchRate2;
ScopedPointer<Slider> pitchRate3;
ScopedPointer<Slider> pitchRate4;
ScopedPointer<Slider> pitchRate1;
ScopedPointer<Slider> pitchLevel2;
ScopedPointer<Slider> pitchLevel3;
ScopedPointer<Slider> pitchLevel4;
ScopedPointer<Slider> pitchLevel1;
ScopedPointer<Slider> feedback;
ScopedPointer<Slider> transpose;
ScopedPointer<ToggleButton> oscSync;
ScopedPointer<Slider> pitchModSens;
ScopedPointer<ToggleButton> lfoSync;
//============================================================================== //==============================================================================

@ -462,6 +462,7 @@ void OperatorEditor::bind(DexedAudioProcessor *parent, int op) {
parent->opCtrl[op].sclRightCurve->bind(kbdRightCurve); parent->opCtrl[op].sclRightCurve->bind(kbdRightCurve);
parent->opCtrl[op].sclLeftDepth->bind(sclLeftLevel); parent->opCtrl[op].sclLeftDepth->bind(sclLeftLevel);
parent->opCtrl[op].sclRightDepth->bind(sclRightLevel); parent->opCtrl[op].sclRightDepth->bind(sclRightLevel);
parent->opCtrl[op].sclRate->bind(sclRateScaling);
} }

@ -0,0 +1,86 @@
/*
==============================================================================
PluginFx.cpp
Created: 26 Dec 2013 7:13:29pm
Author: Pascal Gauthier
The LPF is taken from the PD moog~ object. (David Lowenfels)
Code is based off of Tim Stilson's moog filter code
==============================================================================
*/
#include "math.h"
#include "PluginFx.h"
static float gaintable[199] = {
0.999969, 0.990082, 0.980347, 0.970764, 0.961304, 0.951996, 0.94281, 0.933777, 0.924866, 0.916077, 0.90741, 0.898865, 0.890442,
0.882141, 0.873962, 0.865906, 0.857941, 0.850067, 0.842346, 0.834686, 0.827148, 0.819733, 0.812378, 0.805145, 0.798004, 0.790955,
0.783997, 0.77713, 0.770355, 0.763672, 0.75708 , 0.75058, 0.744141, 0.737793, 0.731537, 0.725342, 0.719238, 0.713196, 0.707245,
0.701355, 0.695557, 0.689819, 0.684174, 0.678558, 0.673035, 0.667572, 0.66217, 0.65686, 0.651581, 0.646393, 0.641235, 0.636169,
0.631134, 0.62619, 0.621277, 0.616425, 0.611633, 0.606903, 0.602234, 0.597626, 0.593048, 0.588531, 0.584045, 0.579651, 0.575287,
0.570953, 0.566681, 0.562469, 0.558289, 0.554169, 0.550079, 0.546051, 0.542053, 0.538116, 0.53421, 0.530334, 0.52652, 0.522736,
0.518982, 0.515289, 0.511627, 0.507996 , 0.504425, 0.500885, 0.497375, 0.493896, 0.490448, 0.487061, 0.483704, 0.480377, 0.477081,
0.473816, 0.470581, 0.467377, 0.464203, 0.46109, 0.457977, 0.454926, 0.451874, 0.448883, 0.445892, 0.442932, 0.440033, 0.437134,
0.434265, 0.431427, 0.428619, 0.425842, 0.423096, 0.42038, 0.417664, 0.415009, 0.412354, 0.409729, 0.407135, 0.404572, 0.402008,
0.399506, 0.397003, 0.394501, 0.392059, 0.389618, 0.387207, 0.384827, 0.382477, 0.380127, 0.377808, 0.375488, 0.37323, 0.370972,
0.368713, 0.366516, 0.364319, 0.362122, 0.359985, 0.357849, 0.355713, 0.353607, 0.351532, 0.349457, 0.347412, 0.345398, 0.343384,
0.34137, 0.339417, 0.337463, 0.33551, 0.333588, 0.331665, 0.329773, 0.327911, 0.32605, 0.324188, 0.322357, 0.320557, 0.318756,
0.316986, 0.315216, 0.313446, 0.311707, 0.309998, 0.308289, 0.30658, 0.304901, 0.303223, 0.301575, 0.299927, 0.298309, 0.296692,
0.295074, 0.293488, 0.291931, 0.290375, 0.288818, 0.287262, 0.285736, 0.284241, 0.282715, 0.28125, 0.279755, 0.27829, 0.276825,
0.275391, 0.273956, 0.272552, 0.271118, 0.269745, 0.268341, 0.266968, 0.265594, 0.264252, 0.262909, 0.261566, 0.260223, 0.258911,
0.257599, 0.256317, 0.255035, 0.25375
};
static inline float saturate(float input) { //clamp without branching
#define _limit 0.95
float x1 = fabsf( input + _limit );
float x2 = fabsf( input - _limit );
return 0.5 * (x1 - x2);
}
static inline float crossfade(float amount, float a, float b) {
return (1-amount) * a + amount * b;
}
void PluginFx::init(int sampleRate) {
srate = sampleRate;
output = 0;
for(int i=0;i<4;i++)
state[i] = 0;
}
void PluginFx::process(float *work, int sampleSize) {
// the UI values haved changed
if ( uiCutoff != pCutoff || uiReso != pReso) {
// calc cutoff
float freqCutoff = uiCutoff * 22000;
float fc = 2 * freqCutoff / srate;
float x2 = fc*fc;
float x3 = fc*x2;
p = -0.69346 * x3 - 0.59515 * x2 + 3.2937 * fc - 1.0072; //cubic fit
// calc reso
float ix = p * 99;
int ixint = floor( ix );
float ixfrac = ix - ixint;
Q = uiReso * crossfade( ixfrac, gaintable[ ixint + 99 ], gaintable[ ixint + 100 ] );
pCutoff = uiCutoff;
pReso = uiReso;
}
for (int i=0; i < sampleSize; i++ ) {
output = 0.25 * ( work[i] - output ); //negative feedback
for(int pole=0; pole < 4; pole++) {
float temp = state[pole];
output = saturate( output + p * (output - temp));
state[pole] = output;
output = saturate( output + temp );
}
work[i] = output;
output *= Q; //scale the feedback
}
}

@ -0,0 +1,34 @@
/*
==============================================================================
PluginFx.h
Created: 26 Dec 2013 7:13:29pm
Author: Pascal Gauthier
==============================================================================
*/
#ifndef PLUGINFX_H_INCLUDED
#define PLUGINFX_H_INCLUDED
class PluginFx {
/**
* Used for the 4pole LFP
*/
// process and ui values
float pReso;
float pCutoff;
float p, Q;
int srate;
float state[4];
float output = 0;
public:
float uiCutoff = 0;
float uiReso = 0;
void init(int sampleRate);
void process(float *work, int sampleSize);
};
#endif // PLUGINFX_H_INCLUDED

@ -20,6 +20,7 @@
#include "PluginParam.h" #include "PluginParam.h"
#include "PluginProcessor.h" #include "PluginProcessor.h"
#include "PluginEditor.h"
// ************************************************************************ // ************************************************************************
// //
@ -65,21 +66,64 @@ void Ctrl::unbind() {
} }
} }
void Ctrl::publishValue(float value) {
parent->beginParameterChangeGesture(idx);
parent->setParameterNotifyingHost(idx, value);
parent->endParameterChangeGesture(idx);
}
void Ctrl::sliderValueChanged(Slider* moved) {
publishValue(moved->getValue());
}
void Ctrl::buttonClicked(Button* clicked) {
publishValue(clicked->getToggleStateValue() == 1 ? 1 : 0);
}
void Ctrl::comboBoxChanged(ComboBox* combo) {
publishValue((combo->getSelectedId() - 1) / combo->getNumItems());
}
// ************************************************************************
// CtrlDX - control DX mapping
CtrlFloat::CtrlFloat(String name, float *storageValue) : Ctrl(name) {
vPointer = storageValue;
}
float CtrlFloat::getValueHost() {
return *vPointer;
}
void CtrlFloat::setValueHost(float v) {
*vPointer = v;
}
String CtrlFloat::getValueDisplay() {
String display;
display << *vPointer;
return display;
}
void CtrlFloat::updateComponent() {
if (slider != NULL) {
slider->setValue(*vPointer, NotificationType::dontSendNotification);
}
}
// ************************************************************************ // ************************************************************************
// CtrlInt ================================================================ // CtrlDX - control DX mapping
CtrlDX::CtrlDX(String name, int steps, int offset, bool starts1) : CtrlDX::CtrlDX(String name, int steps, int offset, bool starts1) : Ctrl(name) {
Ctrl(name) {
add1 = starts1 == 1; add1 = starts1 == 1;
this->steps = steps; this->steps = steps;
value = 0; dxValue = 0;
dxOffset = offset; dxOffset = offset;
} }
float CtrlDX::getValuePlugin() { float CtrlDX::getValueHost() {
return value / steps; return dxValue / steps;
} }
void CtrlDX::setValuePlugin(float f) { void CtrlDX::setValueHost(float f) {
setValue((f * steps)); setValue((f * steps));
} }
@ -88,7 +132,7 @@ void CtrlDX::setValue(int v) {
TRACE("WARNING: value too big %s : %d", label.toRawUTF8(), v); TRACE("WARNING: value too big %s : %d", label.toRawUTF8(), v);
v = steps - 1; v = steps - 1;
} }
value = v; dxValue = v;
if (dxOffset >= 0) { if (dxOffset >= 0) {
if (parent != NULL) if (parent != NULL)
parent->setDxValue(dxOffset, v); parent->setDxValue(dxOffset, v);
@ -97,36 +141,36 @@ void CtrlDX::setValue(int v) {
int CtrlDX::getValue() { int CtrlDX::getValue() {
if (dxOffset >= 0) if (dxOffset >= 0)
value = parent->data[dxOffset]; dxValue = parent->data[dxOffset];
return value; return dxValue;
} }
String CtrlDX::getValueDisplay() { String CtrlDX::getValueDisplay() {
String ret; String ret;
ret << getValue(); ret << ( getValue() + add1 );
return ret; return ret;
} }
void CtrlDX::publishValue(int value) { void CtrlDX::publishValue(float value) {
parent->beginParameterChangeGesture(idx); Ctrl::publishValue(value / steps);
parent->setParameterNotifyingHost(idx, (((float) value) / steps));
parent->endParameterChangeGesture(idx); DexedAudioProcessorEditor *editor = (DexedAudioProcessorEditor *) parent->getActiveEditor();
if ( editor == NULL )
return;
String msg;
msg << label << " = " << getValueDisplay();
editor->global.setParamMessage(msg);
} }
void CtrlDX::sliderValueChanged(Slider* moved) { void CtrlDX::sliderValueChanged(Slider* moved) {
publishValue(((int) moved->getValue() - add1)); publishValue(((int) moved->getValue() - add1));
} }
void CtrlDX::buttonClicked(Button* clicked) {
publishValue(clicked->getToggleStateValue() == 1 ? 1 : 0);
}
void CtrlDX::comboBoxChanged(ComboBox* combo) { void CtrlDX::comboBoxChanged(ComboBox* combo) {
publishValue(combo->getSelectedId() - 1); publishValue(combo->getSelectedId() - 1);
} }
void CtrlDX::updateComponent() { void CtrlDX::updateComponent() {
//TRACE("setting for %s %d", label.toRawUTF8(), getValue());
if (slider != NULL) { if (slider != NULL) {
slider->setValue(getValue() + add1, slider->setValue(getValue() + add1,
NotificationType::dontSendNotification); NotificationType::dontSendNotification);
@ -151,11 +195,18 @@ void CtrlDX::updateComponent() {
} }
} }
// ************************************************************************ /***************************************************************
// Patcher ================================================================ *
*/
void DexedAudioProcessor::initCtrl() { void DexedAudioProcessor::initCtrl() {
importSysex(BinaryData::startup_syx); importSysex(BinaryData::startup_syx);
fxCutoff = new CtrlFloat("Cutoff", &fx.uiCutoff);
ctrl.add(fxCutoff);
fxReso = new CtrlFloat("Resonance", &fx.uiReso);
ctrl.add(fxReso);
// fill operator values; // fill operator values;
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
//// In the Sysex, OP6 comes first, then OP5... //// In the Sysex, OP6 comes first, then OP5...
@ -167,107 +218,129 @@ void DexedAudioProcessor::initCtrl() {
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
String opRate; String opRate;
opRate << opName << "-EGR" << (j + 1); opRate << opName << " EGR" << (j + 1);
opCtrl[opVal].egRate[j] = new CtrlDX(opRate, 100, opTarget + j); opCtrl[opVal].egRate[j] = new CtrlDX(opRate, 100, opTarget + j);
ctrl.add(opCtrl[opVal].egRate[j]); ctrl.add(opCtrl[opVal].egRate[j]);
String opLevel; String opLevel;
opLevel << opName << "-EGL" << (j + 1); opLevel << opName << " EGL" << (j + 1);
opCtrl[opVal].egLevel[j] = new CtrlDX(opLevel, 100, opCtrl[opVal].egLevel[j] = new CtrlDX(opLevel, 100, opTarget + j + 4);
opTarget + j + 4);
ctrl.add(opCtrl[opVal].egLevel[j]); ctrl.add(opCtrl[opVal].egLevel[j]);
} }
String opVol; String opVol;
opVol << opName << "-LEVEL"; opVol << opName << " OUTPUT LEVEL";
opCtrl[opVal].level = new CtrlDX(opVol, 100, opTarget + 16); opCtrl[opVal].level = new CtrlDX(opVol, 100, opTarget + 16);
ctrl.add(opCtrl[opVal].level); ctrl.add(opCtrl[opVal].level);
String opMode; String opMode;
opMode << opName << "-MODE"; opMode << opName << " MODE";
opCtrl[opVal].opMode = new CtrlDX(opMode, 1, opTarget + 17); opCtrl[opVal].opMode = new CtrlDX(opMode, 1, opTarget + 17);
ctrl.add(opCtrl[opVal].opMode); ctrl.add(opCtrl[opVal].opMode);
String coarse; String coarse;
coarse << opName << "-COARSE"; coarse << opName << " F COARSE";
opCtrl[opVal].coarse = new CtrlDX(coarse, 32, opTarget + 18); opCtrl[opVal].coarse = new CtrlDX(coarse, 32, opTarget + 18);
ctrl.add(opCtrl[opVal].coarse); ctrl.add(opCtrl[opVal].coarse);
String fine; String fine;
fine << opName << "-FINE"; fine << opName << " F FINE";
opCtrl[opVal].fine = new CtrlDX(fine, 100, opTarget + 19); opCtrl[opVal].fine = new CtrlDX(fine, 100, opTarget + 19);
ctrl.add(opCtrl[opVal].fine); ctrl.add(opCtrl[opVal].fine);
String detune; String detune;
detune << opName << "-DETUNE"; detune << opName << " OSC DETUNE";
opCtrl[opVal].detune = new CtrlDX(detune, 15, opTarget + 20); opCtrl[opVal].detune = new CtrlDX(detune, 15, opTarget + 20);
ctrl.add(opCtrl[opVal].detune); ctrl.add(opCtrl[opVal].detune);
String sclBrkPt; String sclBrkPt;
sclBrkPt << opName << "-SCL_BRK_PNT"; sclBrkPt << opName << " BREAK POINT";
opCtrl[opVal].sclBrkPt = new CtrlDX(sclBrkPt, 100, opTarget + 8); opCtrl[opVal].sclBrkPt = new CtrlDX(sclBrkPt, 100, opTarget + 8);
ctrl.add(opCtrl[opVal].sclBrkPt); ctrl.add(opCtrl[opVal].sclBrkPt);
String sclLeftDepth; String sclLeftDepth;
sclLeftDepth << opName << "-SCL_LFT_DEPTH"; sclLeftDepth << opName << " L SCALE DEPTH";
opCtrl[opVal].sclLeftDepth = new CtrlDX(sclLeftDepth, 100, opCtrl[opVal].sclLeftDepth = new CtrlDX(sclLeftDepth, 100,
opTarget + 9); opTarget + 9);
ctrl.add(opCtrl[opVal].sclLeftDepth); ctrl.add(opCtrl[opVal].sclLeftDepth);
String sclRightDepth; String sclRightDepth;
sclRightDepth << opName << "-SCL_RHT_DEPTH"; sclRightDepth << opName << " R SCALE DEPTH";
opCtrl[opVal].sclRightDepth = new CtrlDX(sclRightDepth, 100, opCtrl[opVal].sclRightDepth = new CtrlDX(sclRightDepth, 100,
opTarget + 10); opTarget + 10);
ctrl.add(opCtrl[opVal].sclRightDepth); ctrl.add(opCtrl[opVal].sclRightDepth);
String sclLeftCurve; String sclLeftCurve;
sclLeftCurve << opName << "-SCL_LFT_CURVE"; sclLeftCurve << opName << " L KEY SCALE";
opCtrl[opVal].sclLeftCurve = new CtrlDX(sclLeftCurve, 4, opTarget + 11); opCtrl[opVal].sclLeftCurve = new CtrlDX(sclLeftCurve, 4, opTarget + 11);
ctrl.add(opCtrl[opVal].sclLeftCurve); ctrl.add(opCtrl[opVal].sclLeftCurve);
String sclRightCurve; String sclRightCurve;
sclRightCurve << opName << "-SCL_RHT_CURVE"; sclRightCurve << opName << " R KEY SCALE";
opCtrl[opVal].sclRightCurve = new CtrlDX(sclRightCurve, 4, opCtrl[opVal].sclRightCurve = new CtrlDX(sclRightCurve, 4,
opTarget + 12); opTarget + 12);
ctrl.add(opCtrl[opVal].sclRightCurve); ctrl.add(opCtrl[opVal].sclRightCurve);
String sclRate; String sclRate;
sclRate << opName << "-SCL_RATE"; sclRate << opName << " RATE SCALING";
opCtrl[opVal].sclRate = new CtrlDX(sclRate, 7, opTarget + 13); opCtrl[opVal].sclRate = new CtrlDX(sclRate, 7, opTarget + 13);
ctrl.add(opCtrl[opVal].sclRate); ctrl.add(opCtrl[opVal].sclRate);
String ampModSens; String ampModSens;
ampModSens << opName << "-AMP_MODSENS"; ampModSens << opName << " A MOD SENS.";
opCtrl[opVal].ampModSens = new CtrlDX(ampModSens, 3, opTarget + 14); opCtrl[opVal].ampModSens = new CtrlDX(ampModSens, 3, opTarget + 14);
ctrl.add(opCtrl[opVal].ampModSens); ctrl.add(opCtrl[opVal].ampModSens);
String velModSens; String velModSens;
velModSens << opName << "-VEL_MODSENS"; velModSens << opName << " KEY VELOCITY";
opCtrl[opVal].velModSens = new CtrlDX(velModSens, 8, opTarget + 15); opCtrl[opVal].velModSens = new CtrlDX(velModSens, 8, opTarget + 15);
ctrl.add(opCtrl[opVal].velModSens); ctrl.add(opCtrl[opVal].velModSens);
} }
algo = new CtrlDX("Algorithm", 32, 134, true); algo = new CtrlDX("ALGORITHM", 32, 134, true);
ctrl.add(algo); ctrl.add(algo);
lfoRate = new CtrlDX("LFO-Rate", 100, 137); feedback = new CtrlDX("FEEDBACK", 8, 135);
ctrl.add(feedback);
oscSync = new CtrlDX("OSC KEY SYNC", 2, 136);
ctrl.add(oscSync);
lfoRate = new CtrlDX("LFO SPEED", 100, 137);
ctrl.add(lfoRate); ctrl.add(lfoRate);
lfoDelay = new CtrlDX("LFO-Delay", 100, 138); lfoDelay = new CtrlDX("LFO DELAY", 100, 138);
ctrl.add(lfoDelay); ctrl.add(lfoDelay);
lfoPitchDepth = new CtrlDX("LFO-PitchDepth", 100, 139); lfoPitchDepth = new CtrlDX("LFO PM DEPTH", 100, 139);
ctrl.add(lfoPitchDepth); ctrl.add(lfoPitchDepth);
lfoAmpDepth = new CtrlDX("LFO-AmpDepth", 100, 140); lfoAmpDepth = new CtrlDX("LFO AM DEPTH", 100, 140);
ctrl.add(lfoAmpDepth); ctrl.add(lfoAmpDepth);
lfoSync = new CtrlDX("LFO-Sync", 2, 141); lfoSync = new CtrlDX("LFO KEY SYNC", 2, 141);
ctrl.add(lfoSync); ctrl.add(lfoSync);
lfoWaveform = new CtrlDX("LFO-Waveform", 5, 142); lfoWaveform = new CtrlDX("LFO WAVE", 5, 142);
ctrl.add(lfoWaveform); ctrl.add(lfoWaveform);
for (int i = 0; i < ctrl.size(); i++) { transpose = new CtrlDX("MIDDLE C", 49, 144);
ctrl.add(transpose);
pitchModSens = new CtrlDX("P MODE SENS.", 8, 143);
ctrl.add(pitchModSens);
for (int i=0;i<4;i++) {
String rate;
rate << "PITCH EGR" << (i+1);
String level;
level << "PITCH EGL" << (i+1);
pitchEgRate[i] = new CtrlDX(rate, 99, 126+i);
ctrl.add(pitchEgRate[i]);
pitchEgLevel[i] = new CtrlDX(level, 99, 130+i);
ctrl.add(pitchEgLevel[i]);
}
for (int i=0; i < ctrl.size(); i++) {
ctrl[i]->idx = i; ctrl[i]->idx = i;
ctrl[i]->parent = this; ctrl[i]->parent = this;
} }
@ -370,11 +443,11 @@ int DexedAudioProcessor::getNumParameters() {
} }
float DexedAudioProcessor::getParameter(int index) { float DexedAudioProcessor::getParameter(int index) {
return ctrl[index]->getValuePlugin(); return ctrl[index]->getValueHost();
} }
void DexedAudioProcessor::setParameter(int index, float newValue) { void DexedAudioProcessor::setParameter(int index, float newValue) {
ctrl[index]->setValuePlugin(newValue); ctrl[index]->setValueHost(newValue);
} }
int DexedAudioProcessor::getNumPrograms() { int DexedAudioProcessor::getNumPrograms() {

@ -43,11 +43,21 @@ public:
void bind(ComboBox *c); void bind(ComboBox *c);
void unbind(); void unbind();
virtual void setValuePlugin(float f) = 0; // use this to signal a parameter change to the host
virtual float getValuePlugin() = 0; void publishValue(float value);
/**
* Host value is related 0.0 to 1.0 values
*/
virtual void setValueHost(float f) = 0;
virtual float getValueHost() = 0;
virtual String getValueDisplay() = 0; virtual String getValueDisplay() = 0;
virtual void updateComponent() = 0; virtual void updateComponent() = 0;
void comboBoxChanged (ComboBox* combo);
void sliderValueChanged (Slider* moved);
void buttonClicked (Button* buttonThatWasClicked);
/** /**
* Index of this parameter * Index of this parameter
*/ */
@ -55,24 +65,35 @@ public:
DexedAudioProcessor *parent; DexedAudioProcessor *parent;
}; };
class CtrlFloat : public Ctrl {
float *vPointer;
public:
CtrlFloat(String name, float *storageValue);
void setValueHost(float f);
float getValueHost();
String getValueDisplay();
void updateComponent();
};
// CtrlDX is a controller that is related to DX parameters // CtrlDX is a controller that is related to DX parameters
class CtrlDX : public Ctrl { class CtrlDX : public Ctrl {
int value; int dxValue;
int steps; int steps;
int add1; int add1;
int dxOffset; int dxOffset;
public: public:
CtrlDX(String name, int steps, int offset = -1, bool starts1 = false); CtrlDX(String name, int steps, int offset = -1, bool starts1 = false);
void setValuePlugin(float f); void setValueHost(float f);
float getValuePlugin(); float getValueHost();
void publishValue(int value); void publishValue(float value);
void setValue(int value); void setValue(int value);
int getValue(); int getValue();
String getValueDisplay(); String getValueDisplay();
void sliderValueChanged (Slider* moved); void sliderValueChanged (Slider* moved);
void buttonClicked (Button* buttonThatWasClicked);
void comboBoxChanged (ComboBox* combo); void comboBoxChanged (ComboBox* combo);
void updateComponent(); void updateComponent();
}; };

@ -133,6 +133,8 @@ void DexedAudioProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& mi
channelData[i] = (double) f; channelData[i] = (double) f;
} }
//fx.process(channelData, numSamples);
// DX7 is a mono synth // DX7 is a mono synth
for (int channel = 1; channel < getNumInputChannels(); ++channel) { for (int channel = 1; channel < getNumInputChannels(); ++channel) {
buffer.copyFrom(channel, 0, channelData, numSamples, 1); buffer.copyFrom(channel, 0, channelData, numSamples, 1);
@ -384,13 +386,14 @@ bool DexedAudioProcessor::hasEditor() const {
return true; // (change this to false if you choose to not supply an editor) return true; // (change this to false if you choose to not supply an editor)
} }
void DexedAudioProcessor::updateUI() { void DexedAudioProcessor::updateUI() {
AudioProcessorEditor *editor = getActiveEditor(); AudioProcessorEditor *editor = getActiveEditor();
if ( editor == NULL ) { if ( editor == NULL ) {
TRACE("no editor found!?"); TRACE("no editor found!?");
return; return;
} }
DexedAudioProcessorEditor *dexedEditor = (DexedAudioProcessorEditor *) editor; DexedAudioProcessorEditor *dexedEditor = (DexedAudioProcessorEditor *) editor;
dexedEditor->updateUI(); dexedEditor->updateUI();
} }

@ -28,6 +28,7 @@
#include "msfa/lfo.h" #include "msfa/lfo.h"
#include "msfa/synth.h" #include "msfa/synth.h"
#include "PluginParam.h" #include "PluginParam.h"
#include "PluginFx.h"
struct ProcessorVoice { struct ProcessorVoice {
int midi_note; int midi_note;
@ -68,7 +69,12 @@ class DexedAudioProcessor : public AudioProcessor
void updateProgramFromSysex(const uint8 *rawdata); void updateProgramFromSysex(const uint8 *rawdata);
/** /**
* This flag is usd in the audio thread to know if the voice has changed * PlugFX
*/
PluginFx fx;
/**
* This flag is used in the audio thread to know if the voice has changed
* and needs to be updated. * and needs to be updated.
*/ */
bool refreshVoice; bool refreshVoice;
@ -93,13 +99,20 @@ public :
OperatorCtrl opCtrl[6]; OperatorCtrl opCtrl[6];
ScopedPointer<CtrlDX> pitchEgRate[4]; ScopedPointer<CtrlDX> pitchEgRate[4];
ScopedPointer<CtrlDX> pitchEgLevel[4]; ScopedPointer<CtrlDX> pitchEgLevel[4];
ScopedPointer<CtrlDX> pitchModSens;
ScopedPointer<CtrlDX> algo; ScopedPointer<CtrlDX> algo;
ScopedPointer<CtrlDX> oscSync;
ScopedPointer<CtrlDX> feedback;
ScopedPointer<CtrlDX> lfoRate; ScopedPointer<CtrlDX> lfoRate;
ScopedPointer<CtrlDX> lfoDelay; ScopedPointer<CtrlDX> lfoDelay;
ScopedPointer<CtrlDX> lfoAmpDepth; ScopedPointer<CtrlDX> lfoAmpDepth;
ScopedPointer<CtrlDX> lfoPitchDepth; ScopedPointer<CtrlDX> lfoPitchDepth;
ScopedPointer<CtrlDX> lfoWaveform; ScopedPointer<CtrlDX> lfoWaveform;
ScopedPointer<CtrlDX> lfoSync; ScopedPointer<CtrlDX> lfoSync;
ScopedPointer<CtrlDX> transpose;
ScopedPointer<CtrlFloat> fxCutoff;
ScopedPointer<CtrlFloat> fxReso;
int importSysex(const char *imported); int importSysex(const char *imported);
void setDxValue(int offset, int v); void setDxValue(int offset, int v);

Loading…
Cancel
Save