Save ADSR and voice info to state and add Create New Project option

pull/170/head
James Ball 2023-12-21 14:43:15 +00:00
rodzic fd8935a589
commit 185737dea8
8 zmienionych plików z 118 dodań i 9 usunięć

Wyświetl plik

@ -46,6 +46,8 @@ MidiComponent::MidiComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
audioProcessor.sustainLevel->addListener(this);
audioProcessor.releaseTime->addListener(this);
audioProcessor.releaseShape->addListener(this);
handleAsyncUpdate();
}
MidiComponent::~MidiComponent() {

Wyświetl plik

@ -240,6 +240,8 @@ void OscirenderAudioProcessorEditor::changeListenerCallback(juce::ChangeBroadcas
if (source == &audioProcessor.broadcaster) {
initialiseCodeEditors();
settings.update();
resized();
repaint();
} else if (source == &audioProcessor.fileChangeBroadcaster) {
// triggered when the audioProcessor changes the current file (e.g. to Blender)
settings.fileUpdated(audioProcessor.getCurrentFileName());
@ -401,3 +403,10 @@ void OscirenderAudioProcessorEditor::openAudioSettings() {
juce::StandalonePluginHolder* standalone = juce::StandalonePluginHolder::getInstance();
standalone->showAudioSettingsDialog();
}
void OscirenderAudioProcessorEditor::resetToDefault() {
juce::StandaloneFilterWindow* window = findParentComponentOfClass<juce::StandaloneFilterWindow>();
if (window != nullptr) {
window->resetToDefaultState();
}
}

Wyświetl plik

@ -33,6 +33,7 @@ public:
void saveProjectAs();
void updateTitle();
void openAudioSettings();
void resetToDefault();
std::atomic<bool> editingPerspective = false;

Wyświetl plik

@ -148,20 +148,29 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
addParameter(parameter);
}
addParameter(attackTime);
addParameter(attackLevel);
addParameter(attackShape);
addParameter(decayTime);
addParameter(decayShape);
addParameter(sustainLevel);
addParameter(releaseTime);
addParameter(releaseShape);
floatParameters.push_back(attackTime);
floatParameters.push_back(attackLevel);
floatParameters.push_back(attackShape);
floatParameters.push_back(decayTime);
floatParameters.push_back(decayShape);
floatParameters.push_back(sustainLevel);
floatParameters.push_back(releaseTime);
floatParameters.push_back(releaseShape);
for (auto parameter : floatParameters) {
addParameter(parameter);
}
for (int i = 0; i < voices->getValueUnnormalised(); i++) {
synth.addVoice(new ShapeVoice(*this));
}
addParameter(voices);
intParameters.push_back(voices);
for (auto parameter : intParameters) {
addParameter(parameter);
}
voices->addListener(this);
synth.addSound(defaultSound);
@ -332,6 +341,26 @@ BooleanParameter* OscirenderAudioProcessor::getBooleanParameter(juce::String id)
return nullptr;
}
// effectsLock should be held when calling this
FloatParameter* OscirenderAudioProcessor::getFloatParameter(juce::String id) {
for (auto& parameter : floatParameters) {
if (parameter->paramID == id) {
return parameter;
}
}
return nullptr;
}
// effectsLock should be held when calling this
IntParameter* OscirenderAudioProcessor::getIntParameter(juce::String id) {
for (auto& parameter : intParameters) {
if (parameter->paramID == id) {
return parameter;
}
}
return nullptr;
}
// effectsLock MUST be held when calling this
void OscirenderAudioProcessor::updateEffectPrecedence() {
auto sortFunc = [](std::shared_ptr<Effect> a, std::shared_ptr<Effect> b) {
@ -639,6 +668,18 @@ void OscirenderAudioProcessor::getStateInformation(juce::MemoryBlock& destData)
parameter->save(parameterXml);
}
auto floatParametersXml = xml->createNewChildElement("floatParameters");
for (auto parameter : floatParameters) {
auto parameterXml = floatParametersXml->createNewChildElement("parameter");
parameter->save(parameterXml);
}
auto intParametersXml = xml->createNewChildElement("intParameters");
for (auto parameter : intParameters) {
auto parameterXml = intParametersXml->createNewChildElement("parameter");
parameter->save(parameterXml);
}
auto perspectiveFunction = xml->createNewChildElement("perspectiveFunction");
perspectiveFunction->addTextElement(juce::Base64::toBase64(perspectiveEffect->getCode()));
@ -703,6 +744,26 @@ void OscirenderAudioProcessor::setStateInformation(const void* data, int sizeInB
}
}
auto floatParametersXml = xml->getChildByName("floatParameters");
if (floatParametersXml != nullptr) {
for (auto parameterXml : floatParametersXml->getChildIterator()) {
auto parameter = getFloatParameter(parameterXml->getStringAttribute("id"));
if (parameter != nullptr) {
parameter->load(parameterXml);
}
}
}
auto intParametersXml = xml->getChildByName("intParameters");
if (intParametersXml != nullptr) {
for (auto parameterXml : intParametersXml->getChildIterator()) {
auto parameter = getIntParameter(parameterXml->getStringAttribute("id"));
if (parameter != nullptr) {
parameter->load(parameterXml);
}
}
}
auto perspectiveFunction = xml->getChildByName("perspectiveFunction");
if (perspectiveFunction != nullptr) {
auto stream = juce::MemoryOutputStream();

Wyświetl plik

@ -317,6 +317,8 @@ private:
bool prevMidiEnabled = !midiEnabled->getBoolValue();
std::vector<BooleanParameter*> booleanParameters;
std::vector<FloatParameter*> floatParameters;
std::vector<IntParameter*> intParameters;
std::vector<std::shared_ptr<Effect>> allEffects;
std::vector<std::shared_ptr<Effect>> permanentEffects;
@ -332,6 +334,8 @@ private:
void updateObjValues();
std::shared_ptr<Effect> getEffect(juce::String id);
BooleanParameter* getBooleanParameter(juce::String id);
FloatParameter* getFloatParameter(juce::String id);
IntParameter* getIntParameter(juce::String id);
void openLegacyProject(const juce::XmlElement* xml);
std::pair<std::shared_ptr<Effect>, EffectParameter*> effectFromLegacyId(const juce::String& id, bool updatePrecedence = false);
LfoType lfoTypeFromLegacyAnimationType(const juce::String& type);

Wyświetl plik

@ -858,6 +858,12 @@ void EnvelopeComponent::mouseEnter(const juce::MouseEvent& e)
EnvelopeHandleComponent* handle = findHandle(convertPixelsToDomain(e.x));
EnvelopeHandleComponent* prevHandle = handle->getPreviousHandle();
if (handle == nullptr || prevHandle == nullptr) {
adjustable = false;
setMouseCursor(juce::MouseCursor::NormalCursor);
return;
}
auto handleBounds = handle->getBoundsInParent();
auto prevHandleBounds = prevHandle->getBoundsInParent();

Wyświetl plik

@ -227,6 +227,26 @@ public:
return juce::AudioProcessorParameter::genericParameter;
}
void save(juce::XmlElement* xml) {
xml->setAttribute("id", paramID);
xml->setAttribute("value", value.load());
xml->setAttribute("min", min.load());
xml->setAttribute("max", max.load());
}
// opt to not change any values if not found
void load(juce::XmlElement* xml) {
if (xml->hasAttribute("value")) {
value = xml->getIntAttribute("value");
}
if (xml->hasAttribute("min")) {
min = xml->getIntAttribute("min");
}
if (xml->hasAttribute("max")) {
max = xml->getIntAttribute("max");
}
}
private:
// value is not necessarily in the range [min, max] so effect applications may need to clip to a valid range
std::atomic<int> value = 0;

Wyświetl plik

@ -16,6 +16,9 @@ juce::PopupMenu MainMenuBarModel::getMenuForIndex(int topLevelMenuIndex, const j
menu.addItem(1, "Open");
menu.addItem(2, "Save");
menu.addItem(3, "Save As");
if (editor.processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone) {
menu.addItem(4, "Create New Project");
}
} else if (topLevelMenuIndex == 1) {
menu.addItem(1, "Audio Settings");
}
@ -36,6 +39,9 @@ void MainMenuBarModel::menuItemSelected(int menuItemID, int topLevelMenuIndex) {
case 3:
editor.saveProjectAs();
break;
case 4:
editor.resetToDefault();
break;
default:
break;
}