1 /* 2 ============================================================================== 3 4 This file is part of the JUCE examples. 5 Copyright (c) 2020 - Raw Material Software Limited 6 7 The code included in this file is provided under the terms of the ISC license 8 http://www.isc.org/downloads/software-support-policy/isc-license. Permission 9 To use, copy, modify, and/or distribute this software for any purpose with or 10 without fee is hereby granted provided that the above copyright notice and 11 this permission notice appear in all copies. 12 13 THE SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, 14 WHETHER EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR 15 PURPOSE, ARE DISCLAIMED. 16 17 ============================================================================== 18 */ 19 20 /******************************************************************************* 21 The block below describes the properties of this PIP. A PIP is a short snippet 22 of code that can be read by the Projucer and used to generate a JUCE project. 23 24 BEGIN_JUCE_PIP_METADATA 25 26 name: AudioSettingsDemo 27 version: 1.0.0 28 vendor: JUCE 29 website: http://juce.com 30 description: Displays information about audio devices. 31 32 dependencies: juce_audio_basics, juce_audio_devices, juce_audio_formats, 33 juce_audio_processors, juce_audio_utils, juce_core, 34 juce_data_structures, juce_events, juce_graphics, 35 juce_gui_basics, juce_gui_extra 36 exporters: xcode_mac, vs2019, linux_make, androidstudio, xcode_iphone 37 38 moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1 39 40 type: Component 41 mainClass: AudioSettingsDemo 42 43 useLocalCopy: 1 44 45 END_JUCE_PIP_METADATA 46 47 *******************************************************************************/ 48 49 #pragma once 50 51 #include "../Assets/DemoUtilities.h" 52 53 //============================================================================== 54 class AudioSettingsDemo : public Component, 55 public ChangeListener 56 { 57 public: AudioSettingsDemo()58 AudioSettingsDemo() 59 { 60 setOpaque (true); 61 62 #ifndef JUCE_DEMO_RUNNER 63 RuntimePermissions::request (RuntimePermissions::recordAudio, 64 [this] (bool granted) 65 { 66 int numInputChannels = granted ? 2 : 0; 67 audioDeviceManager.initialise (numInputChannels, 2, nullptr, true, {}, nullptr); 68 }); 69 #endif 70 71 audioSetupComp.reset (new AudioDeviceSelectorComponent (audioDeviceManager, 72 0, 256, 0, 256, true, true, true, false)); 73 addAndMakeVisible (audioSetupComp.get()); 74 75 addAndMakeVisible (diagnosticsBox); 76 diagnosticsBox.setMultiLine (true); 77 diagnosticsBox.setReturnKeyStartsNewLine (true); 78 diagnosticsBox.setReadOnly (true); 79 diagnosticsBox.setScrollbarsShown (true); 80 diagnosticsBox.setCaretVisible (false); 81 diagnosticsBox.setPopupMenuEnabled (true); 82 83 audioDeviceManager.addChangeListener (this); 84 85 logMessage ("Audio device diagnostics:\n"); 86 dumpDeviceInfo(); 87 88 setSize (500, 600); 89 } 90 ~AudioSettingsDemo()91 ~AudioSettingsDemo() override 92 { 93 audioDeviceManager.removeChangeListener (this); 94 } 95 paint(Graphics & g)96 void paint (Graphics& g) override 97 { 98 g.fillAll (getUIColourIfAvailable (LookAndFeel_V4::ColourScheme::UIColour::windowBackground)); 99 } 100 resized()101 void resized() override 102 { 103 auto r = getLocalBounds().reduced (4); 104 audioSetupComp->setBounds (r.removeFromTop (proportionOfHeight (0.65f))); 105 diagnosticsBox.setBounds (r); 106 } 107 dumpDeviceInfo()108 void dumpDeviceInfo() 109 { 110 logMessage ("--------------------------------------"); 111 logMessage ("Current audio device type: " + (audioDeviceManager.getCurrentDeviceTypeObject() != nullptr 112 ? audioDeviceManager.getCurrentDeviceTypeObject()->getTypeName() 113 : "<none>")); 114 115 if (AudioIODevice* device = audioDeviceManager.getCurrentAudioDevice()) 116 { 117 logMessage ("Current audio device: " + device->getName().quoted()); 118 logMessage ("Sample rate: " + String (device->getCurrentSampleRate()) + " Hz"); 119 logMessage ("Block size: " + String (device->getCurrentBufferSizeSamples()) + " samples"); 120 logMessage ("Output Latency: " + String (device->getOutputLatencyInSamples()) + " samples"); 121 logMessage ("Input Latency: " + String (device->getInputLatencyInSamples()) + " samples"); 122 logMessage ("Bit depth: " + String (device->getCurrentBitDepth())); 123 logMessage ("Input channel names: " + device->getInputChannelNames().joinIntoString (", ")); 124 logMessage ("Active input channels: " + getListOfActiveBits (device->getActiveInputChannels())); 125 logMessage ("Output channel names: " + device->getOutputChannelNames().joinIntoString (", ")); 126 logMessage ("Active output channels: " + getListOfActiveBits (device->getActiveOutputChannels())); 127 } 128 else 129 { 130 logMessage ("No audio device open"); 131 } 132 } 133 logMessage(const String & m)134 void logMessage (const String& m) 135 { 136 diagnosticsBox.moveCaretToEnd(); 137 diagnosticsBox.insertTextAtCaret (m + newLine); 138 } 139 140 private: 141 // if this PIP is running inside the demo runner, we'll use the shared device manager instead 142 #ifndef JUCE_DEMO_RUNNER 143 AudioDeviceManager audioDeviceManager; 144 #else 145 AudioDeviceManager& audioDeviceManager { getSharedAudioDeviceManager() }; 146 #endif 147 148 std::unique_ptr<AudioDeviceSelectorComponent> audioSetupComp; 149 TextEditor diagnosticsBox; 150 changeListenerCallback(ChangeBroadcaster *)151 void changeListenerCallback (ChangeBroadcaster*) override 152 { 153 dumpDeviceInfo(); 154 } 155 lookAndFeelChanged()156 void lookAndFeelChanged() override 157 { 158 diagnosticsBox.applyFontToAllText (diagnosticsBox.getFont()); 159 } 160 getListOfActiveBits(const BigInteger & b)161 static String getListOfActiveBits (const BigInteger& b) 162 { 163 StringArray bits; 164 165 for (int i = 0; i <= b.getHighestBit(); ++i) 166 if (b[i]) 167 bits.add (String (i)); 168 169 return bits.joinIntoString (", "); 170 } 171 172 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioSettingsDemo) 173 }; 174