2
0
Fork 0

Merge pull request #49 from reales/development

v2.3
This commit is contained in:
reales 2021-04-04 10:08:10 +02:00 committed by GitHub
commit 321dc1e304
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 746 additions and 41 deletions

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,206 @@
/*
==============================================================================
This is an automatically generated GUI class created by the Projucer!
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Created with Projucer version: 6.0.8
------------------------------------------------------------------------------
The Projucer is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited.
==============================================================================
*/
//[Headers] You can add your own extra header files here...
//[/Headers]
#include "SetPresetNameWindow.h"
//[MiscUserDefs] You can add your own user definitions and misc code here...
//[/MiscUserDefs]
//==============================================================================
SetPresetNameWindow::SetPresetNameWindow ()
{
//[Constructor_pre] You can add your own custom stuff here..
//[/Constructor_pre]
nameTextEditor.reset (new juce::TextEditor ("nameTextEditor"));
addAndMakeVisible (nameTextEditor.get());
nameTextEditor->setMultiLine (false);
nameTextEditor->setReturnKeyStartsNewLine (false);
nameTextEditor->setReadOnly (false);
nameTextEditor->setScrollbarsShown (true);
nameTextEditor->setCaretVisible (true);
nameTextEditor->setPopupMenuEnabled (false);
nameTextEditor->setColour (juce::TextEditor::backgroundColourId, juce::Colours::black);
nameTextEditor->setColour (juce::CaretComponent::caretColourId, juce::Colours::white);
nameTextEditor->setText (juce::String());
cancel.reset (new juce::TextButton ("cancel"));
addAndMakeVisible (cancel.get());
cancel->setButtonText (TRANS("Cancel"));
cancel->addListener (this);
cancel->setColour (juce::TextButton::buttonColourId, juce::Colours::black);
Ok.reset (new juce::TextButton ("Ok"));
addAndMakeVisible (Ok.get());
Ok->setButtonText (TRANS("OK"));
Ok->addListener (this);
Ok->setColour (juce::TextButton::buttonColourId, juce::Colours::black);
//[UserPreSize]
cancel->setColour (juce::ComboBox::ColourIds::outlineColourId, juce::Colours::white);
Ok->setColour (juce::ComboBox::ColourIds::outlineColourId, juce::Colours::white);
//[/UserPreSize]
setSize (300, 150);
//[Constructor] You can add your own custom stuff here..
//[/Constructor]
}
SetPresetNameWindow::~SetPresetNameWindow()
{
//[Destructor_pre]. You can add your own custom destruction code here..
//[/Destructor_pre]
nameTextEditor = nullptr;
cancel = nullptr;
Ok = nullptr;
//[Destructor]. You can add your own custom destruction code here..
//[/Destructor]
}
//==============================================================================
void SetPresetNameWindow::paint (juce::Graphics& g)
{
//[UserPrePaint] Add your own custom painting code here..
//[/UserPrePaint]
g.fillAll (juce::Colours::black);
{
int x = 0, y = proportionOfHeight (0.0000f), width = proportionOfWidth (1.0000f), height = proportionOfHeight (1.0000f);
juce::Colour fillColour = juce::Colours::black;
juce::Colour strokeColour = juce::Colour (0xff666666);
//[UserPaintCustomArguments] Customize the painting arguments here..
//[/UserPaintCustomArguments]
g.setColour (fillColour);
g.fillRect (x, y, width, height);
g.setColour (strokeColour);
g.drawRect (x, y, width, height, 1);
}
{
int x = proportionOfWidth (0.0000f), y = proportionOfHeight (0.1000f), width = proportionOfWidth (1.0000f), height = proportionOfHeight (0.2000f);
juce::String text (TRANS("Preset Name"));
juce::Colour fillColour = juce::Colours::white;
//[UserPaintCustomArguments] Customize the painting arguments here..
//[/UserPaintCustomArguments]
g.setColour (fillColour);
g.setFont (juce::Font (15.00f, juce::Font::plain).withTypefaceStyle ("Regular"));
g.drawText (text, x, y, width, height,
juce::Justification::centred, true);
}
//[UserPaint] Add your own custom painting code here..
//[/UserPaint]
}
void SetPresetNameWindow::resized()
{
//[UserPreResize] Add your own custom resize code here..
//[/UserPreResize]
nameTextEditor->setBounds (proportionOfWidth (0.1500f), proportionOfHeight (0.3467f), proportionOfWidth (0.7000f), proportionOfHeight (0.1733f));
cancel->setBounds (proportionOfWidth (0.2000f), proportionOfHeight (0.7000f), proportionOfWidth (0.2500f), proportionOfHeight (0.1600f));
Ok->setBounds (proportionOfWidth (0.5500f), proportionOfHeight (0.7000f), proportionOfWidth (0.2500f), proportionOfHeight (0.1600f));
//[UserResized] Add your own custom resize handling here..
//[/UserResized]
}
void SetPresetNameWindow::buttonClicked (juce::Button* buttonThatWasClicked)
{
//[UserbuttonClicked_Pre]
//[/UserbuttonClicked_Pre]
if (buttonThatWasClicked == cancel.get())
{
//[UserButtonCode_cancel] -- add your button handler code here..
callback(0, nameTextEditor->getText());
//[/UserButtonCode_cancel]
}
else if (buttonThatWasClicked == Ok.get())
{
//[UserButtonCode_Ok] -- add your button handler code here..
callback(1, nameTextEditor->getText());
//[/UserButtonCode_Ok]
}
//[UserbuttonClicked_Post]
//[/UserbuttonClicked_Post]
}
//[MiscUserCode] You can add your own definitions of your custom methods or any other code here...
void SetPresetNameWindow::grabTextEditorFocus()
{
nameTextEditor->grabKeyboardFocus();
};
//[/MiscUserCode]
//==============================================================================
#if 0
/* -- Projucer information section --
This is where the Projucer stores the metadata that describe this GUI layout, so
make changes in here at your peril!
BEGIN_JUCER_METADATA
<JUCER_COMPONENT documentType="Component" className="SetPresetNameWindow" componentName=""
parentClasses="public juce::Component" constructorParams="" variableInitialisers=""
snapPixels="8" snapActive="1" snapShown="1" overlayOpacity="0.330"
fixedSize="1" initialWidth="300" initialHeight="150">
<BACKGROUND backgroundColour="ff000000">
<RECT pos="0 0% 100% 100%" fill="solid: ff000000" hasStroke="1" stroke="1, mitered, butt"
strokeColour="solid: ff666666"/>
<TEXT pos="0% 10% 100% 20%" fill="solid: ffffffff" hasStroke="0" text="Preset Name"
fontname="Default font" fontsize="15.0" kerning="0.0" bold="0"
italic="0" justification="36"/>
</BACKGROUND>
<TEXTEDITOR name="nameTextEditor" id="13e287a1045d7d6d" memberName="nameTextEditor"
virtualName="" explicitFocusOrder="0" pos="15% 34.667% 70% 17.333%"
bkgcol="ff000000" caretcol="ffffffff" initialText="" multiline="0"
retKeyStartsLine="0" readonly="0" scrollbars="1" caret="1" popupmenu="0"/>
<TEXTBUTTON name="cancel" id="873979f2630a3992" memberName="cancel" virtualName=""
explicitFocusOrder="0" pos="20% 70% 25% 16%" bgColOff="ff000000"
buttonText="Cancel" connectedEdges="0" needsCallback="1" radioGroupId="0"/>
<TEXTBUTTON name="Ok" id="2874357d53dac91e" memberName="Ok" virtualName=""
explicitFocusOrder="0" pos="55% 70% 25% 16%" bgColOff="ff000000"
buttonText="OK" connectedEdges="0" needsCallback="1" radioGroupId="0"/>
</JUCER_COMPONENT>
END_JUCER_METADATA
*/
#endif
//[EndFile] You can add extra defines here...
//[/EndFile]

View file

@ -0,0 +1,75 @@
/*
==============================================================================
This is an automatically generated GUI class created by the Projucer!
Be careful when adding custom code to these files, as only the code within
the "//[xyz]" and "//[/xyz]" sections will be retained when the file is loaded
and re-saved.
Created with Projucer version: 6.0.8
------------------------------------------------------------------------------
The Projucer is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited.
==============================================================================
*/
#pragma once
//[Headers] -- You can add your own extra header files here --
#include <JuceHeader.h>
//[/Headers]
//==============================================================================
/**
//[Comments]
An auto-generated component, created by the Projucer.
Describe your class and how it works here!
//[/Comments]
*/
class SetPresetNameWindow : public juce::Component,
public juce::Button::Listener
{
public:
//==============================================================================
SetPresetNameWindow ();
~SetPresetNameWindow() override;
//==============================================================================
//[UserMethods] -- You can add your own custom methods in this section.
std::function<void(int, juce::String)> callback;
void setText(const String &txt){
nameTextEditor->setText(txt);
}
void grabTextEditorFocus();
//[/UserMethods]
void paint (juce::Graphics& g) override;
void resized() override;
void buttonClicked (juce::Button* buttonThatWasClicked) override;
private:
//[UserVariables] -- You can add your own custom variables in this section.
//[/UserVariables]
//==============================================================================
std::unique_ptr<juce::TextEditor> nameTextEditor;
std::unique_ptr<juce::TextButton> cancel;
std::unique_ptr<juce::TextButton> Ok;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SetPresetNameWindow)
};
//[EndFile] You can add extra defines here...
//[/EndFile]

View file

@ -41,7 +41,7 @@ public:
{ {
values[k] = 0.0f; values[k] = 0.0f;
} }
values[VOICE_COUNT] = 1.0f; values[VOICE_COUNT] = 0.2f;
values[BRIGHTNESS]=1.0f; values[BRIGHTNESS]=1.0f;
values[OCTAVE]=0.5; values[OCTAVE]=0.5;
values[TUNE] = 0.5f; values[TUNE] = 0.5f;

BIN
Source/Images/main.psd Normal file

Binary file not shown.

View file

@ -16,12 +16,17 @@ It contains the basic startup code for a Juce application.
ObxdAudioProcessorEditor::ObxdAudioProcessorEditor (ObxdAudioProcessor& ownerFilter) ObxdAudioProcessorEditor::ObxdAudioProcessorEditor (ObxdAudioProcessor& ownerFilter)
: AudioProcessorEditor (&ownerFilter), processor (ownerFilter), : AudioProcessorEditor (&ownerFilter), processor (ownerFilter),
skinFolder (processor.getSkinFolder()), skinFolder (processor.getSkinFolder()),
progStart (2000), progStart (3000),
bankStart (1000), bankStart (2000),
skinStart (0), skinStart (1000),
skins (processor.getSkinFiles()), skins (processor.getSkinFiles()),
banks (processor.getBankFiles()) banks (processor.getBankFiles())
{ {
LookAndFeel& lf = getLookAndFeel();
// Popup Menu Look and Feel
lf.setColour(PopupMenu::backgroundColourId, Colour(20, 20, 20));
lf.setColour(PopupMenu::textColourId, Colour(245, 245, 245));
lf.setColour(PopupMenu::highlightedBackgroundColourId, Colour(60, 60, 60));
//skinFolder = ownerFilter.getCurrentSkinFolder(); // initialized above //skinFolder = ownerFilter.getCurrentSkinFolder(); // initialized above
commandManager.registerAllCommandsForTarget(this); commandManager.registerAllCommandsForTarget(this);
@ -51,6 +56,26 @@ ObxdAudioProcessorEditor::ObxdAudioProcessorEditor (ObxdAudioProcessor& ownerFil
updateFromHost(); updateFromHost();
} }
void ObxdAudioProcessorEditor::resized() {
if (setPresetNameWindow != nullptr )
{
if (auto wrapper = dynamic_cast<ObxdAudioProcessorEditor*>(processor.getActiveEditor()))
{
auto w = proportionOfWidth(0.25f);
auto h = proportionOfHeight(0.3f);
auto x = proportionOfWidth(0.5f) - (w / 2);
auto y = wrapper->getY();
if (setPresetNameWindow != nullptr)
{
y += proportionOfHeight(0.15f);
setPresetNameWindow->setBounds(x, y, w, h);
}
}
}
}
void ObxdAudioProcessorEditor::loadSkin (ObxdAudioProcessor& ownerFilter) void ObxdAudioProcessorEditor::loadSkin (ObxdAudioProcessor& ownerFilter)
{ {
knobAttachments.clear(); knobAttachments.clear();
@ -377,13 +402,68 @@ void ObxdAudioProcessorEditor::rebuildComponents (ObxdAudioProcessor& ownerFilte
void ObxdAudioProcessorEditor::createMenu () void ObxdAudioProcessorEditor::createMenu ()
{ {
popupMenus.clear();
PopupMenu* menu = new PopupMenu(); PopupMenu* menu = new PopupMenu();
PopupMenu progMenu; PopupMenu progMenu;
PopupMenu bankMenu; PopupMenu bankMenu;
PopupMenu skinMenu; PopupMenu skinMenu;
PopupMenu fileMenu;
skins = processor.getSkinFiles(); skins = processor.getSkinFiles();
banks = processor.getBankFiles(); banks = processor.getBankFiles();
{
fileMenu.addItem(static_cast<int>(MenuAction::ImportPreset),
"Import Preset...",
true,
false);
fileMenu.addItem(static_cast<int>(MenuAction::ImportBank),
"Import Bank...",
true,
false);
fileMenu.addSeparator();
fileMenu.addItem(static_cast<int>(MenuAction::ExportPreset),
"Export Preset...",
true,
false);
fileMenu.addItem(static_cast<int>(MenuAction::ExportBank),
"Export Bank...",
true,
false);
fileMenu.addSeparator();
fileMenu.addItem(static_cast<int>(MenuAction::NewPreset),
"New Preset...",
true,//enableNewPresetOption,
false);
fileMenu.addItem(static_cast<int>(MenuAction::RenamePreset),
"Rename Preset...",
true,
false);
fileMenu.addItem(static_cast<int>(MenuAction::SavePreset),
"Save Preset...",
true,
false);
fileMenu.addItem(static_cast<int>(MenuAction::DeletePreset),
"Delete Preset...",
true,
false);
/*
fileMenu.addItem(static_cast<int>(MenuAction::DeleteBank),
"Delete Bank...",
true,
false);
*/
menu->addSubMenu("File", fileMenu);
}
{ {
for (int i = 0; i < processor.getNumPrograms(); ++i) for (int i = 0; i < processor.getNumPrograms(); ++i)
@ -463,7 +543,179 @@ void ObxdAudioProcessorEditor::resultFromMenu (const Point<int> pos)
clean(); clean();
loadSkin (processor); loadSkin (processor);
} }
else if (result < progStart){
MenuActionCallback(result);
} }
}
void ObxdAudioProcessorEditor::MenuActionCallback(int action){
if (action == MenuAction::ImportBank)
{
fileChooser = std::make_unique<juce::FileChooser>("Import Bank (*.fxb)", juce::File(), "*.fxb", true);
if (fileChooser->browseForFileToOpen()) {
File result = fileChooser->getResult();
auto name = result.getFileName().replace("%20", " ");
auto file = processor.getBanksFolder().getChildFile(name);
if (result == file || result.copyFileTo(file)){
processor.loadFromFXBFile(file);
processor.scanAndUpdateBanks();
createMenu();
}
}
};
if (action == MenuAction::ExportBank)
{
auto file = processor.getDocumentFolder().getChildFile("Banks");
FileChooser myChooser ("Export Bank (*.fxb)", file, "*.fxb", true);
if(myChooser.browseForFileToSave(true))
{
File result = myChooser.getResult();
String temp = result.getFullPathName();
if (!temp.endsWith(".fxb")) {
temp += ".fxb";
}
processor.saveBank(File(temp));
}
};
if (action == MenuAction::DeleteBank)
{
if(NativeMessageBox::showOkCancelBox(AlertWindow::NoIcon, "Delete Bank", "Delete current bank: " + processor.currentBank + "?")){
processor.deleteBank();
}
}
if (action == MenuAction::SavePreset)
{
auto presetName = processor.currentPreset;
if (presetName.isEmpty() )
{
processor.saveBank();
return;
}
processor.savePreset();
processor.saveBank();
}
if (action == MenuAction::NewPreset)
{
setPresetNameWindow = std::make_unique<SetPresetNameWindow>();
//preventBackgroundClick();
addAndMakeVisible(setPresetNameWindow.get());
resized();
auto callback = [this](int i, juce::String name)
{
if (i)
{
if (name.isNotEmpty())
{
processor.newPreset(name);
createMenu();
}
}
setPresetNameWindow.reset();
//preventBackgroundClickComponent.reset();
};
setPresetNameWindow->callback = callback;
setPresetNameWindow->grabTextEditorFocus();
return;
}
if (action == MenuAction::RenamePreset)
{
setPresetNameWindow = std::make_unique<SetPresetNameWindow>();
//preventBackgroundClick();
setPresetNameWindow->setText(processor.getProgramName(processor.getCurrentProgram()));
addAndMakeVisible(setPresetNameWindow.get());
resized();
auto callback = [this](int i, juce::String name)
{
if (i)
{
if (name.isNotEmpty())
{
processor.changePresetName(name);
createMenu();
}
}
setPresetNameWindow.reset();
//preventBackgroundClickComponent.reset();
};
setPresetNameWindow->callback = callback;
setPresetNameWindow->grabTextEditorFocus();
return;
}
if (action == MenuAction::DeletePreset)
{
if(NativeMessageBox::showOkCancelBox(AlertWindow::NoIcon, "Delete Preset", "Delete current preset " + processor.currentPreset + "?")){
processor.deletePreset();
createMenu();
}
return;
}
if (action == MenuAction::ImportPreset)
{
DBG("Import Preset");
fileChooser = std::make_unique<juce::FileChooser>("Import Preset (*.fxp)", juce::File(), "*.fxp", true);
if (fileChooser->browseForFileToOpen()) {
File result = fileChooser->getResult();
//auto name = result.getFileName().replace("%20", " ");
//auto file = processor.getPresetsFolder().getChildFile(name);
DBG("Import Preset: " << result.getFileName());
//if (result == file || result.copyFileTo(file)){
processor.loadPreset(result);
createMenu();
//}
}
};
if (action == MenuAction::ExportPreset)
{
auto file = processor.getPresetsFolder();
FileChooser myChooser ("Export Preset (*.fxp)", file, "*.fxp", true);
if(myChooser.browseForFileToSave(true))
{
File result = myChooser.getResult();
String temp = result.getFullPathName();
if (!temp.endsWith(".fxp")) {
temp += ".fxp";
}
processor.savePreset(File(temp));
}
};
}
void ObxdAudioProcessorEditor::deleteBank()
{
}
void ObxdAudioProcessorEditor::nextProgram() { void ObxdAudioProcessorEditor::nextProgram() {
int cur = processor.getCurrentProgram() + 1; int cur = processor.getCurrentProgram() + 1;

View file

@ -17,6 +17,7 @@
#include "Gui/Knob.h" #include "Gui/Knob.h"
#include "Gui/TooglableButton.h" #include "Gui/TooglableButton.h"
#include "Gui/ButtonList.h" #include "Gui/ButtonList.h"
#include "Components/SetPresetNameWindow.h"
enum KeyPressCommandIDs enum KeyPressCommandIDs
{ {
@ -26,6 +27,23 @@ enum KeyPressCommandIDs
buttonPadPrevProgram, buttonPadPrevProgram,
}; };
enum MenuAction
{
Cancel = 0,
ToggleMidiKeyboard,
ImportPreset,
ImportBank,
ExportBank,
ExportPreset,
SavePreset,
NewPreset,
RenamePreset,
DeletePreset,
DeleteBank,
ShowBanks,
LoadBank // LoadBank must be the last enum value
};
//============================================================================== //==============================================================================
/** /**
*/ */
@ -121,6 +139,11 @@ public:
void nextProgram(); void nextProgram();
void prevProgram(); void prevProgram();
void MenuActionCallback(int action);
void deleteBank();
void resized() override;
private: private:
Knob* addKnob (int x, int y, int d, ObxdAudioProcessor& filter, int parameter, String name, float defval); Knob* addKnob (int x, int y, int d, ObxdAudioProcessor& filter, int parameter, String name, float defval);
void placeLabel (int x, int y, String text); void placeLabel (int x, int y, String text);
@ -227,7 +250,8 @@ private:
int skinStart; int skinStart;
Array<File> skins; Array<File> skins;
Array<File> banks; Array<File> banks;
std::unique_ptr<SetPresetNameWindow> setPresetNameWindow;
std::unique_ptr<FileChooser> fileChooser;
// Command manager // Command manager
ApplicationCommandManager commandManager; ApplicationCommandManager commandManager;
}; };

View file

@ -225,10 +225,32 @@ inline void ObxdAudioProcessor::processMidiPerSample (MidiBuffer::Iterator* iter
{ {
synth.procModWheel (midiMsg->getControllerValue() / 127.0f); synth.procModWheel (midiMsg->getControllerValue() / 127.0f);
} }
if (midiMsg->isController()) if(midiMsg->isSustainPedalOn())
{
synth.sustainOn();
}
if(midiMsg->isSustainPedalOff() || midiMsg->isAllNotesOff()||midiMsg->isAllSoundOff())
{
synth.sustainOff();
}
if(midiMsg->isAllNotesOff())
{
synth.allNotesOff();
}
if(midiMsg->isAllSoundOff())
{
synth.allSoundOff();
}
DBG(" Message: " << midiMsg->getChannel() << " "<<midiMsg->getRawData()[0] << " "<< midiMsg->getRawData()[1] << " "<< midiMsg->getRawData()[2]);
if (midiMsg->isProgramChange()){ // xC0
setCurrentProgram(midiMsg->getProgramChangeNumber());
} else
if (midiMsg->isController()) // xB0
{ {
lastMovedController = midiMsg->getControllerNumber(); lastMovedController = midiMsg->getControllerNumber();
if (programs.currentProgramPtr->values[MIDILEARN] > 0.5f){ if (programs.currentProgramPtr->values[MIDILEARN] > 0.5f){
midiControlledParamSet = true; midiControlledParamSet = true;
bindings[lastMovedController] = lastUsedParameter; bindings[lastMovedController] = lastUsedParameter;
@ -250,25 +272,7 @@ inline void ObxdAudioProcessor::processMidiPerSample (MidiBuffer::Iterator* iter
midiControlledParamSet = false; midiControlledParamSet = false;
} }
} }
if(midiMsg->isSustainPedalOn())
{
synth.sustainOn();
}
if(midiMsg->isSustainPedalOff() || midiMsg->isAllNotesOff()||midiMsg->isAllSoundOff())
{
synth.sustainOff();
}
if(midiMsg->isAllNotesOff())
{
synth.allNotesOff();
}
if(midiMsg->isAllSoundOff())
{
synth.allSoundOff();
}
} }
} }
@ -381,7 +385,7 @@ void ObxdAudioProcessor::setStateInformation(const void* data, int sizeInBytes)
if (xmlState) if (xmlState)
{ {
XmlElement* xprogs = xmlState->getFirstChildElement(); XmlElement* xprogs = xmlState->getFirstChildElement();
if (xprogs->hasTagName(S("programs"))) if (xprogs && xprogs->hasTagName(S("programs")))
{ {
int i = 0; int i = 0;
forEachXmlChildElement(*xprogs, e) forEachXmlChildElement(*xprogs, e)
@ -457,6 +461,123 @@ void ObxdAudioProcessor::setCurrentProgramStateInformation(const void* data, in
} }
//============================================================================== //==============================================================================
bool ObxdAudioProcessor::deleteBank() {
currentBankFile.deleteFile();
scanAndUpdateBanks();
if (bankFiles.size() > 0)
{
loadFromFXBFile (bankFiles[0]);
}
return true;
}
void ObxdAudioProcessor::saveBank() {
saveFXBFile(currentBankFile);
}
bool ObxdAudioProcessor::loadPreset(const File& fxpFile) {
loadFromFXBFile(fxpFile);
currentPreset = fxpFile.getFileName();
currentPresetFile = fxpFile;
return true;
}
bool ObxdAudioProcessor::saveFXPFile(const File& fxpFile){
//auto xml = std::unique_ptr<juce::XmlElement>(new juce::XmlElement(""));
juce::MemoryBlock m, memoryBlock;
getCurrentProgramStateInformation(m);
{
memoryBlock.reset();
auto totalLen = sizeof (fxProgramSet) + m.getSize() - 8;
memoryBlock.setSize (totalLen, true);
auto set = static_cast<fxProgramSet*>(memoryBlock.getData());
set->chunkMagic = fxbName ("CcnK");
set->byteSize = 0;
set->fxMagic = fxbName ("FPCh");
set->version = fxbSwap (fxbVersionNum);
set->fxID = fxbName ("Obxd");
set->fxVersion = fxbSwap (fxbVersionNum);
set->numPrograms = fxbSwap (getNumPrograms());
programs.currentProgramPtr->name.copyToUTF8(set->name, 28);
set->chunkSize = fxbSwap (static_cast<int32>(m.getSize()));
m.copyTo (set->chunk, 0, m.getSize());
fxpFile.replaceWithData(memoryBlock.getData(), memoryBlock.getSize());
}
}
bool ObxdAudioProcessor::savePreset(const File& fxpFile) {
saveFXPFile(fxpFile);
currentPreset = fxpFile.getFileName();
currentPresetFile = fxpFile;
}
void ObxdAudioProcessor::changePresetName(const String &name){
programs.currentProgramPtr->name = name;
//savePreset();
//saveBank();
}
void ObxdAudioProcessor::deletePreset(){
programs.currentProgramPtr->setDefaultValues();
programs.currentProgramPtr->name = "Default";
sendChangeMessage();
//saveBank();
}
void ObxdAudioProcessor::newPreset(const String &name) {
for (int i = 0; i < PROGRAMCOUNT; ++i)
{
if (programs.programs[i].name == "Default"){
setCurrentProgram(i);
break;
}
}
//savePreset();
//saveBank();
}
void ObxdAudioProcessor::savePreset() {
savePreset(currentPresetFile);
}
bool ObxdAudioProcessor::saveBank(const File& fxbFile){
saveFXBFile(fxbFile);
currentBankFile = fxbFile;
return true;
}
bool ObxdAudioProcessor::saveFXBFile(const File& fxbFile) {
//auto xml = std::unique_ptr<juce::XmlElement>(new juce::XmlElement(""));
juce::MemoryBlock m, memoryBlock;
getStateInformation(m);
{
memoryBlock.reset();
auto totalLen = sizeof (fxChunkSet) + m.getSize() - 8;
memoryBlock.setSize (totalLen, true);
auto set = static_cast<fxChunkSet*>( memoryBlock.getData());
set->chunkMagic = fxbName ("CcnK");
set->byteSize = 0;
set->fxMagic = fxbName ("FBCh");
set->version = fxbSwap (fxbVersionNum);
set->fxID = fxbName ("Obxd");
set->fxVersion = fxbSwap (fxbVersionNum);
set->numPrograms = fxbSwap (getNumPrograms());
set->chunkSize = fxbSwap (static_cast<int32>(m.getSize()));
m.copyTo (set->chunk, 0, m.getSize());
fxbFile.replaceWithData(memoryBlock.getData(), memoryBlock.getSize());
}
return true;
}
bool ObxdAudioProcessor::loadFromFXBFile(const File& fxbFile) bool ObxdAudioProcessor::loadFromFXBFile(const File& fxbFile)
{ {
MemoryBlock mb; MemoryBlock mb;
@ -551,7 +672,7 @@ bool ObxdAudioProcessor::loadFromFXBFile(const File& fxbFile)
} }
currentBank = fxbFile.getFileName(); currentBank = fxbFile.getFileName();
currentBankFile = fxbFile;
updateHostDisplay(); updateHostDisplay();
return true; return true;
@ -576,13 +697,14 @@ bool ObxdAudioProcessor::restoreProgramSettings(const fxProgram* const prog)
//============================================================================== //==============================================================================
void ObxdAudioProcessor::scanAndUpdateBanks() void ObxdAudioProcessor::scanAndUpdateBanks()
{ {
bankFiles.clearQuick(); bankFiles.clear();
DirectoryIterator it (getBanksFolder(), false, "*.fxb", File::findFiles); DirectoryIterator it (getBanksFolder(), false, "*.fxb", File::findFiles);
while (it.next()) while (it.next())
{ {
bankFiles.addUsingDefaultSort (it.getFile()); bankFiles.addUsingDefaultSort (it.getFile());
DBG("Scan Banks: " << it.getFile().getFullPathName());
} }
} }
@ -638,6 +760,11 @@ File ObxdAudioProcessor::getBanksFolder() const
return getDocumentFolder().getChildFile("Banks"); return getDocumentFolder().getChildFile("Banks");
} }
File ObxdAudioProcessor::getPresetsFolder() const
{
return getDocumentFolder().getChildFile("Presets");
}
File ObxdAudioProcessor::getCurrentSkinFolder() const File ObxdAudioProcessor::getCurrentSkinFolder() const
{ {
return getSkinFolder().getChildFile(currentSkin); return getSkinFolder().getChildFile(currentSkin);
@ -771,6 +898,7 @@ void ObxdAudioProcessor::setEngineParameterValue (int index, float newValue, boo
apvtState.getParameter(getEngineParameterId(index))->setValue(newValue); apvtState.getParameter(getEngineParameterId(index))->setValue(newValue);
} }
//DBG("Set Value Parameter: " << getEngineParameterId(index) << " Val: " << newValue);
switch (index) switch (index)
{ {
case SELF_OSC_PUSH: case SELF_OSC_PUSH:

View file

@ -167,7 +167,17 @@ public:
void scanAndUpdateSkins(); void scanAndUpdateSkins();
const Array<File>& getBankFiles() const; const Array<File>& getBankFiles() const;
const Array<File>& getSkinFiles() const; const Array<File>& getSkinFiles() const;
bool deleteBank();
bool loadPreset(const File& fxpFile);
bool savePreset(const File& fxpFile);
void changePresetName(const String &name);
void newPreset(const String &name);
void deletePreset();
bool loadFromFXBFile(const File& fxbFile); bool loadFromFXBFile(const File& fxbFile);
bool saveFXBFile(const File& fxbFile);
bool saveFXPFile(const File& fxpFile);
bool saveBank(const File& fxbFile);
bool restoreProgramSettings(const fxProgram* const prog); bool restoreProgramSettings(const fxProgram* const prog);
File getCurrentBankFile() const; File getCurrentBankFile() const;
@ -178,6 +188,7 @@ public:
//============================================================================== //==============================================================================
File getDocumentFolder() const; File getDocumentFolder() const;
File getSkinFolder() const; File getSkinFolder() const;
File getPresetsFolder() const;
File getBanksFolder() const; File getBanksFolder() const;
File getCurrentSkinFolder() const; File getCurrentSkinFolder() const;
@ -209,7 +220,16 @@ private:
ObxdBank programs; ObxdBank programs;
String currentSkin; String currentSkin;
public:
String currentBank; String currentBank;
File currentBankFile;
void saveBank();
String currentPreset;
File currentPresetFile;
void savePreset();
private:
Array<File> bankFiles; Array<File> bankFiles;
Array<File> skinFiles; Array<File> skinFiles;