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

Last change on this file since 966 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

  • Property svn:eol-style set to native
File size: 12.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 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 transferred without any extra code.
203 All that is required is to open the QIODevice.
204
205 If able to successfully output audio data to the systems audio device the
206 state() is set to QAudio::ActiveState, error() is set to QAudio::NoError
207 and the stateChanged() signal is emitted.
208
209 If a problem occurs during this process the error() is set to QAudio::OpenError,
210 state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
211
212 In either case, the stateChanged() signal may be emitted either synchronously
213 during execution of the start() function or asynchronously after start() has
214 returned to the caller.
215
216 \sa QIODevice
217*/
218
219void QAudioOutput::start(QIODevice* device)
220{
221 d->start(device);
222}
223
224/*!
225 Returns a pointer to the QIODevice being used to handle the data
226 transfer. This QIODevice can be used to write() audio data directly.
227
228 If able to access the systems audio device the state() is set to
229 QAudio::IdleState, error() is set to QAudio::NoError
230 and the stateChanged() signal is emitted.
231
232 If a problem occurs during this process the error() is set to QAudio::OpenError,
233 state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
234
235 In either case, the stateChanged() signal may be emitted either synchronously
236 during execution of the start() function or asynchronously after start() has
237 returned to the caller.
238
239 \sa QIODevice
240*/
241
242QIODevice* QAudioOutput::start()
243{
244 return d->start(0);
245}
246
247/*!
248 Stops the audio output, detaching from the system resource.
249
250 Sets error() to QAudio::NoError, state() to QAudio::StoppedState and
251 emit stateChanged() signal.
252*/
253
254void QAudioOutput::stop()
255{
256 d->stop();
257}
258
259/*!
260 Drops all audio data in the buffers, resets buffers to zero.
261*/
262
263void QAudioOutput::reset()
264{
265 d->reset();
266}
267
268/*!
269 Stops processing audio data, preserving buffered audio data.
270
271 Sets error() to QAudio::NoError, state() to QAudio::SuspendedState and
272 emit stateChanged() signal.
273*/
274
275void QAudioOutput::suspend()
276{
277 d->suspend();
278}
279
280/*!
281 Resumes processing audio data after a suspend().
282
283 Sets error() to QAudio::NoError.
284 Sets state() to QAudio::ActiveState if you previously called start(QIODevice*).
285 Sets state() to QAudio::IdleState if you previously called start().
286 emits stateChanged() signal.
287
288 Note: signal will always be emitted during execution of the resume() function.
289*/
290
291void QAudioOutput::resume()
292{
293 d->resume();
294}
295
296/*!
297 Returns the free space available in bytes in the audio buffer.
298
299 NOTE: returned value is only valid while in QAudio::ActiveState or QAudio::IdleState
300 state, otherwise returns zero.
301*/
302
303int QAudioOutput::bytesFree() const
304{
305 return d->bytesFree();
306}
307
308/*!
309 Returns the period size in bytes.
310
311 Note: This is the recommended write size in bytes.
312*/
313
314int QAudioOutput::periodSize() const
315{
316 return d->periodSize();
317}
318
319/*!
320 Sets the audio buffer size to \a value in bytes.
321
322 Note: This function can be called anytime before start(), calls to this
323 are ignored after start(). It should not be assumed that the buffer size
324 set is the actual buffer size used, calling bufferSize() anytime after start()
325 will return the actual buffer size being used.
326*/
327
328void QAudioOutput::setBufferSize(int value)
329{
330 d->setBufferSize(value);
331}
332
333/*!
334 Returns the audio buffer size in bytes.
335
336 If called before start(), returns platform default value.
337 If called before start() but setBufferSize() was called prior, returns value set by setBufferSize().
338 If called after start(), returns the actual buffer size being used. This may not be what was set previously
339 by setBufferSize().
340
341*/
342
343int QAudioOutput::bufferSize() const
344{
345 return d->bufferSize();
346}
347
348/*!
349 Sets the interval for notify() signal to be emitted.
350 This is based on the \a ms of audio data processed
351 not on actual real-time.
352 The minimum resolution of the timer is platform specific and values
353 should be checked with notifyInterval() to confirm actual value
354 being used.
355*/
356
357void QAudioOutput::setNotifyInterval(int ms)
358{
359 d->setNotifyInterval(ms);
360}
361
362/*!
363 Returns the notify interval in milliseconds.
364*/
365
366int QAudioOutput::notifyInterval() const
367{
368 return d->notifyInterval();
369}
370
371/*!
372 Returns the amount of audio data processed by the class since start()
373 was called in microseconds.
374
375 Note: The amount of audio data played can be determined by subtracting
376 the microseconds of audio data still in the systems audio buffer.
377
378 \code
379 qint64 bytesInBuffer = bufferSize() - bytesFree();
380 qint64 usInBuffer = (qint64)(1000000) * bytesInBuffer / ( channels() * sampleSize() / 8 ) / frequency();
381 qint64 usPlayed = processedUSecs() - usInBuffer;
382 \endcode
383*/
384
385qint64 QAudioOutput::processedUSecs() const
386{
387 return d->processedUSecs();
388}
389
390/*!
391 Returns the microseconds since start() was called, including time in Idle and
392 Suspend states.
393*/
394
395qint64 QAudioOutput::elapsedUSecs() const
396{
397 return d->elapsedUSecs();
398}
399
400/*!
401 Returns the error state.
402*/
403
404QAudio::Error QAudioOutput::error() const
405{
406 return d->error();
407}
408
409/*!
410 Returns the state of audio processing.
411*/
412
413QAudio::State QAudioOutput::state() const
414{
415 return d->state();
416}
417
418/*!
419 \fn QAudioOutput::stateChanged(QAudio::State state)
420 This signal is emitted when the device \a state has changed.
421 This is the current state of the audio output.
422*/
423
424/*!
425 \fn QAudioOutput::notify()
426 This signal is emitted when x ms of audio data has been processed
427 the interval set by setNotifyInterval(x).
428*/
429
430QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.