/** * @file * @brief Example code to list available devices and play a test sound * @author Jonathan Thomas * @author FeRD (Frank Dana) * * Copyright (c) 2008-2020 OpenShot Studios, LLC * . This file is part of OpenShot Audio * Library (libopenshot-audio), an open-source project dedicated to delivering * high quality audio editing and playback solutions to the world. For more * information visit . * * OpenShot Audio Library (libopenshot-audio) is free software: you can * redistribute it and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation, either version * 3 of the License, or (at your option) any later version. * * OpenShot Audio Library (libopenshot-audio) is distributed in the hope that * it will be useful, but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenShot Library. If not, see . * * @mainpage OpenShot Audio Library C++ API * * Welcome to the OpenShot Audio Library C++ API. * This library is used by libopenshot to enable audio features, which powers the * OpenShot Video Editor application. */ #include #include #include // Avoid an implicit (and deprecated) 'using namespace juce;' #ifndef DONT_SET_USING_JUCE_NAMESPACE #define DONT_SET_USING_JUCE_NAMESPACE 1 #endif #include "OpenShotAudio.h" // Subclass the AudioDeviceManager so we can skip WASAPI devices on Windows class TestAudioDeviceManager : public juce::AudioDeviceManager { public: static void addIfNotNull ( juce::OwnedArray& list, juce::AudioIODeviceType* const device) { if (device != nullptr) list.add (device); } void createAudioDeviceTypes (juce::OwnedArray& list) override { addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_WASAPI (juce::WASAPIDeviceMode::shared)); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_WASAPI (juce::WASAPIDeviceMode::exclusive)); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_WASAPI (juce::WASAPIDeviceMode::sharedLowLatency)); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_DirectSound()); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_ASIO()); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_CoreAudio()); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_iOSAudio()); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_Bela()); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_ALSA()); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_JACK()); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_Oboe()); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_OpenSLES()); addIfNotNull (list, juce::AudioIODeviceType::createAudioIODeviceType_Android()); } }; void display_device_probe(TestAudioDeviceManager& deviceManager) { std::cout << "Audio device probe results:\n"; int device_count = 0; for (const auto& t : deviceManager.getAvailableDeviceTypes()) { juce::String typeString; typeString << "Type " << t->getTypeName() << ":"; std::cout << typeString << std::endl; auto deviceNames = t->getDeviceNames(); device_count += deviceNames.size(); for (const auto deviceName : deviceNames) { std::cout << " - " << deviceName << std::endl; } } std::cout << "Discovered " << device_count << " total audio devices.\n\n"; const auto* curType = deviceManager.getCurrentDeviceTypeObject(); auto* curDevice = deviceManager.getCurrentAudioDevice(); std::cout << "Current audio device: "; if (curType == nullptr || curDevice == nullptr) { std::cout << "\n"; } else { std::cout << curType->getTypeName() << " - " << curDevice->getName().quoted() << '\n'; std::cout << "Sample rate: " << curDevice->getCurrentSampleRate() << " Hz\n"; std::cout << "Block size: " << curDevice->getCurrentBufferSizeSamples() << " samples\n"; std::cout << "Bit depth: " << curDevice->getCurrentBitDepth() << '\n'; } } int main(int argc, char* argv[]) { juce::ignoreUnused (argc, argv); // Initialize default audio device std::cout << "Initialising audio playback device.\n"; TestAudioDeviceManager deviceManager; auto error = deviceManager.initialise ( 0, // numInputChannelsNeeded 2, // numOutputChannelsNeeded nullptr, // savedState true // selectDefaultDeviceOnFailure ); // Output error (if any) if (error.isNotEmpty()) { std::cout << "Error on initialise(): " << error.toStdString() << std::endl; exit(-1); } // Show detected audio devices display_device_probe(deviceManager); // Pause to take all that in std::this_thread::sleep_for(std::chrono::seconds(1)); // Play test sound const int pause(2); using stride = std::chrono::duration>; std::cout << "\nYou should hear five test tones, precisely " << pause << " second" << (pause > 1 ? "s" : "") << " apart.\n"; auto start = std::chrono::steady_clock::now(); for (auto s = static_cast(1); s < static_cast(6); ++s) { std::cout << s.count() << (s.count() < 5 ? "... " : ".") << std::flush; deviceManager.playTestSound(); std::this_thread::sleep_until(start + s); } std::cout << "\nDemo complete. Shutting down device manager.\n"; // Stop audio devices deviceManager.closeAudioDevice(); deviceManager.removeAllChangeListeners(); deviceManager.dispatchPendingMessages(); return 0; }