diff --git a/Source/SosciPluginEditor.cpp b/Source/SosciPluginEditor.cpp index f84f8b0..56000f2 100644 --- a/Source/SosciPluginEditor.cpp +++ b/Source/SosciPluginEditor.cpp @@ -24,9 +24,21 @@ SosciPluginEditor::SosciPluginEditor(SosciAudioProcessor& p) : CommonPluginEdito resized(); visualiserFullScreen->addListener(this); + + if (juce::JUCEApplication::isStandaloneApp()) { + juce::StandalonePluginHolder* standalone = juce::StandalonePluginHolder::getInstance(); + juce::AudioDeviceManager& manager = standalone->deviceManager; + manager.addChangeListener(this); + currentInputDevice = getInputDeviceName(); + } } SosciPluginEditor::~SosciPluginEditor() { + if (juce::JUCEApplication::isStandaloneApp()) { + juce::StandalonePluginHolder* standalone = juce::StandalonePluginHolder::getInstance(); + juce::AudioDeviceManager& manager = standalone->deviceManager; + manager.removeChangeListener(this); + } audioProcessor.visualiserParameters.visualiserFullScreen->removeListener(this); menuBar.setModel(nullptr); } @@ -98,3 +110,28 @@ void SosciPluginEditor::parameterValueChanged(int parameterIndex, float newValue } void SosciPluginEditor::parameterGestureChanged(int parameterIndex, bool gestureIsStarting) {} + +void SosciPluginEditor::changeListenerCallback(juce::ChangeBroadcaster* source) { + if (juce::JUCEApplication::isStandaloneApp()) { + juce::String inputDevice = getInputDeviceName(); + if (inputDevice != currentInputDevice) { + currentInputDevice = inputDevice; + // switch to getting audio from input if the user changes the input device + // because we assume they are debugging and want to hear the audio from mic + audioProcessor.stopAudioFile(); + } + } +} + +juce::String SosciPluginEditor::getInputDeviceName() { + if (juce::StandalonePluginHolder::getInstance() == nullptr) { + return "Unknown"; + } + juce::StandalonePluginHolder* standalone = juce::StandalonePluginHolder::getInstance(); + juce::AudioDeviceManager& manager = standalone->deviceManager; + auto device = manager.getCurrentAudioDevice(); + auto deviceType = manager.getCurrentDeviceTypeObject(); + int inputIndex = deviceType->getIndexOfDevice(device, true); + auto inputName = deviceType->getDeviceNames(true)[inputIndex]; + return inputName; +} diff --git a/Source/SosciPluginEditor.h b/Source/SosciPluginEditor.h index 405fef2..dcc8ddb 100644 --- a/Source/SosciPluginEditor.h +++ b/Source/SosciPluginEditor.h @@ -9,7 +9,7 @@ #include "components/SosciMainMenuBarModel.h" #include "components/SvgButton.h" -class SosciPluginEditor : public CommonPluginEditor, public juce::FileDragAndDropTarget, public juce::AudioProcessorParameter::Listener { +class SosciPluginEditor : public CommonPluginEditor, public juce::FileDragAndDropTarget, public juce::AudioProcessorParameter::Listener, public juce::ChangeListener { public: SosciPluginEditor(SosciAudioProcessor&); ~SosciPluginEditor() override; @@ -21,10 +21,15 @@ public: void visualiserFullScreenChanged(); void parameterValueChanged(int parameterIndex, float newValue) override; void parameterGestureChanged(int parameterIndex, bool gestureIsStarting) override; + void changeListenerCallback(juce::ChangeBroadcaster* source) override; private: SosciAudioProcessor& audioProcessor; + juce::String getInputDeviceName(); + + juce::String currentInputDevice; + ScrollableComponent visualiserSettingsWrapper = ScrollableComponent(visualiserSettings); SosciMainMenuBarModel model{*this, audioProcessor}; diff --git a/Source/components/AudioPlayerComponent.cpp b/Source/components/AudioPlayerComponent.cpp index 73604c3..2338a69 100644 --- a/Source/components/AudioPlayerComponent.cpp +++ b/Source/components/AudioPlayerComponent.cpp @@ -109,6 +109,9 @@ void AudioPlayerComponent::setPaused(bool paused) { void AudioPlayerComponent::parserChanged() { setup(); repaint(); + if (onParserChanged != nullptr) { + onParserChanged(); + } } void AudioPlayerComponent::resized() { diff --git a/Source/components/AudioPlayerComponent.h b/Source/components/AudioPlayerComponent.h index 7d0a8f5..bba3ba4 100644 --- a/Source/components/AudioPlayerComponent.h +++ b/Source/components/AudioPlayerComponent.h @@ -63,6 +63,9 @@ public: void setup(); void parserChanged() override; void setPaused(bool paused); + bool isInitialised() const { return audioProcessor.wavParser.isInitialised(); } + + std::function onParserChanged; private: CommonAudioProcessor& audioProcessor; diff --git a/Source/visualiser/VisualiserComponent.cpp b/Source/visualiser/VisualiserComponent.cpp index 446bc5a..fa74954 100644 --- a/Source/visualiser/VisualiserComponent.cpp +++ b/Source/visualiser/VisualiserComponent.cpp @@ -115,8 +115,24 @@ VisualiserComponent::VisualiserComponent( popoutWindow(); }; + if (visualiserOnly && juce::JUCEApplication::isStandaloneApp()) { + addAndMakeVisible(audioInputButton); + audioInputButton.setTooltip("Appears red when audio input is being used. Click to enable audio input and close any open audio files."); + audioInputButton.setClickingTogglesState(false); + audioInputButton.setToggleState(!audioPlayer.isInitialised(), juce::NotificationType::dontSendNotification); + audioPlayer.onParserChanged = [this] { + juce::MessageManager::callAsync([this] { + audioInputButton.setToggleState(!audioPlayer.isInitialised(), juce::NotificationType::dontSendNotification); + }); + }; + audioInputButton.onClick = [this] { + audioProcessor.stopAudioFile(); + }; + } + addAndMakeVisible(audioPlayer); + openGLContext.setRenderer(this); openGLContext.attachTo(*this); @@ -441,6 +457,9 @@ void VisualiserComponent::resized() { } else { settingsButton.setVisible(false); } + if (visualiserOnly && juce::JUCEApplication::isStandaloneApp()) { + audioInputButton.setBounds(buttons.removeFromRight(30)); + } #if SOSCI_FEATURES sharedTextureButton.setBounds(buttons.removeFromRight(30)); #endif diff --git a/Source/visualiser/VisualiserComponent.h b/Source/visualiser/VisualiserComponent.h index 70fcaad..1f3bcd7 100644 --- a/Source/visualiser/VisualiserComponent.h +++ b/Source/visualiser/VisualiserComponent.h @@ -87,6 +87,7 @@ private: SvgButton fullScreenButton{ "fullScreen", BinaryData::fullscreen_svg, juce::Colours::white, juce::Colours::white }; SvgButton popOutButton{ "popOut", BinaryData::open_in_new_svg, juce::Colours::white, juce::Colours::white }; SvgButton settingsButton{ "settings", BinaryData::cog_svg, juce::Colours::white, juce::Colours::white }; + SvgButton audioInputButton{ "audioInput", BinaryData::microphone_svg, juce::Colours::white, juce::Colours::red }; #if SOSCI_FEATURES SvgButton sharedTextureButton{ "sharedTexture", BinaryData::spout_svg, juce::Colours::white, juce::Colours::red };