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

Last change on this file since 890 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