28#include <condition_variable>
47 static std::mutex mutex;
48 std::lock_guard<std::mutex> lock(mutex);
52 m_pInstance =
new AudioDeviceManagerSingleton;
53 auto* mgr = &m_pInstance->audioDeviceManager;
54 AudioIODevice *foundAudioIODevice = NULL;
55 m_pInstance->initialise_error =
"";
56 m_pInstance->currentAudioDevice.name =
"";
57 m_pInstance->currentAudioDevice.type =
"";
58 m_pInstance->defaultSampleRate = 0.0;
60 std::stringstream constructor_title;
61 constructor_title <<
"AudioDeviceManagerSingleton::Instance (default audio device type: " <<
71 if (requested_device.
type.isEmpty() && !requested_device.
name.isEmpty()) {
72 for (
const auto t : mgr->getAvailableDeviceTypes()) {
74 for (
const auto n : t->getDeviceNames()) {
75 if (requested_device.
name.trim().equalsIgnoreCase(n.trim())) {
76 requested_device.
type = t->getTypeName();
84 std::vector<openshot::AudioDeviceInfo> devices{ { requested_device } };
85 for (
const auto t : mgr->getAvailableDeviceTypes()) {
86 std::stringstream type_debug;
87 type_debug <<
"AudioDeviceManagerSingleton::Instance (iterate audio device type: " << t->getTypeName() <<
")";
91 for (
const auto n : t->getDeviceNames()) {
93 devices.push_back(device);
94 std::stringstream device_debug;
95 device_debug <<
"AudioDeviceManagerSingleton::Instance (iterate audio device name: " << device.
name <<
", type: " << t->getTypeName() <<
")";
101 for (
auto attempt_device : devices) {
102 m_pInstance->currentAudioDevice = attempt_device;
105 m_pInstance->audioDeviceManager.initialiseWithDefaultDevices(0, channels);
108 if (!attempt_device.type.isEmpty()) {
109 m_pInstance->audioDeviceManager.setCurrentAudioDeviceType(attempt_device.type,
true);
113 AudioDeviceManager::AudioDeviceSetup deviceSetup = AudioDeviceManager::AudioDeviceSetup();
114 deviceSetup.inputChannels = 0;
115 deviceSetup.outputChannels = channels;
121 int possible_rates[] { rate, 48000, 44100, 22050 };
122 for(
int attempt_rate : possible_rates) {
123 std::stringstream title_rate;
124 title_rate <<
"AudioDeviceManagerSingleton::Instance (attempt audio device name: " << attempt_device.name <<
")";
128 m_pInstance->defaultSampleRate = attempt_rate;
129 deviceSetup.sampleRate = attempt_rate;
130 m_pInstance->audioDeviceManager.setAudioDeviceSetup(deviceSetup,
true);
134 juce::String audio_error = m_pInstance->audioDeviceManager.initialise(
144 m_pInstance->initialise_error = audio_error.toStdString();
146 if (!m_pInstance->initialise_error.empty()) {
147 std::stringstream title_error;
148 title_error <<
"AudioDeviceManagerSingleton::Instance (audio device error: " <<
149 m_pInstance->initialise_error <<
")";
155 foundAudioIODevice = m_pInstance->audioDeviceManager.getCurrentAudioDevice();
156 if (foundAudioIODevice && foundAudioIODevice->getCurrentSampleRate() == attempt_rate) {
158 std::stringstream title_found;
159 title_found <<
"AudioDeviceManagerSingleton::Instance (successful audio device found: " <<
160 foundAudioIODevice->getTypeName() <<
", name: " << foundAudioIODevice->getName() <<
")";
166 if (foundAudioIODevice) {
199 , time_thread(
"audio-buffer")
205 AudioPlaybackThread::~AudioPlaybackThread()
210 void AudioPlaybackThread::Reader(openshot::ReaderBase *reader) {
212 source->Reader(reader);
215 auto starting_frame = 1;
216 source =
new AudioReaderSource(reader, starting_frame);
226 source->setVideoCache(videoCache);
233 std::shared_ptr<openshot::Frame> AudioPlaybackThread::getFrame()
235 if (source)
return source->getFrame();
236 return std::shared_ptr<openshot::Frame>();
240 void AudioPlaybackThread::Seek(int64_t new_position)
243 source->Seek(new_position);
248 void AudioPlaybackThread::Play() {
250 NotifyTransportStateChanged();
253 void AudioPlaybackThread::Stop() {
255 NotifyTransportStateChanged();
258 void AudioPlaybackThread::NotifyTransportStateChanged()
260 std::lock_guard<std::mutex> lock(transportMutex);
261 transportCondition.notify_all();
265 void AudioPlaybackThread::run()
267 while (!threadShouldExit())
269 if (source && !transport.isPlaying() && is_playing) {
271 AudioDeviceManagerSingleton *audioInstance =
275 audioInstance->audioDeviceManager.addAudioCallback(&player);
278 time_thread.startThread(Priority::high);
287 transport.setPosition(0);
288 transport.setGain(1.0);
291 mixer.addInputSource(&transport,
false);
292 player.setSource(&mixer);
297 while (!threadShouldExit() && transport.isPlaying() && is_playing) {
299 std::unique_lock<std::mutex> lock(transportMutex);
300 transportCondition.wait_for(lock, std::chrono::milliseconds(10), [
this]() {
301 return threadShouldExit() || !transport.isPlaying() || !is_playing;
310 transport.setSource(NULL);
312 player.setSource(NULL);
313 audioInstance->audioDeviceManager.removeAudioCallback(&player);
320 time_thread.stopThread(-1);
Header file for Audio Device Info struct.
Source file for AudioPlaybackThread class.
Header file for AudioReaderSource class.
Header file for ReaderBase class.
Header file for RendererBase class.
Header file for global Settings class.
Header file for ZeroMQ-based Logger class.
Singleton wrapper for AudioDeviceManager (to prevent multiple instances).
void CloseAudioDevice()
Close audio device.
static AudioDeviceManagerSingleton * Instance()
Override with default sample rate & channels (44100, 2) and no preferred audio device.
juce::AudioDeviceManager audioDeviceManager
Public device manager property.
openshot::ReaderInfo info
Information about the current media file.
int PLAYBACK_AUDIO_BUFFER_SIZE
Size of playback buffer before audio playback starts.
std::string PLAYBACK_AUDIO_DEVICE_NAME
The audio device name to use during playback.
std::string PLAYBACK_AUDIO_DEVICE_TYPE
The device type for the playback audio devices.
static Settings * Instance()
Create or get an instance of this logger singleton (invoke the class with this method).
Handles prefetching and caching of video/audio frames for smooth playback.
void AppendDebugMethod(std::string method_name, std::string arg1_name="", float arg1_value=-1.0, std::string arg2_name="", float arg2_value=-1.0, std::string arg3_name="", float arg3_value=-1.0, std::string arg4_name="", float arg4_value=-1.0, std::string arg5_name="", float arg5_value=-1.0, std::string arg6_name="", float arg6_value=-1.0)
Append debug information.
static ZmqLogger * Instance()
Create or get an instance of this logger singleton (invoke the class with this method).
This namespace is the default namespace for all code in the openshot library.
This struct hold information about Audio Devices.
int channels
The number of audio channels used in the audio stream.
int sample_rate
The number of audio samples per second (44100 is a common sample rate).