OpenShot Library | libopenshot  0.1.2
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  // Construtor
34  AudioPlaybackThread::AudioPlaybackThread()
35  : Thread("audio-playback")
36  , audioDeviceManager()
37  , player()
38  , transport()
39  , mixer()
40  , source(NULL)
41  , sampleRate(0.0)
42  , numChannels(0)
43  , buffer_size(12000)
44  , is_playing(false)
45  , time_thread("audio-buffer")
46  {
47  }
48 
49  // Destructor
50  AudioPlaybackThread::~AudioPlaybackThread()
51  {
52  }
53 
54  // Set the reader object
55  void AudioPlaybackThread::Reader(ReaderBase *reader) {
56  if (source)
57  source->Reader(reader);
58  else {
59  // Create new audio source reader
60  source = new AudioReaderSource(reader, 1, buffer_size);
61  source->setLooping(true); // prevent this source from terminating when it reaches the end
62  }
63 
64  // Set local vars
65  sampleRate = reader->info.sample_rate;
66  numChannels = reader->info.channels;
67 
68  // TODO: Update transport or audio source's sample rate, incase the sample rate
69  // is different than the original Reader
70 
71  // Mark as 'playing'
72  Play();
73  }
74 
75  // Get the current frame object (which is filling the buffer)
76  tr1::shared_ptr<Frame> AudioPlaybackThread::getFrame()
77  {
78  if (source) return source->getFrame();
79  return tr1::shared_ptr<Frame>();
80  }
81 
82  // Get the currently playing frame number
83  int AudioPlaybackThread::getCurrentFramePosition()
84  {
85  return source ? source->getEstimatedFrame() : 0;
86  }
87 
88  // Seek the audio thread
89  void AudioPlaybackThread::Seek(int new_position)
90  {
91  source->Seek(new_position);
92  }
93 
94  // Play the audio
95  void AudioPlaybackThread::Play() {
96  // Start playing
97  is_playing = true;
98  }
99 
100  // Stop the audio
101  void AudioPlaybackThread::Stop() {
102  // Stop playing
103  is_playing = false;
104  }
105 
106  // Start audio thread
107  void AudioPlaybackThread::run()
108  {
109  while (!threadShouldExit())
110  {
111  if (source && !transport.isPlaying() && is_playing) {
112 
113  // Start new audio device
114  // Init audio device
115  audioDeviceManager.initialise (
116  0, /* number of input channels */
117  numChannels, /* number of output channels */
118  0, /* no XML settings.. */
119  true /* select default device on failure */);
120 
121  // Add callback
122  audioDeviceManager.addAudioCallback(&player);
123 
124  // Create TimeSliceThread for audio buffering
125  time_thread.startThread();
126 
127  // Connect source to transport
128  transport.setSource(
129  source,
130  buffer_size, // tells it to buffer this many samples ahead
131  &time_thread,
132  sampleRate,
133  numChannels);
134  transport.setPosition(0);
135  transport.setGain(1.0);
136 
137  // Connect transport to mixer and player
138  mixer.addInputSource(&transport, false);
139  player.setSource(&mixer);
140 
141  // Start the transport
142  transport.start();
143 
144  while (!threadShouldExit() && transport.isPlaying() && is_playing)
145  sleep(100);
146 
147 
148  // Stop audio and shutdown transport
149  Stop();
150  transport.stop();
151 
152  // Kill previous audio
153  transport.setSource(NULL);
154 
155  player.setSource(NULL);
156  audioDeviceManager.removeAudioCallback(&player);
157  audioDeviceManager.closeAudioDevice();
158  audioDeviceManager.removeAllChangeListeners();
159  audioDeviceManager.dispatchPendingMessages();
160 
161  // Remove source
162  delete source;
163  source = NULL;
164 
165  // Stop time slice thread
166  time_thread.stopThread(-1);
167  }
168  }
169 
170  }
171 }
This namespace is the default namespace for all code in the openshot library.