kopia lustrzana https://github.com/jameshball/osci-render
Add ability to save state of project to xml
rodzic
e56ec999fe
commit
c75a036048
|
@ -34,7 +34,7 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
|
||||||
{
|
{
|
||||||
producer.startThread();
|
producer.startThread();
|
||||||
|
|
||||||
juce::SpinLock::ScopedLockType lock(effectsLock);
|
// locking isn't necessary here because we are in the constructor
|
||||||
|
|
||||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||||
std::make_shared<BitCrushEffect>(),
|
std::make_shared<BitCrushEffect>(),
|
||||||
|
@ -46,19 +46,19 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
|
||||||
));
|
));
|
||||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||||
std::make_shared<RotateEffect>(),
|
std::make_shared<RotateEffect>(),
|
||||||
new EffectParameter("2D Rotate", "rotateSpeed", 0.0, 0.0, 1.0)
|
new EffectParameter("2D Rotate", "2DRotateSpeed", 0.0, 0.0, 1.0)
|
||||||
));
|
));
|
||||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||||
std::make_shared<VectorCancellingEffect>(),
|
std::make_shared<VectorCancellingEffect>(),
|
||||||
new EffectParameter("Vector Cancel", "vectorCancelling", 0.0, 0.0, 1.0)
|
new EffectParameter("Vector Cancelling", "vectorCancelling", 0.0, 0.0, 1.0)
|
||||||
));
|
));
|
||||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||||
std::make_shared<DistortEffect>(false),
|
std::make_shared<DistortEffect>(false),
|
||||||
new EffectParameter("X Distort", "horizontalDistort", 0.0, 0.0, 1.0)
|
new EffectParameter("Distort X", "distortX", 0.0, 0.0, 1.0)
|
||||||
));
|
));
|
||||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||||
std::make_shared<DistortEffect>(true),
|
std::make_shared<DistortEffect>(true),
|
||||||
new EffectParameter("Y Distort", "verticalDistort", 0.0, 0.0, 1.0)
|
new EffectParameter("Distort Y", "distortY", 0.0, 0.0, 1.0)
|
||||||
));
|
));
|
||||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||||
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
|
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
|
||||||
|
@ -77,17 +77,17 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
|
||||||
));
|
));
|
||||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||||
delayEffect,
|
delayEffect,
|
||||||
std::vector<EffectParameter*>{new EffectParameter("Delay Decay", "delayDecay", 0.0, 0.0, 1.0), new EffectParameter("Delay Length", "delayEchoLength", 0.5, 0.0, 1.0)}
|
std::vector<EffectParameter*>{new EffectParameter("Delay Decay", "delayDecay", 0.0, 0.0, 1.0), new EffectParameter("Delay Length", "delayLength", 0.5, 0.0, 1.0)}
|
||||||
));
|
));
|
||||||
toggleableEffects.push_back(std::make_shared<Effect>(
|
toggleableEffects.push_back(std::make_shared<Effect>(
|
||||||
perspectiveEffect,
|
perspectiveEffect,
|
||||||
std::vector<EffectParameter*>{
|
std::vector<EffectParameter*>{
|
||||||
new EffectParameter("3D Perspective", "depthScale", 0.0, 0.0, 1.0),
|
new EffectParameter("3D Perspective", "perspectiveStrength", 0.0, 0.0, 1.0),
|
||||||
new EffectParameter("3D Depth (z)", "zPos", 0.1, 0.0, 1.0),
|
new EffectParameter("Depth (z)", "perspectiveZPos", 0.1, 0.0, 1.0),
|
||||||
new EffectParameter("3D Rotate Speed", "rotateSpeed3D", 0.0, -1.0, 1.0),
|
new EffectParameter("Rotate Speed", "perspectiveRotateSpeed", 0.0, -1.0, 1.0),
|
||||||
new EffectParameter("Rotate X", "rotateX", 1.0, -1.0, 1.0),
|
new EffectParameter("Rotate X", "perspectiveRotateX", 1.0, -1.0, 1.0),
|
||||||
new EffectParameter("Rotate Y", "rotateY", 1.0, -1.0, 1.0),
|
new EffectParameter("Rotate Y", "perspectiveRotateY", 1.0, -1.0, 1.0),
|
||||||
new EffectParameter("Rotate Z", "rotateZ", 0.0, -1.0, 1.0),
|
new EffectParameter("Rotate Z", "perspectiveRotateZ", 0.0, -1.0, 1.0),
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
toggleableEffects.push_back(traceMax);
|
toggleableEffects.push_back(traceMax);
|
||||||
|
@ -112,11 +112,11 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
|
||||||
addLuaSlider();
|
addLuaSlider();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto effects = toggleableEffects;
|
allEffects = toggleableEffects;
|
||||||
effects.insert(effects.end(), permanentEffects.begin(), permanentEffects.end());
|
allEffects.insert(allEffects.end(), permanentEffects.begin(), permanentEffects.end());
|
||||||
effects.insert(effects.end(), luaEffects.begin(), luaEffects.end());
|
allEffects.insert(allEffects.end(), luaEffects.begin(), luaEffects.end());
|
||||||
|
|
||||||
for (auto effect : effects) {
|
for (auto effect : allEffects) {
|
||||||
for (auto effectParameter : effect->parameters) {
|
for (auto effectParameter : effect->parameters) {
|
||||||
auto parameters = effectParameter->getParameters();
|
auto parameters = effectParameter->getParameters();
|
||||||
for (auto parameter : parameters) {
|
for (auto parameter : parameters) {
|
||||||
|
@ -553,26 +553,41 @@ void OscirenderAudioProcessor::incrementShapeDrawing() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
bool OscirenderAudioProcessor::hasEditor() const
|
bool OscirenderAudioProcessor::hasEditor() const {
|
||||||
{
|
|
||||||
return true; // (change this to false if you choose to not supply an editor)
|
return true; // (change this to false if you choose to not supply an editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
juce::AudioProcessorEditor* OscirenderAudioProcessor::createEditor()
|
juce::AudioProcessorEditor* OscirenderAudioProcessor::createEditor() {
|
||||||
{
|
|
||||||
return new OscirenderAudioProcessorEditor (*this);
|
return new OscirenderAudioProcessorEditor (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
void OscirenderAudioProcessor::getStateInformation (juce::MemoryBlock& destData)
|
void OscirenderAudioProcessor::getStateInformation(juce::MemoryBlock& destData) {
|
||||||
{
|
juce::SpinLock::ScopedLockType lock1(parsersLock);
|
||||||
// You should use this method to store your parameters in the memory block.
|
juce::SpinLock::ScopedLockType lock2(effectsLock);
|
||||||
// You could do that either as raw data, or use the XML or ValueTree classes
|
|
||||||
// as intermediaries to make it easy to save and load complex data.
|
std::unique_ptr<juce::XmlElement> xml = std::make_unique<juce::XmlElement>("project");
|
||||||
|
xml->setAttribute("version", ProjectInfo::versionString);
|
||||||
|
auto effectsXml = xml->createNewChildElement("effects");
|
||||||
|
for (auto effect : allEffects) {
|
||||||
|
effect->save(effectsXml->createNewChildElement("effect"));
|
||||||
|
}
|
||||||
|
auto perspectiveFunction = xml->createNewChildElement("perspectiveFunction");
|
||||||
|
perspectiveFunction->addTextElement(juce::Base64::toBase64(perspectiveEffect->getCode()));
|
||||||
|
auto filesXml = xml->createNewChildElement("files");
|
||||||
|
|
||||||
|
for (int i = 0; i < fileBlocks.size(); i++) {
|
||||||
|
auto fileXml = filesXml->createNewChildElement("file");
|
||||||
|
fileXml->setAttribute("name", fileNames[i]);
|
||||||
|
auto fileString = juce::MemoryInputStream(*fileBlocks[i], false).readEntireStreamAsString();
|
||||||
|
fileXml->addTextElement(juce::Base64::toBase64(fileString));
|
||||||
|
}
|
||||||
|
xml->setAttribute("currentFile", currentFile);
|
||||||
|
DBG(xml->toString());
|
||||||
|
copyXmlToBinary(*xml, destData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OscirenderAudioProcessor::setStateInformation (const void* data, int sizeInBytes)
|
void OscirenderAudioProcessor::setStateInformation(const void* data, int sizeInBytes) {
|
||||||
{
|
|
||||||
// You should use this method to restore your parameters from this memory block,
|
// You should use this method to restore your parameters from this memory block,
|
||||||
// whose contents will have been created by the getStateInformation() call.
|
// whose contents will have been created by the getStateInformation() call.
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ public:
|
||||||
camera->setFocalLength(values[0]);
|
camera->setFocalLength(values[0]);
|
||||||
}
|
}
|
||||||
return input;
|
return input;
|
||||||
}, new EffectParameter("Focal length", "focalLength", 1.0, 0.0, 2.0)
|
}, new EffectParameter("Focal length", "objFocalLength", 1.0, 0.0, 2.0)
|
||||||
);
|
);
|
||||||
|
|
||||||
BooleanParameter* fixedRotateX = new BooleanParameter("Object Fixed Rotate X", "objFixedRotateX", false);
|
BooleanParameter* fixedRotateX = new BooleanParameter("Object Fixed Rotate X", "objFixedRotateX", false);
|
||||||
|
@ -214,6 +214,7 @@ private:
|
||||||
double lengthIncrement = 0.0;
|
double lengthIncrement = 0.0;
|
||||||
bool invalidateFrameBuffer = false;
|
bool invalidateFrameBuffer = false;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Effect>> allEffects;
|
||||||
std::vector<std::shared_ptr<Effect>> permanentEffects;
|
std::vector<std::shared_ptr<Effect>> permanentEffects;
|
||||||
|
|
||||||
std::shared_ptr<Effect> traceMax = std::make_shared<Effect>(
|
std::shared_ptr<Effect> traceMax = std::make_shared<Effect>(
|
||||||
|
|
|
@ -148,3 +148,12 @@ juce::String Effect::getId() {
|
||||||
juce::String Effect::getName() {
|
juce::String Effect::getName() {
|
||||||
return parameters[0]->name;
|
return parameters[0]->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Effect::save(juce::XmlElement* xml) {
|
||||||
|
if (enabled != nullptr) {
|
||||||
|
xml->setAttribute("enabled", enabled->getBoolValue());
|
||||||
|
}
|
||||||
|
for (auto parameter : parameters) {
|
||||||
|
parameter->save(xml->createNewChildElement("parameter"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ public:
|
||||||
void markEnableable(bool enabled);
|
void markEnableable(bool enabled);
|
||||||
juce::String getId();
|
juce::String getId();
|
||||||
juce::String getName();
|
juce::String getName();
|
||||||
|
void save(juce::XmlElement* xml);
|
||||||
|
|
||||||
std::vector<EffectParameter*> parameters;
|
std::vector<EffectParameter*> parameters;
|
||||||
BooleanParameter* enabled;
|
BooleanParameter* enabled;
|
||||||
|
|
|
@ -96,6 +96,14 @@ 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());
|
||||||
|
xml->setAttribute("step", step.load());
|
||||||
|
}
|
||||||
|
|
||||||
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<float> value = 0.0;
|
std::atomic<float> value = 0.0;
|
||||||
|
@ -259,6 +267,10 @@ public:
|
||||||
return (int)LfoType::Static;
|
return (int)LfoType::Static;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void save(juce::XmlElement* xml) {
|
||||||
|
xml->setAttribute("lfo", getText(getValue(), 100));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class EffectParameter : public FloatParameter {
|
class EffectParameter : public FloatParameter {
|
||||||
|
@ -287,5 +299,15 @@ public:
|
||||||
lfoRate = nullptr;
|
lfoRate = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void save(juce::XmlElement* xml) {
|
||||||
|
FloatParameter::save(xml);
|
||||||
|
|
||||||
|
if (lfo != nullptr && lfoRate != nullptr) {
|
||||||
|
auto lfoXml = xml->createNewChildElement("lfo");
|
||||||
|
lfo->save(lfoXml);
|
||||||
|
lfoRate->save(lfoXml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EffectParameter(juce::String name, juce::String id, float value, float min, float max, float step = 0.001, bool smoothValueChange = true) : FloatParameter(name, id, value, min, max, step), smoothValueChange(smoothValueChange) {}
|
EffectParameter(juce::String name, juce::String id, float value, float min, float max, float step = 0.001, bool smoothValueChange = true) : FloatParameter(name, id, value, min, max, step), smoothValueChange(smoothValueChange) {}
|
||||||
};
|
};
|
|
@ -4,7 +4,8 @@
|
||||||
addUsingNamespaceToJuceHeader="0" displaySplashScreen="0" jucerFormatVersion="1"
|
addUsingNamespaceToJuceHeader="0" displaySplashScreen="0" jucerFormatVersion="1"
|
||||||
pluginCharacteristicsValue="pluginProducesMidiOut,pluginWantsMidiIn"
|
pluginCharacteristicsValue="pluginProducesMidiOut,pluginWantsMidiIn"
|
||||||
pluginManufacturer="jameshball" aaxIdentifier="sh.ball.oscirender"
|
pluginManufacturer="jameshball" aaxIdentifier="sh.ball.oscirender"
|
||||||
cppLanguageStandard="20" projectLineFeed=" " headerPath="./include">
|
cppLanguageStandard="20" projectLineFeed=" " headerPath="./include"
|
||||||
|
version="2.0.0">
|
||||||
<MAINGROUP id="j5Ge2T" name="osci-render">
|
<MAINGROUP id="j5Ge2T" name="osci-render">
|
||||||
<GROUP id="{5ABCED88-0059-A7AF-9596-DBF91DDB0292}" name="Resources">
|
<GROUP id="{5ABCED88-0059-A7AF-9596-DBF91DDB0292}" name="Resources">
|
||||||
<GROUP id="{C2609827-4F4A-1ADA-8BA1-A40C1D92649C}" name="lua">
|
<GROUP id="{C2609827-4F4A-1ADA-8BA1-A40C1D92649C}" name="lua">
|
||||||
|
|
Ładowanie…
Reference in New Issue