Storing programs

pull/1/head
asb2m10 11 years ago
parent 7211900796
commit 26f049653b
  1. BIN
      Builds/MacOSX/Dexed.xcodeproj/project.xcworkspace/xcuserdata/asb2m10.xcuserdatad/UserInterfaceState.xcuserstate
  2. 90
      Source/PluginEditor.cpp
  3. 2
      Source/PluginEditor.h
  4. 61
      Source/PluginParam.cpp
  5. 9
      Source/PluginProcessor.h

@ -31,6 +31,7 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner
: AudioProcessorEditor (ownerFilter),
midiKeyboard (ownerFilter->keyboardState, MidiKeyboardComponent::horizontalKeyboard)
{
LookAndFeel::setDefaultLookAndFeel(&dx_lnf);
// This is where our plugin's editor size is set.
@ -38,13 +39,13 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner
processor = ownerFilter;
cachedImage_background_png = ImageCache::getFromMemory (BinaryData::background_png, BinaryData::background_pngSize);
addAndMakeVisible (loadButton = new TextButton("LOAD"));
loadButton->setButtonText ("LOAD");
loadButton->addListener (this);
loadButton->setBounds(5, 5, 50, 18);
cachedImage_background_png = ImageCache::getFromMemory (BinaryData::background_png, BinaryData::background_pngSize);
addAndMakeVisible( saveButton = new TextButton("SAVE"));
saveButton->setButtonText ("SAVE");
saveButton->addListener (this);
@ -66,12 +67,7 @@ DexedAudioProcessorEditor::DexedAudioProcessorEditor (DexedAudioProcessor* owner
presets.setTextWhenNothingSelected (String::empty);
presets.setBounds(115, 5, 180, 18);
for(int i=0;i<processor->getNumPrograms();i++) {
String id;
id << (i+1) << ". " << processor->getProgramName(i);
presets.addItem(id, i+1);
}
presets.setSelectedId(processor->getCurrentProgram()+1, NotificationType::dontSendNotification);
rebuildPresetCombobox();
presets.addListener(this);
// OPERATORS
@ -130,7 +126,7 @@ void DexedAudioProcessorEditor::paint (Graphics& g) {
void DexedAudioProcessorEditor::buttonClicked(Button *buttonThatWasClicked) {
if (buttonThatWasClicked == loadButton) {
FileChooser fc ("Import original DX sysex...", File::nonexistent, "*.syx;*.SYX", 1);
FileChooser fc ("Import original DX sysex...", File::nonexistent, "*.syx;*.SYX;*.*", 1);
if ( fc.browseForFileToOpen()) {
String f = fc.getResults().getReference(0).getFullPathName();
@ -143,14 +139,10 @@ void DexedAudioProcessorEditor::buttonClicked(Button *buttonThatWasClicked) {
return;
}
fp_in.read((char *)syx_data, 4104);
fp_in.close();
processor->importSysex((char *) &syx_data);
presets.clear(NotificationType::dontSendNotification);
for(int i=0;i<processor->getNumPrograms();i++) {
String id;
id << (i+1) << ". " << processor->getProgramName(i);
presets.addItem(id, i+1);
}
rebuildPresetCombobox();
presets.setSelectedId(processor->getCurrentProgram()+1, NotificationType::dontSendNotification);
processor->setCurrentProgram(0);
@ -160,9 +152,62 @@ void DexedAudioProcessorEditor::buttonClicked(Button *buttonThatWasClicked) {
return;
}
if (buttonThatWasClicked == saveButton) {
FileChooser fc ("Export DX sysex...", File::nonexistent, "*.syx", 1);
if ( fc.browseForFileToSave(true) ) {
String f = fc.getResults().getReference(0).getFullPathName();
uint8_t syx_data[4104];
processor->exportSysex((char *) syx_data);
ofstream fp_out(f.toRawUTF8(), ios::binary);
fp_out.write((char *)syx_data, 4104);
fp_out.close();
if (fp_out.fail()) {
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
"Error",
"Unable to write: " + f);
return;
}
}
return;
}
if (buttonThatWasClicked == storeButton) {
AlertWindow dialog(String("Store Program Destination"), "", AlertWindow::NoIcon, this);
dialog.addTextEditor(String("Name"), processor->getProgramName(processor->getCurrentProgram()), String("Name"), false);
StringArray programs;
for(int i=0;i<32;i++) {
programs.add(presets.getItemText(i));
}
dialog.addComboBox(String("Dest"), programs);
dialog.addButton("OK", 0, KeyPress(KeyPress::returnKey));
dialog.addButton("Cancel", 1, KeyPress(KeyPress::escapeKey));
if ( dialog.runModalLoop() == 0 ) {
TextEditor *name = dialog.getTextEditor(String("Name"));
ComboBox *dest = dialog.getComboBoxComponent(String("Dest"));
int programNum = dest->getSelectedItemIndex();
const char *programName = name->getText().toRawUTF8();
processor->packProgram(programNum, programName);
rebuildPresetCombobox();
processor->setCurrentProgram(programNum);
processor->updateHostDisplay();
}
return;
}
if (buttonThatWasClicked == aboutButton) {
AlertWindow::showMessageBoxAsync(AlertWindow::NoIcon, "DEXED - DX Emulator", "(c) 2013 Pascal Gauthier\nUnder the GPL v2"
"\nBased on Music Synthesizer for Android\n");
AlertWindow::showMessageBoxAsync(AlertWindow::NoIcon, "DEXED - DX Emulator 0.3", "https://github.com/asb2m10/dexed\n"
"(c) 2013 Pascal Gauthier\nUnder the GPL v2\n\n"
"Based on Music Synthesizer for Android\nhttps://code.google.com/p/music-synthesizer-for-android");
return;
}
@ -206,3 +251,14 @@ void DexedAudioProcessorEditor::updateUI() {
global.repaint();
}
void DexedAudioProcessorEditor::rebuildPresetCombobox() {
presets.clear(NotificationType::dontSendNotification);
for(int i=0;i<processor->getNumPrograms();i++) {
String id;
id << (i+1) << ". " << processor->getProgramName(i);
presets.addItem(id, i+1);
}
presets.setSelectedId(processor->getCurrentProgram()+1, NotificationType::dontSendNotification);
}

@ -60,6 +60,8 @@ public:
GlobalEditor global;
void updateUI();
void rebuildPresetCombobox();
Image cachedImage_background_png;
};

@ -352,7 +352,10 @@ void DexedAudioProcessor::initCtrl() {
}
int DexedAudioProcessor::importSysex(const char *imported) {
memcpy(sysex, imported + 6, 4104);
// reset current program
currentProgram = 0;
memcpy(sysex, imported + 6, 4096);
for (int i = 0; i < 32; i++) {
memcpy(patchNames[i], sysex + ((i * 128) + 118), 11);
@ -380,6 +383,26 @@ int DexedAudioProcessor::importSysex(const char *imported) {
return 0;
}
void DexedAudioProcessor::exportSysex(char *dest) {
uint8_t header[] = { 0xF0, 0x43, 0x00, 0x09, 0x20, 0x00 };
memcpy(dest, header, 6);
// copy 32 voices
memcpy(dest+6, sysex, 4096);
// make checksum for dump
uint8_t footer[] = { 0x00, 0xF7 };
uint8_t sum = 0;
for (int i=0; i<4096; i++)
sum = (sum + sysex[i]) % (1 << 8);
footer[0] = ((1 << 8) - sum);
memcpy(dest+4102, footer, 2);
}
/*
*/
void DexedAudioProcessor::unpackProgram(int idx) {
char *bulk = sysex + (idx * 128);
@ -419,6 +442,42 @@ void DexedAudioProcessor::unpackProgram(int idx) {
data[160] = 1;
}
void DexedAudioProcessor::packProgram(int idx, const char *name) {
char *bulk = sysex + (idx * 128);
for(int op = 0; op < 6; op++) {
// eg rate and level, brk pt, depth, scaling
memcpy(bulk + op * 17, data + op * 21, 11);
int pp = op*17;
int up = op*21;
bulk[pp+11] = (data[up+11]&0x03) | ((data[up+12]&0x03) << 2);
bulk[pp+12] = (data[up+13]&0x07) | ((data[up+20]*0x0f) << 3);
bulk[pp+13] = (data[up+14]&0x03) | ((data[up+15]*0x07) << 2);
bulk[pp+14] = data[up+16];
}
memcpy(bulk + 102, data + 126, 9); // pitch env, algo
bulk[111] = (data[135]&0x07) | ((data[136]&0x01) << 3);
memcpy(bulk + 112, data + 137, 4); // lfo
bulk[116] = (data[141]&0x01) | (((data[142]&0x07) << 1) | ((data[143]&0x07) << 4));
int eos = 0;
for(int i=0; i < 10; i++) {
char c = name[i];
if ( c == 0 )
eos = 1;
if ( eos ) {
bulk[117+i] = ' ';
continue;
}
c = c < 32 ? ' ' : c;
c = c > 127 ? ' ' : c;
bulk[117+i] = c;
}
memcpy(patchNames[idx], bulk+117, 10);
patchNames[idx][10] = 0;
}
void DexedAudioProcessor::updateProgramFromSysex(const uint8 *rawdata) {
memcpy(data, rawdata, 160);
refreshUI = true;

@ -64,10 +64,6 @@ class DexedAudioProcessor : public AudioProcessor
char sysex[4096];
char patchNames[32][13];
void packProgram(int idx);
void unpackProgram(int idx);
void updateProgramFromSysex(const uint8 *rawdata);
/**
* PlugFX
*/
@ -88,7 +84,6 @@ class DexedAudioProcessor : public AudioProcessor
void initCtrl();
public :
static const int REFRESH_MSG = 1;
static const int REFRESH_COMP = 1 << 1;
@ -118,6 +113,7 @@ public :
ScopedPointer<CtrlFloat> fxReso;
int importSysex(const char *imported);
void exportSysex(char *dest);
void setDxValue(int offset, int v);
//==============================================================================
@ -134,6 +130,9 @@ public :
bool hasEditor() const;
void updateUI();
bool peekEnvStatus(int32_t *values);
void packProgram(int idx, const char *name);
void unpackProgram(int idx);
void updateProgramFromSysex(const uint8 *rawdata);
//==============================================================================
const String getName() const;

Loading…
Cancel
Save