kopia lustrzana https://github.com/jameshball/osci-render
Remove hacky trace effect, and replace it with a different version of the trace line effect
rodzic
6ac05f9345
commit
56db10fa69
|
@ -47,10 +47,11 @@ OscirenderAudioProcessor::OscirenderAudioProcessor() : CommonAudioProcessor(Buse
|
|||
toggleableEffects.push_back(TranslateEffectApp().build());
|
||||
toggleableEffects.push_back(SwirlEffectApp().build());
|
||||
toggleableEffects.push_back(SmoothEffect().build());
|
||||
toggleableEffects.push_back(WobbleEffect(*this).build());
|
||||
toggleableEffects.push_back(TwistEffect().build());
|
||||
toggleableEffects.push_back(DelayEffect().build());
|
||||
toggleableEffects.push_back(DashedLineEffect(*this).build());
|
||||
toggleableEffects.push_back(TwistEffect().build());
|
||||
toggleableEffects.push_back(TraceEffect(*this).build());
|
||||
toggleableEffects.push_back(WobbleEffect(*this).build());
|
||||
|
||||
auto scaleEffect = ScaleEffectApp().build();
|
||||
booleanParameters.push_back(scaleEffect->linked);
|
||||
|
@ -63,11 +64,6 @@ OscirenderAudioProcessor::OscirenderAudioProcessor() : CommonAudioProcessor(Buse
|
|||
custom->setIcon(BinaryData::lua_svg);
|
||||
toggleableEffects.push_back(custom);
|
||||
|
||||
trace->setName("Trace");
|
||||
trace->setIcon(BinaryData::trace_svg);
|
||||
toggleableEffects.push_back(trace);
|
||||
// LFO default for traceLength will be encoded in its constructor defaults (see header)
|
||||
|
||||
for (int i = 0; i < toggleableEffects.size(); i++) {
|
||||
auto effect = toggleableEffects[i];
|
||||
effect->markSelectable(false);
|
||||
|
|
|
@ -72,20 +72,6 @@ public:
|
|||
"frequency",
|
||||
VERSION_HINT, 220.0, 0.0, 4200.0));
|
||||
|
||||
std::shared_ptr<osci::Effect> trace = std::make_shared<osci::Effect>(
|
||||
std::vector<osci::EffectParameter*>{
|
||||
new osci::EffectParameter(
|
||||
"Trace Start",
|
||||
"Defines how far into the frame the drawing is started at. This has the effect of 'tracing' out the image from a single dot when animated. By default, we start drawing from the beginning of the frame, so this value is 0.0.",
|
||||
"traceStart",
|
||||
VERSION_HINT, 0.0, 0.0, 1.0, 0.001),
|
||||
new osci::EffectParameter(
|
||||
"Trace Length",
|
||||
"Defines how much of the frame is drawn per cycle. This has the effect of 'tracing' out the image from a single dot when animated. By default, we draw the whole frame, corresponding to a value of 1.0.",
|
||||
"traceLength",
|
||||
VERSION_HINT, 1.0, 0.0, 1.0, 0.001, osci::LfoType::Sawtooth),
|
||||
});
|
||||
|
||||
std::shared_ptr<DelayEffect> delayEffect = std::make_shared<DelayEffect>();
|
||||
|
||||
std::function<void(int, juce::String, juce::String)> errorCallback = [this](int lineNum, juce::String fileName, juce::String error) { notifyErrorListeners(lineNum, fileName, error); };
|
||||
|
@ -94,13 +80,7 @@ public:
|
|||
customEffect,
|
||||
new osci::EffectParameter("Lua Effect", "Controls the strength of the custom Lua effect applied. You can write your own custom effect using Lua by pressing the edit button on the right.", "customEffectStrength", VERSION_HINT, 1.0, 0.0, 1.0));
|
||||
|
||||
std::shared_ptr<PerspectiveEffect> perspectiveEffect = std::make_shared<PerspectiveEffect>();
|
||||
std::shared_ptr<osci::Effect> perspective = std::make_shared<osci::Effect>(
|
||||
perspectiveEffect,
|
||||
std::vector<osci::EffectParameter*>{
|
||||
new osci::EffectParameter("Perspective", "Controls the strength of the 3D perspective projection.", "perspectiveStrength", VERSION_HINT, 1.0, 0.0, 1.0),
|
||||
new osci::EffectParameter("FOV", "Controls the camera's field of view in degrees. A lower field of view makes the image look more flat, and a higher field of view makes the image look more 3D.", "perspectiveFov", VERSION_HINT, 50.0, 5.0, 130.0),
|
||||
});
|
||||
std::shared_ptr<osci::Effect> perspective = PerspectiveEffect().build();
|
||||
|
||||
osci::BooleanParameter* midiEnabled = new osci::BooleanParameter("MIDI Enabled", "midiEnabled", VERSION_HINT, false, "Enable MIDI input for the synth. If disabled, the synth will play a constant tone, as controlled by the frequency slider.");
|
||||
osci::BooleanParameter* inputEnabled = new osci::BooleanParameter("Audio Input Enabled", "inputEnabled", VERSION_HINT, false, "Enable to use input audio, instead of the generated audio.");
|
||||
|
|
|
@ -16,8 +16,8 @@ public:
|
|||
dashCount = juce::jmax(1.0, values[i++].load()); // Dashes per cycle
|
||||
}
|
||||
|
||||
double dashCoverage = juce::jlimit(0.0, 1.0, values[i++].load());
|
||||
double dashOffset = values[i++];
|
||||
double dashCoverage = juce::jlimit(0.0, 1.0, values[i++].load());
|
||||
|
||||
double dashLengthSamples = (sampleRate / audioProcessor.frequency) / dashCount;
|
||||
double dashPhase = framePhase * dashCount - dashOffset;
|
||||
|
@ -47,8 +47,8 @@ public:
|
|||
std::make_shared<DashedLineEffect>(audioProcessor),
|
||||
std::vector<osci::EffectParameter*>{
|
||||
new osci::EffectParameter("Dash Count", "Controls the number of dashed lines in the drawing.", "dashCount", VERSION_HINT, 16.0, 1.0, 32.0),
|
||||
new osci::EffectParameter("Dash Width", "Controls how much each dash unit is drawn.", "dashWidth", VERSION_HINT, 0.5, 0.0, 1.0),
|
||||
new osci::EffectParameter("Dash Offset", "Offsets the location of the dashed lines.", "dashOffset", VERSION_HINT, 0.0, 0.0, 1.0, 0.0001f, osci::LfoType::Sawtooth, 1.0f),
|
||||
new osci::EffectParameter("Dash Width", "Controls how much each dash unit is drawn.", "dashWidth", VERSION_HINT, 0.5, 0.0, 1.0),
|
||||
}
|
||||
);
|
||||
eff->setName("Dash");
|
||||
|
@ -56,10 +56,39 @@ public:
|
|||
return eff;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
OscirenderAudioProcessor &audioProcessor;
|
||||
private:
|
||||
const static int MAX_BUFFER = 192000;
|
||||
std::vector<osci::Point> buffer = std::vector<osci::Point>(MAX_BUFFER);
|
||||
int bufferIndex = 0;
|
||||
double framePhase = 0.0; // [0, 1]
|
||||
};
|
||||
|
||||
class TraceEffect : public DashedLineEffect {
|
||||
public:
|
||||
TraceEffect(OscirenderAudioProcessor& p) : DashedLineEffect(p) {}
|
||||
|
||||
std::shared_ptr<osci::Effect> build() const override {
|
||||
auto eff = std::make_shared<osci::Effect>(
|
||||
std::make_shared<TraceEffect>(audioProcessor),
|
||||
std::vector<osci::EffectParameter*>{
|
||||
new osci::EffectParameter(
|
||||
"Trace Start",
|
||||
"Defines how far into the frame the drawing is started at. This has the effect of 'tracing' out the image from a single dot when animated. By default, we start drawing from the beginning of the frame, so this value is 0.0.",
|
||||
"traceStart",
|
||||
VERSION_HINT, 0.0, 0.0, 1.0, 0.001
|
||||
),
|
||||
new osci::EffectParameter(
|
||||
"Trace Length",
|
||||
"Defines how much of the frame is drawn per cycle. This has the effect of 'tracing' out the image from a single dot when animated. By default, we draw the whole frame, corresponding to a value of 1.0.",
|
||||
"traceLength",
|
||||
VERSION_HINT, 1.0, 0.0, 1.0, 0.001, osci::LfoType::Sawtooth
|
||||
)
|
||||
}
|
||||
);
|
||||
eff->setName("Trace");
|
||||
eff->setIcon(BinaryData::trace_svg);
|
||||
return eff;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ public:
|
|||
std::make_shared<PerspectiveEffect>(),
|
||||
std::vector<osci::EffectParameter*>{
|
||||
new osci::EffectParameter("Perspective", "Controls the strength of the 3D perspective projection.", "perspectiveStrength", VERSION_HINT, 1.0, 0.0, 1.0),
|
||||
new osci::EffectParameter("Focal Length", "Controls the focal length of the 3D perspective effect. A higher focal length makes the image look more flat, and a lower focal length makes the image look more 3D.", "perspectiveFocalLength", VERSION_HINT, 2.0, 0.0, 10.0),
|
||||
new osci::EffectParameter("FOV", "Controls the camera's field of view in degrees. A lower field of view makes the image look more flat, and a higher field of view makes the image look more 3D.", "perspectiveFov", VERSION_HINT, 50.0, 5.0, 130.0),
|
||||
}
|
||||
);
|
||||
return eff;
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
#include "ShapeVoice.h"
|
||||
#include "../PluginProcessor.h"
|
||||
|
||||
ShapeVoice::ShapeVoice(OscirenderAudioProcessor& p, juce::AudioSampleBuffer& externalAudio) : audioProcessor(p), externalAudio(externalAudio) {
|
||||
actualTraceStart = audioProcessor.trace->getValue(0);
|
||||
actualTraceLength = audioProcessor.trace->getValue(1);
|
||||
}
|
||||
ShapeVoice::ShapeVoice(OscirenderAudioProcessor& p, juce::AudioSampleBuffer& externalAudio) : audioProcessor(p), externalAudio(externalAudio) {}
|
||||
|
||||
bool ShapeVoice::canPlaySound(juce::SynthesiserSound* sound) {
|
||||
return dynamic_cast<ShapeSound*> (sound) != nullptr;
|
||||
|
@ -93,14 +90,7 @@ void ShapeVoice::renderNextBlock(juce::AudioSampleBuffer& outputBuffer, int star
|
|||
}
|
||||
|
||||
for (auto sample = startSample; sample < startSample + numSamples; ++sample) {
|
||||
bool traceEnabled = audioProcessor.trace->enabled->getBoolValue()
|
||||
|| (audioProcessor.previewEffect && audioProcessor.previewEffect == audioProcessor.trace);
|
||||
|
||||
// update length increment
|
||||
double traceLen = traceEnabled ? actualTraceLength : 1.0;
|
||||
double traceMin = traceEnabled ? actualTraceStart : 0.0;
|
||||
double proportionalLength = std::max(0.001, traceLen) * frameLength;
|
||||
lengthIncrement = juce::jmax(proportionalLength / (audioProcessor.currentSampleRate / actualFrequency), MIN_LENGTH_INCREMENT);
|
||||
lengthIncrement = juce::jmax(frameLength / (audioProcessor.currentSampleRate / actualFrequency), MIN_LENGTH_INCREMENT);
|
||||
|
||||
osci::Point channels;
|
||||
double x = 0.0;
|
||||
|
@ -164,27 +154,11 @@ void ShapeVoice::renderNextBlock(juce::AudioSampleBuffer& outputBuffer, int star
|
|||
outputBuffer.addSample(0, sample, x * gain);
|
||||
}
|
||||
|
||||
double traceStartValue = audioProcessor.trace->getActualValue(0);
|
||||
double traceLengthValue = audioProcessor.trace->getActualValue(1);
|
||||
traceLengthValue = traceEnabled ? traceLengthValue : 1.0;
|
||||
traceStartValue = traceEnabled ? traceStartValue : 0.0;
|
||||
actualTraceLength = std::max(0.01, traceLengthValue);
|
||||
actualTraceStart = traceStartValue;
|
||||
if (actualTraceStart < 0) {
|
||||
actualTraceStart = 0;
|
||||
}
|
||||
|
||||
if (!renderingSample) {
|
||||
incrementShapeDrawing();
|
||||
}
|
||||
|
||||
double drawnFrameLength = frameLength;
|
||||
bool willLoopOver = false;
|
||||
if (traceEnabled) {
|
||||
drawnFrameLength *= actualTraceLength + actualTraceStart;
|
||||
}
|
||||
|
||||
if (!renderingSample && frameDrawn >= drawnFrameLength) {
|
||||
if (!renderingSample && frameDrawn >= frameLength) {
|
||||
double currentShapeLength = 0;
|
||||
if (currentShape < frame.size()) {
|
||||
currentShapeLength = frame[currentShape]->len;
|
||||
|
@ -192,22 +166,9 @@ void ShapeVoice::renderNextBlock(juce::AudioSampleBuffer& outputBuffer, int star
|
|||
if (sound.load() != nullptr && currentlyPlaying) {
|
||||
frameLength = sound.load()->updateFrame(frame);
|
||||
}
|
||||
frameDrawn -= drawnFrameLength;
|
||||
if (traceEnabled) {
|
||||
shapeDrawn = juce::jlimit(0.0, currentShapeLength, frameDrawn);
|
||||
}
|
||||
double prevFrameLength = frameLength;
|
||||
frameDrawn -= prevFrameLength;
|
||||
currentShape = 0;
|
||||
|
||||
// TODO: updateFrame already iterates over all the shapes,
|
||||
// so we can improve performance by calculating frameDrawn
|
||||
// and shapeDrawn directly. frameDrawn is simply actualTraceStart * frameLength
|
||||
// but shapeDrawn is the amount of the current shape that has been drawn so
|
||||
// we need to iterate over all the shapes to calculate it.
|
||||
if (traceEnabled) {
|
||||
while (frameDrawn < actualTraceStart * frameLength) {
|
||||
incrementShapeDrawing();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,14 +21,11 @@ public:
|
|||
|
||||
bool renderingSample = false;
|
||||
private:
|
||||
const double MIN_TRACE = 0.005;
|
||||
const double MIN_LENGTH_INCREMENT = 0.000001;
|
||||
|
||||
OscirenderAudioProcessor& audioProcessor;
|
||||
std::vector<std::unique_ptr<osci::Shape>> frame;
|
||||
std::atomic<ShapeSound*> sound = nullptr;
|
||||
double actualTraceStart;
|
||||
double actualTraceLength;
|
||||
|
||||
double frameLength = 0.0;
|
||||
int currentShape = 0;
|
||||
|
|
|
@ -814,13 +814,14 @@
|
|||
microphonePermissionNeeded="1" frameworkSearchPaths="/Library/Frameworks"
|
||||
extraCustomFrameworks="/Library/Frameworks/Syphon.framework"
|
||||
hardenedRuntime="1" hardenedRuntimeOptions="com.apple.security.cs.disable-library-validation,com.apple.security.device.audio-input"
|
||||
userNotes="D86A3M3H2L">
|
||||
iosDevelopmentTeamID="D86A3M3H2L">
|
||||
<CONFIGURATIONS>
|
||||
<CONFIGURATION isDebug="1" name="Debug" targetName="osci-render" customXcodeFlags="LD_RUNPATH_SEARCH_PATHS = '/Library/Frameworks',OTHER_CODE_SIGN_FLAGS = --timestamp --force --deep"
|
||||
codeSigningIdentity="Developer ID Application: James Ball (D86A3M3H2L)"/>
|
||||
<CONFIGURATION name="Release" targetName="osci-render" customXcodeFlags="LD_RUNPATH_SEARCH_PATHS = '/Library/Frameworks',CODE_SIGN_INJECT_BASE_ENTITLEMENTS=NO,OTHER_CODE_SIGN_FLAGS = --timestamp --force --deep"
|
||||
codeSigningIdentity="Developer ID Application: James Ball (D86A3M3H2L)"/>
|
||||
<CONFIGURATION name="Release (Development)" targetName="osci-render" customXcodeFlags="LD_RUNPATH_SEARCH_PATHS = '/Library/Frameworks',OTHER_CODE_SIGN_FLAGS = --timestamp --force --deep"/>
|
||||
<CONFIGURATION name="Release (Development)" targetName="osci-render" customXcodeFlags="LD_RUNPATH_SEARCH_PATHS = '/Library/Frameworks',OTHER_CODE_SIGN_FLAGS = --timestamp --force --deep"
|
||||
codeSigningIdentity="Developer ID Application: James Ball (D86A3M3H2L)"/>
|
||||
</CONFIGURATIONS>
|
||||
<MODULEPATHS>
|
||||
<MODULEPATH id="juce_audio_basics" path="../../../JUCE/modules"/>
|
||||
|
|
Ładowanie…
Reference in New Issue