External midi interface sysex support

pull/1/head
asb2m10 11 years ago
parent 3c5417f3e9
commit bcb05fa1e9
  1. 6
      Builds/Linux/Makefile
  2. 4724
      Builds/MacOSX/Dexed.xcodeproj/project.pbxproj
  3. BIN
      Builds/MacOSX/Dexed.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad/UserInterfaceState.xcuserstate
  4. 12
      Builds/VisualStudio2012/Dexed.sln
  5. 1073
      Builds/VisualStudio2012/Dexed.vcxproj
  6. 105
      Builds/VisualStudio2012/Dexed.vcxproj.filters
  7. 2
      Builds/VisualStudio2013/Dexed.vcxproj
  8. 6
      Builds/VisualStudio2013/Dexed.vcxproj.filters
  9. 2
      Dexed.jucer
  10. 15
      README.md
  11. 130
      Source/ParamDialog.cpp
  12. 15
      Source/ParamDialog.h
  13. 44
      Source/PluginData.cpp
  14. 8
      Source/PluginData.h
  15. 71
      Source/PluginEditor.cpp
  16. 2
      Source/PluginEditor.h
  17. 49
      Source/PluginParam.cpp
  18. 8
      Source/PluginParam.h
  19. 42
      Source/PluginProcessor.cpp
  20. 12
      Source/PluginProcessor.h
  21. 109
      Source/SysexComm.cpp
  22. 44
      Source/SysexComm.h

@ -70,6 +70,7 @@ OBJECTS := \
$(OBJDIR)/DXLookNFeel_cfc3afa2.o \
$(OBJDIR)/DXComponents_a6963633.o \
$(OBJDIR)/PluginFx_d84f776e.o \
$(OBJDIR)/SysexComm_f57b4ecd.o \
$(OBJDIR)/BinaryData_ce4232d4.o \
$(OBJDIR)/juce_audio_basics_2442e4ea.o \
$(OBJDIR)/juce_audio_devices_a4c8a728.o \
@ -198,6 +199,11 @@ $(OBJDIR)/PluginFx_d84f776e.o: ../../Source/PluginFx.cpp
@echo "Compiling PluginFx.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/SysexComm_f57b4ecd.o: ../../Source/SysexComm.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling SysexComm.cpp"
@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
$(OBJDIR)/BinaryData_ce4232d4.o: ../../JuceLibraryCode/BinaryData.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling BinaryData.cpp"

File diff suppressed because it is too large Load Diff

@ -1,23 +1,17 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2012 for Windows Desktop
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dexed", "Dexed.vcxproj", "{1A9EF105-5BF5-9FB6-9634-A91A6D840866}"
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2012
Project("{BD26B4C3-163D-4785-A63F-D3E66858BFF3}") = "Dexed", "Dexed.vcxproj", "{1A9EF105-5BF5-9FB6-9634-A91A6D840866}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1A9EF105-5BF5-9FB6-9634-A91A6D840866}.Debug|Win32.ActiveCfg = Debug|Win32
{1A9EF105-5BF5-9FB6-9634-A91A6D840866}.Debug|Win32.Build.0 = Debug|Win32
{1A9EF105-5BF5-9FB6-9634-A91A6D840866}.Debug|x64.ActiveCfg = Debug|x64
{1A9EF105-5BF5-9FB6-9634-A91A6D840866}.Debug|x64.Build.0 = Debug|x64
{1A9EF105-5BF5-9FB6-9634-A91A6D840866}.Release|Win32.ActiveCfg = Release|Win32
{1A9EF105-5BF5-9FB6-9634-A91A6D840866}.Release|Win32.Build.0 = Release|Win32
{1A9EF105-5BF5-9FB6-9634-A91A6D840866}.Release|x64.ActiveCfg = Release|x64
{1A9EF105-5BF5-9FB6-9634-A91A6D840866}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

File diff suppressed because it is too large Load Diff

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Dexed">
@ -327,6 +328,9 @@
<ClCompile Include="..\..\Source\PluginFx.cpp">
<Filter>Dexed\Source</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\SysexComm.cpp">
<Filter>Dexed\Source</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.cpp">
<Filter>Juce Modules\juce_audio_basics\buffers</Filter>
</ClCompile>
@ -381,6 +385,9 @@
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_basics\synthesisers\juce_Synthesiser.cpp">
<Filter>Juce Modules\juce_audio_basics\synthesisers</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\AU\juce_AU_Wrapper.mm">
<Filter>Juce Modules\juce_audio_plugin_client\AU</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_DigiCode1.cpp">
<Filter>Juce Modules\juce_audio_plugin_client\RTAS</Filter>
</ClCompile>
@ -396,15 +403,27 @@
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_Wrapper.cpp">
<Filter>Juce Modules\juce_audio_plugin_client\RTAS</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_MacUtilities.mm">
<Filter>Juce Modules\juce_audio_plugin_client\RTAS</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\VST\juce_VST_Wrapper.cpp">
<Filter>Juce Modules\juce_audio_plugin_client\VST</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\VST\juce_VST_Wrapper.mm">
<Filter>Juce Modules\juce_audio_plugin_client\VST</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\VST3\juce_VST3_Wrapper.cpp">
<Filter>Juce Modules\juce_audio_plugin_client\VST3</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\VST3\juce_VST3_Wrapper.mm">
<Filter>Juce Modules\juce_audio_plugin_client\VST3</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\AAX\juce_AAX_Wrapper.cpp">
<Filter>Juce Modules\juce_audio_plugin_client\AAX</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\AAX\juce_AAX_Wrapper.mm">
<Filter>Juce Modules\juce_audio_plugin_client\AAX</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\utility\juce_PluginUtilities.cpp">
<Filter>Juce Modules\juce_audio_plugin_client\utility</Filter>
</ClCompile>
@ -429,6 +448,9 @@
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_processors\format\juce_AudioPluginFormatManager.cpp">
<Filter>Juce Modules\juce_audio_processors\format</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_processors\format_types\juce_AudioUnitPluginFormat.mm">
<Filter>Juce Modules\juce_audio_processors\format_types</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_processors\format_types\juce_LADSPAPluginFormat.cpp">
<Filter>Juce Modules\juce_audio_processors\format_types</Filter>
</ClCompile>
@ -669,6 +691,21 @@
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_core\native\juce_linux_Threads.cpp">
<Filter>Juce Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_core\native\juce_mac_Files.mm">
<Filter>Juce Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_core\native\juce_mac_Network.mm">
<Filter>Juce Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_core\native\juce_mac_Strings.mm">
<Filter>Juce Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_core\native\juce_mac_SystemStats.mm">
<Filter>Juce Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_core\native\juce_mac_Threads.mm">
<Filter>Juce Modules\juce_core\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_core\native\juce_posix_NamedPipe.cpp">
<Filter>Juce Modules\juce_core\native</Filter>
</ClCompile>
@ -741,9 +778,15 @@
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_events\native\juce_android_Messaging.cpp">
<Filter>Juce Modules\juce_events\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_events\native\juce_ios_MessageManager.mm">
<Filter>Juce Modules\juce_events\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_events\native\juce_linux_Messaging.cpp">
<Filter>Juce Modules\juce_events\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_events\native\juce_mac_MessageManager.mm">
<Filter>Juce Modules\juce_events\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_events\native\juce_win32_Messaging.cpp">
<Filter>Juce Modules\juce_events\native</Filter>
</ClCompile>
@ -843,6 +886,12 @@
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_graphics\native\juce_linux_Fonts.cpp">
<Filter>Juce Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_graphics\native\juce_mac_CoreGraphicsContext.mm">
<Filter>Juce Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_graphics\native\juce_mac_Fonts.mm">
<Filter>Juce Modules\juce_graphics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_graphics\native\juce_win32_Direct2DGraphicsContext.cpp">
<Filter>Juce Modules\juce_graphics\native</Filter>
</ClCompile>
@ -1191,6 +1240,12 @@
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_basics\native\juce_android_Windowing.cpp">
<Filter>Juce Modules\juce_gui_basics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_basics\native\juce_ios_UIViewComponentPeer.mm">
<Filter>Juce Modules\juce_gui_basics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_basics\native\juce_ios_Windowing.mm">
<Filter>Juce Modules\juce_gui_basics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_basics\native\juce_linux_Clipboard.cpp">
<Filter>Juce Modules\juce_gui_basics\native</Filter>
</ClCompile>
@ -1200,6 +1255,21 @@
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_basics\native\juce_linux_Windowing.cpp">
<Filter>Juce Modules\juce_gui_basics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_basics\native\juce_mac_FileChooser.mm">
<Filter>Juce Modules\juce_gui_basics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_basics\native\juce_mac_MainMenu.mm">
<Filter>Juce Modules\juce_gui_basics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_basics\native\juce_mac_MouseCursor.mm">
<Filter>Juce Modules\juce_gui_basics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_basics\native\juce_mac_NSViewComponentPeer.mm">
<Filter>Juce Modules\juce_gui_basics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_basics\native\juce_mac_Windowing.mm">
<Filter>Juce Modules\juce_gui_basics\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_basics\native\juce_win32_DragAndDrop.cpp">
<Filter>Juce Modules\juce_gui_basics\native</Filter>
</ClCompile>
@ -1254,15 +1324,27 @@
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_extra\native\juce_android_WebBrowserComponent.cpp">
<Filter>Juce Modules\juce_gui_extra\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_extra\native\juce_ios_UIViewComponent.mm">
<Filter>Juce Modules\juce_gui_extra\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_extra\native\juce_linux_SystemTrayIcon.cpp">
<Filter>Juce Modules\juce_gui_extra\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_extra\native\juce_linux_WebBrowserComponent.cpp">
<Filter>Juce Modules\juce_gui_extra\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_extra\native\juce_mac_AppleRemote.mm">
<Filter>Juce Modules\juce_gui_extra\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_extra\native\juce_mac_NSViewComponent.mm">
<Filter>Juce Modules\juce_gui_extra\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_extra\native\juce_mac_SystemTrayIcon.cpp">
<Filter>Juce Modules\juce_gui_extra\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_extra\native\juce_mac_WebBrowserComponent.mm">
<Filter>Juce Modules\juce_gui_extra\native</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_gui_extra\native\juce_win32_ActiveXComponent.cpp">
<Filter>Juce Modules\juce_gui_extra\native</Filter>
</ClCompile>
@ -1335,24 +1417,6 @@
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\VST\juce_VST_Wrapper.cpp">
<Filter>Juce Library Code</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\AAX\juce_AAX_Wrapper.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\utility\juce_PluginUtilities.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_DigiCode1.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_DigiCode2.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_DigiCode3.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_WinUtilities.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_Wrapper.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\VST3\juce_VST3_Wrapper.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\VST\juce_VST_Wrapper.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\AAX\juce_AAX_Wrapper.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\utility\juce_PluginUtilities.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_DigiCode1.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_DigiCode2.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_DigiCode3.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_WinUtilities.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\RTAS\juce_RTAS_Wrapper.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\VST3\juce_VST3_Wrapper.cpp" />
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_plugin_client\VST\juce_VST_Wrapper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\Source\PluginProcessor.h">
@ -1424,6 +1488,9 @@
<ClInclude Include="..\..\Source\PluginFx.h">
<Filter>Dexed\Source</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\SysexComm.h">
<Filter>Dexed\Source</Filter>
</ClInclude>
<ClInclude Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.h">
<Filter>Juce Modules\juce_audio_basics\buffers</Filter>
</ClInclude>

@ -157,6 +157,7 @@
<ClCompile Include="..\..\Source\DXLookNFeel.cpp"/>
<ClCompile Include="..\..\Source\DXComponents.cpp"/>
<ClCompile Include="..\..\Source\PluginFx.cpp"/>
<ClCompile Include="..\..\Source\SysexComm.cpp"/>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.cpp">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ClCompile>
@ -1158,6 +1159,7 @@
<ClInclude Include="..\..\Source\DXLookNFeel.h"/>
<ClInclude Include="..\..\Source\DXComponents.h"/>
<ClInclude Include="..\..\Source\PluginFx.h"/>
<ClInclude Include="..\..\Source\SysexComm.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_FloatVectorOperations.h"/>

@ -328,6 +328,9 @@
<ClCompile Include="..\..\Source\PluginFx.cpp">
<Filter>Dexed\Source</Filter>
</ClCompile>
<ClCompile Include="..\..\Source\SysexComm.cpp">
<Filter>Dexed\Source</Filter>
</ClCompile>
<ClCompile Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.cpp">
<Filter>Juce Modules\juce_audio_basics\buffers</Filter>
</ClCompile>
@ -1485,6 +1488,9 @@
<ClInclude Include="..\..\Source\PluginFx.h">
<Filter>Dexed\Source</Filter>
</ClInclude>
<ClInclude Include="..\..\Source\SysexComm.h">
<Filter>Dexed\Source</Filter>
</ClInclude>
<ClInclude Include="..\..\JuceLibraryCode\modules\juce_audio_basics\buffers\juce_AudioDataConverters.h">
<Filter>Juce Modules\juce_audio_basics\buffers</Filter>
</ClInclude>

@ -67,6 +67,8 @@
<FILE id="x2E8Zg" name="DXComponents.h" compile="0" resource="0" file="Source/DXComponents.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"/>
<FILE id="KLqlYP" name="SysexComm.cpp" compile="1" resource="0" file="Source/SysexComm.cpp"/>
<FILE id="DWALdR" name="SysexComm.h" compile="0" resource="0" file="Source/SysexComm.h"/>
</GROUP>
</MAINGROUP>
<EXPORTFORMATS>

@ -24,6 +24,12 @@ Features
Changelog
---------
#### Version 0.6.0 (current sprint)
* Added external midi interface to send / receive sysex
* Fix Tracktion crash upon startup
* Middle C (transpose) now works
* Mouse over the interface controls now tells what it does without having to change it
#### Version 0.5.1
* Fix distortion issue with FL (DAW blocksize not multiple of 64)
* OS X 64bit build (the VST package contains both 32bit and 64bit)
@ -50,10 +56,7 @@ in normal operation it shouldn't crash and the VST state saving works.
Using as a DX7 editor
---------------------
This plugin can process original DX7 sysex messages. If you change a parameter,
it will send the corresponding DX7 sysex to midi out. Not all DAW supports
sysex; for example Ableton Live simply discard any sysex data. Reaper does
process midi out, but doesn't pass any midi in sysex input data to the plugin.
You can use this plugin to edit your real DX7 patch. Since sysex support on most DAW is missing, you might need to configure this plugin to send/receive sysex data to a specific midi port.
Randomized programs
-------------------
@ -72,7 +75,7 @@ FAQ (possibly)
--------------
* Some programs can generate distortion : This is because the voice summing still needs some tuning. You can simply lower the volume on those programs.
* Some sysex seems to be corrupted : Even if the sysex checksum doesn't match, Dexed will try to load it (this is a kind of randomize feature). Right now Dexed supports only original DX7 sysex, other DX family sysex (like the DX21) is considered as random data.
* Dexed doesn't receive/send parameter data from/to my DX7 : Most DX7 parameter change are done via sysex and very few VST host actually implements sysex. I'm planning to do a standalone executable to handle this issue.
* Dexed doesn't receive/send parameter data from/to my DX7 : Most DX7 parameter change are done via sysex and very few VST host actually implements sysex. Configure this plugin to send sysex data to a specific midi interface (see PARM panel).
Credits & thanks
----------------
@ -86,10 +89,10 @@ TODO - Dexed
------------
* Implement a better DX look and feel (amp, pitch, algo)
* Various code cleanup
* Standalone executable (for full support of the sysex editor)
TODO - msfa
-----------
* The sample rate should not change the response of the envelopes
* Portamento implentation
* LFO/Mod-wheel Amplitude
* Algo 4 & 6 feedback

@ -41,15 +41,46 @@ ParamDialog::ParamDialog ()
pitchStep->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20);
pitchStep->addListener (this);
addAndMakeVisible (sysexIn = new ComboBox ("sysexIn"));
sysexIn->setEditableText (false);
sysexIn->setJustificationType (Justification::centredLeft);
sysexIn->setTextWhenNothingSelected (String::empty);
sysexIn->setTextWhenNoChoicesAvailable (TRANS("(no choices)"));
sysexIn->addListener (this);
addAndMakeVisible (sysexOut = new ComboBox ("sysexOut"));
sysexOut->setEditableText (false);
sysexOut->setJustificationType (Justification::centredLeft);
sysexOut->setTextWhenNothingSelected (String::empty);
sysexOut->setTextWhenNoChoicesAvailable (TRANS("(no choices)"));
sysexOut->addListener (this);
addAndMakeVisible (sysexChl = new Slider ("sysexChl"));
sysexChl->setRange (1, 16, 1);
sysexChl->setSliderStyle (Slider::Rotary);
sysexChl->setTextBoxStyle (Slider::TextBoxLeft, false, 80, 20);
sysexChl->addListener (this);
//[UserPreSize]
//[/UserPreSize]
setSize (280, 200);
setSize (280, 300);
//[Constructor] You can add your own custom stuff here..
pitchRange->setEnabled(pitchStep->getValue() == 0);
StringArray input;
input.add("None");
input.addArray(MidiInput::getDevices());
sysexIn->addItemList(input, 1);
StringArray output;
output.add("None");
output.addArray(MidiOutput::getDevices());
sysexOut->addItemList(output, 1);
//[/Constructor]
}
@ -60,6 +91,9 @@ ParamDialog::~ParamDialog()
pitchRange = nullptr;
pitchStep = nullptr;
sysexIn = nullptr;
sysexOut = nullptr;
sysexChl = nullptr;
//[Destructor]. You can add your own custom destruction code here..
@ -77,13 +111,31 @@ void ParamDialog::paint (Graphics& g)
g.setColour (Colours::white);
g.setFont (Font (15.00f, Font::plain));
g.drawText (TRANS("Pitch Bend Range"),
28, 20, 131, 23,
19, 21, 205, 23,
Justification::centredLeft, true);
g.setColour (Colours::white);
g.setFont (Font (15.00f, Font::plain));
g.drawText (TRANS("Pitch Bend Step"),
28, 52, 128, 23,
19, 61, 229, 23,
Justification::centredLeft, true);
g.setColour (Colours::white);
g.setFont (Font (15.00f, Font::plain));
g.drawText (TRANS("Sysex In"),
19, 170, 131, 23,
Justification::centredLeft, true);
g.setColour (Colours::white);
g.setFont (Font (15.00f, Font::plain));
g.drawText (TRANS("Sysex Out"),
19, 210, 131, 23,
Justification::centredLeft, true);
g.setColour (Colours::white);
g.setFont (Font (15.00f, Font::plain));
g.drawText (TRANS("Sysex Channel"),
19, 258, 245, 23,
Justification::centredLeft, true);
//[UserPaint] Add your own custom painting code here..
@ -92,8 +144,11 @@ void ParamDialog::paint (Graphics& g)
void ParamDialog::resized()
{
pitchRange->setBounds (184, 16, 72, 24);
pitchStep->setBounds (184, 56, 72, 24);
pitchRange->setBounds (192, 16, 72, 24);
pitchStep->setBounds (192, 56, 72, 24);
sysexIn->setBounds (104, 168, 152, 24);
sysexOut->setBounds (104, 208, 152, 24);
sysexChl->setBounds (184, 256, 72, 24);
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
}
@ -114,23 +169,58 @@ void ParamDialog::sliderValueChanged (Slider* sliderThatWasMoved)
pitchRange->setEnabled(pitchStep->getValue() == 0);
//[/UserSliderCode_pitchStep]
}
else if (sliderThatWasMoved == sysexChl)
{
//[UserSliderCode_sysexChl] -- add your slider handling code here..
//[/UserSliderCode_sysexChl]
}
//[UsersliderValueChanged_Post]
//[/UsersliderValueChanged_Post]
}
void ParamDialog::comboBoxChanged (ComboBox* comboBoxThatHasChanged)
{
//[UsercomboBoxChanged_Pre]
//[/UsercomboBoxChanged_Pre]
if (comboBoxThatHasChanged == sysexIn)
{
//[UserComboBoxCode_sysexIn] -- add your combo box handling code here..
//[/UserComboBoxCode_sysexIn]
}
else if (comboBoxThatHasChanged == sysexOut)
{
//[UserComboBoxCode_sysexOut] -- add your combo box handling code here..
//[/UserComboBoxCode_sysexOut]
}
//[UsercomboBoxChanged_Post]
//[/UsercomboBoxChanged_Post]
}
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
void ParamDialog::setDialogValues(Controllers &c) {
void ParamDialog::setDialogValues(Controllers &c, SysexComm &mgr) {
pitchRange->setValue(c.values_[kControllerPitchRange]);
pitchStep->setValue(c.values_[kControllerPitchStep]);
sysexChl->setValue(mgr.getChl() + 1);
StringArray inputs = MidiInput::getDevices();
sysexIn->setItemEnabled(inputs.indexOf(mgr.getInput()), true);
StringArray outputs = MidiOutput::getDevices();
sysexOut->setItemEnabled(outputs.indexOf(mgr.getOutput()), true);
}
void ParamDialog::getDialogValues(Controllers &c) {
void ParamDialog::getDialogValues(Controllers &c, SysexComm &mgr) {
c.values_[kControllerPitchRange] = pitchRange->getValue();
c.values_[kControllerPitchStep] = pitchStep->getValue();
mgr.setInput(sysexIn->getItemText(sysexIn->getSelectedItemIndex()));
mgr.setOutput(sysexOut->getItemText(sysexOut->getSelectedItemIndex()));
mgr.setChl(sysexChl->getValue() - 1);
}
//[/MiscUserCode]
@ -148,21 +238,37 @@ BEGIN_JUCER_METADATA
<JUCER_COMPONENT documentType="Component" className="ParamDialog" componentName=""
parentClasses="public Component" constructorParams="" variableInitialisers=""
snapPixels="8" snapActive="1" snapShown="1" overlayOpacity="0.330"
fixedSize="1" initialWidth="280" initialHeight="200">
fixedSize="1" initialWidth="280" initialHeight="300">
<BACKGROUND backgroundColour="ff4e270d">
<TEXT pos="28 20 131 23" fill="solid: ffffffff" hasStroke="0" text="Pitch Bend Range"
<TEXT pos="19 21 205 23" fill="solid: ffffffff" hasStroke="0" text="Pitch Bend Range"
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/>
<TEXT pos="19 61 229 23" fill="solid: ffffffff" hasStroke="0" text="Pitch Bend Step"
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/>
<TEXT pos="19 170 131 23" fill="solid: ffffffff" hasStroke="0" text="Sysex In"
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/>
<TEXT pos="19 210 131 23" fill="solid: ffffffff" hasStroke="0" text="Sysex Out"
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/>
<TEXT pos="28 52 128 23" fill="solid: ffffffff" hasStroke="0" text="Pitch Bend Step"
<TEXT pos="19 258 245 23" fill="solid: ffffffff" hasStroke="0" text="Sysex Channel"
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/>
</BACKGROUND>
<SLIDER name="pitchRange" id="7409be5a8dfaa91" memberName="pitchRange"
virtualName="" explicitFocusOrder="0" pos="184 16 72 24" min="0"
virtualName="" explicitFocusOrder="0" pos="192 16 72 24" min="0"
max="12" int="1" style="Rotary" textBoxPos="TextBoxLeft" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<SLIDER name="pitchStep" id="b86af4b792e768ca" memberName="pitchStep"
virtualName="" explicitFocusOrder="0" pos="184 56 72 24" min="0"
virtualName="" explicitFocusOrder="0" pos="192 56 72 24" min="0"
max="12" int="1" style="Rotary" textBoxPos="TextBoxLeft" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<COMBOBOX name="sysexIn" id="3750642d8b5be11" memberName="sysexIn" virtualName=""
explicitFocusOrder="0" pos="104 168 152 24" editable="0" layout="33"
items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/>
<COMBOBOX name="sysexOut" id="44730115841c2214" memberName="sysexOut" virtualName=""
explicitFocusOrder="0" pos="104 208 152 24" editable="0" layout="33"
items="" textWhenNonSelected="" textWhenNoItems="(no choices)"/>
<SLIDER name="sysexChl" id="7fdc8830f90a7c86" memberName="sysexChl" virtualName=""
explicitFocusOrder="0" pos="184 256 72 24" min="1" max="16" int="1"
style="Rotary" textBoxPos="TextBoxLeft" textBoxEditable="1" textBoxWidth="80"
textBoxHeight="20" skewFactor="1"/>
</JUCER_COMPONENT>
END_JUCER_METADATA

@ -23,6 +23,7 @@
//[Headers] -- You can add your own extra header files here --
#include "JuceHeader.h"
#include "msfa/controllers.h"
#include "SysexComm.h"
//[/Headers]
@ -36,7 +37,8 @@
//[/Comments]
*/
class ParamDialog : public Component,
public SliderListener
public SliderListener,
public ComboBoxListener
{
public:
//==============================================================================
@ -45,16 +47,14 @@ public:
//==============================================================================
//[UserMethods] -- You can add your own custom methods in this section.
void setDialogValues(Controllers &c);
void getDialogValues(Controllers &c);
void setDialogValues(Controllers &c, SysexComm &mgr);
void getDialogValues(Controllers &c, SysexComm &mgr);
//[/UserMethods]
void paint (Graphics& g);
void resized();
void sliderValueChanged (Slider* sliderThatWasMoved);
void comboBoxChanged (ComboBox* comboBoxThatHasChanged);
private:
//[UserVariables] -- You can add your own custom variables in this section.
@ -63,6 +63,9 @@ private:
//==============================================================================
ScopedPointer<Slider> pitchRange;
ScopedPointer<Slider> pitchStep;
ScopedPointer<ComboBox> sysexIn;
ScopedPointer<ComboBox> sysexOut;
ScopedPointer<Slider> sysexChl;
//==============================================================================

@ -25,7 +25,7 @@
#include "PluginData.h"
uint8_t sysexChecksum(const char *sysex) {
uint8_t sysexChecksum(const char *sysex, int size) {
int sum = 0;
int i;
@ -66,19 +66,40 @@ void extractProgramNames(const char *block, StringArray &dest) {
}
}
void exportSysex(char *dest, char *src) {
void exportSysexCart(char *dest, char *src, char sysexChl) {
uint8_t header[] = { 0xF0, 0x43, 0x00, 0x09, 0x20, 0x00 };
header[2] = sysexChl;
memcpy(dest, header, 6);
// copy 32 voices
memcpy(dest+6, src, 4096);
// make checksum for dump
uint8_t footer[] = { sysexChecksum(src), 0xF7 };
uint8_t footer[] = { sysexChecksum(src, 4096), 0xF7 };
memcpy(dest+4102, footer, 2);
}
void exportSysexPgm(char *dest, char *src, char sysexChl) {
uint8_t header[] = { 0xF0, 0x43, 0x00, 0x00, 0x01, 0x1B };
header[2] = sysexChl;
memcpy(dest, header, 6);
// copy 1 unpacked voices
memcpy(dest+6, src, 155);
// put some logic to "mute" an operator if the level is 0
// make checksum for dump
uint8_t footer[] = { sysexChecksum(src, 155), 0xF7 };
memcpy(dest+161, footer, 2);
}
/**
* Pack a program into a 32 packed sysex
*/
@ -194,7 +215,7 @@ void DexedAudioProcessor::unpackProgram(int idx) {
int DexedAudioProcessor::importSysex(const char *imported) {
memcpy(sysex, imported + 6, 4096);
uint8_t checksum = sysexChecksum(((char *) &sysex));
uint8_t checksum = sysexChecksum(((char *) &sysex), 4096);
extractProgramNames(sysex, programNames);
if ( checksum != imported[4102] ) {
@ -234,7 +255,7 @@ void DexedAudioProcessor::getStateInformation(MemoryBlock& destData) {
dexedState.setAttribute("currentProgram", currentProgram);
char sysex_blob[4104];
exportSysex((char *) &sysex_blob, (char *) sysex);
exportSysexCart((char *) &sysex_blob, (char *) sysex, 0);
NamedValueSet blobSet;
blobSet.set("sysex", var((void *) &sysex_blob, 4104));
@ -286,19 +307,6 @@ void DexedAudioProcessor::setStateInformation(const void* source, int sizeInByte
updateUI();
}
//==============================================================================
/*void DexedAudioProcessor::getCurrentProgramStateInformation(
MemoryBlock& destData) {
destData.insert(data, 161, 0);
}
void DexedAudioProcessor::setCurrentProgramStateInformation(const void* source,
int sizeInBytes) {
memcpy((void *) data, source, sizeInBytes);
updateUI();
}*/
CartridgeManager::CartridgeManager() {
MemoryInputStream *mis = new MemoryInputStream(BinaryData::builtin_pgm_zip, BinaryData::builtin_pgm_zipSize, false);
builtin_pgm = new ZipFile(mis, true);

@ -25,7 +25,7 @@
#define SYSEX_SIZE 4104
enum UpackedOffset {
enum UnpackedOffset {
egRate,
egLevel = 4,
breakpoint = 8,
@ -54,11 +54,13 @@ enum UpackedOffset {
lfoKeySync,
lfoWave,
middleC,
pModeSens
pModeSens,
osc6state
};
void extractProgramNames(const char *block, StringArray &dest);
void exportSysex(char *dest, char *src);
void exportSysexCart(char *dest, char *src, char sysexChl);
void exportSysexPgm(char *dest, char *src, char sysexChl);
void packProgram(uint8_t *dest, uint8_t *src, int idx, String name);
class CartridgeManager {

@ -73,16 +73,16 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner
addAndMakeVisible (loadButton = new TextButton("LOAD"));
loadButton->setButtonText ("LOAD");
loadButton->addListener (this);
loadButton->addListener(this);
loadButton->setBounds(59, 6, 50, 18);
addAndMakeVisible(saveButton = new TextButton("SAVE"));
saveButton->setButtonText ("SAVE");
saveButton->addListener (this);
saveButton->setBounds (113, 6, 50, 18);
saveButton->setBounds(113, 6, 50, 18);
addAndMakeVisible (&programs);
programs.setEditableText (false);
programs.setEditableText(false);
programs.setJustificationType (Justification::centredLeft);
programs.setTextWhenNothingSelected (String::empty);
programs.setBounds(167, 6, 160, 18);
@ -90,20 +90,24 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner
programs.addListener(this);
addAndMakeVisible(storeButton = new TextButton("STORE"));
storeButton->setButtonText ("STORE");
storeButton->addListener (this);
storeButton->setBounds (331, 6, 50, 18);
storeButton->setButtonText("STORE");
storeButton->addListener(this);
storeButton->setBounds(331, 6, 50, 18);
addAndMakeVisible(sendButton = new TextButton("SEND"));
sendButton->setButtonText("SEND");
sendButton->addListener(this);
sendButton->setBounds(385, 6, 50, 18);
addAndMakeVisible(settingsButton = new TextButton("PARMS"));
settingsButton->setButtonText ("PARMS");
settingsButton->addListener (this);
settingsButton->setBounds (755, 6, 50, 18);
settingsButton->setButtonText("PARMS");
settingsButton->addListener(this);
settingsButton->setBounds(755, 6, 50, 18);
addAndMakeVisible(aboutButton = new TextButton("ABOUT"));
aboutButton->setButtonText ("ABOUT");
aboutButton->addListener (this);
aboutButton->setBounds (807, 6, 50, 18);
aboutButton->setButtonText("ABOUT");
aboutButton->addListener(this);
aboutButton->setBounds(807, 6, 50, 18);
// OPERATORS
addAndMakeVisible(&(operators[0]));
@ -143,6 +147,9 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner
global.setBounds(5,235,855,90);
global.bind(processor);
sendPopup.addItem(1, "Send current program to DX7 via sysex");
sendPopup.addItem(2, "Send current cartridge to DX7 via sysex");
updateUI();
startTimer(100);
}
@ -208,7 +215,7 @@ void DexedAudioProcessorEditor::buttonClicked(Button *buttonThatWasClicked) {
String f = fc.getResults().getReference(0).getFullPathName();
char syx_data[4104];
exportSysex((char *) syx_data, (char *) &processor->sysex);
exportSysexCart((char *) syx_data, (char *) &processor->sysex, 0);
ofstream fp_out(f.toRawUTF8(), ios::binary);
fp_out.write((char *)syx_data, 4104);
@ -229,12 +236,42 @@ void DexedAudioProcessorEditor::buttonClicked(Button *buttonThatWasClicked) {
return;
}
if (buttonThatWasClicked == sendButton) {
int result = sendPopup.show();
if ( result == 1 ) {
uint8_t raw[165];
exportSysexPgm((char *) raw, processor->data, processor->sysexComm.getChl());
if ( processor->sysexComm.isOutputActive() ) {
processor->sysexComm.send(MidiMessage(raw, 165));
} else {
processor->midiOut.addEvent(raw, 165, 0);
}
return;
}
if ( result == 2 ) {
uint8_t raw[4104];
exportSysexCart((char *) raw, processor->sysex, processor->sysexComm.getChl());
if ( processor->sysexComm.isOutputActive() ) {
processor->sysexComm.send(MidiMessage(raw, 4104));
} else {
processor->midiOut.addEvent(raw, 4104, 0);
}
return;
}
return;
}
if (buttonThatWasClicked == settingsButton) {
AlertWindow window("","", AlertWindow::NoIcon, this);
ParamDialog param;
param.setColour(AlertWindow::backgroundColourId, Colour(0x32FFFFFF));
param.setDialogValues(processor->controllers);
param.setDialogValues(processor->controllers, processor->sysexComm);
window.addCustomComponent(&param);
window.addButton("OK", 0);
@ -242,7 +279,7 @@ void DexedAudioProcessorEditor::buttonClicked(Button *buttonThatWasClicked) {
if ( window.runModalLoop() != 0 )
return;
param.getDialogValues(processor->controllers);
param.getDialogValues(processor->controllers, processor->sysexComm);
processor->savePreference();
return;
@ -368,7 +405,7 @@ void DexedAudioProcessorEditor::storeProgram() {
} else {
packProgram((uint8_t *) &destSysex, (uint8_t *) processor->data, programNum, programName);
char sysexFile[4104];
exportSysex((char *) &sysexFile, (char *) &destSysex);
exportSysexCart((char *) &sysexFile, (char *) &destSysex, 0);
if ( ! externalFile->replaceWithData(sysexFile, 4104) ) {
AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Write error", "Unable to write file");
}

@ -37,6 +37,7 @@ class DexedAudioProcessorEditor : public AudioProcessorEditor,
DexedAudioProcessor *processor;
ComboBox programs;
PopupMenu cartPopup;
PopupMenu sendPopup;
MidiKeyboardComponent midiKeyboard;
DXLookNFeel dx_lnf;
@ -47,6 +48,7 @@ class DexedAudioProcessorEditor : public AudioProcessorEditor,
ScopedPointer<TextButton> storeButton;
ScopedPointer<TextButton> aboutButton;
ScopedPointer<TextButton> settingsButton;
ScopedPointer<TextButton> sendButton;
void storeProgram();

@ -37,18 +37,21 @@ void Ctrl::bind(Slider *s) {
slider = s;
updateComponent();
s->addListener(this);
s->addMouseListener(this, true);
}
void Ctrl::bind(Button *b) {
button = b;
updateComponent();
b->addListener(this);
b->addMouseListener(this, true);
}
void Ctrl::bind(ComboBox *c) {
comboBox = c;
updateComponent();
c->addListener(this);
c->addMouseListener(this, true);
}
void Ctrl::unbind() {
@ -86,6 +89,13 @@ void Ctrl::comboBoxChanged(ComboBox* combo) {
publishValue((combo->getSelectedId() - 1) / combo->getNumItems());
}
void Ctrl::mouseEnter(const juce::MouseEvent &event) {
updateDisplayName();
}
void Ctrl::updateDisplayName() {
}
// ************************************************************************
// CtrlDX - control DX mapping
CtrlFloat::CtrlFloat(String name, float *storageValue) : Ctrl(name) {
@ -166,9 +176,7 @@ String CtrlDX::getValueDisplay() {
return ret;
}
void CtrlDX::publishValue(float value) {
Ctrl::publishValue(value / steps);
void CtrlDX::updateDisplayName() {
DexedAudioProcessorEditor *editor = (DexedAudioProcessorEditor *) parent->getActiveEditor();
if ( editor == NULL ) {
return;
@ -178,6 +186,12 @@ void CtrlDX::publishValue(float value) {
editor->global.setParamMessage(msg);
}
void CtrlDX::publishValue(float value) {
Ctrl::publishValue(value / steps);
updateDisplayName();
}
void CtrlDX::sliderValueChanged(Slider* moved) {
publishValue(((int) moved->getValue() - displayValue));
}
@ -376,11 +390,22 @@ void DexedAudioProcessor::setDxValue(int offset, int v) {
if (offset >= 0)
data[offset] = v;
// MIDDLE C (transpose)
if (offset == 144)
panic();
if (!sendSysexChange)
return;
uint8 msg[7] = { 0xF0, 0x43, 0x10, offset > 127, 0, (uint8) v, 0xF7 };
msg[2] = 0x10 | sysexComm.getChl();
msg[4] = offset & 0x7F;
midiOut.addEvent(msg, 7, 0);
if ( sysexComm.isOutputActive() ) {
sysexComm.send(MidiMessage(msg,7));
} else {
midiOut.addEvent(msg, 7, 0);
}
}
void DexedAudioProcessor::unbindUI() {
@ -474,6 +499,18 @@ void DexedAudioProcessor::loadPreference() {
controllers.values_[kControllerPitchStep] = prop.getIntValue( String("pitchStep") );
}
if ( prop.containsKey( String("sysexIn") ) ) {
sysexComm.setInput( prop.getValue("sysexIn") );
}
if ( prop.containsKey( String("sysexOut") ) ) {
sysexComm.setOutput( prop.getValue("sysexOut") );
}
if ( prop.containsKey( String("sysexChl") ) ) {
sysexComm.setChl( prop.getIntValue( String("sysexChl") ) );
}
}
void DexedAudioProcessor::savePreference() {
@ -483,6 +520,10 @@ void DexedAudioProcessor::savePreference() {
prop.setValue(String("pitchRange"), controllers.values_[kControllerPitchRange]);
prop.setValue(String("pitchStep"), controllers.values_[kControllerPitchStep]);
prop.setValue(String("sysexIn"), sysexComm.getInput());
prop.setValue(String("sysexOut"), sysexComm.getOutput());
prop.setValue(String("sysexChl"), sysexComm.getChl());
prop.save();
}

@ -25,7 +25,7 @@
class DexedAudioProcessor;
class Ctrl : public SliderListener, public ButtonListener, public ComboBoxListener {
class Ctrl : public SliderListener, public ButtonListener, public ComboBoxListener, public MouseListener {
protected:
/**
* Binded components of the UI
@ -57,6 +57,8 @@ public:
void comboBoxChanged (ComboBox* combo);
void sliderValueChanged (Slider* moved);
void buttonClicked (Button* buttonThatWasClicked);
void mouseEnter(const MouseEvent &event);
virtual void updateDisplayName();
/**
* Index of this parameter
@ -73,7 +75,7 @@ public:
void setValueHost(float f);
float getValueHost();
String getValueDisplay();
void updateComponent();
void updateComponent();
};
// CtrlDX is a controller that is related to DX parameters
@ -98,6 +100,8 @@ public:
void comboBoxChanged (ComboBox* combo);
void buttonClicked (Button* buttonThatWasClicked);
void updateComponent();
void updateDisplayName();
};

@ -51,6 +51,7 @@ DexedAudioProcessor::DexedAudioProcessor() {
setCurrentProgram(0);
sendSysexChange = true;
normalizeDxVelocity = false;
sysexComm.listener = this;
memset(&voiceStatus, 0, sizeof(VoiceStatus));
@ -62,6 +63,12 @@ DexedAudioProcessor::DexedAudioProcessor() {
controllers.values_[kControllerPitchRange] = 3;
controllers.values_[kControllerPitchStep] = 0;
loadPreference();
for (int note = 0; note < MAX_ACTIVE_NOTES; ++note) {
voices[note].dx7_note = NULL;
}
nextMidi = NULL;
midiMsg = NULL;
}
DexedAudioProcessor::~DexedAudioProcessor() {
@ -99,16 +106,24 @@ void DexedAudioProcessor::releaseResources() {
currentNote = -1;
for (int note = 0; note < MAX_ACTIVE_NOTES; ++note) {
delete voices[note].dx7_note;
if ( voices[note].dx7_note != NULL ) {
delete voices[note].dx7_note;
voices[note].dx7_note = NULL;
}
voices[note].keydown = false;
voices[note].sustained = false;
voices[note].live = false;
}
keyboardState.reset();
delete nextMidi;
delete midiMsg;
if ( nextMidi != NULL ) {
delete nextMidi;
nextMidi = NULL;
}
if ( midiMsg != NULL ) {
delete midiMsg;
midiMsg = NULL;
}
}
void DexedAudioProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& midiMessages) {
@ -243,7 +258,7 @@ bool DexedAudioProcessor::getNextEvent(MidiBuffer::Iterator* iter,const int samp
return false;
}
void DexedAudioProcessor::processMidiMessage(MidiMessage *msg) {
void DexedAudioProcessor::processMidiMessage(const MidiMessage *msg) {
if ( msg->isSysEx() ) {
const uint8 *buf = msg->getSysExData();
@ -335,12 +350,20 @@ void DexedAudioProcessor::processMidiMessage(MidiMessage *msg) {
}
void DexedAudioProcessor::handleIncomingMidiMessage(MidiInput* source, const MidiMessage& message) {
if ( ! message.isSysEx() )
return;
processMidiMessage(&message);
}
void DexedAudioProcessor::keydown(uint8_t pitch, uint8_t velo) {
if ( velo == 0 ) {
keyup(pitch);
return;
}
pitch += (data[144] - 24);
if ( normalizeDxVelocity ) {
velo = ((float)velo) * 0.7874015; // 100/127
}
@ -363,6 +386,8 @@ void DexedAudioProcessor::keydown(uint8_t pitch, uint8_t velo) {
}
void DexedAudioProcessor::keyup(uint8_t pitch) {
pitch += (data[144] - 24);
for (int note = 0; note < MAX_ACTIVE_NOTES; ++note) {
if (voices[note].midi_note == pitch && voices[note].keydown) {
if (sustain) {
@ -375,6 +400,13 @@ void DexedAudioProcessor::keyup(uint8_t pitch) {
}
}
void DexedAudioProcessor::panic() {
for(int i=0;i<MAX_ACTIVE_NOTES;i++) {
voices[i].keydown = false;
}
keyboardState.reset();
}
// ====================================================================
bool DexedAudioProcessor::peekVoiceStatus() {
if ( currentNote == -1 )

@ -30,6 +30,7 @@
#include "PluginParam.h"
#include "PluginData.h"
#include "PluginFx.h"
#include "SysexComm.h"
struct ProcessorVoice {
int midi_note;
@ -42,7 +43,7 @@ struct ProcessorVoice {
//==============================================================================
/**
*/
class DexedAudioProcessor : public AudioProcessor, public AsyncUpdater
class DexedAudioProcessor : public AudioProcessor, public AsyncUpdater, public MidiInputCallback
{
static const int MAX_ACTIVE_NOTES = 16;
ProcessorVoice voices[MAX_ACTIVE_NOTES];
@ -78,9 +79,7 @@ class DexedAudioProcessor : public AudioProcessor, public AsyncUpdater
bool normalizeDxVelocity;
bool sendSysexChange;
MidiBuffer midiOut;
void processMidiMessage(MidiMessage *msg);
void processMidiMessage(const MidiMessage *msg);
void keydown(uint8_t pitch, uint8_t velo);
void keyup(uint8_t pitch);
@ -98,6 +97,7 @@ class DexedAudioProcessor : public AudioProcessor, public AsyncUpdater
int midiEventPos;
bool getNextEvent(MidiBuffer::Iterator* iter,const int samplePos);
void handleIncomingMidiMessage(MidiInput* source, const MidiMessage& message);
public :
// in MIDI units (0x4000 is neutral)
@ -107,6 +107,9 @@ public :
char data[161];
CartridgeManager cartManager;
SysexComm sysexComm;
MidiBuffer midiOut;
VoiceStatus voiceStatus;
bool forceRefreshUI;
@ -145,6 +148,7 @@ public :
void prepareToPlay (double sampleRate, int samplesPerBlock);
void releaseResources();
void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);
void panic();
//==============================================================================
AudioProcessorEditor* createEditor();

@ -0,0 +1,109 @@
/*
==============================================================================
MidiMgr.cpp
Created: 24 Jun 2014 2:43:55am
Author: Pascal Gauthier
==============================================================================
*/
#include "SysexComm.h"
SysexComm::SysexComm() {
sysexChl = 1;
listener = NULL; // this will get injected later
inputName = "";
outputName = "";
input = NULL;
output = NULL;
}
SysexComm::~SysexComm() {
if ( input != NULL ) {
input->stop();
delete input;
}
if ( output != NULL )
delete output;
}
String SysexComm::getInput() {
return inputName;
}
void SysexComm::setInput(String target) {
if ( input != NULL ) {
input->stop();
delete input;
input = NULL;
}
if ( listener == NULL )
return;
StringArray devices = MidiInput::getDevices();
int idx = devices.indexOf(target);
if ( idx == -1 ) {
// device not found
inputName = "";
return;
}
input = MidiInput::openDevice(idx, listener);
if ( input != NULL ) {
inputName = target;
input->start();
}
}
String SysexComm::getOutput() {
return outputName;
}
void SysexComm::setOutput(String target) {
if ( output != NULL ) {
delete output;
output = NULL;
}
StringArray devices = MidiOutput::getDevices();
int idx = devices.indexOf(target);
if ( idx == -1 ) {
// device not found
return;
}
output = MidiOutput::openDevice(idx);
if ( output != NULL ) {
outputName = target;
}
}
bool SysexComm::isInputActive() {
return input != NULL;
}
bool SysexComm::isOutputActive() {
return output != NULL;
}
int SysexComm::getChl() {
return sysexChl;
}
void SysexComm::setChl(int chl) {
sysexChl = chl;
}
void SysexComm::send(const juce::MidiMessage &message) {
if ( output == NULL )
return;
output->sendMessageNow(message);
}

@ -0,0 +1,44 @@
/*
==============================================================================
MidiMgr.h
Created: 24 Jun 2014 2:43:55am
Author: Pascal Gauthier
==============================================================================
*/
#ifndef SYSEXCOMM_H_INCLUDED
#define SYSEXCOMM_H_INCLUDED
#include "../JuceLibraryCode/JuceHeader.h"
class SysexComm {
MidiInput *input;
MidiOutput *output;
String inputName;
String outputName;
int sysexChl;
public :
MidiInputCallback *listener;
SysexComm();
~SysexComm();
void setInput(String name);
void setOutput(String name);
void setChl(int chl);
String getInput();
String getOutput();
int getChl();
bool isInputActive();
bool isOutputActive();
void send(const MidiMessage& message);
};
#endif // SYSEXCOMM_H_INCLUDED
Loading…
Cancel
Save