OpenShot Library | libopenshot  0.1.9
AudioPlaybackThread.cpp
Go to the documentation of this file.
1 /**
2  * @file
3  * @brief Source file for AudioPlaybackThread class
4  * @author Duzy Chan <code@duzy.info>
5  * @author Jonathan Thomas <jonathan@openshot.org> *
6  *
7  * @section LICENSE
8  *
9  * Copyright (c) 2008-2014 OpenShot Studios, LLC
10  * <http://www.openshotstudios.com/>. This file is part of
11  * OpenShot Library (libopenshot), an open-source project dedicated to
12  * delivering high quality video editing and animation solutions to the
13  * world. For more information visit <http://www.openshot.org/>.
14  *
15  * OpenShot Library (libopenshot) is free software: you can redistribute it
16  * and/or modify it under the terms of the GNU Lesser General Public License
17  * as published by the Free Software Foundation, either version 3 of the
18  * License, or (at your option) any later version.
19  *
20  * OpenShot Library (libopenshot) is distributed in the hope that it will be
21  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU Lesser General Public License for more details.
24  *
25  * You should have received a copy of the GNU Lesser General Public License
26  * along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
27  */
28 
29 #include "../../include/Qt/AudioPlaybackThread.h"
30 
31 namespace openshot
32 {
33 
34  // Global reference to device manager
35  AudioDeviceManagerSingleton *AudioDeviceManagerSingleton::m_pInstance = NULL;
36 
37  // Create or Get an instance of the device manager singleton
39  {
40  if (!m_pInstance) {
41  // Create the actual instance of device manager only once
42  m_pInstance = new AudioDeviceManagerSingleton;
43 
44  // Initialize audio device only 1 time
45  m_pInstance->audioDeviceManager.initialise (
46  0, /* number of input channels */
47  numChannels, /* number of output channels */
48  0, /* no XML settings.. */
49  true /* select default device on failure */);
50  }
51 
52  return m_pInstance;
53  }
54 
55  // Close audio device
57  {
58  // Close Audio Device
59  audioDeviceManager.closeAudioDevice();
60  audioDeviceManager.removeAllChangeListeners();
61  audioDeviceManager.dispatchPendingMessages();
62  }
63 
64  // Construtor
65  AudioPlaybackThread::AudioPlaybackThread()
66  : Thread("audio-playback")
67  , player()
68  , transport()
69  , mixer()
70  , source(NULL)
71  , sampleRate(0.0)
72  , numChannels(0)
73  , buffer_size(12000)
74  , is_playing(false)
75  , time_thread("audio-buffer")
76  {
77  }
78 
79  // Destructor
80  AudioPlaybackThread::~AudioPlaybackThread()
81  {
82  }
83 
84  // Set the reader object
85  void AudioPlaybackThread::Reader(ReaderBase *reader) {
86  if (source)
87  source->Reader(reader);
88  else {
89  // Create new audio source reader
90  source = new AudioReaderSource(reader, 1, buffer_size);
91  source->setLooping(true); // prevent this source from terminating when it reaches the end
92  }
93 
94  // Set local vars
95  sampleRate = reader->info.sample_rate;
96  numChannels = reader->info.channels;
97 
98  // TODO: Update transport or audio source's sample rate, incase the sample rate
99  // is different than the original Reader
100 
101  // Mark as 'playing'
102  Play();
103  }
104 
105  // Get the current frame object (which is filling the buffer)
106  std::shared_ptr<Frame> AudioPlaybackThread::getFrame()
107  {
108  if (source) return source->getFrame();
109  return std::shared_ptr<Frame>();
110  }
111 
112  // Get the currently playing frame number
113  int64_t AudioPlaybackThread::getCurrentFramePosition()
114  {
115  return source ? source->getEstimatedFrame() : 0;
116  }
117 
118  // Seek the audio thread
119  void AudioPlaybackThread::Seek(int64_t new_position)
120  {
121  source->Seek(new_position);
122  }
123 
124  // Play the audio
125  void AudioPlaybackThread::Play() {
126  // Start playing
127  is_playing = true;
128  }
129 
130  // Stop the audio
131  void AudioPlaybackThread::Stop() {
132  // Stop playing
133  is_playing = false;
134  }
135 
136  // Start audio thread
137  void AudioPlaybackThread::run()
138  {
139  while (!threadShouldExit())
140  {
141  if (source && !transport.isPlaying() && is_playing) {
142 
143  // Start new audio device (or get existing one)
144  // Add callback
145  AudioDeviceManagerSingleton::Instance(numChannels)->audioDeviceManager.addAudioCallback(&player);
146 
147  // Create TimeSliceThread for audio buffering
148  time_thread.startThread();
149 
150  // Connect source to transport
151  transport.setSource(
152  source,
153  buffer_size, // tells it to buffer this many samples ahead
154  &time_thread,
155  sampleRate,
156  numChannels);
157  transport.setPosition(0);
158  transport.setGain(1.0);
159 
160  // Connect transport to mixer and player
161  mixer.addInputSource(&transport, false);
162  player.setSource(&mixer);
163 
164  // Start the transport
165  transport.start();
166 
167  while (!threadShouldExit() && transport.isPlaying() && is_playing)
168  sleep(100);
169 
170 
171  // Stop audio and shutdown transport
172  Stop();
173  transport.stop();
174 
175  // Kill previous audio
176  transport.setSource(NULL);
177 
178  player.setSource(NULL);
179  AudioDeviceManagerSingleton::Instance(0)->audioDeviceManager.removeAudioCallback(&player);
180 
181  // Remove source
182  delete source;
183  source = NULL;
184 
185  // Stop time slice thread
186  time_thread.stopThread(-1);
187  }
188  }
189 
190  }
191 }
void CloseAudioDevice()
Close audio device.
AudioDeviceManager audioDeviceManager
Public device manager property.
This abstract class is the base class, used by all readers in libopenshot.
Definition: ReaderBase.h:95
ReaderInfo info
Information about the current media file.
Definition: ReaderBase.h:111
This class is used to expose any ReaderBase derived class as an AudioSource in JUCE.
This namespace is the default namespace for all code in the openshot library.
Singleton wrapper for AudioDeviceManager (to prevent multiple instances).
static AudioDeviceManagerSingleton * Instance(int numChannels)
Create or get an instance of this singleton (invoke the class with this method)
int channels
The number of audio channels used in the audio stream.
Definition: ReaderBase.h:82
int sample_rate
The number of audio samples per second (44100 is a common sample rate)
Definition: ReaderBase.h:81