| /**************************************************************************** |
| ** |
| ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). |
| ** All rights reserved. |
| ** Contact: Nokia Corporation (qt-info@nokia.com) |
| ** |
| ** This file is part of the QtGui module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** GNU Lesser General Public License Usage |
| ** This file may be used under the terms of the GNU Lesser General Public |
| ** License version 2.1 as published by the Free Software Foundation and |
| ** appearing in the file LICENSE.LGPL included in the packaging of this |
| ** file. Please review the following information to ensure the GNU Lesser |
| ** General Public License version 2.1 requirements will be met: |
| ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
| ** |
| ** In addition, as a special exception, Nokia gives you certain additional |
| ** rights. These rights are described in the Nokia Qt LGPL Exception |
| ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU General |
| ** Public License version 3.0 as published by the Free Software Foundation |
| ** and appearing in the file LICENSE.GPL included in the packaging of this |
| ** file. Please review the following information to ensure the GNU General |
| ** Public License version 3.0 requirements will be met: |
| ** http://www.gnu.org/copyleft/gpl.html. |
| ** |
| ** Other Usage |
| ** Alternatively, this file may be used in accordance with the terms and |
| ** conditions contained in a signed written agreement between you and Nokia. |
| ** |
| ** |
| ** |
| ** |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| |
| |
| #ifndef QT_NO_SOUND |
| |
| #include "qdir.h" |
| #include "qapplication.h" |
| #include "qsound.h" |
| #include "qsound_p.h" |
| #include "qfileinfo.h" |
| #include <private/qcore_symbian_p.h> |
| |
| #include <e32std.h> |
| #include <mdaaudiosampleplayer.h> |
| |
| QT_BEGIN_NAMESPACE |
| |
| class QAuServerS60; |
| |
| class QAuBucketS60 : public QAuBucket, public MMdaAudioPlayerCallback |
| { |
| public: |
| QAuBucketS60(QAuServerS60 *server, QSound *sound); |
| ~QAuBucketS60(); |
| |
| void play(); |
| void stop(); |
| |
| inline QSound *sound() const { return m_sound; } |
| |
| public: // from MMdaAudioPlayerCallback |
| void MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& aDuration); |
| void MapcPlayComplete(TInt aError); |
| |
| private: |
| QSound *m_sound; |
| QAuServerS60 *m_server; |
| bool m_prepared; |
| bool m_playCalled; |
| CMdaAudioPlayerUtility *m_playUtility; |
| }; |
| |
| |
| class QAuServerS60 : public QAuServer |
| { |
| public: |
| QAuServerS60(QObject *parent); |
| |
| void init(QSound *s) |
| { |
| QAuBucketS60 *bucket = new QAuBucketS60(this, s); |
| setBucket(s, bucket); |
| } |
| |
| void play(QSound *s) |
| { |
| bucket(s)->play(); |
| } |
| |
| void stop(QSound *s) |
| { |
| bucket(s)->stop(); |
| } |
| |
| bool okay() { return true; } |
| |
| void play(const QString& filename); |
| |
| protected: |
| void playCompleted(QAuBucketS60 *bucket, int error); |
| |
| protected: |
| QAuBucketS60 *bucket(QSound *s) |
| { |
| return (QAuBucketS60 *)QAuServer::bucket( s ); |
| } |
| |
| friend class QAuBucketS60; |
| |
| // static QSound::play(filename) cannot be stopped, meaning that playCompleted |
| // will get always called and QSound gets removed form this list. |
| QList<QSound *> staticPlayingSounds; |
| }; |
| |
| QAuServerS60::QAuServerS60(QObject *parent) : |
| QAuServer(parent) |
| { |
| setObjectName(QLatin1String("QAuServerS60")); |
| } |
| |
| void QAuServerS60::play(const QString& filename) |
| { |
| QSound *s = new QSound(filename); |
| staticPlayingSounds.append(s); |
| play(s); |
| } |
| |
| void QAuServerS60::playCompleted(QAuBucketS60 *bucket, int error) |
| { |
| QSound *sound = bucket->sound(); |
| if (!error) { |
| // We need to handle repeats by ourselves, since with Symbian API we don't |
| // know how many loops have been played when user asks it |
| if (decLoop(sound)) { |
| play(sound); |
| } else { |
| if (staticPlayingSounds.removeAll(sound)) |
| delete sound; |
| } |
| } else { |
| // We don't have a way to inform about errors -> just decrement loops |
| // in order that QSound::isFinished will return true; |
| while (decLoop(sound) > 0) {} |
| if (staticPlayingSounds.removeAll(sound)) |
| delete sound; |
| } |
| } |
| |
| QAuServer *qt_new_audio_server() |
| { |
| return new QAuServerS60(qApp); |
| } |
| |
| QAuBucketS60::QAuBucketS60(QAuServerS60 *server, QSound *sound) |
| : m_sound(sound), m_server(server), m_prepared(false), m_playCalled(false) |
| { |
| QString filepath = QFileInfo(m_sound->fileName()).absoluteFilePath(); |
| filepath = QDir::toNativeSeparators(filepath); |
| TPtrC filepathPtr(qt_QString2TPtrC(filepath)); |
| TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this); |
| m_playUtility->OpenFileL(filepathPtr)); |
| if (err) { |
| m_server->playCompleted(this, err); |
| } |
| } |
| |
| void QAuBucketS60::play() |
| { |
| if (m_prepared) { |
| // OpenFileL call is completed we can start playing immediately |
| m_playUtility->Play(); |
| } else { |
| m_playCalled = true; |
| } |
| |
| } |
| |
| void QAuBucketS60::stop() |
| { |
| m_playCalled = false; |
| m_playUtility->Stop(); |
| } |
| |
| void QAuBucketS60::MapcPlayComplete(TInt aError) |
| { |
| m_server->playCompleted(this, aError); |
| } |
| |
| void QAuBucketS60::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& /*aDuration*/) |
| { |
| if (aError) { |
| m_server->playCompleted(this, aError); |
| } else { |
| m_prepared = true; |
| if (m_playCalled){ |
| play(); |
| } |
| } |
| } |
| |
| QAuBucketS60::~QAuBucketS60() |
| { |
| if (m_playUtility){ |
| m_playUtility->Stop(); |
| m_playUtility->Close(); |
| } |
| |
| delete m_playUtility; |
| } |
| |
| |
| #endif // QT_NO_SOUND |
| |
| QT_END_NAMESPACE |