pull/1/head
asb2m10 10 years ago
parent 26f049653b
commit 9bc7fc9003
  1. 4636
      Builds/MacOSX/Dexed.xcodeproj/project.pbxproj
  2. BIN
      Builds/MacOSX/Dexed.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad/UserInterfaceState.xcuserstate
  3. 48
      README.md
  4. 27
      Source/DXLookNFeel.cpp
  5. 6
      Source/DXLookNFeel.h
  6. 66
      Source/OperatorEditor.cpp
  7. 3
      Source/OperatorEditor.h
  8. 16
      Source/PluginEditor.cpp
  9. 99
      Source/PluginParam.cpp
  10. 6
      Source/PluginParam.h
  11. 3
      Source/PluginProcessor.cpp
  12. 13
      Source/PluginProcessor.h

File diff suppressed because it is too large Load Diff

@ -1,43 +1,53 @@
Dexed DX7 Software Emulator
===========================
Dexed is a multi platform, multiformat plugin synth that is closely modeled on the Yamaha DX7.
Dexed is a multi platform, multi format 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)
for the synth engine and [JUCE](http://wwww.juce.com) as a plugin wrapper.
Dexed is licensed on the GPL v2. The msfa component (music synthesizer for android, see msfa in the source
folder) stays on the Apache 2.0 license to able to collaborate between projects.
The goal of this project is to be a great tool/companion for the original DX7. Yes, the sound engine
with 'float' values parameter; different waveform (à la TX81z) would be great but anything that
goes beyond the DX7 should will be a fork of this project. This is to keep the compatiblity with
the original synth.
Dexed is licensed on the GPL v2. The msfa component (acronym for music synthesizer for android, see msfa
in the source folder) stays on the Apache 2.0 license to able to collaborate between projects.
Features
--------
* Multi platform (OS X, Windows, Linux) and multi format (VST, AU and others that I don't use); 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
Binary downloads
----------------
It is far from finish but for those who want to try the "music-synthesizer-for-android" project
It is far from finished 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).
Using has a DX7 editor
----------------------
Using as a DX7 editor
---------------------
This plugin can process original DX7 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 data to the plugin.
midi in sysex input data to the plugin.
(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 (SynprezFM-II-builtins.tgz)](http://www.synprez.com/SynprezFM/) for great collection of DX7 patches
Randomized programs
-------------------
Dexed doesn't check the sysex checksum so you can load any type of files. If the checksum doesn't
match, it will tell you but load it anyway. This features enable a somekind of randomized DX
programs.
TODO - Dexed
------------
* Implement a better DX look and feel
* Implement a better DX look and feel (amp, pitch, algo)
* Better implementation of the LPF filter
* Better display of the amplitude envelope
* Better display of the algo
* Various code cleanup
TODO - msfa
-----------
* LFO Amplitude
* MOD Wheel action
* Algo 4 & 6 feedback
* Algo 4 & 6 feedback

@ -152,12 +152,37 @@ void AlgoDisplay::drawOp(Graphics &g, int x, int y, int num, bool feedback) {
int x1 = (x*21) + 19;
g.drawLine(x1, y*14+1, x1, y*14+14, 3);
}
}
void VuMeter::paint(Graphics &g) {
// taken from the drawLevelMeter ;
float width = getWidth();
float height = getHeight();
g.setColour (Colours::black);
g.fillRoundedRectangle (0.0f, 0.0f, (float) width, (float) height, 0);
/*g.setColour (Colours::black.withAlpha (0.2f));
g.drawRoundedRectangle (1.0f, 1.0f, width - 2.0f, height - 2.0f, 3.0f, 1.0f);*/
const int totalBlocks = 16;
const int numBlocks = roundToInt (totalBlocks * v);
const float h = (height - 6.0f) / (float) totalBlocks;
for (int i = 0; i < totalBlocks; ++i) {
g.setColour (Colours::red);
if (i >= numBlocks)
g.setColour (Colours::red.withAlpha (0.2f));
else
g.setColour (Colours::red);
//g.fillRoundedRectangle (3.0f + i * w + w * 0.1f, 3.0f, w * 0.8f, height - 6.0f, w * 0.4f);
g.fillRoundedRectangle (3.0f, (height-3.0f) - (3.0f + i * h + h * 0.1f) , width - 6.0f, h * 0.8f, 0);
}
}
DXLookNFeel::DXLookNFeel() {
setColour(TextButton::buttonColourId,Colour(0xFF0FC00F));
setColour(Slider::rotarySliderOutlineColourId,Colour(0xFF0FC00F));
setColour(Slider::rotarySliderFillColourId,Colour(0xFFFFFFFF));
}

@ -51,5 +51,9 @@ public:
DXLookNFeel();
};
class VuMeter: public Component {
void paint(Graphics &g);
public :
float v;
};
#endif // DXLOOKNFEEL_H_INCLUDED

@ -86,14 +86,6 @@ OperatorEditor::OperatorEditor ()
opMode->addItem ("FIXED", 2);
opMode->addListener (this);
addAndMakeVisible (opId = new Label ("new label",
"OP1"));
opId->setFont (Font (9.30f, Font::plain));
opId->setJustificationType (Justification::centredLeft);
opId->setEditable (false, false, false);
opId->setColour (TextEditor::textColourId, Colours::black);
opId->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
addAndMakeVisible (opLevel = new Slider ("opLevel"));
opLevel->setRange (0, 99, 1);
opLevel->setSliderStyle (Slider::Rotary);
@ -112,16 +104,6 @@ OperatorEditor::OperatorEditor ()
opCoarse->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
opCoarse->addListener (this);
addAndMakeVisible (gain = new Slider ("new slider"));
gain->setRange (0, 1, 0);
gain->setSliderStyle (Slider::LinearVertical);
gain->setTextBoxStyle (Slider::NoTextBox, true, 80, 20);
gain->setColour (Slider::thumbColourId, Colours::black);
gain->setColour (Slider::trackColourId, Colour (0x00ffffff));
gain->setColour (Slider::rotarySliderFillColourId, Colour (0x000000ff));
gain->setColour (Slider::textBoxBackgroundColourId, Colours::white);
gain->addListener (this);
addAndMakeVisible (khzDisplay = new Label ("khz",
"1,000 kHz"));
khzDisplay->setFont (Font (11.00f, Font::plain));
@ -133,7 +115,7 @@ OperatorEditor::OperatorEditor ()
khzDisplay->setColour (TextEditor::backgroundColourId, Colour (0x00000000));
addAndMakeVisible (detune = new Slider ("detune"));
detune->setRange (0, 14, 1);
detune->setRange (-7, 7, 1);
detune->setSliderStyle (Slider::LinearHorizontal);
detune->setTextBoxStyle (Slider::NoTextBox, true, 80, 20);
detune->addListener (this);
@ -203,6 +185,9 @@ OperatorEditor::OperatorEditor ()
ampModSens->setTextBoxStyle (Slider::NoTextBox, false, 80, 20);
ampModSens->addListener (this);
addAndMakeVisible (vu = new VuMeter());
vu->setName ("vu");
//[UserPreSize]
//[/UserPreSize]
@ -236,11 +221,9 @@ OperatorEditor::~OperatorEditor()
s_egv3 = nullptr;
s_egv4 = nullptr;
opMode = nullptr;
opId = nullptr;
opLevel = nullptr;
opFine = nullptr;
opCoarse = nullptr;
gain = nullptr;
khzDisplay = nullptr;
detune = nullptr;
envDisplay = nullptr;
@ -252,6 +235,7 @@ OperatorEditor::~OperatorEditor()
sclRateScaling = nullptr;
keyVelSens = nullptr;
ampModSens = nullptr;
vu = nullptr;
//[Destructor]. You can add your own custom destruction code here..
@ -264,6 +248,9 @@ void OperatorEditor::paint (Graphics& g)
//[UserPrePaint] Add your own custom painting code here..
//[/UserPrePaint]
g.setColour (Colour (0x41000000));
g.fillRect (-5, -8, 293, 100);
//[UserPaint] Add your own custom painting code here..
//[/UserPaint]
}
@ -279,11 +266,9 @@ void OperatorEditor::resized()
s_egv3->setBounds (184, 64, 24, 24);
s_egv4->setBounds (208, 64, 24, 24);
opMode->setBounds (24, 48, 104, 16);
opId->setBounds (0, 0, 24, 16);
opLevel->setBounds (232, 56, 32, 32);
opFine->setBounds (104, 24, 24, 24);
opCoarse->setBounds (80, 24, 24, 24);
gain->setBounds (260, 0, 24, 88);
khzDisplay->setBounds (32, 8, 88, 16);
detune->setBounds (24, 24, 56, 24);
envDisplay->setBounds (136, 5, 96, 32);
@ -295,6 +280,7 @@ void OperatorEditor::resized()
sclRateScaling->setBounds (0, 16, 24, 24);
keyVelSens->setBounds (240, 24, 24, 24);
ampModSens->setBounds (240, 0, 24, 24);
vu->setBounds (268, 0, 12, 88);
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
}
@ -369,11 +355,6 @@ void OperatorEditor::sliderValueChanged (Slider* sliderThatWasMoved)
updateDisplay();
//[/UserSliderCode_opCoarse]
}
else if (sliderThatWasMoved == gain)
{
//[UserSliderCode_gain] -- add your slider handling code here..
//[/UserSliderCode_gain]
}
else if (sliderThatWasMoved == detune)
{
//[UserSliderCode_detune] -- add your slider handling code here..
@ -445,12 +426,6 @@ void OperatorEditor::comboBoxChanged (ComboBox* comboBoxThatHasChanged)
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
void OperatorEditor::bind(DexedAudioProcessor *parent, int op) {
int targetNum = op+1;
String opName;
opName << "OP" << targetNum;
opId->setText(opName, NotificationType::dontSendNotification);
parent->opCtrl[op].egLevel[0]->bind(s_egl1);
parent->opCtrl[op].egLevel[1]->bind(s_egl2);
parent->opCtrl[op].egLevel[2]->bind(s_egl3);
@ -474,7 +449,8 @@ void OperatorEditor::bind(DexedAudioProcessor *parent, int op) {
void OperatorEditor::updateGain(float v) {
gain->setValue(v);
vu->v = v;
vu->repaint();
}
@ -493,7 +469,7 @@ void OperatorEditor::updateDisplay() {
txtFreq << freq << " Hz";
}
int det = detune->getValue() - 7;
int det = detune->getValue();
if ( det != 0 ) {
if ( det > 0 )
txtFreq << " +" << det;
@ -524,7 +500,9 @@ BEGIN_JUCER_METADATA
parentClasses="public Component" constructorParams="" variableInitialisers=""
snapPixels="8" snapActive="1" snapShown="1" overlayOpacity="0.330"
fixedSize="1" initialWidth="280" initialHeight="90">
<BACKGROUND backgroundColour="ffffff"/>
<BACKGROUND backgroundColour="ffffff">
<RECT pos="-5 -8 293 100" fill="solid: 41000000" hasStroke="0"/>
</BACKGROUND>
<SLIDER name="egl1" id="dc070cc41347df47" memberName="s_egl1" virtualName=""
explicitFocusOrder="0" pos="136 40 24 24" min="0" max="99" int="1"
style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1" textBoxWidth="80"
@ -560,11 +538,6 @@ BEGIN_JUCER_METADATA
<COMBOBOX name="opMode" id="2cf8156bb94cdc40" memberName="opMode" virtualName=""
explicitFocusOrder="0" pos="24 48 104 16" editable="0" layout="33"
items="RATIO&#10;FIXED" textWhenNonSelected="" textWhenNoItems="(no choices)"/>
<LABEL name="new label" id="75765097f6c5c142" memberName="opId" virtualName=""
explicitFocusOrder="0" pos="0 0 24 16" edTextCol="ff000000" edBkgCol="0"
labelText="OP1" editableSingleClick="0" editableDoubleClick="0"
focusDiscardsChanges="0" fontname="Default font" fontsize="9.3000000000000007105"
bold="0" italic="0" justification="33"/>
<SLIDER name="opLevel" id="f8521c8214fb8993" memberName="opLevel" virtualName=""
explicitFocusOrder="0" pos="232 56 32 32" min="0" max="99" int="1"
style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1" textBoxWidth="80"
@ -577,18 +550,13 @@ BEGIN_JUCER_METADATA
explicitFocusOrder="0" pos="80 24 24 24" min="0" max="31" int="1"
style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1" textBoxWidth="80"
textBoxHeight="20" skewFactor="1"/>
<SLIDER name="new slider" id="21f21cc5fae8e54b" memberName="gain" virtualName=""
explicitFocusOrder="0" pos="260 0 24 88" thumbcol="ff000000"
trackcol="ffffff" rotarysliderfill="ff" textboxbkgd="ffffffff"
min="0" max="1" int="0" style="LinearVertical" textBoxPos="NoTextBox"
textBoxEditable="0" textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<LABEL name="khz" id="eb961eed8902a6fc" memberName="khzDisplay" virtualName=""
explicitFocusOrder="0" pos="32 8 88 16" bkgCol="6a000000" outlineCol="0"
edTextCol="ff000000" edBkgCol="0" labelText="1,000 kHz" editableSingleClick="0"
editableDoubleClick="0" focusDiscardsChanges="0" fontname="Default font"
fontsize="11" bold="0" italic="0" justification="36"/>
<SLIDER name="detune" id="f093ec8defca2fc2" memberName="detune" virtualName=""
explicitFocusOrder="0" pos="24 24 56 24" min="0" max="14" int="1"
explicitFocusOrder="0" pos="24 24 56 24" min="-7" max="7" int="1"
style="LinearHorizontal" textBoxPos="NoTextBox" textBoxEditable="0"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<GENERICCOMPONENT name="envDisplay" id="b18856de924c6340" memberName="envDisplay"
@ -626,6 +594,8 @@ BEGIN_JUCER_METADATA
virtualName="" explicitFocusOrder="0" pos="240 0 24 24" min="0"
max="4" int="1" style="Rotary" textBoxPos="NoTextBox" textBoxEditable="1"
textBoxWidth="80" textBoxHeight="20" skewFactor="1"/>
<GENERICCOMPONENT name="vu" id="6f952594ea99dc1e" memberName="vu" virtualName=""
explicitFocusOrder="0" pos="268 0 12 88" class="VuMeter" params=""/>
</JUCER_COMPONENT>
END_JUCER_METADATA

@ -75,11 +75,9 @@ private:
ScopedPointer<Slider> s_egv3;
ScopedPointer<Slider> s_egv4;
ScopedPointer<ComboBox> opMode;
ScopedPointer<Label> opId;
ScopedPointer<Slider> opLevel;
ScopedPointer<Slider> opFine;
ScopedPointer<Slider> opCoarse;
ScopedPointer<Slider> gain;
ScopedPointer<Label> khzDisplay;
ScopedPointer<Slider> detune;
ScopedPointer<EnvDisplay> envDisplay;
@ -91,6 +89,7 @@ private:
ScopedPointer<Slider> sclRateScaling;
ScopedPointer<Slider> keyVelSens;
ScopedPointer<Slider> ampModSens;
ScopedPointer<VuMeter> vu;
//==============================================================================

@ -72,27 +72,27 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner
// OPERATORS
addAndMakeVisible(&(operators[0]));
operators[0].setBounds(5, 40, 280, 90);
operators[0].setBounds(5, 39, 280, 90);
operators[0].bind(processor, 0);
addAndMakeVisible(&(operators[1]));
operators[1].setBounds(290, 40, 280, 90);
operators[1].setBounds(290, 39, 280, 90);
operators[1].bind(processor, 1);
addAndMakeVisible(&(operators[2]));
operators[2].setBounds(575, 40, 280, 90);
operators[2].setBounds(575, 39, 280, 90);
operators[2].bind(processor, 2);
addAndMakeVisible(&(operators[3]));
operators[3].setBounds(5, 130, 280, 90);
operators[3].setBounds(5, 133, 280, 90);
operators[3].bind(processor, 3);
addAndMakeVisible(&(operators[4]));
operators[4].setBounds(290, 130, 280, 90);
operators[4].setBounds(290, 133, 280, 90);
operators[4].bind(processor, 4);
addAndMakeVisible(&(operators[5]));
operators[5].setBounds(575, 130, 280, 90);
operators[5].setBounds(575, 133, 280, 90);
operators[5].bind(processor, 5);
// add the midi keyboard component..
@ -141,7 +141,7 @@ void DexedAudioProcessorEditor::buttonClicked(Button *buttonThatWasClicked) {
fp_in.read((char *)syx_data, 4104);
fp_in.close();
processor->importSysex((char *) &syx_data);
processor->setCurrentProgram(0);
rebuildPresetCombobox();
presets.setSelectedId(processor->getCurrentProgram()+1, NotificationType::dontSendNotification);
@ -175,7 +175,7 @@ void DexedAudioProcessorEditor::buttonClicked(Button *buttonThatWasClicked) {
}
if (buttonThatWasClicked == storeButton) {
AlertWindow dialog(String("Store Program Destination"), "", AlertWindow::NoIcon, this);
AlertWindow dialog(String("Store Program"), "", AlertWindow::NoIcon, this);
dialog.addTextEditor(String("Name"), processor->getProgramName(processor->getCurrentProgram()), String("Name"), false);
StringArray programs;

@ -112,8 +112,8 @@ void CtrlFloat::updateComponent() {
// ************************************************************************
// CtrlDX - control DX mapping
CtrlDX::CtrlDX(String name, int steps, int offset, bool starts1) : Ctrl(name) {
add1 = starts1 == 1;
CtrlDX::CtrlDX(String name, int steps, int offset, int displayValue) : Ctrl(name) {
this->displayValue = displayValue;
this->steps = steps;
dxValue = 0;
dxOffset = offset;
@ -147,7 +147,7 @@ int CtrlDX::getValue() {
String CtrlDX::getValueDisplay() {
String ret;
ret << ( getValue() + add1 );
ret << ( getValue() + displayValue );
return ret;
}
@ -163,7 +163,7 @@ void CtrlDX::publishValue(float value) {
}
void CtrlDX::sliderValueChanged(Slider* moved) {
publishValue(((int) moved->getValue() - add1));
publishValue(((int) moved->getValue() - displayValue));
}
void CtrlDX::comboBoxChanged(ComboBox* combo) {
@ -172,7 +172,7 @@ void CtrlDX::comboBoxChanged(ComboBox* combo) {
void CtrlDX::updateComponent() {
if (slider != NULL) {
slider->setValue(getValue() + add1,
slider->setValue(getValue() + displayValue,
NotificationType::dontSendNotification);
}
@ -200,14 +200,15 @@ void CtrlDX::updateComponent() {
*/
void DexedAudioProcessor::initCtrl() {
importSysex(BinaryData::startup_syx);
currentProgram = 0;
fxCutoff = new CtrlFloat("Cutoff", &fx.uiCutoff);
ctrl.add(fxCutoff);
fxReso = new CtrlFloat("Resonance", &fx.uiReso);
ctrl.add(fxReso);
algo = new CtrlDX("ALGORITHM", 32, 134, true);
algo = new CtrlDX("ALGORITHM", 32, 134, 1);
ctrl.add(algo);
feedback = new CtrlDX("FEEDBACK", 8, 135);
@ -298,7 +299,7 @@ void DexedAudioProcessor::initCtrl() {
String detune;
detune << opName << " OSC DETUNE";
opCtrl[opVal].detune = new CtrlDX(detune, 15, opTarget + 20);
opCtrl[opVal].detune = new CtrlDX(detune, 15, opTarget + 20, -7);
ctrl.add(opCtrl[opVal].detune);
String sclBrkPt;
@ -351,10 +352,7 @@ void DexedAudioProcessor::initCtrl() {
}
}
int DexedAudioProcessor::importSysex(const char *imported) {
// reset current program
currentProgram = 0;
int DexedAudioProcessor::importSysex(const char *imported) {
memcpy(sysex, imported + 6, 4096);
for (int i = 0; i < 32; i++) {
memcpy(patchNames[i], sysex + ((i * 128) + 118), 11);
@ -524,21 +522,19 @@ int DexedAudioProcessor::getCurrentProgram() {
}
void DexedAudioProcessor::setCurrentProgram(int index) {
/*// VST has a naughty problem of calling setCurrentProgram after a host has loaded
// an edited preset. We ignore the 16th value, since we want to keep the user values
if ( index == 32 ) {
return;
}*/
for (int i = 0; i < MAX_ACTIVE_NOTES; i++) {
if (voices[i].keydown == false && voices[i].live == true) {
voices[i].live = false;
TRACE("setting program %d state %d", index, bypassVstChangeProgram);
if ( bypassVstChangeProgram ) {
for (int i = 0; i < MAX_ACTIVE_NOTES; i++) {
if (voices[i].keydown == false && voices[i].live == true) {
voices[i].live = false;
}
}
index = index > 31 ? 31 : index;
unpackProgram(index);
lfo.reset(data + 137);
}
index = index > 31 ? 31 : index;
unpackProgram(index);
bypassVstChangeProgram = 1;
currentProgram = index;
lfo.reset(data + 137);
updateUI();
}
@ -559,24 +555,65 @@ const String DexedAudioProcessor::getParameterText(int index) {
return ctrl[index]->getValueDisplay();
}
struct PluginState {
uint8_t sysex[4011];
uint8_t program[161];
float cutoff;
float reso;
};
//==============================================================================
void DexedAudioProcessor::getStateInformation(MemoryBlock& destData) {
// You should use this method to store your parameters in the memory block.
// You could do that either as raw data, or use the XML or ValueTree classes
// as intermediaries to make it easy to save and load complex data.*/
destData.insert(data, 161, 0);
// as intermediaries to make it easy to save and load complex data.
// used to SAVE plugin state
PluginState state;
exportSysex((char *)(&state.sysex));
memcpy(state.program, data, 161);
state.cutoff = fx.uiCutoff;
state.reso = fx.uiReso;
destData.insert(&state, sizeof(PluginState), 0);
}
void DexedAudioProcessor::setStateInformation(const void* source,
int sizeInBytes) {
void DexedAudioProcessor::setStateInformation(const void* source, int sizeInBytes) {
// You should use this method to restore your parameters from this memory block,
// whose contents will have been created by the getStateInformation() call.
memcpy((void *) data, source, sizeInBytes);
// used to LOAD plugin state
PluginState state;
bypassVstChangeProgram = 0;
if ( sizeInBytes < sizeof(PluginState) ) {
TRACE("too small plugin state size %d", sizeInBytes);
return;
}
if ( sizeInBytes > sizeof(PluginState) ) {
TRACE("hmmm, too big plugin state size %d", sizeInBytes);
sizeInBytes = sizeof(PluginState);
}
memcpy((void *) &state, source, sizeInBytes);
importSysex((char *) state.sysex);
memcpy(data, state.program, 161);
fx.uiCutoff = state.cutoff;
fx.uiReso = state.reso;
// TODO: this should only be set if it is a VST
TRACE("setting VST STATE");
updateUI();
}
//==============================================================================
void DexedAudioProcessor::getCurrentProgramStateInformation(
/*void DexedAudioProcessor::getCurrentProgramStateInformation(
MemoryBlock& destData) {
destData.insert(data, 161, 0);
}
@ -585,5 +622,5 @@ void DexedAudioProcessor::setCurrentProgramStateInformation(const void* source,
int sizeInBytes) {
memcpy((void *) data, source, sizeInBytes);
updateUI();
}
}*/

@ -80,11 +80,11 @@ public:
class CtrlDX : public Ctrl {
int dxValue;
int steps;
int add1;
int dxOffset;
int displayValue;
public:
CtrlDX(String name, int steps, int offset = -1, bool starts1 = false);
CtrlDX(String name, int steps, int offset = -1, int displayValue = 0);
void setValueHost(float f);
float getValueHost();
void publishValue(float value);

@ -47,6 +47,7 @@ DexedAudioProcessor::DexedAudioProcessor() {
initCtrl();
setCurrentProgram(0);
sendSysexChange = true;
bypassVstChangeProgram = 1;
}
DexedAudioProcessor::~DexedAudioProcessor() {
@ -198,6 +199,7 @@ void DexedAudioProcessor::processMidiMessage(MidiMessage *msg) {
}
TRACE("update 32bulk voice)");
importSysex((const char *)buf+4);
currentProgram = 0;
refreshUI |= REFRESH_COMP;
}
return;
@ -411,7 +413,6 @@ bool DexedAudioProcessor::hasEditor() const {
void DexedAudioProcessor::updateUI() {
AudioProcessorEditor *editor = getActiveEditor();
if ( editor == NULL ) {
TRACE("no editor found!?");
return;
}
DexedAudioProcessorEditor *dexedEditor = (DexedAudioProcessorEditor *) editor;

@ -64,6 +64,14 @@ class DexedAudioProcessor : public AudioProcessor
char sysex[4096];
char patchNames[32][13];
/**
* This flag is used to ignore change program when a VST chunk has been loaded.
* This is because the VST host will set the chunk value THEN change the program
* number. By doing this, it erase the current state of the program to the
* original one in the cartrige.
*/
bool bypassVstChangeProgram;
/**
* PlugFX
*/
@ -162,8 +170,9 @@ public :
//==============================================================================
void getStateInformation (MemoryBlock& destData);
void setStateInformation (const void* data, int sizeInBytes);
void getCurrentProgramStateInformation (MemoryBlock& destData);
void setCurrentProgramStateInformation (const void* data, int sizeInBytes);
//void getCurrentProgramStateInformation (MemoryBlock& destData);
//void setCurrentProgramStateInformation (const void* data, int sizeInBytes);
//==============================================================================
// this is kept up to date with the midi messages that arrive, and the UI component

Loading…
Cancel
Save