src/multimedia/audio/qaudiooutput.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtMultimedia module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    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 
       
    51 QT_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;
       
    77       inputFile.setFileName("/tmp/test.raw");
       
    78       inputFile.open(QIODevice::ReadOnly);
       
    79 
       
    80       QAudioFormat format;
       
    81       // Set up the format, eg.
       
    82       format.setFrequency(8000);
       
    83       format.setChannels(1);
       
    84       format.setSampleSize(8);
       
    85       format.setCodec("audio/pcm");
       
    86       format.setByteOrder(QAudioFormat::LittleEndian);
       
    87       format.setSampleType(QAudioFormat::UnSignedInt);
       
    88 
       
    89       QAudioOutput *audio = new QAudioOutput(format, this);
       
    90       connect(audio,SIGNAL(stateChanged(QAudio::State)),SLOT(finishedPlaying(QAudio::State)));
       
    91       audio->start(inputFile);
       
    92 
       
    93     \endcode
       
    94 
       
    95     The file will start playing assuming that the audio system and
       
    96     output device support it. If you run out of luck, check what's
       
    97     up with the error() function.
       
    98 
       
    99     After the file has finished playing, we need to stop the device:
       
   100 
       
   101     \code
       
   102       void finishedPlaying(QAudio::State state)
       
   103       {
       
   104         if(state == QAudio::IdleState) {
       
   105           audio->stop();
       
   106           inputFile.close();
       
   107         }
       
   108       }
       
   109     \endcode
       
   110 
       
   111     At any given time, the QAudioOutput will be in one of four states:
       
   112     active, suspended, stopped, or idle. These states are described
       
   113     by the QAudio::State enum.
       
   114     State changes are reported through the stateChanged() signal. You
       
   115     can use this signal to, for instance, update the GUI of the
       
   116     application; the mundane example here being changing the state of
       
   117     a \c { play/pause } button. You request a state change directly
       
   118     with suspend(), stop(), reset(), resume(), and start().
       
   119 
       
   120     While the stream is playing, you can set a notify interval in
       
   121     milliseconds with setNotifyInterval(). This interval specifies the
       
   122     time between two emissions of the notify() signal. This is
       
   123     relative to the position in the stream, i.e., if the QAudioOutput
       
   124     is in the SuspendedState or the IdleState, the notify() signal is
       
   125     not emitted. A typical use-case would be to update a
       
   126     \l{QSlider}{slider} that allows seeking in the stream.
       
   127     If you want the time since playback started regardless of which
       
   128     states the audio output has been in, clock() is the function for you.
       
   129 
       
   130     If an error occurs, you can fetch the \l{QAudio::Error}{error
       
   131     type} with the error() function. Please see the QAudio::Error enum
       
   132     for a description of the possible errors that are reported.  When
       
   133     an error is encountered, the state changes to QAudio::StopState.
       
   134     You can check for errors by connecting to the stateChanged()
       
   135     signal:
       
   136 
       
   137     \snippet doc/src/snippets/audio/main.cpp 3
       
   138 
       
   139     \sa QAudioInput, QAudioDeviceInfo
       
   140 */
       
   141 
       
   142 /*!
       
   143     Construct a new audio output and attach it to \a parent.
       
   144     The default audio output device is used with the output
       
   145     \a format parameters.
       
   146 */
       
   147 
       
   148 QAudioOutput::QAudioOutput(const QAudioFormat &format, QObject *parent):
       
   149     QObject(parent)
       
   150 {
       
   151     d = QAudioDeviceFactory::createDefaultOutputDevice(format);
       
   152     connect(d, SIGNAL(notify()), SIGNAL(notify()));
       
   153     connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State)));
       
   154 }
       
   155 
       
   156 /*!
       
   157     Construct a new audio output and attach it to \a parent.
       
   158     The device referenced by \a audioDevice is used with the output
       
   159     \a format parameters.
       
   160 */
       
   161 
       
   162 QAudioOutput::QAudioOutput(const QAudioDeviceInfo &audioDevice, const QAudioFormat &format, QObject *parent):
       
   163     QObject(parent)
       
   164 {
       
   165     d = QAudioDeviceFactory::createOutputDevice(audioDevice, format);
       
   166     connect(d, SIGNAL(notify()), SIGNAL(notify()));
       
   167     connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State)));
       
   168 }
       
   169 
       
   170 /*!
       
   171     Destroys this audio output.
       
   172 */
       
   173 
       
   174 QAudioOutput::~QAudioOutput()
       
   175 {
       
   176     delete d;
       
   177 }
       
   178 
       
   179 /*!
       
   180     Returns the QAudioFormat being used.
       
   181 
       
   182 */
       
   183 
       
   184 QAudioFormat QAudioOutput::format() const
       
   185 {
       
   186     return d->format();
       
   187 }
       
   188 
       
   189 /*!
       
   190     Uses the \a device as the QIODevice to transfer data.
       
   191     If \a device is null then the class creates an internal QIODevice.
       
   192     Returns a pointer to the QIODevice being used to handle the data
       
   193     transfer. This QIODevice can be used to write() audio data
       
   194     directly.
       
   195     Passing a QIODevice allows the data to be transfered without any extra code.
       
   196     All that is required is to open the QIODevice.
       
   197 
       
   198     \sa QIODevice
       
   199 */
       
   200 
       
   201 QIODevice* QAudioOutput::start(QIODevice* device)
       
   202 {
       
   203     /*
       
   204     PULL MODE (valid QIODevice)
       
   205     -If currently not StopState, stop.
       
   206     -If previous start was push mode, delete internal QIODevice.
       
   207     -open audio output.
       
   208     -If ok, NoError and ActiveState, else OpenError and StopState
       
   209     -emit stateChanged()
       
   210     -return device
       
   211 
       
   212     PUSH MODE (device = 0)
       
   213     -If currently not StopState, stop.
       
   214     -If no internal QIODevice, create one.
       
   215     -open audio output.
       
   216     -If ok, NoError and IdleState, else OpenError and StopState
       
   217     -emit stateChanged()
       
   218     -return internal QIODevice
       
   219     */
       
   220     return d->start(device);
       
   221 }
       
   222 
       
   223 /*!
       
   224     Stops the audio output.
       
   225 */
       
   226 
       
   227 void QAudioOutput::stop()
       
   228 {
       
   229     /*
       
   230     -If StopState, return
       
   231     -set to StopState
       
   232     -detach from audio device
       
   233     -emit stateChanged()
       
   234     */
       
   235     d->stop();
       
   236 }
       
   237 
       
   238 /*!
       
   239     Drops all audio data in the buffers, resets buffers to zero.
       
   240 */
       
   241 
       
   242 void QAudioOutput::reset()
       
   243 {
       
   244     /*
       
   245     -drop all buffered audio, set buffers to zero.
       
   246     -call stop()
       
   247     */
       
   248     d->reset();
       
   249 }
       
   250 
       
   251 /*!
       
   252     Stops processing audio data, preserving buffered audio data.
       
   253 */
       
   254 
       
   255 void QAudioOutput::suspend()
       
   256 {
       
   257     /*
       
   258     -If not ActiveState|IdleState, return
       
   259     -stop processing audio, saving all buffered audio data
       
   260     -set NoError and SuspendState
       
   261     -emit stateChanged()
       
   262     */
       
   263     d->suspend();
       
   264 }
       
   265 
       
   266 /*!
       
   267     Resumes processing audio data after a suspend().
       
   268 */
       
   269 
       
   270 void QAudioOutput::resume()
       
   271 {
       
   272     /*
       
   273     -If SuspendState, return
       
   274     -resume audio
       
   275     -(PULL MODE): set ActiveState, NoError
       
   276     -(PUSH MODE): set IdleState, NoError
       
   277     -kick start audio if needed
       
   278     -emit stateChanged()
       
   279     */
       
   280      d->resume();
       
   281 }
       
   282 
       
   283 /*!
       
   284     Returns the free space available in bytes in the audio buffer.
       
   285 */
       
   286 
       
   287 int QAudioOutput::bytesFree() const
       
   288 {
       
   289     /*
       
   290     -If not ActiveState|IdleState, return 0
       
   291     -return space available in audio buffer in bytes
       
   292     */
       
   293     return d->bytesFree();
       
   294 }
       
   295 
       
   296 /*!
       
   297     Returns the period size in bytes.
       
   298 
       
   299     Note: This is the recommended write size in bytes.
       
   300 */
       
   301 
       
   302 int QAudioOutput::periodSize() const
       
   303 {
       
   304     return d->periodSize();
       
   305 }
       
   306 
       
   307 /*!
       
   308     Sets the audio buffer size to \a value in bytes.
       
   309 
       
   310     Note: This function can be called anytime before start(), calls to this
       
   311     are ignored after start(). It should not be assumed that the buffer size
       
   312     set is the actual buffer size used, calling bufferSize() anytime after start()
       
   313     will return the actual buffer size being used.
       
   314 */
       
   315 
       
   316 void QAudioOutput::setBufferSize(int value)
       
   317 {
       
   318     d->setBufferSize(value);
       
   319 }
       
   320 
       
   321 /*!
       
   322     Returns the audio buffer size in bytes.
       
   323 
       
   324     If called before start(), returns platform default value.
       
   325     If called before start() but setBufferSize() was called prior, returns value set by setBufferSize().
       
   326     If called after start(), returns the actual buffer size being used. This may not be what was set previously
       
   327     by setBufferSize().
       
   328 
       
   329 */
       
   330 
       
   331 int QAudioOutput::bufferSize() const
       
   332 {
       
   333     return d->bufferSize();
       
   334 }
       
   335 
       
   336 /*!
       
   337     Sets the interval for notify() signal to be emitted.
       
   338     This is based on the \a ms of audio data processed
       
   339     not on actual real-time. The resolution of the timer is platform specific.
       
   340 */
       
   341 
       
   342 void QAudioOutput::setNotifyInterval(int ms)
       
   343 {
       
   344     d->setNotifyInterval(ms);
       
   345 }
       
   346 
       
   347 /*!
       
   348     Returns the notify interval in milliseconds.
       
   349 */
       
   350 
       
   351 int QAudioOutput::notifyInterval() const
       
   352 {
       
   353     return d->notifyInterval();
       
   354 }
       
   355 
       
   356 /*!
       
   357     Returns the amount of audio data processed since start()
       
   358     was called in microseconds.
       
   359 */
       
   360 
       
   361 qint64 QAudioOutput::totalTime() const
       
   362 {
       
   363     return d->totalTime();
       
   364 }
       
   365 
       
   366 /*!
       
   367     Returns the microseconds since start() was called, including time in Idle and
       
   368     Suspend states.
       
   369 */
       
   370 
       
   371 qint64 QAudioOutput::clock() const
       
   372 {
       
   373     return d->clock();
       
   374 }
       
   375 
       
   376 /*!
       
   377     Returns the error state.
       
   378 */
       
   379 
       
   380 QAudio::Error QAudioOutput::error() const
       
   381 {
       
   382     return d->error();
       
   383 }
       
   384 
       
   385 /*!
       
   386     Returns the state of audio processing.
       
   387 */
       
   388 
       
   389 QAudio::State QAudioOutput::state() const
       
   390 {
       
   391     return d->state();
       
   392 }
       
   393 
       
   394 /*!
       
   395     \fn QAudioOutput::stateChanged(QAudio::State state)
       
   396     This signal is emitted when the device \a state has changed.
       
   397     This is the current state of the audio output.
       
   398 */
       
   399 
       
   400 /*!
       
   401     \fn QAudioOutput::notify()
       
   402     This signal is emitted when x ms of audio data has been processed
       
   403     the interval set by setNotifyInterval(x).
       
   404 */
       
   405 
       
   406 QT_END_NAMESPACE