qtmobility/src/multimedia/audio/qaudiooutput.cpp
changeset 14 6fbed849b4f4
child 15 1f895d8a5b2b
equal deleted inserted replaced
11:06b8e2af4411 14:6fbed849b4f4
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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 Qt Mobility Components.
       
     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 "qaudio.h"
       
    44 #include "qaudiodeviceinfo.h"
       
    45 #include "qaudiosystem.h"
       
    46 #include "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;     // 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     \code
       
   149         void stateChanged(QAudio::State newState)
       
   150         {
       
   151             switch (newState) {
       
   152             case QAudio::StopState:
       
   153                 if (output->error() != QAudio::NoError) {
       
   154                     // Perform error handling
       
   155                 } else {
       
   156                     // Normal stop
       
   157                 }
       
   158                 break;
       
   159     \endcode
       
   160 
       
   161     \sa QAudioInput, QAudioDeviceInfo
       
   162 */
       
   163 
       
   164 /*!
       
   165     Construct a new audio output and attach it to \a parent.
       
   166     The default audio output device is used with the output
       
   167     \a format parameters.
       
   168 */
       
   169 
       
   170 QAudioOutput::QAudioOutput(const QAudioFormat &format, QObject *parent):
       
   171     QObject(parent)
       
   172 {
       
   173     d = QAudioDeviceFactory::createDefaultOutputDevice(format);
       
   174     connect(d, SIGNAL(notify()), SIGNAL(notify()));
       
   175     connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State)));
       
   176 }
       
   177 
       
   178 /*!
       
   179     Construct a new audio output and attach it to \a parent.
       
   180     The device referenced by \a audioDevice is used with the output
       
   181     \a format parameters.
       
   182 */
       
   183 
       
   184 QAudioOutput::QAudioOutput(const QAudioDeviceInfo &audioDevice, const QAudioFormat &format, QObject *parent):
       
   185     QObject(parent)
       
   186 {
       
   187     d = QAudioDeviceFactory::createOutputDevice(audioDevice, format);
       
   188     connect(d, SIGNAL(notify()), SIGNAL(notify()));
       
   189     connect(d, SIGNAL(stateChanged(QAudio::State)), SIGNAL(stateChanged(QAudio::State)));
       
   190 }
       
   191 
       
   192 /*!
       
   193     Destroys this audio output.
       
   194 */
       
   195 
       
   196 QAudioOutput::~QAudioOutput()
       
   197 {
       
   198     delete d;
       
   199 }
       
   200 
       
   201 /*!
       
   202     Returns the QAudioFormat being used.
       
   203 
       
   204 */
       
   205 
       
   206 QAudioFormat QAudioOutput::format() const
       
   207 {
       
   208     return d->format();
       
   209 }
       
   210 
       
   211 /*!
       
   212     Uses the \a device as the QIODevice to transfer data.
       
   213     Passing a QIODevice allows the data to be transfered without any extra code.
       
   214     All that is required is to open the QIODevice.
       
   215 
       
   216     If able to successfully output audio data to the systems audio device the
       
   217     state() is set to QAudio::ActiveState, error() is set to QAudio::NoError
       
   218     and the stateChanged() signal is emitted.
       
   219 
       
   220     If a problem occurs during this process the error() is set to QAudio::OpenError,
       
   221     state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
       
   222 
       
   223     \sa QIODevice
       
   224 */
       
   225 
       
   226 void QAudioOutput::start(QIODevice* device)
       
   227 {
       
   228     d->start(device);
       
   229 }
       
   230 
       
   231 /*!
       
   232     Returns a pointer to the QIODevice being used to handle the data
       
   233     transfer. This QIODevice can be used to write() audio data directly.
       
   234 
       
   235     If able to access the systems audio device the state() is set to
       
   236     QAudio::IdleState, error() is set to QAudio::NoError
       
   237     and the stateChanged() signal is emitted.
       
   238 
       
   239     If a problem occurs during this process the error() is set to QAudio::OpenError,
       
   240     state() is set to QAudio::StoppedState and stateChanged() signal is emitted.
       
   241 
       
   242     \sa QIODevice
       
   243 */
       
   244 
       
   245 QIODevice* QAudioOutput::start()
       
   246 {
       
   247     return d->start();
       
   248 }
       
   249 
       
   250 /*!
       
   251     Stops the audio output, detaching from the system resource.
       
   252 
       
   253     Sets error() to QAudio::NoError, state() to QAudio::StoppedState and
       
   254     emit stateChanged() signal.
       
   255 */
       
   256 
       
   257 void QAudioOutput::stop()
       
   258 {
       
   259     d->stop();
       
   260 }
       
   261 
       
   262 /*!
       
   263     Drops all audio data in the buffers, resets buffers to zero.
       
   264 */
       
   265 
       
   266 void QAudioOutput::reset()
       
   267 {
       
   268     d->reset();
       
   269 }
       
   270 
       
   271 /*!
       
   272     Stops processing audio data, preserving buffered audio data.
       
   273 
       
   274     Sets error() to QAudio::NoError, state() to QAudio::SuspendedState and
       
   275     emit stateChanged() signal.
       
   276 */
       
   277 
       
   278 void QAudioOutput::suspend()
       
   279 {
       
   280     d->suspend();
       
   281 }
       
   282 
       
   283 /*!
       
   284     Resumes processing audio data after a suspend().
       
   285 
       
   286     Sets error() to QAudio::NoError.
       
   287     Sets state() to QAudio::ActiveState if you previously called start(QIODevice*).
       
   288     Sets state() to QAudio::IdleState if you previously called start().
       
   289     emits stateChanged() signal.
       
   290 */
       
   291 
       
   292 void QAudioOutput::resume()
       
   293 {
       
   294      d->resume();
       
   295 }
       
   296 
       
   297 /*!
       
   298     Returns the free space available in bytes in the audio buffer.
       
   299 
       
   300     NOTE: returned value is only valid while in QAudio::ActiveState or QAudio::IdleState
       
   301     state, otherwise returns zero.
       
   302 */
       
   303 
       
   304 int QAudioOutput::bytesFree() const
       
   305 {
       
   306     return d->bytesFree();
       
   307 }
       
   308 
       
   309 /*!
       
   310     Returns the period size in bytes.
       
   311 
       
   312     Note: This is the recommended write size in bytes.
       
   313 */
       
   314 
       
   315 int QAudioOutput::periodSize() const
       
   316 {
       
   317     return d->periodSize();
       
   318 }
       
   319 
       
   320 /*!
       
   321     Sets the audio buffer size to \a value in bytes.
       
   322 
       
   323     Note: This function can be called anytime before start(), calls to this
       
   324     are ignored after start(). It should not be assumed that the buffer size
       
   325     set is the actual buffer size used, calling bufferSize() anytime after start()
       
   326     will return the actual buffer size being used.
       
   327 */
       
   328 
       
   329 void QAudioOutput::setBufferSize(int value)
       
   330 {
       
   331     d->setBufferSize(value);
       
   332 }
       
   333 
       
   334 /*!
       
   335     Returns the audio buffer size in bytes.
       
   336 
       
   337     If called before start(), returns platform default value.
       
   338     If called before start() but setBufferSize() was called prior, returns value set by setBufferSize().
       
   339     If called after start(), returns the actual buffer size being used. This may not be what was set previously
       
   340     by setBufferSize().
       
   341 
       
   342 */
       
   343 
       
   344 int QAudioOutput::bufferSize() const
       
   345 {
       
   346     return d->bufferSize();
       
   347 }
       
   348 
       
   349 /*!
       
   350     Sets the interval for notify() signal to be emitted.
       
   351     This is based on the \a ms of audio data processed
       
   352     not on actual real-time.
       
   353     The minimum resolution of the timer is platform specific and values
       
   354     should be checked with notifyInterval() to confirm actual value
       
   355     being used.
       
   356 */
       
   357 
       
   358 void QAudioOutput::setNotifyInterval(int ms)
       
   359 {
       
   360     d->setNotifyInterval(ms);
       
   361 }
       
   362 
       
   363 /*!
       
   364     Returns the notify interval in milliseconds.
       
   365 */
       
   366 
       
   367 int QAudioOutput::notifyInterval() const
       
   368 {
       
   369     return d->notifyInterval();
       
   370 }
       
   371 
       
   372 /*!
       
   373     Returns the amount of audio data processed since start()
       
   374     was called in microseconds.
       
   375 */
       
   376 
       
   377 qint64 QAudioOutput::processedUSecs() const
       
   378 {
       
   379     return d->processedUSecs();
       
   380 }
       
   381 
       
   382 /*!
       
   383     Returns the microseconds since start() was called, including time in Idle and
       
   384     Suspend states.
       
   385 */
       
   386 
       
   387 qint64 QAudioOutput::elapsedUSecs() const
       
   388 {
       
   389     return d->elapsedUSecs();
       
   390 }
       
   391 
       
   392 /*!
       
   393     Returns the error state.
       
   394 */
       
   395 
       
   396 QAudio::Error QAudioOutput::error() const
       
   397 {
       
   398     return d->error();
       
   399 }
       
   400 
       
   401 /*!
       
   402     Returns the state of audio processing.
       
   403 */
       
   404 
       
   405 QAudio::State QAudioOutput::state() const
       
   406 {
       
   407     return d->state();
       
   408 }
       
   409 
       
   410 /*!
       
   411     \fn QAudioOutput::stateChanged(QAudio::State state)
       
   412     This signal is emitted when the device \a state has changed.
       
   413     This is the current state of the audio output.
       
   414 */
       
   415 
       
   416 /*!
       
   417     \fn QAudioOutput::notify()
       
   418     This signal is emitted when x ms of audio data has been processed
       
   419     the interval set by setNotifyInterval(x).
       
   420 */
       
   421 
       
   422 QT_END_NAMESPACE