diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bca3fef
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+Builds/VisualStudio2012/Dexed.vcxproj.user
\ No newline at end of file
diff --git a/Builds/VisualStudio2012/Dexed.v11.suo b/Builds/VisualStudio2012/Dexed.v11.suo
index c48c1b6..649c126 100644
Binary files a/Builds/VisualStudio2012/Dexed.v11.suo and b/Builds/VisualStudio2012/Dexed.v11.suo differ
diff --git a/Builds/VisualStudio2012/Dexed.vcxproj b/Builds/VisualStudio2012/Dexed.vcxproj
index 28766d5..f9f21df 100644
--- a/Builds/VisualStudio2012/Dexed.vcxproj
+++ b/Builds/VisualStudio2012/Dexed.vcxproj
@@ -1,5 +1,4 @@
-
-
+
@@ -15,7 +14,7 @@
{1A9EF105-5BF5-9FB6-9634-A91A6D840866}
v110
-
+
DynamicLibrary
false
@@ -27,11 +26,10 @@
true
v110
-
-
+
+
-
+
v110
@@ -52,16 +50,16 @@
true
true
Win32
-
+
Disabled
EditAndContinue
..\..\JuceLibraryCode;..\..\JuceLibraryCode\modules;C:\work\vstsdk2.4;%(AdditionalIncludeDirectories)
WIN32;_WINDOWS;DEBUG;_DEBUG;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;%(PreprocessorDefinitions)
- MultiThreadedDebugDLL
+ MultiThreadedDebug
true
-
+
$(IntDir)\
$(IntDir)\
$(IntDir)\
@@ -89,7 +87,7 @@
$(IntDir)\Dexed.bsc
- copy /Y "$(OutDir)\$(TargetFileName)" "$(OutDir)\$(TargetName).vst3"
+ copy /Y "$(OutDir)\$(TargetFileName)" "$(OutDir)\$(TargetName).vst3"
@@ -98,7 +96,7 @@
true
true
Win32
-
+
MinSpace
@@ -106,7 +104,7 @@
WIN32;_WINDOWS;NDEBUG;JUCER_VS2012_78A501F=1;JUCE_APP_VERSION=1.0.0;JUCE_APP_VERSION_HEX=0x10000;%(PreprocessorDefinitions)
MultiThreadedDLL
true
-
+
$(IntDir)\
$(IntDir)\
$(IntDir)\
@@ -135,30 +133,30 @@
$(IntDir)\Dexed.bsc
- copy /Y "$(OutDir)\$(TargetFileName)" "$(OutDir)\$(TargetName).vst3"
+ copy /Y "$(OutDir)\$(TargetFileName)" "$(OutDir)\$(TargetName).vst3"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
true
@@ -1104,20 +1102,20 @@
true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
StdCall
@@ -1133,445 +1131,445 @@
StdCall
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
+
+
\ No newline at end of file
diff --git a/Builds/VisualStudio2012/Dexed.vcxproj.filters b/Builds/VisualStudio2012/Dexed.vcxproj.filters
index 0ec4f8e..b7e6961 100644
--- a/Builds/VisualStudio2012/Dexed.vcxproj.filters
+++ b/Builds/VisualStudio2012/Dexed.vcxproj.filters
@@ -1,5 +1,4 @@
-
-
+
@@ -385,9 +384,6 @@
Juce Modules\juce_audio_basics\synthesisers
-
- Juce Modules\juce_audio_plugin_client\AU
-
Juce Modules\juce_audio_plugin_client\RTAS
@@ -403,27 +399,15 @@
Juce Modules\juce_audio_plugin_client\RTAS
-
- Juce Modules\juce_audio_plugin_client\RTAS
-
Juce Modules\juce_audio_plugin_client\VST
-
- Juce Modules\juce_audio_plugin_client\VST
-
Juce Modules\juce_audio_plugin_client\VST3
-
- Juce Modules\juce_audio_plugin_client\VST3
-
Juce Modules\juce_audio_plugin_client\AAX
-
- Juce Modules\juce_audio_plugin_client\AAX
-
Juce Modules\juce_audio_plugin_client\utility
@@ -448,9 +432,6 @@
Juce Modules\juce_audio_processors\format
-
- Juce Modules\juce_audio_processors\format_types
-
Juce Modules\juce_audio_processors\format_types
@@ -691,21 +672,6 @@
Juce Modules\juce_core\native
-
- Juce Modules\juce_core\native
-
-
- Juce Modules\juce_core\native
-
-
- Juce Modules\juce_core\native
-
-
- Juce Modules\juce_core\native
-
-
- Juce Modules\juce_core\native
-
Juce Modules\juce_core\native
@@ -778,15 +744,9 @@
Juce Modules\juce_events\native
-
- Juce Modules\juce_events\native
-
Juce Modules\juce_events\native
-
- Juce Modules\juce_events\native
-
Juce Modules\juce_events\native
@@ -886,12 +846,6 @@
Juce Modules\juce_graphics\native
-
- Juce Modules\juce_graphics\native
-
-
- Juce Modules\juce_graphics\native
-
Juce Modules\juce_graphics\native
@@ -1240,12 +1194,6 @@
Juce Modules\juce_gui_basics\native
-
- Juce Modules\juce_gui_basics\native
-
-
- Juce Modules\juce_gui_basics\native
-
Juce Modules\juce_gui_basics\native
@@ -1255,21 +1203,6 @@
Juce Modules\juce_gui_basics\native
-
- Juce Modules\juce_gui_basics\native
-
-
- Juce Modules\juce_gui_basics\native
-
-
- Juce Modules\juce_gui_basics\native
-
-
- Juce Modules\juce_gui_basics\native
-
-
- Juce Modules\juce_gui_basics\native
-
Juce Modules\juce_gui_basics\native
@@ -1324,27 +1257,15 @@
Juce Modules\juce_gui_extra\native
-
- Juce Modules\juce_gui_extra\native
-
Juce Modules\juce_gui_extra\native
Juce Modules\juce_gui_extra\native
-
- Juce Modules\juce_gui_extra\native
-
-
- Juce Modules\juce_gui_extra\native
-
Juce Modules\juce_gui_extra\native
-
- Juce Modules\juce_gui_extra\native
-
Juce Modules\juce_gui_extra\native
@@ -1417,6 +1338,15 @@
Juce Library Code
+
+
+
+
+
+
+
+
+
@@ -2714,4 +2644,4 @@
Juce Library Code
-
+
\ No newline at end of file
diff --git a/README.md b/README.md
index 81d9cb7..8a3d4aa 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ Features
Changelog
---------
#### Version 0.6.0 (current sprint)
-* Added external midi interface to send / receive sysex message
+* Added external midi interface to send / receive sysex messages
* 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
@@ -47,7 +47,9 @@ Changelog
Binary downloads
----------------
Dexed is not a finished product but it is stable enough to be used in a DAW environment:
-in normal operation it shouldn't crash and the VST state saving works. If you don't see the new version here but you see it in the change log, it's because this version is in development (current sprint). Only officials (tested) builds are listed here.
+in normal operation it shouldn't crash and the VST state saving works. If you don't see the
+new version here but you see it in the change log, it's because this version is in development
+(current sprint). Only officials (tested) builds are listed here.
* Version 0.5.1 [vst win32](http://le-son666.com/software/dexed/dexed-0.5.1-win32.zip) - [vst win64](http://le-son666.com/software/dexed/dexed-0.5.1-win64.zip) - [vst os x](http://le-son666.com/software/dexed/dexed-0.5.1-osx.vst.zip)
* Version 0.5.0 [vst win32](http://le-son666.com/software/dexed/dexed-0.5.0a-win32.zip) - [vst win64](http://le-son666.com/software/dexed/dexed-0.5.0a-win64.zip) - [vst os x](http://le-son666.com/software/dexed/dexed-0.5.0-osx.vst.zip)
@@ -56,7 +58,32 @@ in normal operation it shouldn't crash and the VST state saving works. If you do
Using as a DX7 editor
---------------------
-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.
+You can use this plugin to edit your real DX7 patchs. Since midi send/receive are quirky for the
+majority of VST hosts, any sysex messages (editor messages) must be send or received with the external Dexed
+midi interface, configurable in the "PARM" panel. By setting a DX7 in / DX7 out, Dexed will
+listen to specific program/cartridge changes from your DX7 and send controller/program/cartridge
+you edit.
+
+### Prerequisite
+* Before you use this interface, your DX7 must be configured to send or receive sysex messages. By hitting [FUNCTION] and [8] button :
+* The first one is the midi channel. By reading some of DX7 literature, most DX7 are supposed to support only 1 channel. Unless you are running a cluster of DX7, you should keep this to 1.
+* The second one (press [8] again) is "SYS INFO AVAIL" or "SYS INFO UNAVAIL". Keep it to "SYS INFO AVAIL" to be able to receive sysex messages.
+* The third one, you need to remove MEMORY PROTECT on the internal or cartridge memory to be able to receive a Dexed 32 voice bulk dump.
+
+### To send to your DX7
+* If the midi port is configured, any parameter change will be sent to your DX7.
+* Use the [SEND] button on Dexed to send program or cartridge changes to your DX7. Be sure you have set [MEMORY PROTECT] to off so the cartridge (internal et external one) on the DX7 can be overridden.
+
+### To receive to your DX7
+* Receive a program by simply using [MEMORY SELECT] then the program you want to change ([1] to [32]).
+* Receive a cartridge by pressing [FUNCTION] then 3 times on [8] you should see " MIDI TRANSMIT ? ". If you hit yes, Dexed should receive the complete cartridge.
+
+### Troubleshooting
+* If the midi ports are opened correcly you should see a DX7 light flashing when you send or receive midi data from/to your DX7. If you don't see anything, or just the input, it because it was unable to open the output midi interface.
+* If you play on your DX7 keyboard, the |DX7 In light| should be flashing. Use this to test the midi in communication.
+* If you click/play on the Dexed virtual keyboard, it will send the correspoding midi note to the DX7 port; if configured. Use this to test the midi out communication.
+* If the data sent is corrupted (wrong checksum, DX7 crash); it might be the midi interface implementation. Default Windows USB midi driver can send corrupt sysex data. If it is the case, use a third party device (like the midiman uno) that have his own USB driver.
+* If you are unable to open the interface (error message after the [PARM] dialog), it might be because the midi driver doesn't support multiple clients (common on Windows). Be sure that there are no other applications that are using the same midi interface.
Randomized programs
-------------------
diff --git a/Source/DXComponents.cpp b/Source/DXComponents.cpp
index e1b522b..3e7e9ed 100644
--- a/Source/DXComponents.cpp
+++ b/Source/DXComponents.cpp
@@ -457,11 +457,18 @@ void LcdDisplay::handleAsyncUpdate() {
startTimer(5000);
}
+#ifdef _WIN32
+ const float LCD_FONTSIZE = 13.0f;
+#else
+ const float LCD_FONTSIZE = 15.0f;
+#endif
+
void LcdDisplay::paint(Graphics &g) {
+
g.setColour(Colours::black.withAlpha(0.4f));
g.fillRoundedRectangle (0.0f, 0.0f, (float) getWidth(), (float) getHeight(), 1.0f);
g.setColour (Colours::white);
- g.setFont (Font (Font::getDefaultMonospacedFontName(), 15.00f, Font::plain));
+ g.setFont (Font (Font::getDefaultMonospacedFontName(), LCD_FONTSIZE, Font::plain));
g.drawText (systemMsg,
7, 4, 300, 8,
Justification::centredLeft, true);
diff --git a/Source/ParamDialog.cpp b/Source/ParamDialog.cpp
index f3aaea3..855fccd 100644
--- a/Source/ParamDialog.cpp
+++ b/Source/ParamDialog.cpp
@@ -123,19 +123,19 @@ void ParamDialog::paint (Graphics& g)
g.setColour (Colours::white);
g.setFont (Font (15.00f, Font::plain));
- g.drawText (TRANS("Sysex In"),
+ g.drawText (TRANS("DX7 In"),
19, 178, 131, 23,
Justification::centredLeft, true);
g.setColour (Colours::white);
g.setFont (Font (15.00f, Font::plain));
- g.drawText (TRANS("Sysex Out"),
+ g.drawText (TRANS("DX7 Out"),
19, 218, 131, 23,
Justification::centredLeft, true);
g.setColour (Colours::white);
g.setFont (Font (15.00f, Font::plain));
- g.drawText (TRANS("Sysex Channel"),
+ g.drawText (TRANS("DX7 Channel"),
19, 258, 245, 23,
Justification::centredLeft, true);
@@ -221,12 +221,16 @@ void ParamDialog::setDialogValues(Controllers &c, SysexComm &mgr) {
sysexOut->setSelectedItemIndex(idx);
}
-void ParamDialog::getDialogValues(Controllers &c, SysexComm &mgr) {
+bool ParamDialog::getDialogValues(Controllers &c, SysexComm &mgr) {
+ bool ret = true;
+
c.values_[kControllerPitchRange] = pitchRange->getValue();
c.values_[kControllerPitchStep] = pitchStep->getValue();
- mgr.setInput(sysexIn->getItemText(sysexIn->getSelectedItemIndex()));
- mgr.setOutput(sysexOut->getItemText(sysexOut->getSelectedItemIndex()));
+ ret &= mgr.setInput(sysexIn->getItemText(sysexIn->getSelectedItemIndex()));
+ ret &= mgr.setOutput(sysexOut->getItemText(sysexOut->getSelectedItemIndex()));
mgr.setChl(sysexChl->getValue() - 1);
+
+ return ret;
}
//[/MiscUserCode]
@@ -250,11 +254,11 @@ BEGIN_JUCER_METADATA
fontname="Default font" fontsize="15" bold="0" italic="0" justification="33"/>
-
-
-
> */
+ case 127:
+ c = '<';
+ break; /* << */
+ default:
+ if (c < 32 || c > 127)
+ c = 32;
+ break;
+ }
+ buffer[j] = c;
+ }
+ buffer[10] = 0;
+
+ return String(buffer);
+}
+
+
void extractProgramNames(const char *block, StringArray &dest) {
- char programName[11];
-
dest.clear();
for (int i = 0; i < 32; i++) {
- memcpy(programName, block + ((i * 128) + 118), 11);
-
- for (int j = 0; j < 10; j++) {
- char c = (unsigned char) programName[j];
- switch (c) {
- case 92:
- c = 'Y';
- break; /* yen */
- case 126:
- c = '>';
- break; /* >> */
- case 127:
- c = '<';
- break; /* << */
- default:
- if (c < 32 || c > 127)
- c = 32;
- break;
- }
- programName[j] = c;
- }
- programName[10] = 0;
-
- dest.add(String(programName));
+ dest.add(String(normalizeSysexName(block + ((i * 128) + 118))));
}
}
@@ -77,7 +82,7 @@ void exportSysexCart(char *dest, char *src, char sysexChl) {
// make checksum for dump
uint8_t footer[] = { sysexChecksum(src, 4096), 0xF7 };
-
+
memcpy(dest+4102, footer, 2);
}
@@ -131,6 +136,7 @@ void packProgram(uint8_t *dest, uint8_t *src, int idx, String name) {
bulk[117] = src[144];
int eos = 0;
+
for(int i=0; i < 10; i++) {
char c = (char) name[i];
if ( c == 0 )
@@ -227,7 +233,7 @@ int DexedAudioProcessor::importSysex(const char *imported) {
}
void DexedAudioProcessor::updateProgramFromSysex(const uint8 *rawdata) {
- memcpy(data, rawdata, 160);
+ memcpy(data, rawdata, 161);
triggerAsyncUpdate();
}
diff --git a/Source/PluginData.h b/Source/PluginData.h
index f273a41..0dc28d0 100644
--- a/Source/PluginData.h
+++ b/Source/PluginData.h
@@ -58,6 +58,7 @@ enum UnpackedOffset {
osc6state
};
+String normalizeSysexName(const char *sysexName);
void extractProgramNames(const char *block, StringArray &dest);
void exportSysexCart(char *dest, char *src, char sysexChl);
void exportSysexPgm(char *dest, char *src, char sysexChl);
diff --git a/Source/PluginEditor.cpp b/Source/PluginEditor.cpp
index 1070efb..04e4f53 100644
--- a/Source/PluginEditor.cpp
+++ b/Source/PluginEditor.cpp
@@ -22,6 +22,7 @@
#include "PluginEditor.h"
#include "GlobalEditor.h"
#include "ParamDialog.h"
+#include "SysexComm.h"
#include "Dexed.h"
#include "math.h"
#include
@@ -55,6 +56,53 @@ public:
}
};
+/**
+ * Ugly but usefull midi monitor to know if you are really sending/receiving something from the DX7
+ * If the midi is not configured this component wont show up
+ */
+class MidiMonitor : public Component {
+ SysexComm *midi;
+public:
+ MidiMonitor(SysexComm *sysexComm) {
+ midi = sysexComm;
+ }
+
+ void paint(Graphics &g) {
+ if ( ! (midi->isInputActive() || midi->isOutputActive() ) )
+ return;
+
+ g.setColour(DXLookNFeel::dxDarkBrown);
+ g.fillRect(0, 0, getWidth(), getHeight());
+ g.setColour(Colours::black);
+ g.drawSingleLineText("DX7 ", 0, 13);
+
+ if ( midi->isInputActive() ) {
+ g.drawSingleLineText("IN", 27,13);
+ if ( midi->inActivity ) {
+ g.setColour(Colours::red);
+ } else {
+ g.setColour(Colours::darkgrey);
+ }
+ g.fillRect(44, 4, 7, 9);
+
+ midi->inActivity = false;
+ }
+
+ if ( midi->isOutputActive() ) {
+ g.setColour(Colours::black);
+ g.drawSingleLineText("OUT", 55, 13);
+ if ( midi->outActivity ) {
+ g.setColour(Colours::red);
+ } else {
+ g.setColour(Colours::darkgrey);
+ }
+ g.fillRect(83, 4, 7, 9);
+
+ midi->outActivity = false;
+ }
+ }
+};
+
//==============================================================================
DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* ownerFilter)
: AudioProcessorEditor (ownerFilter),
@@ -98,10 +146,15 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner
storeButton->setBounds(331, 6, 50, 18);
addAndMakeVisible(sendButton = new TextButton("SEND"));
+ sendButton->setVisible(false);
sendButton->setButtonText("SEND");
sendButton->addListener(this);
sendButton->setBounds(385, 6, 50, 18);
+ sendButton->setVisible(processor->sysexComm.isOutputActive());
+ addAndMakeVisible(midiMonitor = new MidiMonitor(&processor->sysexComm));
+ midiMonitor->setBounds(645, 6, 110, 18);
+
addAndMakeVisible(settingsButton = new TextButton("PARMS"));
settingsButton->setButtonText("PARMS");
settingsButton->addListener(this);
@@ -150,8 +203,8 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner
global.setBounds(5,235,855,90);
global.bind(processor);
- sendPopup.addItem(1, "Send current program to DX7");
- sendPopup.addItem(2, "Send current cartridge to DX7");
+ sendPopup.addItem(1, "Send program to DX7");
+ sendPopup.addItem(2, "Send cartridge to DX7");
updateUI();
startTimer(100);
@@ -243,26 +296,24 @@ void DexedAudioProcessorEditor::buttonClicked(Button *buttonThatWasClicked) {
int result = sendPopup.show();
if ( result == 1 ) {
- uint8_t raw[165];
+ uint8_t raw[167];
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);
+ processor->sysexComm.send(MidiMessage(raw, 163));
}
+ global.setSystemMessage(String("Done sending program"));
return;
}
if ( result == 2 ) {
uint8_t raw[4104];
-
- exportSysexCart((char *) raw, processor->sysex, processor->sysexComm.getChl());
+
+ exportSysexCart((char *) raw, (char *) &processor->sysex, processor->sysexComm.getChl());
if ( processor->sysexComm.isOutputActive() ) {
processor->sysexComm.send(MidiMessage(raw, 4104));
- } else {
- processor->midiOut.addEvent(raw, 4104, 0);
}
+ global.setSystemMessage(String("Done sending cartridge"));
return;
}
@@ -270,7 +321,6 @@ void DexedAudioProcessorEditor::buttonClicked(Button *buttonThatWasClicked) {
}
if (buttonThatWasClicked == settingsButton) {
-
AlertWindow window("","", AlertWindow::NoIcon, this);
ParamDialog param;
param.setColour(AlertWindow::backgroundColourId, Colour(0x32FFFFFF));
@@ -282,9 +332,14 @@ void DexedAudioProcessorEditor::buttonClicked(Button *buttonThatWasClicked) {
if ( window.runModalLoop() != 0 )
return;
- param.getDialogValues(processor->controllers, processor->sysexComm);
+ bool ret = param.getDialogValues(processor->controllers, processor->sysexComm);
processor->savePreference();
+ if ( ret == false ) {
+ AlertWindow::showMessageBoxAsync(AlertWindow::WarningIcon, "Midi Interface", "Error opening midi ports");
+ }
+
+ sendButton->setVisible(processor->sysexComm.isOutputActive());
return;
}
@@ -317,6 +372,7 @@ void DexedAudioProcessorEditor::timerCallback() {
}
global.updatePitchPos(processor->voiceStatus.pitchStep);
global.updateVu(processor->vuSignal);
+ midiMonitor->repaint();
}
void DexedAudioProcessorEditor::updateUI() {
@@ -326,10 +382,7 @@ void DexedAudioProcessorEditor::updateUI() {
for(int i=0;i<6;i++) {
operators[i].updateDisplay();
}
-
- int id = processor->getCurrentProgram() + 1;
- programs.setSelectedId(id, dontSendNotification);
-
+ rebuildProgramCombobox();
global.updateDisplay();
}
diff --git a/Source/PluginEditor.h b/Source/PluginEditor.h
index d91fda9..1e889ba 100644
--- a/Source/PluginEditor.h
+++ b/Source/PluginEditor.h
@@ -21,11 +21,13 @@
#ifndef PLUGINEDITOR_H_INCLUDED
#define PLUGINEDITOR_H_INCLUDED
+
#include "../JuceLibraryCode/JuceHeader.h"
#include "PluginProcessor.h"
#include "OperatorEditor.h"
#include "GlobalEditor.h"
#include "DXComponents.h"
+#include "DXLookNFeel.h"
//==============================================================================
/**
@@ -49,7 +51,7 @@ class DexedAudioProcessorEditor : public AudioProcessorEditor,
ScopedPointer aboutButton;
ScopedPointer settingsButton;
ScopedPointer sendButton;
-
+ ScopedPointer midiMonitor;
void storeProgram();
public:
diff --git a/Source/PluginParam.cpp b/Source/PluginParam.cpp
index 5d09062..716dbe4 100644
--- a/Source/PluginParam.cpp
+++ b/Source/PluginParam.cpp
@@ -407,8 +407,6 @@ void DexedAudioProcessor::setDxValue(int offset, int v) {
if ( sysexComm.isOutputActive() ) {
sysexComm.send(MidiMessage(msg,7));
- } else {
- midiOut.addEvent(msg, 7, 0);
}
}
diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp
index 706108c..5e670c1 100644
--- a/Source/PluginProcessor.cpp
+++ b/Source/PluginProcessor.cpp
@@ -53,6 +53,7 @@ DexedAudioProcessor::DexedAudioProcessor() {
sendSysexChange = true;
normalizeDxVelocity = false;
sysexComm.listener = this;
+ keyboardState.addListener(&sysexComm);
memset(&voiceStatus, 0, sizeof(VoiceStatus));
@@ -236,11 +237,6 @@ void DexedAudioProcessor::processBlock(AudioSampleBuffer& buffer, MidiBuffer& mi
for (int i = getNumInputChannels(); i < getNumOutputChannels(); ++i) {
buffer.clear (i, 0, buffer.getNumSamples());
}
-
- midiMessages.clear();
- if ( ! midiOut.isEmpty() ) {
- midiMessages.swapWith(midiOut);
- }
}
@@ -260,46 +256,6 @@ bool DexedAudioProcessor::getNextEvent(MidiBuffer::Iterator* iter,const int samp
}
void DexedAudioProcessor::processMidiMessage(const MidiMessage *msg) {
- if ( msg->isSysEx() ) {
-
- const uint8 *buf = msg->getSysExData();
- int sz = msg->getSysExDataSize();
- TRACE("SYSEX RECEIVED %d", sz);
- if ( sz < 3 )
- return;
-
- // test if it is a Yamaha Sysex
- if ( buf[0] != 0x43 ) {
- TRACE("not a yamaha sysex %d", buf[0]);
- return;
- }
-
- // single voice dump
- if ( buf[2] == 0 ) {
- if ( sz < 155 ) {
- TRACE("wrong single voice datasize %d", sz);
- return;
- }
- TRACE("program update sysex");
- updateProgramFromSysex(buf+4);
- triggerAsyncUpdate();
- return;
- }
-
- // 32 voice dump
- if ( buf[2] == 9 ) {
- if ( sz < 4016 ) {
- TRACE("wrong 32 voice datasize %d", sz);
- return;
- }
- TRACE("update 32bulk voice)");
- importSysex((const char *)buf+4);
- currentProgram = 0;
- triggerAsyncUpdate();
- }
- return;
- }
-
const uint8 *buf = msg->getRawData();
uint8_t cmd = buf[0];
@@ -351,12 +307,6 @@ void DexedAudioProcessor::processMidiMessage(const 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);
@@ -408,6 +358,59 @@ void DexedAudioProcessor::panic() {
keyboardState.reset();
}
+void DexedAudioProcessor::handleIncomingMidiMessage(MidiInput* source, const MidiMessage& message) {
+ if ( message.isActiveSense() )
+ return;
+
+ sysexComm.inActivity = true;
+
+ if ( ! message.isSysEx() )
+ return;
+
+ //const uint8 *buf = msg->getSysExData();
+ const uint8 *buf = message.getRawData();
+ int sz = message.getRawDataSize();
+
+ if ( sz < 3 )
+ return;
+
+ TRACE("SYSEX RECEIVED %d", sz);
+
+ // test if it is a Yamaha Sysex
+ if ( buf[1] != 0x43 ) {
+ TRACE("not a yamaha sysex %d", buf[0]);
+ return;
+ }
+
+ // single voice dump
+ if ( buf[3] == 0 ) {
+ if ( sz < 155 ) {
+ TRACE("wrong single voice datasize %d", sz);
+ return;
+ }
+
+ TRACE("program update sysex");
+ updateProgramFromSysex(buf+6);
+ String name = normalizeSysexName((const char *) buf+151);
+ packProgram((uint8_t *) sysex, (uint8_t *) data, currentProgram, name);
+ programNames.set(currentProgram, name);
+ }
+
+ // 32 voice dump
+ if ( buf[3] == 9 ) {
+ if ( sz < 4104 ) {
+ TRACE("wrong 32 voice datasize %d", sz);
+ return;
+ }
+ TRACE("update 32bulk voice");
+ importSysex((const char *)buf);
+ setCurrentProgram(0);
+ }
+
+ updateHostDisplay();
+ forceRefreshUI = true;
+}
+
// ====================================================================
bool DexedAudioProcessor::peekVoiceStatus() {
if ( currentNote == -1 )
@@ -490,7 +493,7 @@ bool DexedAudioProcessor::hasEditor() const {
void DexedAudioProcessor::updateUI() {
// notify host something has changed
updateHostDisplay();
-
+
AudioProcessorEditor *editor = getActiveEditor();
if ( editor == NULL ) {
return;
diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h
index aeb9929..8db6e88 100644
--- a/Source/PluginProcessor.h
+++ b/Source/PluginProcessor.h
@@ -75,7 +75,7 @@ class DexedAudioProcessor : public AudioProcessor, public AsyncUpdater, public
* and needs to be updated.
*/
bool refreshVoice;
-
+
bool normalizeDxVelocity;
bool sendSysexChange;
@@ -108,7 +108,6 @@ public :
CartridgeManager cartManager;
SysexComm sysexComm;
- MidiBuffer midiOut;
VoiceStatus voiceStatus;
@@ -155,7 +154,6 @@ public :
bool hasEditor() const;
void updateUI();
bool peekVoiceStatus();
- void packProgram(int idx, const char *name);
void unpackProgram(int idx);
void updateProgramFromSysex(const uint8 *rawdata);
void loadBuiltin(int idx);
diff --git a/Source/SysexComm.cpp b/Source/SysexComm.cpp
index 3450f29..d6f227a 100644
--- a/Source/SysexComm.cpp
+++ b/Source/SysexComm.cpp
@@ -22,7 +22,7 @@
#include "Dexed.h"
SysexComm::SysexComm() {
- sysexChl = 1;
+ sysexChl = 0;
listener = NULL; // this will get injected later
inputName = "";
@@ -46,7 +46,7 @@ String SysexComm::getInput() {
return inputName;
}
-void SysexComm::setInput(String target) {
+bool SysexComm::setInput(String target) {
if ( input != NULL ) {
input->stop();
delete input;
@@ -54,7 +54,7 @@ void SysexComm::setInput(String target) {
}
if ( listener == NULL )
- return;
+ return true;
StringArray devices = MidiInput::getDevices();
int idx = devices.indexOf(target);
@@ -62,24 +62,28 @@ void SysexComm::setInput(String target) {
if ( idx == -1 ) {
TRACE("device %s not found", target.toRawUTF8());
inputName = "";
- return;
+ if ( target == "None" || target == "" )
+ return true;
+ return false;
}
input = MidiInput::openDevice(idx, listener);
- if ( input != NULL ) {
- inputName = target;
- input->start();
- TRACE("sysex %s opened", target.toRawUTF8());
- } else {
+ if ( input == NULL ) {
TRACE("unable to open %s", target.toRawUTF8());
+ return false;
}
+
+ inputName = target;
+ TRACE("sysex %s opened", target.toRawUTF8());
+ input->start();
+ return true;
}
String SysexComm::getOutput() {
return outputName;
}
-void SysexComm::setOutput(String target) {
+bool SysexComm::setOutput(String target) {
if ( output != NULL ) {
delete output;
output = NULL;
@@ -91,16 +95,20 @@ void SysexComm::setOutput(String target) {
if ( idx == -1 ) {
TRACE("device %s not found", target.toRawUTF8());
outputName = "";
- return;
+ if ( target == "None" || target == "" )
+ return true;
+ return false;
}
output = MidiOutput::openDevice(idx);
- if ( output != NULL ) {
- outputName = target;
- TRACE("sysex %s opened", target.toRawUTF8());
- } else {
+ if ( output == NULL ) {
TRACE("unable to open %s", target.toRawUTF8());
+ return false;
}
+
+ outputName = target;
+ TRACE("sysex %s opened", target.toRawUTF8());
+ return true;
}
bool SysexComm::isInputActive() {
@@ -119,10 +127,26 @@ void SysexComm::setChl(int chl) {
sysexChl = chl;
}
-void SysexComm::send(const juce::MidiMessage &message) {
+int SysexComm::send(const MidiMessage &message) {
if ( output == NULL )
- return;
+ return 2;
- TRACE("sending sysex...");
+ outActivity = true;
output->sendMessageNow(message);
+ return 0;
+}
+
+// This is called from the UI Keyboard...
+void SysexComm::handleNoteOn(MidiKeyboardState*, int, int midiNoteNumber, float velocity) {
+ if ( output == NULL )
+ return;
+
+ outActivity = true;
+ char iVelo = velocity * 100;
+ MidiMessage msg(0x90 + sysexChl, midiNoteNumber, iVelo);
+ output->sendMessageNow(msg);
+}
+
+void SysexComm::handleNoteOff(MidiKeyboardState* source, int midiChannel, int midiNoteNumber) {
+ handleNoteOn(source, midiChannel, midiNoteNumber, 0);
}
\ No newline at end of file
diff --git a/Source/SysexComm.h b/Source/SysexComm.h
index 04f5da3..bc69f25 100644
--- a/Source/SysexComm.h
+++ b/Source/SysexComm.h
@@ -23,20 +23,21 @@
#include "../JuceLibraryCode/JuceHeader.h"
-class SysexComm {
+class SysexComm : public MidiKeyboardStateListener {
MidiInput *input;
MidiOutput *output;
String inputName;
String outputName;
int sysexChl;
+
public :
MidiInputCallback *listener;
SysexComm();
~SysexComm();
- void setInput(String name);
- void setOutput(String name);
+ bool setInput(String name);
+ bool setOutput(String name);
void setChl(int chl);
String getInput();
@@ -46,7 +47,13 @@ public :
bool isInputActive();
bool isOutputActive();
- void send(const MidiMessage& message);
+ int send(const MidiMessage& message);
+
+ void handleNoteOn(MidiKeyboardState* source, int midiChannel, int midiNoteNumber, float velocity);
+ void handleNoteOff(MidiKeyboardState* source, int midiChannel, int midiNoteNumber);
+
+ bool inActivity;
+ bool outActivity;
};
#endif // SYSEXCOMM_H_INCLUDED
\ No newline at end of file