/******************************************************************************* The block below describes the properties of this PIP. A PIP is a short snippet of code that can be read by the Projucer and used to generate a JUCE project. BEGIN_JUCE_PIP_METADATA name: JuceADMIssues version: 1 vendor: nh@sonnox.co.uk description: Demonstrates discrepencies with the AudioDeviceManager and AudioDeviceSelectorComponent dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, juce_audio_processors, juce_audio_utils, juce_core, juce_cryptography, juce_data_structures, juce_events, juce_graphics, juce_gui_basics, juce_gui_extra, juce_opengl, juce_video exporters: xcode_mac type: Component mainClass: MyComponent END_JUCE_PIP_METADATA *******************************************************************************/ #pragma once //============================================================================== class MyComponent : public Component , private ChangeListener { public: //============================================================================== MyComponent() : m_AudioDeviceManager() , m_DeviceSelector(m_AudioDeviceManager, 1, 64, 1, 64, false, false, false, false) { setSize (600, 400); m_AudioDeviceManager.initialise (64, 64, nullptr, false); m_AudioDeviceManager.addChangeListener (this); m_DeviceSelector.setItemHeight (46); addAndMakeVisible (m_DeviceSelector); } ~MyComponent() { } //============================================================================== void paint (Graphics& g) override { g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); } void resized() override { m_DeviceSelector.setBounds (getLocalBounds()); } void changeListenerCallback (ChangeBroadcaster*) override { DBG ("\nchangeListenerCallback: AudioDeviceManager state:"); String allegedOutputDevice; String allegedInputDevice; if (ScopedPointer xmlState = m_AudioDeviceManager.createStateXml()) { allegedOutputDevice = xmlState->getStringAttribute ("audioOutputDeviceName"); allegedInputDevice = xmlState->getStringAttribute ("audioInputDeviceName"); } DBG (" createStateXML: I/O = \"" + allegedInputDevice + "\" / \"" + allegedOutputDevice + "\""); AudioDeviceManager::AudioDeviceSetup setup; m_AudioDeviceManager.getAudioDeviceSetup (setup); allegedOutputDevice = setup.outputDeviceName; allegedInputDevice = setup.inputDeviceName; DBG (" AudioDeviceSetup: I/O = \"" + allegedInputDevice + "\" / \"" + allegedOutputDevice + "\""); DBG ("Actual System Devices:"); // check if the input output device names exist: StringArray inputDevices; StringArray outputDevices; { OwnedArray deviceTypes; m_AudioDeviceManager.createAudioDeviceTypes (deviceTypes); for (auto* type : deviceTypes) // this will be just core audio for mac { type->scanForDevices(); outputDevices = type->getDeviceNames (false); inputDevices = type->getDeviceNames (true); } for (auto device : outputDevices) DBG (" Output Device: " + device); for (auto device : inputDevices) DBG (" Input Device: " + device); } if (! outputDevices.contains (allegedOutputDevice)) DBG ("AudioDeviceManager output device does not exist: " + allegedOutputDevice); if (! inputDevices.contains (allegedInputDevice)) DBG ("AudioDeviceManager input device does not exist: " + allegedInputDevice); } private: //============================================================================== // Your private member variables go here... AudioDeviceManager m_AudioDeviceManager; AudioDeviceSelectorComponent m_DeviceSelector; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MyComponent) };