qtmobility/src/multimedia/audio/qaudioinput_symbian_p.cpp
changeset 14 6fbed849b4f4
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 #include "qaudioinput_symbian_p.h"
       
    43 
       
    44 QT_BEGIN_NAMESPACE
       
    45 
       
    46 //-----------------------------------------------------------------------------
       
    47 // Constants
       
    48 //-----------------------------------------------------------------------------
       
    49 
       
    50 const int PushInterval = 50; // ms
       
    51 
       
    52 
       
    53 //-----------------------------------------------------------------------------
       
    54 // Private class
       
    55 //-----------------------------------------------------------------------------
       
    56 
       
    57 SymbianAudioInputPrivate::SymbianAudioInputPrivate(
       
    58                               QAudioInputPrivate *audioDevice)
       
    59     :   m_audioDevice(audioDevice)
       
    60 {
       
    61 
       
    62 }
       
    63 
       
    64 SymbianAudioInputPrivate::~SymbianAudioInputPrivate()
       
    65 {
       
    66 
       
    67 }
       
    68 
       
    69 qint64 SymbianAudioInputPrivate::readData(char *data, qint64 len)
       
    70 {
       
    71     qint64 totalRead = 0;
       
    72 
       
    73     if (m_audioDevice->state() == QAudio::ActiveState ||
       
    74         m_audioDevice->state() == QAudio::IdleState) {
       
    75 
       
    76         while (totalRead < len) {
       
    77             const qint64 read = m_audioDevice->read(data + totalRead,
       
    78                                                     len - totalRead);
       
    79             if (read > 0)
       
    80                 totalRead += read;
       
    81             else
       
    82                 break;
       
    83         }
       
    84     }
       
    85 
       
    86     return totalRead;
       
    87 }
       
    88 
       
    89 qint64 SymbianAudioInputPrivate::writeData(const char *data, qint64 len)
       
    90 {
       
    91     Q_UNUSED(data)
       
    92     Q_UNUSED(len)
       
    93     return 0;
       
    94 }
       
    95 
       
    96 void SymbianAudioInputPrivate::dataReady()
       
    97 {
       
    98     emit readyRead();
       
    99 }
       
   100 
       
   101 
       
   102 //-----------------------------------------------------------------------------
       
   103 // Public functions
       
   104 //-----------------------------------------------------------------------------
       
   105 
       
   106 QAudioInputPrivate::QAudioInputPrivate(const QByteArray &device)
       
   107     :   m_device(device)
       
   108     ,   m_clientBufferSize(SymbianAudio::DefaultBufferSize)
       
   109     ,   m_notifyInterval(SymbianAudio::DefaultNotifyInterval)
       
   110     ,   m_notifyTimer(new QTimer(this))
       
   111     ,   m_error(QAudio::NoError)
       
   112     ,   m_internalState(SymbianAudio::ClosedState)
       
   113     ,   m_externalState(QAudio::StoppedState)
       
   114     ,   m_pullMode(false)
       
   115     ,   m_sink(0)
       
   116     ,   m_pullTimer(new QTimer(this))
       
   117     ,   m_devSoundBuffer(0)
       
   118     ,   m_devSoundBufferSize(0)
       
   119     ,   m_totalBytesReady(0)
       
   120     ,   m_devSoundBufferPos(0)
       
   121     ,   m_totalSamplesRecorded(0)
       
   122 {
       
   123     connect(m_notifyTimer.data(), SIGNAL(timeout()), this, SIGNAL(notify()));
       
   124 
       
   125     //SymbianAudio::Utils::formatQtToNative(m_format, m_nativeFourCC,
       
   126     //                                      m_nativeFormat);
       
   127 
       
   128     m_pullTimer->setInterval(PushInterval);
       
   129     connect(m_pullTimer.data(), SIGNAL(timeout()), this, SLOT(pullData()));
       
   130 }
       
   131 
       
   132 void QAudioInputPrivate::setFormat(const QAudioFormat& fmt)
       
   133 {
       
   134     m_format = const_cast<QAudioFormat&>(fmt);
       
   135     SymbianAudio::Utils::formatQtToNative(m_format, m_nativeFourCC,
       
   136                                           m_nativeFormat);
       
   137 }
       
   138 
       
   139 QAudioInputPrivate::~QAudioInputPrivate()
       
   140 {
       
   141     close();
       
   142 }
       
   143 
       
   144 void QAudioInputPrivate::start(QIODevice *device)
       
   145 {
       
   146     stop();
       
   147 
       
   148     open();
       
   149     if (SymbianAudio::ClosedState != m_internalState) {
       
   150         m_pullMode = true;
       
   151         m_sink = device;
       
   152         m_elapsed.restart();
       
   153     }
       
   154 }
       
   155 
       
   156 QIODevice* QAudioInputPrivate::start()
       
   157 {
       
   158     stop();
       
   159 
       
   160     open();
       
   161     if (SymbianAudio::ClosedState != m_internalState) {
       
   162         m_sink = new SymbianAudioInputPrivate(this);
       
   163         m_sink->open(QIODevice::ReadOnly | QIODevice::Unbuffered);
       
   164         m_elapsed.restart();
       
   165     }
       
   166 
       
   167     return m_sink;
       
   168 }
       
   169 
       
   170 void QAudioInputPrivate::stop()
       
   171 {
       
   172     close();
       
   173 }
       
   174 
       
   175 void QAudioInputPrivate::reset()
       
   176 {
       
   177     m_totalSamplesRecorded += getSamplesRecorded();
       
   178     m_devSound->Stop();
       
   179     startRecording();
       
   180 }
       
   181 
       
   182 void QAudioInputPrivate::suspend()
       
   183 {
       
   184     if (SymbianAudio::ActiveState == m_internalState
       
   185         || SymbianAudio::IdleState == m_internalState) {
       
   186         m_notifyTimer->stop();
       
   187         m_pullTimer->stop();
       
   188         m_devSound->Pause();
       
   189         const qint64 samplesRecorded = getSamplesRecorded();
       
   190         m_totalSamplesRecorded += samplesRecorded;
       
   191 
       
   192         if (m_devSoundBuffer) {
       
   193             m_devSoundBufferQ.append(m_devSoundBuffer);
       
   194             m_devSoundBuffer = 0;
       
   195         }
       
   196 
       
   197         setState(SymbianAudio::SuspendedState);
       
   198     }
       
   199 }
       
   200 
       
   201 void QAudioInputPrivate::resume()
       
   202 {
       
   203     if (SymbianAudio::SuspendedState == m_internalState)
       
   204         startDataTransfer();
       
   205 }
       
   206 
       
   207 int QAudioInputPrivate::bytesReady() const
       
   208 {
       
   209     Q_ASSERT(m_devSoundBufferPos <= m_totalBytesReady);
       
   210     return m_totalBytesReady - m_devSoundBufferPos;
       
   211 }
       
   212 
       
   213 int QAudioInputPrivate::periodSize() const
       
   214 {
       
   215     return bufferSize();
       
   216 }
       
   217 
       
   218 void QAudioInputPrivate::setBufferSize(int value)
       
   219 {
       
   220     // Note that DevSound does not allow its client to specify the buffer size.
       
   221     // This functionality is available via custom interfaces, but since these
       
   222     // cannot be guaranteed to work across all DevSound implementations, we
       
   223     // do not use them here.
       
   224     // In order to comply with the expected bevahiour of QAudioInput, we store
       
   225     // the value and return it from bufferSize(), but the underlying DevSound
       
   226     // buffer size remains unchanged.
       
   227     if (value > 0)
       
   228         m_clientBufferSize = value;
       
   229 }
       
   230 
       
   231 int QAudioInputPrivate::bufferSize() const
       
   232 {
       
   233     return m_devSoundBufferSize ? m_devSoundBufferSize : m_clientBufferSize;
       
   234 }
       
   235 
       
   236 void QAudioInputPrivate::setNotifyInterval(int ms)
       
   237 {
       
   238     if (ms > 0) {
       
   239         const int oldNotifyInterval = m_notifyInterval;
       
   240         m_notifyInterval = ms;
       
   241         if (m_notifyTimer->isActive() && ms != oldNotifyInterval)
       
   242             m_notifyTimer->start(m_notifyInterval);
       
   243     }
       
   244 }
       
   245 
       
   246 int QAudioInputPrivate::notifyInterval() const
       
   247 {
       
   248     return m_notifyInterval;
       
   249 }
       
   250 
       
   251 qint64 QAudioInputPrivate::processedUSecs() const
       
   252 {
       
   253     int samplesPlayed = 0;
       
   254     if (m_devSound && SymbianAudio::SuspendedState != m_internalState)
       
   255         samplesPlayed = getSamplesRecorded();
       
   256 
       
   257     // Protect against division by zero
       
   258     Q_ASSERT_X(m_format.frequency() > 0, Q_FUNC_INFO, "Invalid frequency");
       
   259 
       
   260     const qint64 result = qint64(1000000) *
       
   261                           (samplesPlayed + m_totalSamplesRecorded)
       
   262                         / m_format.frequency();
       
   263 
       
   264     return result;
       
   265 }
       
   266 
       
   267 qint64 QAudioInputPrivate::elapsedUSecs() const
       
   268 {
       
   269     const qint64 result = (QAudio::StoppedState == state()) ?
       
   270                               0 : m_elapsed.elapsed() * 1000;
       
   271     return result;
       
   272 }
       
   273 
       
   274 QAudio::Error QAudioInputPrivate::error() const
       
   275 {
       
   276     return m_error;
       
   277 }
       
   278 
       
   279 QAudio::State QAudioInputPrivate::state() const
       
   280 {
       
   281     return m_externalState;
       
   282 }
       
   283 
       
   284 QAudioFormat QAudioInputPrivate::format() const
       
   285 {
       
   286     return m_format;
       
   287 }
       
   288 
       
   289 //-----------------------------------------------------------------------------
       
   290 // MDevSoundObserver implementation
       
   291 //-----------------------------------------------------------------------------
       
   292 
       
   293 void QAudioInputPrivate::InitializeComplete(TInt aError)
       
   294 {
       
   295     Q_ASSERT_X(SymbianAudio::InitializingState == m_internalState,
       
   296         Q_FUNC_INFO, "Invalid state");
       
   297 
       
   298     if (KErrNone == aError)
       
   299         startRecording();
       
   300 }
       
   301 
       
   302 void QAudioInputPrivate::ToneFinished(TInt aError)
       
   303 {
       
   304     Q_UNUSED(aError)
       
   305     // This class doesn't use DevSound's tone playback functions, so should
       
   306     // never receive this callback.
       
   307     Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback");
       
   308 }
       
   309 
       
   310 void QAudioInputPrivate::BufferToBeFilled(CMMFBuffer *aBuffer)
       
   311 {
       
   312     Q_UNUSED(aBuffer)
       
   313     // This class doesn't use DevSound in play mode, so should never receive
       
   314     // this callback.
       
   315     Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback");
       
   316 }
       
   317 
       
   318 void QAudioInputPrivate::PlayError(TInt aError)
       
   319 {
       
   320     Q_UNUSED(aError)
       
   321     // This class doesn't use DevSound in play mode, so should never receive
       
   322     // this callback.
       
   323     Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback");
       
   324 }
       
   325 
       
   326 void QAudioInputPrivate::BufferToBeEmptied(CMMFBuffer *aBuffer)
       
   327 {
       
   328     // Following receipt of this callback, DevSound should not provide another
       
   329     // buffer until we have returned the current one.
       
   330     Q_ASSERT_X(!m_devSoundBuffer, Q_FUNC_INFO, "Buffer already held");
       
   331 
       
   332     CMMFDataBuffer *const buffer = static_cast<CMMFDataBuffer*>(aBuffer);
       
   333 
       
   334     if (!m_devSoundBufferSize)
       
   335         m_devSoundBufferSize = buffer->Data().MaxLength();
       
   336 
       
   337     m_totalBytesReady += buffer->Data().Length();
       
   338 
       
   339     if (SymbianAudio::SuspendedState == m_internalState) {
       
   340         m_devSoundBufferQ.append(buffer);
       
   341     } else {
       
   342         // Will be returned to DevSound by bufferEmptied().
       
   343         m_devSoundBuffer = buffer;
       
   344         m_devSoundBufferPos = 0;
       
   345 
       
   346         if (bytesReady() && !m_pullMode)
       
   347             pushData();
       
   348     }
       
   349 }
       
   350 
       
   351 void QAudioInputPrivate::RecordError(TInt aError)
       
   352 {
       
   353     Q_UNUSED(aError)
       
   354     setError(QAudio::IOError);
       
   355 }
       
   356 
       
   357 void QAudioInputPrivate::ConvertError(TInt aError)
       
   358 {
       
   359     Q_UNUSED(aError)
       
   360     // This class doesn't use DevSound's format conversion functions, so
       
   361     // should never receive this callback.
       
   362     Q_ASSERT_X(false, Q_FUNC_INFO, "Unexpected callback");
       
   363 }
       
   364 
       
   365 void QAudioInputPrivate::DeviceMessage(TUid aMessageType, const TDesC8 &aMsg)
       
   366 {
       
   367     Q_UNUSED(aMessageType)
       
   368     Q_UNUSED(aMsg)
       
   369     // Ignore this callback.
       
   370 }
       
   371 
       
   372 //-----------------------------------------------------------------------------
       
   373 // Private functions
       
   374 //-----------------------------------------------------------------------------
       
   375 
       
   376 void QAudioInputPrivate::open()
       
   377 {
       
   378     Q_ASSERT_X(SymbianAudio::ClosedState == m_internalState,
       
   379         Q_FUNC_INFO, "DevSound already opened");
       
   380 
       
   381     QT_TRAP_THROWING( m_devSound.reset(CMMFDevSound::NewL()) )
       
   382 
       
   383     QScopedPointer<SymbianAudio::DevSoundCapabilities> caps(
       
   384         new SymbianAudio::DevSoundCapabilities(*m_devSound, QAudio::AudioInput));
       
   385 
       
   386     int err = SymbianAudio::Utils::isFormatSupported(m_format, *caps) ?
       
   387                   KErrNone : KErrNotSupported;
       
   388 
       
   389     if (KErrNone == err) {
       
   390         setState(SymbianAudio::InitializingState);
       
   391         TRAP(err, m_devSound->InitializeL(*this, m_nativeFourCC,
       
   392                                           EMMFStateRecording));
       
   393     }
       
   394 
       
   395     if (KErrNone != err) {
       
   396         setError(QAudio::OpenError);
       
   397         m_devSound.reset();
       
   398     }
       
   399 }
       
   400 
       
   401 void QAudioInputPrivate::startRecording()
       
   402 {
       
   403     const int samplesRecorded = m_devSound->SamplesRecorded();
       
   404     Q_ASSERT(samplesRecorded == 0);
       
   405 
       
   406     TRAPD(err, startDevSoundL());
       
   407     if (KErrNone == err) {
       
   408         startDataTransfer();
       
   409     } else {
       
   410         setError(QAudio::OpenError);
       
   411         close();
       
   412     }
       
   413 }
       
   414 
       
   415 void QAudioInputPrivate::startDevSoundL()
       
   416 {
       
   417     TMMFCapabilities nativeFormat = m_devSound->Config();
       
   418     m_nativeFormat.iBufferSize = nativeFormat.iBufferSize;
       
   419     m_devSound->SetConfigL(m_nativeFormat);
       
   420     m_devSound->RecordInitL();
       
   421 }
       
   422 
       
   423 void QAudioInputPrivate::startDataTransfer()
       
   424 {
       
   425     m_notifyTimer->start(m_notifyInterval);
       
   426 
       
   427     if (m_pullMode)
       
   428         m_pullTimer->start();
       
   429 
       
   430     if (bytesReady()) {
       
   431         setState(SymbianAudio::ActiveState);
       
   432         if (!m_pullMode)
       
   433             pushData();
       
   434     } else {
       
   435         if (SymbianAudio::SuspendedState == m_internalState)
       
   436             setState(SymbianAudio::ActiveState);
       
   437         else
       
   438             setState(SymbianAudio::IdleState);
       
   439     }
       
   440 }
       
   441 
       
   442 CMMFDataBuffer* QAudioInputPrivate::currentBuffer() const
       
   443 {
       
   444     CMMFDataBuffer *result = m_devSoundBuffer;
       
   445     if (!result && !m_devSoundBufferQ.empty())
       
   446         result = m_devSoundBufferQ.front();
       
   447     return result;
       
   448 }
       
   449 
       
   450 void QAudioInputPrivate::pushData()
       
   451 {
       
   452     Q_ASSERT_X(bytesReady(), Q_FUNC_INFO, "No data available");
       
   453     Q_ASSERT_X(!m_pullMode, Q_FUNC_INFO, "pushData called when in pull mode");
       
   454     qobject_cast<SymbianAudioInputPrivate *>(m_sink)->dataReady();
       
   455 }
       
   456 
       
   457 qint64 QAudioInputPrivate::read(char *data, qint64 len)
       
   458 {
       
   459     // SymbianAudioInputPrivate is ready to read data
       
   460 
       
   461     Q_ASSERT_X(!m_pullMode, Q_FUNC_INFO,
       
   462         "read called when in pull mode");
       
   463 
       
   464     qint64 bytesRead = 0;
       
   465 
       
   466     CMMFDataBuffer *buffer = 0;
       
   467     while ((buffer = currentBuffer()) && (bytesRead < len)) {
       
   468         if (SymbianAudio::IdleState == m_internalState)
       
   469             setState(SymbianAudio::ActiveState);
       
   470 
       
   471         TDesC8 &inputBuffer = buffer->Data();
       
   472 
       
   473         const qint64 inputBytes = bytesReady();
       
   474         const qint64 outputBytes = len - bytesRead;
       
   475         const qint64 copyBytes = outputBytes < inputBytes ?
       
   476                                      outputBytes : inputBytes;
       
   477 
       
   478         memcpy(data, inputBuffer.Ptr() + m_devSoundBufferPos, copyBytes);
       
   479 
       
   480         m_devSoundBufferPos += copyBytes;
       
   481         data += copyBytes;
       
   482         bytesRead += copyBytes;
       
   483 
       
   484         if (!bytesReady())
       
   485             bufferEmptied();
       
   486     }
       
   487 
       
   488     return bytesRead;
       
   489 }
       
   490 
       
   491 void QAudioInputPrivate::pullData()
       
   492 {
       
   493     Q_ASSERT_X(m_pullMode, Q_FUNC_INFO,
       
   494         "pullData called when in push mode");
       
   495 
       
   496     CMMFDataBuffer *buffer = 0;
       
   497     while (buffer = currentBuffer()) {
       
   498         if (SymbianAudio::IdleState == m_internalState)
       
   499             setState(SymbianAudio::ActiveState);
       
   500 
       
   501         TDesC8 &inputBuffer = buffer->Data();
       
   502 
       
   503         const qint64 inputBytes = bytesReady();
       
   504         const qint64 bytesPushed = m_sink->write(
       
   505             (char*)inputBuffer.Ptr() + m_devSoundBufferPos, inputBytes);
       
   506 
       
   507         m_devSoundBufferPos += bytesPushed;
       
   508 
       
   509         if (!bytesReady())
       
   510             bufferEmptied();
       
   511 
       
   512         if (!bytesPushed)
       
   513             break;
       
   514     }
       
   515 }
       
   516 
       
   517 void QAudioInputPrivate::bufferEmptied()
       
   518 {
       
   519     m_devSoundBufferPos = 0;
       
   520 
       
   521     if (m_devSoundBuffer) {
       
   522         m_totalBytesReady -= m_devSoundBuffer->Data().Length();
       
   523         m_devSoundBuffer = 0;
       
   524         m_devSound->RecordData();
       
   525     } else {
       
   526         Q_ASSERT(!m_devSoundBufferQ.empty());
       
   527         m_totalBytesReady -= m_devSoundBufferQ.front()->Data().Length();
       
   528         m_devSoundBufferQ.erase(m_devSoundBufferQ.begin());
       
   529 
       
   530         // If the queue has been emptied, resume transfer from the hardware
       
   531         if (m_devSoundBufferQ.empty())
       
   532             m_devSound->RecordInitL();
       
   533     }
       
   534 
       
   535     Q_ASSERT(m_totalBytesReady >= 0);
       
   536 }
       
   537 
       
   538 void QAudioInputPrivate::close()
       
   539 {
       
   540     m_notifyTimer->stop();
       
   541     m_pullTimer->stop();
       
   542 
       
   543     m_error = QAudio::NoError;
       
   544 
       
   545     if (m_devSound)
       
   546         m_devSound->Stop();
       
   547     m_devSound.reset();
       
   548     m_devSoundBuffer = 0;
       
   549     m_devSoundBufferSize = 0;
       
   550     m_totalBytesReady = 0;
       
   551 
       
   552     if (!m_pullMode) // m_sink is owned
       
   553         delete m_sink;
       
   554     m_pullMode = false;
       
   555     m_sink = 0;
       
   556 
       
   557     m_devSoundBufferQ.clear();
       
   558     m_devSoundBufferPos = 0;
       
   559     m_totalSamplesRecorded = 0;
       
   560 
       
   561     setState(SymbianAudio::ClosedState);
       
   562 }
       
   563 
       
   564 qint64 QAudioInputPrivate::getSamplesRecorded() const
       
   565 {
       
   566     qint64 result = 0;
       
   567     if (m_devSound)
       
   568         result = qint64(m_devSound->SamplesRecorded());
       
   569     return result;
       
   570 }
       
   571 
       
   572 void QAudioInputPrivate::setError(QAudio::Error error)
       
   573 {
       
   574     m_error = error;
       
   575 
       
   576     // Although no state transition actually occurs here, a stateChanged event
       
   577     // must be emitted to inform the client that the call to start() was
       
   578     // unsuccessful.
       
   579     if (QAudio::OpenError == error)
       
   580         emit stateChanged(QAudio::StoppedState);
       
   581 
       
   582     // Close the DevSound instance.  This causes a transition to StoppedState.
       
   583     // This must be done asynchronously in case the current function was called
       
   584     // from a DevSound event handler, in which case deleting the DevSound
       
   585     // instance may cause an exception.
       
   586     QMetaObject::invokeMethod(this, "close", Qt::QueuedConnection);
       
   587 }
       
   588 
       
   589 void QAudioInputPrivate::setState(SymbianAudio::State newInternalState)
       
   590 {
       
   591     const QAudio::State oldExternalState = m_externalState;
       
   592     m_internalState = newInternalState;
       
   593     m_externalState = SymbianAudio::Utils::stateNativeToQt(
       
   594                             m_internalState, initializingState());
       
   595 
       
   596     if (m_externalState != oldExternalState)
       
   597         emit stateChanged(m_externalState);
       
   598 }
       
   599 
       
   600 QAudio::State QAudioInputPrivate::initializingState() const
       
   601 {
       
   602     return QAudio::IdleState;
       
   603 }
       
   604 
       
   605 QT_END_NAMESPACE