diff --git a/Resources/svg/microphone.svg b/Resources/svg/microphone.svg
new file mode 100644
index 0000000..33084ec
--- /dev/null
+++ b/Resources/svg/microphone.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp
index 03ce1d9..ea85c74 100644
--- a/Source/MainComponent.cpp
+++ b/Source/MainComponent.cpp
@@ -45,6 +45,10 @@ MainComponent::MainComponent(OscirenderAudioProcessor& p, OscirenderAudioProcess
pluginEditor.fileUpdated(audioProcessor.getCurrentFileName());
};
+ addAndMakeVisible(inputEnabled);
+ inputEnabled.onClick = [this] {
+ audioProcessor.inputEnabled->setBoolValueNotifyingHost(!audioProcessor.inputEnabled->getBoolValue());
+ };
addAndMakeVisible(fileLabel);
updateFileLabel();
@@ -125,6 +129,8 @@ void MainComponent::resized() {
auto row = bounds.removeFromTop(buttonHeight);
fileButton.setBounds(row.removeFromLeft(buttonWidth));
+ row.removeFromLeft(rowPadding);
+ inputEnabled.setBounds(row.removeFromLeft(20));
row.removeFromLeft(rowPadding);
fileLabel.setBounds(row);
bounds.removeFromTop(padding);
diff --git a/Source/MainComponent.h b/Source/MainComponent.h
index 955648d..57f0f05 100644
--- a/Source/MainComponent.h
+++ b/Source/MainComponent.h
@@ -7,6 +7,7 @@
#include "components/VisualiserComponent.h"
#include "audio/PitchDetector.h"
#include "UGen/ugen_JuceEnvelopeComponent.h"
+#include "components/SvgButton.h"
class OscirenderAudioProcessorEditor;
class MainComponent : public juce::GroupComponent {
@@ -24,6 +25,7 @@ private:
std::unique_ptr chooser;
juce::TextButton fileButton;
juce::TextButton closeFileButton;
+ SvgButton inputEnabled{"inputEnabled", juce::String(BinaryData::microphone_svg), "white", "red", audioProcessor.inputEnabled};
juce::Label fileLabel;
juce::TextEditor fileName;
diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp
index 105a204..d367041 100644
--- a/Source/PluginProcessor.cpp
+++ b/Source/PluginProcessor.cpp
@@ -147,6 +147,7 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
booleanParameters.push_back(perspectiveEffect->fixedRotateY);
booleanParameters.push_back(perspectiveEffect->fixedRotateZ);
booleanParameters.push_back(midiEnabled);
+ booleanParameters.push_back(inputEnabled);
for (auto parameter : booleanParameters) {
addParameter(parameter);
@@ -474,7 +475,13 @@ void OscirenderAudioProcessor::processBlock(juce::AudioBuffer& buffer, ju
auto totalNumInputChannels = getTotalNumInputChannels();
auto totalNumOutputChannels = getTotalNumOutputChannels();
- buffer.clear();
+ // clear output channels
+ for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i) {
+ buffer.clear(i, 0, buffer.getNumSamples());
+ }
+
+ bool usingInput = inputEnabled->getBoolValue();
+
bool usingMidi = midiEnabled->getBoolValue();
if (!usingMidi) {
midiMessages.clear();
@@ -495,13 +502,26 @@ void OscirenderAudioProcessor::processBlock(juce::AudioBuffer& buffer, ju
prevMidiEnabled = usingMidi;
const double EPSILON = 0.00001;
-
-
- if (volume > EPSILON) {
- juce::SpinLock::ScopedLockType lock1(parsersLock);
- juce::SpinLock::ScopedLockType lock2(effectsLock);
- synth.renderNextBlock(buffer, midiMessages, 0, buffer.getNumSamples());
+
+ if (usingInput && totalNumInputChannels >= 2) {
+ // handle all midi messages
+ auto midiIterator = midiMessages.cbegin();
+ std::for_each(midiIterator,
+ midiMessages.cend(),
+ [&] (const juce::MidiMessageMetadata& meta) { synth.publicHandleMidiEvent(meta.getMessage()); }
+ );
+ } else {
+ for (auto i = 0; i < totalNumInputChannels; ++i) {
+ buffer.clear(i, 0, buffer.getNumSamples());
+ }
+ if (volume > EPSILON) {
+ juce::SpinLock::ScopedLockType lock1(parsersLock);
+ juce::SpinLock::ScopedLockType lock2(effectsLock);
+ synth.renderNextBlock(buffer, midiMessages, 0, buffer.getNumSamples());
+ }
}
+
+
midiMessages.clear();
auto* channelData = buffer.getArrayOfWritePointers();
diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h
index c87e977..9a3936f 100644
--- a/Source/PluginProcessor.h
+++ b/Source/PluginProcessor.h
@@ -14,6 +14,7 @@
#include "audio/Effect.h"
#include "audio/ShapeSound.h"
#include "audio/ShapeVoice.h"
+#include "audio/PublicSynthesiser.h"
#include
#include "audio/AudioWebSocketServer.h"
#include "audio/DelayEffect.h"
@@ -192,6 +193,7 @@ public:
std::shared_ptr perspectiveEffect = std::make_shared(VERSION_HINT);
BooleanParameter* midiEnabled = new BooleanParameter("MIDI Enabled", "midiEnabled", VERSION_HINT, !juce::JUCEApplicationBase::isStandaloneApp());
+ BooleanParameter* inputEnabled = new BooleanParameter("Audio Input Enabled", "inputEnabled", VERSION_HINT, false);
std::atomic frequency = 440.0f;
juce::SpinLock parsersLock;
@@ -268,7 +270,7 @@ private:
std::vector> permanentEffects;
ShapeSound::Ptr defaultSound = new ShapeSound(std::make_shared());
- juce::Synthesiser synth;
+ PublicSynthesiser synth;
AudioWebSocketServer softwareOscilloscopeServer{*this};
ObjectServer objectServer{*this};
diff --git a/Source/audio/PublicSynthesiser.h b/Source/audio/PublicSynthesiser.h
new file mode 100644
index 0000000..b3e0a76
--- /dev/null
+++ b/Source/audio/PublicSynthesiser.h
@@ -0,0 +1,9 @@
+#pragma once
+#include
+
+class PublicSynthesiser : public juce::Synthesiser {
+public:
+ void publicHandleMidiEvent(const juce::MidiMessage& m) {
+ handleMidiEvent(m);
+ }
+};
\ No newline at end of file
diff --git a/osci-render.jucer b/osci-render.jucer
index 6482fb5..91fdc1d 100644
--- a/osci-render.jucer
+++ b/osci-render.jucer
@@ -18,6 +18,7 @@
+
@@ -64,6 +65,8 @@
+