17 #include "../ReaderBase.h"
18 #include "../RendererBase.h"
19 #include "../AudioReaderSource.h"
20 #include "../AudioDevices.h"
21 #include "../Settings.h"
22 #include "../ZmqLogger.h"
34 AudioDeviceManagerSingleton *AudioDeviceManagerSingleton::m_pInstance = NULL;
39 return AudioDeviceManagerSingleton::Instance(44100, 2);
45 static std::mutex mutex;
46 std::lock_guard<std::mutex> lock(mutex);
52 AudioIODevice *foundAudioIODevice = NULL;
53 m_pInstance->initialise_error =
"";
54 m_pInstance->currentAudioDevice.name =
"";
55 m_pInstance->currentAudioDevice.type =
"";
56 m_pInstance->defaultSampleRate = 0.0;
58 std::stringstream constructor_title;
59 constructor_title <<
"AudioDeviceManagerSingleton::Instance (default audio device type: " <<
60 Settings::Instance()->PLAYBACK_AUDIO_DEVICE_TYPE <<
", default audio device name: " <<
61 Settings::Instance()->PLAYBACK_AUDIO_DEVICE_NAME <<
")";
62 ZmqLogger::Instance()->AppendDebugMethod(constructor_title.str(),
"channels", channels);
66 Settings::Instance()->PLAYBACK_AUDIO_DEVICE_NAME};
69 if (requested_device.
type.isEmpty() && !requested_device.
name.isEmpty()) {
70 for (
const auto t : mgr->getAvailableDeviceTypes()) {
72 for (
const auto n : t->getDeviceNames()) {
73 if (requested_device.
name.trim().equalsIgnoreCase(n.trim())) {
74 requested_device.
type = t->getTypeName();
82 std::vector<openshot::AudioDeviceInfo> devices{ { requested_device } };
83 for (
const auto t : mgr->getAvailableDeviceTypes()) {
85 for (
const auto n : t->getDeviceNames()) {
87 devices.push_back(device);
92 for (
auto attempt_device : devices) {
93 m_pInstance->currentAudioDevice = attempt_device;
96 m_pInstance->audioDeviceManager.initialiseWithDefaultDevices(0, channels);
99 if (!attempt_device.type.isEmpty()) {
100 m_pInstance->audioDeviceManager.setCurrentAudioDeviceType(attempt_device.type,
true);
104 AudioDeviceManager::AudioDeviceSetup deviceSetup = AudioDeviceManager::AudioDeviceSetup();
105 deviceSetup.inputChannels = 0;
106 deviceSetup.outputChannels = channels;
111 int possible_rates[] { rate, 48000, 44100, 22050 };
112 for(
int attempt_rate : possible_rates) {
113 std::stringstream title_rate;
114 title_rate <<
"AudioDeviceManagerSingleton::Instance (attempt audio device name: " << attempt_device.name <<
")";
115 ZmqLogger::Instance()->AppendDebugMethod(title_rate.str(),
"rate", attempt_rate,
"channels", channels);
118 m_pInstance->defaultSampleRate = attempt_rate;
119 deviceSetup.sampleRate = attempt_rate;
120 m_pInstance->audioDeviceManager.setAudioDeviceSetup(deviceSetup,
true);
124 juce::String audio_error = m_pInstance->audioDeviceManager.initialise(
134 m_pInstance->initialise_error = audio_error.toStdString();
136 if (!m_pInstance->initialise_error.empty()) {
137 std::stringstream title_error;
138 title_error <<
"AudioDeviceManagerSingleton::Instance (audio device error: " <<
139 m_pInstance->initialise_error <<
")";
140 ZmqLogger::Instance()->AppendDebugMethod(title_error.str(),
"rate", attempt_rate,
"channels", channels);
145 foundAudioIODevice = m_pInstance->audioDeviceManager.getCurrentAudioDevice();
146 if (foundAudioIODevice && foundAudioIODevice->getCurrentSampleRate() == attempt_rate) {
148 std::stringstream title_found;
149 title_found <<
"AudioDeviceManagerSingleton::Instance (successful audio device found: " <<
150 foundAudioIODevice->getTypeName() <<
", name: " << foundAudioIODevice->getName() <<
")";
151 ZmqLogger::Instance()->AppendDebugMethod(title_found.str(),
"rate", attempt_rate,
"channels", channels);
156 if (foundAudioIODevice) {
162 ZmqLogger::Instance()->AppendDebugMethod(
"AudioDeviceManagerSingleton::Instance (audio device initialization completed)");
168 void AudioDeviceManagerSingleton::CloseAudioDevice()
171 audioDeviceManager.closeAudioDevice();
172 audioDeviceManager.removeAllChangeListeners();
173 audioDeviceManager.dispatchPendingMessages();
181 :
juce::Thread(
"audio-playback")
189 , time_thread(
"audio-buffer")
195 AudioPlaybackThread::~AudioPlaybackThread()
205 auto starting_frame = 1;
206 source =
new AudioReaderSource(reader, starting_frame);
223 std::shared_ptr<openshot::Frame> AudioPlaybackThread::getFrame()
225 if (source)
return source->
getFrame();
226 return std::shared_ptr<openshot::Frame>();
230 void AudioPlaybackThread::Seek(int64_t new_position)
233 source->
Seek(new_position);
238 void AudioPlaybackThread::Play() {
244 void AudioPlaybackThread::Stop() {
250 void AudioPlaybackThread::run()
252 while (!threadShouldExit())
254 if (source && !transport.isPlaying() && is_playing) {
256 AudioDeviceManagerSingleton *audioInstance =
260 audioInstance->audioDeviceManager.addAudioCallback(&player);
263 time_thread.startThread();
272 transport.setPosition(0);
273 transport.setGain(1.0);
276 mixer.addInputSource(&transport,
false);
277 player.setSource(&mixer);
282 while (!threadShouldExit() && transport.isPlaying() && is_playing)
283 std::this_thread::sleep_for(std::chrono::milliseconds(2));
290 transport.setSource(NULL);
292 player.setSource(NULL);
293 audioInstance->audioDeviceManager.removeAudioCallback(&player);
300 time_thread.stopThread(-1);
Source file for AudioPlaybackThread class.
Header file for global Settings class.
Singleton wrapper for AudioDeviceManager (to prevent multiple instances).
static AudioDeviceManagerSingleton * Instance()
Override with default sample rate & channels (44100, 2) and no preferred audio device.
juce::AudioDeviceManager audioDeviceManager
Public device manager property.
void Seek(int64_t new_position)
Seek to a specific frame.
void Reader(ReaderBase *audio_reader)
Set Reader.
std::shared_ptr< Frame > getFrame() const
Return the current frame object.
void setVideoCache(openshot::VideoCacheThread *newCache)
Set playback video cache thread (for pre-roll reference)
This abstract class is the base class, used by all readers in libopenshot.
openshot::ReaderInfo info
Information about the current media file.
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)