kopia lustrzana https://github.com/jameshball/osci-render
Save ADSR and voice info to state and add Create New Project option
rodzic
fd8935a589
commit
185737dea8
|
@ -46,6 +46,8 @@ MidiComponent::MidiComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
|
||||||
audioProcessor.sustainLevel->addListener(this);
|
audioProcessor.sustainLevel->addListener(this);
|
||||||
audioProcessor.releaseTime->addListener(this);
|
audioProcessor.releaseTime->addListener(this);
|
||||||
audioProcessor.releaseShape->addListener(this);
|
audioProcessor.releaseShape->addListener(this);
|
||||||
|
|
||||||
|
handleAsyncUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
MidiComponent::~MidiComponent() {
|
MidiComponent::~MidiComponent() {
|
||||||
|
|
|
@ -240,6 +240,8 @@ void OscirenderAudioProcessorEditor::changeListenerCallback(juce::ChangeBroadcas
|
||||||
if (source == &audioProcessor.broadcaster) {
|
if (source == &audioProcessor.broadcaster) {
|
||||||
initialiseCodeEditors();
|
initialiseCodeEditors();
|
||||||
settings.update();
|
settings.update();
|
||||||
|
resized();
|
||||||
|
repaint();
|
||||||
} else if (source == &audioProcessor.fileChangeBroadcaster) {
|
} else if (source == &audioProcessor.fileChangeBroadcaster) {
|
||||||
// triggered when the audioProcessor changes the current file (e.g. to Blender)
|
// triggered when the audioProcessor changes the current file (e.g. to Blender)
|
||||||
settings.fileUpdated(audioProcessor.getCurrentFileName());
|
settings.fileUpdated(audioProcessor.getCurrentFileName());
|
||||||
|
@ -401,3 +403,10 @@ void OscirenderAudioProcessorEditor::openAudioSettings() {
|
||||||
juce::StandalonePluginHolder* standalone = juce::StandalonePluginHolder::getInstance();
|
juce::StandalonePluginHolder* standalone = juce::StandalonePluginHolder::getInstance();
|
||||||
standalone->showAudioSettingsDialog();
|
standalone->showAudioSettingsDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OscirenderAudioProcessorEditor::resetToDefault() {
|
||||||
|
juce::StandaloneFilterWindow* window = findParentComponentOfClass<juce::StandaloneFilterWindow>();
|
||||||
|
if (window != nullptr) {
|
||||||
|
window->resetToDefaultState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ public:
|
||||||
void saveProjectAs();
|
void saveProjectAs();
|
||||||
void updateTitle();
|
void updateTitle();
|
||||||
void openAudioSettings();
|
void openAudioSettings();
|
||||||
|
void resetToDefault();
|
||||||
|
|
||||||
std::atomic<bool> editingPerspective = false;
|
std::atomic<bool> editingPerspective = false;
|
||||||
|
|
||||||
|
|
|
@ -148,20 +148,29 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
|
||||||
addParameter(parameter);
|
addParameter(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
addParameter(attackTime);
|
floatParameters.push_back(attackTime);
|
||||||
addParameter(attackLevel);
|
floatParameters.push_back(attackLevel);
|
||||||
addParameter(attackShape);
|
floatParameters.push_back(attackShape);
|
||||||
addParameter(decayTime);
|
floatParameters.push_back(decayTime);
|
||||||
addParameter(decayShape);
|
floatParameters.push_back(decayShape);
|
||||||
addParameter(sustainLevel);
|
floatParameters.push_back(sustainLevel);
|
||||||
addParameter(releaseTime);
|
floatParameters.push_back(releaseTime);
|
||||||
addParameter(releaseShape);
|
floatParameters.push_back(releaseShape);
|
||||||
|
|
||||||
|
for (auto parameter : floatParameters) {
|
||||||
|
addParameter(parameter);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < voices->getValueUnnormalised(); i++) {
|
for (int i = 0; i < voices->getValueUnnormalised(); i++) {
|
||||||
synth.addVoice(new ShapeVoice(*this));
|
synth.addVoice(new ShapeVoice(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
addParameter(voices);
|
intParameters.push_back(voices);
|
||||||
|
|
||||||
|
for (auto parameter : intParameters) {
|
||||||
|
addParameter(parameter);
|
||||||
|
}
|
||||||
|
|
||||||
voices->addListener(this);
|
voices->addListener(this);
|
||||||
|
|
||||||
synth.addSound(defaultSound);
|
synth.addSound(defaultSound);
|
||||||
|
@ -332,6 +341,26 @@ BooleanParameter* OscirenderAudioProcessor::getBooleanParameter(juce::String id)
|
||||||
return nullptr;
|
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
|
// effectsLock MUST be held when calling this
|
||||||
void OscirenderAudioProcessor::updateEffectPrecedence() {
|
void OscirenderAudioProcessor::updateEffectPrecedence() {
|
||||||
auto sortFunc = [](std::shared_ptr<Effect> a, std::shared_ptr<Effect> b) {
|
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);
|
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");
|
auto perspectiveFunction = xml->createNewChildElement("perspectiveFunction");
|
||||||
perspectiveFunction->addTextElement(juce::Base64::toBase64(perspectiveEffect->getCode()));
|
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");
|
auto perspectiveFunction = xml->getChildByName("perspectiveFunction");
|
||||||
if (perspectiveFunction != nullptr) {
|
if (perspectiveFunction != nullptr) {
|
||||||
auto stream = juce::MemoryOutputStream();
|
auto stream = juce::MemoryOutputStream();
|
||||||
|
|
|
@ -317,6 +317,8 @@ private:
|
||||||
bool prevMidiEnabled = !midiEnabled->getBoolValue();
|
bool prevMidiEnabled = !midiEnabled->getBoolValue();
|
||||||
|
|
||||||
std::vector<BooleanParameter*> booleanParameters;
|
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>> allEffects;
|
||||||
std::vector<std::shared_ptr<Effect>> permanentEffects;
|
std::vector<std::shared_ptr<Effect>> permanentEffects;
|
||||||
|
|
||||||
|
@ -332,6 +334,8 @@ private:
|
||||||
void updateObjValues();
|
void updateObjValues();
|
||||||
std::shared_ptr<Effect> getEffect(juce::String id);
|
std::shared_ptr<Effect> getEffect(juce::String id);
|
||||||
BooleanParameter* getBooleanParameter(juce::String id);
|
BooleanParameter* getBooleanParameter(juce::String id);
|
||||||
|
FloatParameter* getFloatParameter(juce::String id);
|
||||||
|
IntParameter* getIntParameter(juce::String id);
|
||||||
void openLegacyProject(const juce::XmlElement* xml);
|
void openLegacyProject(const juce::XmlElement* xml);
|
||||||
std::pair<std::shared_ptr<Effect>, EffectParameter*> effectFromLegacyId(const juce::String& id, bool updatePrecedence = false);
|
std::pair<std::shared_ptr<Effect>, EffectParameter*> effectFromLegacyId(const juce::String& id, bool updatePrecedence = false);
|
||||||
LfoType lfoTypeFromLegacyAnimationType(const juce::String& type);
|
LfoType lfoTypeFromLegacyAnimationType(const juce::String& type);
|
||||||
|
|
|
@ -858,6 +858,12 @@ void EnvelopeComponent::mouseEnter(const juce::MouseEvent& e)
|
||||||
EnvelopeHandleComponent* handle = findHandle(convertPixelsToDomain(e.x));
|
EnvelopeHandleComponent* handle = findHandle(convertPixelsToDomain(e.x));
|
||||||
EnvelopeHandleComponent* prevHandle = handle->getPreviousHandle();
|
EnvelopeHandleComponent* prevHandle = handle->getPreviousHandle();
|
||||||
|
|
||||||
|
if (handle == nullptr || prevHandle == nullptr) {
|
||||||
|
adjustable = false;
|
||||||
|
setMouseCursor(juce::MouseCursor::NormalCursor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
auto handleBounds = handle->getBoundsInParent();
|
auto handleBounds = handle->getBoundsInParent();
|
||||||
auto prevHandleBounds = prevHandle->getBoundsInParent();
|
auto prevHandleBounds = prevHandle->getBoundsInParent();
|
||||||
|
|
||||||
|
|
|
@ -227,6 +227,26 @@ public:
|
||||||
return juce::AudioProcessorParameter::genericParameter;
|
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:
|
private:
|
||||||
// value is not necessarily in the range [min, max] so effect applications may need to clip to a valid range
|
// 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;
|
std::atomic<int> value = 0;
|
||||||
|
|
|
@ -16,6 +16,9 @@ juce::PopupMenu MainMenuBarModel::getMenuForIndex(int topLevelMenuIndex, const j
|
||||||
menu.addItem(1, "Open");
|
menu.addItem(1, "Open");
|
||||||
menu.addItem(2, "Save");
|
menu.addItem(2, "Save");
|
||||||
menu.addItem(3, "Save As");
|
menu.addItem(3, "Save As");
|
||||||
|
if (editor.processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone) {
|
||||||
|
menu.addItem(4, "Create New Project");
|
||||||
|
}
|
||||||
} else if (topLevelMenuIndex == 1) {
|
} else if (topLevelMenuIndex == 1) {
|
||||||
menu.addItem(1, "Audio Settings");
|
menu.addItem(1, "Audio Settings");
|
||||||
}
|
}
|
||||||
|
@ -36,6 +39,9 @@ void MainMenuBarModel::menuItemSelected(int menuItemID, int topLevelMenuIndex) {
|
||||||
case 3:
|
case 3:
|
||||||
editor.saveProjectAs();
|
editor.saveProjectAs();
|
||||||
break;
|
break;
|
||||||
|
case 4:
|
||||||
|
editor.resetToDefault();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue