17#include "../ReaderBase.h"
18#include "../RendererBase.h"
19#include "../AudioReaderSource.h"
20#include "../AudioDevices.h"
21#include "../Settings.h"
28#include <condition_variable>
36 AudioDeviceManagerSingleton *AudioDeviceManagerSingleton::m_pInstance = NULL;
47 static std::mutex mutex;
48 std::lock_guard<std::mutex> lock(mutex);
54 AudioIODevice *foundAudioIODevice = NULL;
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) {
108 if (!attempt_device.type.isEmpty()) {
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 <<
")";
129 deviceSetup.sampleRate = attempt_rate;
147 std::stringstream title_error;
148 title_error <<
"AudioDeviceManagerSingleton::Instance (audio device error: " <<
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) {
191 :
juce::Thread(
"audio-playback")
199 , time_thread(
"audio-buffer")
205 AudioPlaybackThread::~AudioPlaybackThread()
208 signalThreadShouldExit();
209 NotifyTransportStateChanged();
223 auto starting_frame = 1;
224 source =
new AudioReaderSource(reader, starting_frame);
241 std::shared_ptr<openshot::Frame> AudioPlaybackThread::getFrame()
243 if (source)
return source->
getFrame();
244 return std::shared_ptr<openshot::Frame>();
248 void AudioPlaybackThread::Seek(int64_t new_position)
251 source->
Seek(new_position);
256 void AudioPlaybackThread::Play() {
258 NotifyTransportStateChanged();
261 void AudioPlaybackThread::Stop() {
263 if (source) source->
Seek(1);
264 NotifyTransportStateChanged();
267 void AudioPlaybackThread::NotifyTransportStateChanged()
269 std::lock_guard<std::mutex> lock(transportMutex);
270 transportCondition.notify_all();
274 void AudioPlaybackThread::run()
276 while (!threadShouldExit())
278 if (source && !transport.isPlaying() && is_playing) {
280 AudioDeviceManagerSingleton *audioInstance =
284 audioInstance->audioDeviceManager.addAudioCallback(&player);
287 time_thread.startThread(Priority::high);
296 transport.setPosition(0);
297 transport.setGain(1.0);
300 mixer.addInputSource(&transport,
false);
301 player.setSource(&mixer);
306 while (!threadShouldExit() && transport.isPlaying() && is_playing) {
308 std::unique_lock<std::mutex> lock(transportMutex);
309 transportCondition.wait_for(lock, std::chrono::milliseconds(10), [
this]() {
310 return threadShouldExit() || !transport.isPlaying() || !is_playing;
319 transport.setSource(NULL);
321 player.setSource(NULL);
322 audioInstance->audioDeviceManager.removeAudioCallback(&player);
327 mixer.removeInputSource(&transport);
330 time_thread.stopThread(-1);
332 std::unique_lock<std::mutex> lock(transportMutex);
333 transportCondition.wait_for(lock, std::chrono::milliseconds(10), [
this] {
334 return threadShouldExit() || (source && is_playing.load());
Source file for AudioPlaybackThread class.
Header file for global Settings class.
Singleton wrapper for AudioDeviceManager (to prevent multiple instances).
double defaultSampleRate
Default sample rate (as detected)
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.
AudioDeviceInfo currentAudioDevice
Current open audio device (or last attempted device - if none were successful)
std::string initialise_error
Error found during JUCE initialise method.
std::shared_ptr< Frame > getFrame() const
Return the current frame object.
void Reader(ReaderBase *audio_reader)
Set Reader.
void Seek(int64_t new_position)
Seek to a specific frame.
void setVideoCache(openshot::VideoCacheThread *newCache)
Set playback video cache thread (for pre-roll reference)
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)
static Logger * Instance()
This abstract class is the base class, used by all readers in libopenshot.
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.
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)