source: trunk/src/multimedia/audio/qaudiooutput.cpp@ 568

Last change on this file since 568 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

  • Property svn:eol-style set to native
File size: 11.5 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtMultimedia module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42
43#include <QtMultimedia/qaudio.h>
44#include <QtMultimedia/qaudiodeviceinfo.h>
45#include <QtMultimedia/qaudioengine.h>
46#include <QtMultimedia/qaudiooutput.h>
47
48#include "qaudiodevicefactory_p.h"
49
50
51QT_BEGIN_NAMESPACE
52
53/*!
54 \class QAudioOutput
55 \brief The QAudioOutput class provides an interface for sending audio data to an audio output device.
56
57 \inmodule QtMultimedia
58 \ingroup multimedia
59 \since 4.6
60
61 You can construct an audio output with the system's
62 \l{QAudioDeviceInfo::defaultOutputDevice()}{default audio output
63 device}. It is also possible to create QAudioOutput with a
64 specific QAudioDeviceInfo. When you create the audio output, you
65 should also send in the QAudioFormat to be used for the playback
66 (see the QAudioFormat class description for details).
67
68 To play a file:
69
70 Starting to play an audio stream is simply a matter of calling
71 start() with a QIODevice. QAudioOutput will then fetch the data it
72 needs from the io device. So playing back an audio file is as
73 simple as:
74
75 \code
76 QFile inputFile; // class member.
77 QAudioOutput* audio; // class member.
78 \endcode
79
80 \code
81 inputFile.setFileName("/tmp/test.raw");
82 inputFile.open(QIODevice::ReadOnly);
83
84 QAudioFormat format;
85 // Set up the format, eg.
86 format.setFrequency(8000);
87 format.setChannels(1);
88 format.setSampleSize(8);
89 format.setCodec("audio/pcm");
90 format.setByteOrder(QAudioFormat::LittleEndian);
91 format.setSampleType(QAudioFormat::UnSignedInt);
92
93 QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
94 if (!info.isFormatSupported(format)) {
95 qWarning()<<"raw audio format not supported by backend, cannot play audio.";
96 return;
97 }
98
99 audio = new QAudioOutput(format, this);
100 connect(audio,SIGNAL(stateChanged(QAudio::State)),SLOT(finishedPlaying(QAudio::State)));
101 audio->start(inputFile);
102
103 \endcode
104
105 The file will start playing assuming that the audio system and
106 output device support it. If you run out of luck, check what's
107 up with the error() function.
108
109 After the file has finished playing, we need to stop the device:
110
111 \code
112 void finishedPlaying(QAudio::State state)
113 {
114 if(state == QAudio::IdleState) {
115 audio->stop();
116 inputFile.close();
117 delete audio;
118 }
119 }
120 \endcode
121
122 At any given time, the QAudioOutput will be in one of four states:
123 active, suspended, stopped, or idle. These states are described
124 by the QAudio::State enum.
125 State changes are reported through the stateChanged() signal. You
126 can use this signal to, for instance, update the GUI of the
127 application; the mundane example here being changing the state of
128 a \c { play/pause } button. You request a state change directly
129 with suspend(), stop(), reset(), resume(), and start().
130
131 While the stream is playing, you can set a notify interval in
132 milliseconds with setNotifyInterval(). This interval specifies the
133 time between two emissions of the notify() signal. This is
134 relative to the position in the stream, i.e., if the QAudioOutput
135 is in the SuspendedState or the IdleState, the notify() signal is
136 not emitted. A typical use-case would be to update a
137 \l{QSlider}{slider} that allows seeking in the stream.
138 If you want the time since playback started regardless of which
139 states the audio output has been in, elapsedUSecs() is the function for you.
140
141 If an error occurs, you can fetch the \l{QAudio::Error}{error
142 type} with the error() function. Please see the QAudio::Error enum
143 for a description of the possible errors that are reported. When
144 an error is encountered, the state changes to QAudio::StoppedState.
145 You can check for errors by connecting to the stateChanged()
146 signal:
147
148 \snippet doc/src/snippets/audio/main.cpp 3
149
150 \sa QAudioInput, QAudioDeviceInfo
151*/
152
153/*!
154 Construct a new audio output and attach it to \a parent.
155 The default audio output device is used with the output
156 \a format parameters.
157*/
158
159QAudioOutput::QAudioOutput(const QAudioFormat &format, QObject *parent):
160 QObject(parent)
161{
162 d = QAudioDeviceFactory::createDefaultOutputDevice(format);
163 connect(d, SIGNAL(notify()), SIGNAL(notify()));
164 connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State)));
165}
166
167/*!
168 Construct a new audio output and attach it to \a parent.
169 The device referenced by \a audioDevice is used with the output
170 \a format parameters.
171*/
172
173QAudioOutput::QAudioOutput(const QAudioDeviceInfo &audioDevice, const QAudioFormat &format, QObject *parent):
174 QObject(parent)
175{
176 d = QAudioDeviceFactory::createOutputDevice(audioDevice, format);
177 connect(d, SIGNAL(notify()), SIGNAL(notify()));
178 connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State)));
179}
180
181/*!
182 Destroys this audio output.
183*/
184
185QAudioOutput::~QAudioOutput()
186{
187 delete d;
188}
189
190/*!
191 Returns the QAudioFormat being used.
192
193*/
194
195QAudioFormat QAudioOutput::format() const
196{
197 return d->format();
198}
199
200/*!
201 Uses the \a device as the QIODevice to transfer data.
202 Passing a QIODevice allows the data to be transfered without any extra code.
203 All that is required is to open the QIODevice.
204
205 \sa QIODevice
206*/
207
208void QAudioOutput::start(QIODevice* device)
209{
210 /*
211 -If currently not StoppedState, stop.
212 -If previous start was push mode, delete internal QIODevice.
213 -open audio output.
214 -If ok, NoError and ActiveState, else OpenError and StoppedState
215 -emit stateChanged()
216 */
217 d->start(device);
218}
219
220/*!
221 Returns a pointer to the QIODevice being used to handle the data
222 transfer. This QIODevice can be used to write() audio data directly.
223
224 \sa QIODevice
225*/
226
227QIODevice* QAudioOutput::start()
228{
229 /*
230 -If currently not StoppedState, stop.
231 -If no internal QIODevice, create one.
232 -open audio output.
233 -If ok, NoError and IdleState, else OpenError and StoppedState
234 -emit stateChanged()
235 -return internal QIODevice
236 */
237 return d->start(0);
238}
239
240/*!
241 Stops the audio output.
242*/
243
244void QAudioOutput::stop()
245{
246 /*
247 -If StoppedState, return
248 -set to StoppedState
249 -detach from audio device
250 -emit stateChanged()
251 */
252 d->stop();
253}
254
255/*!
256 Drops all audio data in the buffers, resets buffers to zero.
257*/
258
259void QAudioOutput::reset()
260{
261 /*
262 -drop all buffered audio, set buffers to zero.
263 -call stop()
264 */
265 d->reset();
266}
267
268/*!
269 Stops processing audio data, preserving buffered audio data.
270*/
271
272void QAudioOutput::suspend()
273{
274 /*
275 -If not ActiveState|IdleState, return
276 -stop processing audio, saving all buffered audio data
277 -set NoError and SuspendedState
278 -emit stateChanged()
279 */
280 d->suspend();
281}
282
283/*!
284 Resumes processing audio data after a suspend().
285*/
286
287void QAudioOutput::resume()
288{
289 /*
290 -If SuspendedState, return
291 -resume audio
292 -(PULL MODE): set ActiveState, NoError
293 -(PUSH MODE): set IdleState, NoError
294 -kick start audio if needed
295 -emit stateChanged()
296 */
297 d->resume();
298}
299
300/*!
301 Returns the free space available in bytes in the audio buffer.
302*/
303
304int QAudioOutput::bytesFree() const
305{
306 /*
307 -If not ActiveState|IdleState, return 0
308 -return space available in audio buffer in bytes
309 */
310 return d->bytesFree();
311}
312
313/*!
314 Returns the period size in bytes.
315
316 Note: This is the recommended write size in bytes.
317*/
318
319int QAudioOutput::periodSize() const
320{
321 return d->periodSize();
322}
323
324/*!
325 Sets the audio buffer size to \a value in bytes.
326
327 Note: This function can be called anytime before start(), calls to this
328 are ignored after start(). It should not be assumed that the buffer size
329 set is the actual buffer size used, calling bufferSize() anytime after start()
330 will return the actual buffer size being used.
331*/
332
333void QAudioOutput::setBufferSize(int value)
334{
335 d->setBufferSize(value);
336}
337
338/*!
339 Returns the audio buffer size in bytes.
340
341 If called before start(), returns platform default value.
342 If called before start() but setBufferSize() was called prior, returns value set by setBufferSize().
343 If called after start(), returns the actual buffer size being used. This may not be what was set previously
344 by setBufferSize().
345
346*/
347
348int QAudioOutput::bufferSize() const
349{
350 return d->bufferSize();
351}
352
353/*!
354 Sets the interval for notify() signal to be emitted.
355 This is based on the \a ms of audio data processed
356 not on actual real-time. The resolution of the timer is platform specific.
357*/
358
359void QAudioOutput::setNotifyInterval(int ms)
360{
361 d->setNotifyInterval(ms);
362}
363
364/*!
365 Returns the notify interval in milliseconds.
366*/
367
368int QAudioOutput::notifyInterval() const
369{
370 return d->notifyInterval();
371}
372
373/*!
374 Returns the amount of audio data processed since start()
375 was called in microseconds.
376*/
377
378qint64 QAudioOutput::processedUSecs() const
379{
380 return d->processedUSecs();
381}
382
383/*!
384 Returns the microseconds since start() was called, including time in Idle and
385 Suspend states.
386*/
387
388qint64 QAudioOutput::elapsedUSecs() const
389{
390 return d->elapsedUSecs();
391}
392
393/*!
394 Returns the error state.
395*/
396
397QAudio::Error QAudioOutput::error() const
398{
399 return d->error();
400}
401
402/*!
403 Returns the state of audio processing.
404*/
405
406QAudio::State QAudioOutput::state() const
407{
408 return d->state();
409}
410
411/*!
412 \fn QAudioOutput::stateChanged(QAudio::State state)
413 This signal is emitted when the device \a state has changed.
414 This is the current state of the audio output.
415*/
416
417/*!
418 \fn QAudioOutput::notify()
419 This signal is emitted when x ms of audio data has been processed
420 the interval set by setNotifyInterval(x).
421*/
422
423QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.