2
0
Fork 0

2.3 update

Preset management.
Dark background menu.
JUCE 6.0.8 update.
This commit is contained in:
George Reales 2021-03-30 18:27:29 +02:00
parent 92383753b0
commit 576e6f52bc
7 changed files with 735 additions and 50 deletions

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]

BIN
Source/Images/main.psd Normal file

Binary file not shown.

View file

@ -16,14 +16,19 @@ It contains the basic startup code for a Juce application.
ObxdAudioProcessorEditor::ObxdAudioProcessorEditor (ObxdAudioProcessor& ownerFilter)
: AudioProcessorEditor (&ownerFilter), processor (ownerFilter),
skinFolder (processor.getSkinFolder()),
progStart (2000),
bankStart (1000),
skinStart (0),
progStart (3000),
bankStart (2000),
skinStart (1000),
skins (processor.getSkinFiles()),
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.setFirstCommandTarget(this);
@ -51,6 +56,26 @@ ObxdAudioProcessorEditor::ObxdAudioProcessorEditor (ObxdAudioProcessor& ownerFil
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)
{
knobAttachments.clear();
@ -377,13 +402,64 @@ void ObxdAudioProcessorEditor::rebuildComponents (ObxdAudioProcessor& ownerFilte
void ObxdAudioProcessorEditor::createMenu ()
{
popupMenus.clear();
PopupMenu* menu = new PopupMenu();
PopupMenu progMenu;
PopupMenu bankMenu;
PopupMenu skinMenu;
PopupMenu fileMenu;
skins = processor.getSkinFiles();
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.addItem(static_cast<int>(MenuAction::ExportPreset),
"Export Preset...",
true,
false);
fileMenu.addItem(static_cast<int>(MenuAction::ExportBank),
"Export Bank...",
true,
false);
fileMenu.addItem(static_cast<int>(MenuAction::SavePreset),
"Save Preset...",
true,
false);
fileMenu.addItem(static_cast<int>(MenuAction::RenamePreset),
"Rename Preset...",
true,
false);
fileMenu.addItem(static_cast<int>(MenuAction::NewPreset),
"New Preset...",
true,//enableNewPresetOption,
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)
@ -463,8 +539,180 @@ void ObxdAudioProcessorEditor::resultFromMenu (const Point<int> pos)
clean();
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() {
int cur = processor.getCurrentProgram() + 1;
if (cur == processor.getNumPrograms()) {

View file

@ -17,6 +17,7 @@
#include "Gui/Knob.h"
#include "Gui/TooglableButton.h"
#include "Gui/ButtonList.h"
#include "Components/SetPresetNameWindow.h"
enum KeyPressCommandIDs
{
@ -26,6 +27,23 @@ enum KeyPressCommandIDs
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 prevProgram();
void MenuActionCallback(int action);
void deleteBank();
void resized() override;
private:
Knob* addKnob (int x, int y, int d, ObxdAudioProcessor& filter, int parameter, String name, float defval);
void placeLabel (int x, int y, String text);
@ -227,7 +250,8 @@ private:
int skinStart;
Array<File> skins;
Array<File> banks;
std::unique_ptr<SetPresetNameWindow> setPresetNameWindow;
std::unique_ptr<FileChooser> fileChooser;
// Command manager
ApplicationCommandManager commandManager;
};

View file

@ -225,33 +225,6 @@ inline void ObxdAudioProcessor::processMidiPerSample (MidiBuffer::Iterator* iter
{
synth.procModWheel (midiMsg->getControllerValue() / 127.0f);
}
if (midiMsg->isController())
{
lastMovedController = midiMsg->getControllerNumber();
if (programs.currentProgramPtr->values[MIDILEARN] > 0.5f){
midiControlledParamSet = true;
bindings[lastMovedController] = lastUsedParameter;
setEngineParameterValue (MIDILEARN, 0, true);
lastMovedController = 0;
lastUsedParameter = 0;
midiControlledParamSet = false;
}
if (bindings[lastMovedController] > 0)
{
midiControlledParamSet = true;
setEngineParameterValue (bindings[lastMovedController],
midiMsg->getControllerValue() / 127.0f, true);
setEngineParameterValue (MIDILEARN, 0, true);
lastMovedController = 0;
lastUsedParameter = 0;
midiControlledParamSet = false;
}
}
if(midiMsg->isSustainPedalOn())
{
synth.sustainOn();
@ -267,20 +240,39 @@ inline void ObxdAudioProcessor::processMidiPerSample (MidiBuffer::Iterator* iter
if(midiMsg->isAllSoundOff())
{
synth.allSoundOff();
}
char* midi_data = (char*)midiMsg->getRawData();
int const status = midi_data[0] & 0xF0;
if (status == 0xC0)
{
{
//const ScopedUnlock unlocker(criticalSection);
// TODO - must issue setProgram
setCurrentProgram(midi_data[1]);
}
//sendChangeMessage();
//updateHostDisplay();
}
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();
if (programs.currentProgramPtr->values[MIDILEARN] > 0.5f){
midiControlledParamSet = true;
bindings[lastMovedController] = lastUsedParameter;
setEngineParameterValue (MIDILEARN, 0, true);
lastMovedController = 0;
lastUsedParameter = 0;
midiControlledParamSet = false;
}
if (bindings[lastMovedController] > 0)
{
midiControlledParamSet = true;
setEngineParameterValue (bindings[lastMovedController],
midiMsg->getControllerValue() / 127.0f, true);
setEngineParameterValue (MIDILEARN, 0, true);
lastMovedController = 0;
lastUsedParameter = 0;
midiControlledParamSet = false;
}
}
}
}
@ -469,6 +461,119 @@ void ObxdAudioProcessor::setCurrentProgramStateInformation(const void* data, in
}
//==============================================================================
bool ObxdAudioProcessor::deleteBank() {
currentBankFile.deleteFile();
scanAndUpdateBanks();
if (bankFiles.size() > 0)
{
loadFromFXBFile (bankFiles[0]);
}
}
void ObxdAudioProcessor::saveBank() {
saveFXBFile(currentBankFile);
}
bool ObxdAudioProcessor::loadPreset(const File& fxpFile) {
loadFromFXBFile(fxpFile);
currentPreset = fxpFile.getFileName();
currentPresetFile = fxpFile;
}
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";
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;
}
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)
{
MemoryBlock mb;
@ -563,7 +668,7 @@ bool ObxdAudioProcessor::loadFromFXBFile(const File& fxbFile)
}
currentBank = fxbFile.getFileName();
currentBankFile = fxbFile;
updateHostDisplay();
return true;
@ -588,13 +693,14 @@ bool ObxdAudioProcessor::restoreProgramSettings(const fxProgram* const prog)
//==============================================================================
void ObxdAudioProcessor::scanAndUpdateBanks()
{
bankFiles.clearQuick();
bankFiles.clear();
DirectoryIterator it (getBanksFolder(), false, "*.fxb", File::findFiles);
while (it.next())
{
bankFiles.addUsingDefaultSort (it.getFile());
DBG("Scan Banks: " << it.getFile().getFullPathName());
}
}
@ -650,6 +756,11 @@ File ObxdAudioProcessor::getBanksFolder() const
return getDocumentFolder().getChildFile("Banks");
}
File ObxdAudioProcessor::getPresetsFolder() const
{
return getDocumentFolder().getChildFile("Presets");
}
File ObxdAudioProcessor::getCurrentSkinFolder() const
{
return getSkinFolder().getChildFile(currentSkin);
@ -783,6 +894,7 @@ void ObxdAudioProcessor::setEngineParameterValue (int index, float newValue, boo
apvtState.getParameter(getEngineParameterId(index))->setValue(newValue);
}
//DBG("Set Value Parameter: " << getEngineParameterId(index) << " Val: " << newValue);
switch (index)
{
case SELF_OSC_PUSH:

View file

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