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