diff options
Diffstat (limited to 'src/imports')
13 files changed, 425 insertions, 229 deletions
diff --git a/src/imports/audioengine/audioengine.cpp b/src/imports/audioengine/audioengine.cpp index 612524447..4d29528f9 100644 --- a/src/imports/audioengine/audioengine.cpp +++ b/src/imports/audioengine/audioengine.cpp @@ -68,6 +68,10 @@ public: qmlRegisterType<QDeclarativeAttenuationModelLinear>(uri, 1, 0, "AttenuationModelLinear"); qmlRegisterType<QDeclarativeAttenuationModelInverse>(uri, 1, 0, "AttenuationModelInverse"); + + // Dynamically adding audio engine related objects is only supported through revision 1 + qmlRegisterRevision<QDeclarativeAudioEngine, 1>(uri, 1, 1); + qmlRegisterRevision<QDeclarativeSound, 1>(uri, 1, 1); } }; diff --git a/src/imports/audioengine/qdeclarative_attenuationmodel_p.cpp b/src/imports/audioengine/qdeclarative_attenuationmodel_p.cpp index 0814e9d62..7ecdb41ae 100644 --- a/src/imports/audioengine/qdeclarative_attenuationmodel_p.cpp +++ b/src/imports/audioengine/qdeclarative_attenuationmodel_p.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include "qdeclarative_attenuationmodel_p.h" +#include "qdeclarative_audioengine_p.h" #include "qdebug.h" #define DEBUG_AUDIOENGINE @@ -40,7 +41,7 @@ QT_USE_NAMESPACE QDeclarativeAttenuationModel::QDeclarativeAttenuationModel(QObject *parent) : QObject(parent) - , m_complete(false) + , m_engine(0) { } @@ -48,22 +49,9 @@ QDeclarativeAttenuationModel::~QDeclarativeAttenuationModel() { } -void QDeclarativeAttenuationModel::classBegin() +void QDeclarativeAttenuationModel::setEngine(QDeclarativeAudioEngine *engine) { - if (!parent() || !parent()->inherits("QDeclarativeAudioEngine")) { - qWarning("AttenuationModel must be defined inside AudioEngine!"); - //TODO: COMPILE_EXCEPTION ? - return; - } -} - -void QDeclarativeAttenuationModel::componentComplete() -{ - if (m_name.isEmpty()) { - qWarning("AttenuationModel must have a name!"); - return; - } - m_complete = true; + m_engine = engine; } QString QDeclarativeAttenuationModel::name() const @@ -73,7 +61,7 @@ QString QDeclarativeAttenuationModel::name() const void QDeclarativeAttenuationModel::setName(const QString& name) { - if (m_complete) { + if (m_engine) { qWarning("AttenuationModel: you can not change name after initialization."); return; } @@ -93,7 +81,9 @@ void QDeclarativeAttenuationModel::setName(const QString& name) This type is part of the \b{QtAudioEngine 1.0} module. - AttenuationModelLinear must be defined inside \l AudioEngine. + AttenuationModelLinear must be defined inside \l AudioEngine or be added to it using + \l{QtAudioEngine::AudioEngine::addAttenuationModel()}{AudioEngine.addAttenuationModel()} + if AttenuationModelLinear is created dynamically. \qml import QtQuick 2.0 @@ -144,13 +134,13 @@ QDeclarativeAttenuationModelLinear::QDeclarativeAttenuationModelLinear(QObject * { } -void QDeclarativeAttenuationModelLinear::componentComplete() +void QDeclarativeAttenuationModelLinear::setEngine(QDeclarativeAudioEngine *engine) { if (m_start > m_end) { qSwap(m_start, m_end); qWarning() << "AttenuationModelLinear[" << m_name << "]: start must be less or equal than end."; } - QDeclarativeAttenuationModel::componentComplete(); + QDeclarativeAttenuationModel::setEngine(engine); } /*! @@ -167,7 +157,7 @@ qreal QDeclarativeAttenuationModelLinear::startDistance() const void QDeclarativeAttenuationModelLinear::setStartDistance(qreal startDist) { - if (m_complete) { + if (m_engine) { qWarning() << "AttenuationModelLinear[" << m_name << "]: you can not change properties after initialization."; return; } @@ -192,7 +182,7 @@ qreal QDeclarativeAttenuationModelLinear::endDistance() const void QDeclarativeAttenuationModelLinear::setEndDistance(qreal endDist) { - if (m_complete) { + if (m_engine) { qWarning() << "AttenuationModelLinear[" << m_name << "]: you can not change properties after initialization."; return; } @@ -226,7 +216,9 @@ qreal QDeclarativeAttenuationModelLinear::calculateGain(const QVector3D &listene This type is part of the \b{QtAudioEngine 1.0} module. - AttenuationModelInverse must be defined inside AudioEngine. + AttenuationModelInverse must be defined inside \l AudioEngine or be added to it using + \l{QtAudioEngine::AudioEngine::addAttenuationModel()}{AudioEngine.addAttenuationModel()} + if AttenuationModelInverse is created dynamically. \qml import QtQuick 2.0 @@ -309,13 +301,13 @@ QDeclarativeAttenuationModelInverse::QDeclarativeAttenuationModelInverse(QObject { } -void QDeclarativeAttenuationModelInverse::componentComplete() +void QDeclarativeAttenuationModelInverse::setEngine(QDeclarativeAudioEngine *engine) { if (m_ref > m_max) { qSwap(m_ref, m_max); qWarning() << "AttenuationModelInverse[" << m_name << "]: referenceDistance must be less or equal than maxDistance."; } - QDeclarativeAttenuationModel::componentComplete(); + QDeclarativeAttenuationModel::setEngine(engine); } qreal QDeclarativeAttenuationModelInverse::referenceDistance() const @@ -325,7 +317,7 @@ qreal QDeclarativeAttenuationModelInverse::referenceDistance() const void QDeclarativeAttenuationModelInverse::setReferenceDistance(qreal referenceDistance) { - if (m_complete) { + if (m_engine) { qWarning() << "AttenuationModelInverse[" << m_name << "]: you can not change properties after initialization."; return; } @@ -343,7 +335,7 @@ qreal QDeclarativeAttenuationModelInverse::maxDistance() const void QDeclarativeAttenuationModelInverse::setMaxDistance(qreal maxDistance) { - if (m_complete) { + if (m_engine) { qWarning() << "AttenuationModelInverse[" << m_name << "]: you can not change properties after initialization."; return; } @@ -361,7 +353,7 @@ qreal QDeclarativeAttenuationModelInverse::rolloffFactor() const void QDeclarativeAttenuationModelInverse::setRolloffFactor(qreal rolloffFactor) { - if (m_complete) { + if (m_engine) { qWarning() << "AttenuationModelInverse[" << m_name << "]: you can not change properties after initialization."; return; } diff --git a/src/imports/audioengine/qdeclarative_attenuationmodel_p.h b/src/imports/audioengine/qdeclarative_attenuationmodel_p.h index dc8bff36f..f276757de 100644 --- a/src/imports/audioengine/qdeclarative_attenuationmodel_p.h +++ b/src/imports/audioengine/qdeclarative_attenuationmodel_p.h @@ -35,32 +35,31 @@ #define QDECLARATIVEATTENUATIONMODEL_P_H #include <QtQml/qqml.h> -#include <QtQml/qqmlcomponent.h> #include <QVector3D> QT_BEGIN_NAMESPACE -class QDeclarativeAttenuationModel : public QObject, public QQmlParserStatus +class QDeclarativeAudioEngine; + +class QDeclarativeAttenuationModel : public QObject { Q_OBJECT - Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QString name READ name WRITE setName) public: QDeclarativeAttenuationModel(QObject *parent = 0); ~QDeclarativeAttenuationModel(); - void classBegin(); - void componentComplete(); - QString name() const; void setName(const QString& name); virtual qreal calculateGain(const QVector3D &listenerPosition, const QVector3D &sourcePosition) const = 0; + virtual void setEngine(QDeclarativeAudioEngine *engine); + protected: - bool m_complete; QString m_name; + QDeclarativeAudioEngine *m_engine; private: Q_DISABLE_COPY(QDeclarativeAttenuationModel); @@ -75,8 +74,6 @@ class QDeclarativeAttenuationModelLinear : public QDeclarativeAttenuationModel public: QDeclarativeAttenuationModelLinear(QObject *parent = 0); - void componentComplete(); - qreal startDistance() const; void setStartDistance(qreal startDist); @@ -85,6 +82,8 @@ public: qreal calculateGain(const QVector3D &listenerPosition, const QVector3D &sourcePosition) const; + void setEngine(QDeclarativeAudioEngine *engine); + private: Q_DISABLE_COPY(QDeclarativeAttenuationModelLinear); qreal m_start; @@ -101,8 +100,6 @@ class QDeclarativeAttenuationModelInverse : public QDeclarativeAttenuationModel public: QDeclarativeAttenuationModelInverse(QObject *parent = 0); - void componentComplete(); - qreal referenceDistance() const; void setReferenceDistance(qreal referenceDistance); @@ -114,6 +111,8 @@ public: qreal calculateGain(const QVector3D &listenerPosition, const QVector3D &sourcePosition) const; + void setEngine(QDeclarativeAudioEngine *engine); + private: Q_DISABLE_COPY(QDeclarativeAttenuationModelInverse); qreal m_ref; diff --git a/src/imports/audioengine/qdeclarative_audiocategory_p.cpp b/src/imports/audioengine/qdeclarative_audiocategory_p.cpp index df1a3cec9..847941ca9 100644 --- a/src/imports/audioengine/qdeclarative_audiocategory_p.cpp +++ b/src/imports/audioengine/qdeclarative_audiocategory_p.cpp @@ -51,7 +51,9 @@ QT_USE_NAMESPACE This type is part of the \b{QtAudioEngine 1.0} module. An instance of AudioCategory can be accessed through \l {QtAudioEngine::AudioEngine::categories} - {AudioEngine.categories} with its unique name and must be defined inside AudioEngine. + {AudioEngine.categories} with its unique name and must be defined inside AudioEngine or be added + to it using \l{QtAudioEngine::AudioEngine::addAudioCategory()}{AudioEngine.addAudioCategory()} if + AudioCategory is created dynamically. \qml import QtQuick 2.0 @@ -103,8 +105,8 @@ QT_USE_NAMESPACE */ QDeclarativeAudioCategory::QDeclarativeAudioCategory(QObject *parent) : QObject(parent) - , m_complete(false) , m_volume(1) + , m_engine(0) { } @@ -112,21 +114,9 @@ QDeclarativeAudioCategory::~QDeclarativeAudioCategory() { } -void QDeclarativeAudioCategory::classBegin() +void QDeclarativeAudioCategory::setEngine(QDeclarativeAudioEngine *engine) { - if (!parent() || !parent()->inherits("QDeclarativeAudioEngine")) { - qWarning("AudioCategory must be defined inside AudioEngine!"); - return; - } -} - -void QDeclarativeAudioCategory::componentComplete() -{ - if (m_name.isEmpty()) { - qWarning("AudioCategory must have a name!"); - return; - } - m_complete = true; + m_engine = engine; } /*! @@ -159,7 +149,7 @@ void QDeclarativeAudioCategory::setVolume(qreal volume) */ void QDeclarativeAudioCategory::setName(const QString& name) { - if (m_complete) { + if (m_engine) { qWarning("AudioCategory: you can not change name after initialization."); return; } diff --git a/src/imports/audioengine/qdeclarative_audiocategory_p.h b/src/imports/audioengine/qdeclarative_audiocategory_p.h index a797b2698..0345edfdb 100644 --- a/src/imports/audioengine/qdeclarative_audiocategory_p.h +++ b/src/imports/audioengine/qdeclarative_audiocategory_p.h @@ -35,14 +35,14 @@ #define QDECLARATIVEAUDIOCATEGORY_P_H #include <QtQml/qqml.h> -#include <QtQml/qqmlcomponent.h> QT_BEGIN_NAMESPACE -class QDeclarativeAudioCategory : public QObject, public QQmlParserStatus +class QDeclarativeAudioEngine; + +class QDeclarativeAudioCategory : public QObject { Q_OBJECT - Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(qreal volume READ volume WRITE setVolume NOTIFY volumeChanged) Q_PROPERTY(QString name READ name WRITE setName) @@ -50,15 +50,14 @@ public: QDeclarativeAudioCategory(QObject *parent = 0); ~QDeclarativeAudioCategory(); - void classBegin(); - void componentComplete(); - qreal volume() const; void setVolume(qreal volume); QString name() const; void setName(const QString& name); + void setEngine(QDeclarativeAudioEngine *engine); + Q_SIGNALS: void volumeChanged(qreal newVolume); void stopped(); @@ -72,9 +71,9 @@ public Q_SLOTS: private: Q_DISABLE_COPY(QDeclarativeAudioCategory); - bool m_complete; QString m_name; qreal m_volume; + QDeclarativeAudioEngine *m_engine; }; QT_END_NAMESPACE diff --git a/src/imports/audioengine/qdeclarative_audioengine_p.cpp b/src/imports/audioengine/qdeclarative_audioengine_p.cpp index cf0a22644..dd80c698d 100644 --- a/src/imports/audioengine/qdeclarative_audioengine_p.cpp +++ b/src/imports/audioengine/qdeclarative_audioengine_p.cpp @@ -221,6 +221,222 @@ void QDeclarativeAudioEngine::releaseSoundInstance(QSoundInstance* instance) emit liveInstanceCountChanged(); } +void QDeclarativeAudioEngine::initAudioSample(QDeclarativeAudioSample *sample) +{ + sample->init(); +} + +void QDeclarativeAudioEngine::initSound(QDeclarativeSound *sound) +{ + QDeclarativeAudioCategory *category = m_defaultCategory; + if (m_categories.contains(sound->category())) { + category = qobject_cast<QDeclarativeAudioCategory*>( + qvariant_cast<QObject*>(m_categories[sound->category()])); + } + sound->setCategoryObject(category); + + QDeclarativeAttenuationModel *attenuationModel = 0; + if (sound->attenuationModel().isEmpty()) { + if (m_defaultAttenuationModel) + attenuationModel = m_defaultAttenuationModel; + } else if (m_attenuationModels.contains(sound->attenuationModel())){ + attenuationModel = m_attenuationModels[sound->attenuationModel()]; + } else { + qWarning() << "Sound[" << sound->name() << "] contains invalid attenuationModel[" + << sound->attenuationModel() << "]"; + } + sound->setAttenuationModelObject(attenuationModel); + + foreach (QDeclarativePlayVariation *playVariation, sound->playlist()) { + if (m_samples.contains(playVariation->sample())) { + playVariation->setSampleObject( + qobject_cast<QDeclarativeAudioSample*>( + qvariant_cast<QObject*>(m_samples[playVariation->sample()]))); + } else { + qWarning() << "Sound[" << sound->name() << "] contains invalid sample[" + << playVariation->sample() << "] for its playVarations"; + } + } +} + +/*! + \qmlmethod QtAudioEngine::AudioEngine::addAudioSample(AudioSample sample) + + Adds the given \a sample to the engine. + This can be used when the AudioSample is created dynamically: + + \qml + import QtAudioEngine 1.1 + + AudioEngine { + id: engine + + Component.onCompleted: { + var sample = Qt.createQmlObject('import QtAudioEngine 1.1; AudioSample {}', engine); + sample.name = "example"; + sample.source = "example.wav"; + engine.addAudioSample(sample); + } + } + \endqml +*/ +void QDeclarativeAudioEngine::addAudioSample(QDeclarativeAudioSample *sample) +{ +#ifdef DEBUG_AUDIOENGINE + qDebug() << "add QDeclarativeAudioSample[" << sample->name() << "]"; +#endif + if (sample->name().isEmpty()) { + qWarning("AudioSample must have a name!"); + return; + } + + if (m_samples.contains(sample->name())) { + qWarning() << "Failed to add AudioSample[" << sample->name() << "], already exists!"; + return; + } + m_samples.insert(sample->name(), QVariant::fromValue(sample)); + sample->setEngine(this); + + if (m_complete) { initAudioSample(sample); } +} + +/*! + \qmlmethod QtAudioEngine::AudioEngine::addSound(Sound sound) + + Adds the given \a sound to the engine. + This can be used when the Sound is created dynamically: + + \qml + import QtAudioEngine 1.1 + + AudioEngine { + id: engine + + Component.onCompleted: { + var sound = Qt.createQmlObject('import QtAudioEngine 1.1; Sound {}', engine); + sound.name = "example"; + engine.addSound(sound); + } + } + \endqml +*/ +void QDeclarativeAudioEngine::addSound(QDeclarativeSound *sound) +{ +#ifdef DEBUG_AUDIOENGINE + qDebug() << "add QDeclarativeSound[" << sound->name() << "]"; +#endif + if (sound->name().isEmpty()) { + qWarning("Sound must have a name!"); + return; + } + + if (m_sounds.contains(sound->name())) { + qWarning() << "Failed to add Sound[" << sound->name() << "], already exists!"; + return; + } + m_sounds.insert(sound->name(), QVariant::fromValue(sound)); + sound->setEngine(this); + + if (m_complete) { initSound(sound); } + +} + +/*! + \qmlmethod QtAudioEngine::AudioEngine::addAudioCategory(AudioCategory category) + + Adds the given \a category to the engine. + This can be used when the AudioCategory is created dynamically: + + \qml + import QtAudioEngine 1.1 + + AudioEngine { + id: engine + + Component.onCompleted: { + var category = Qt.createQmlObject('import QtAudioEngine 1.1; AudioCategory {}', engine); + category.name = "sample"; + category.volume = 0.9; + engine.addAudioCategory(category); + } + } + \endqml +*/ +void QDeclarativeAudioEngine::addAudioCategory(QDeclarativeAudioCategory *category) +{ +#ifdef DEBUG_AUDIOENGINE + qDebug() << "add QDeclarativeAudioCategory[" << category->name() << "]"; +#endif + if (category->name().isEmpty()) { + qWarning("AudioCategory must have a name!"); + return; + } + + if (m_categories.contains(category->name())) { + qWarning() << "Failed to add AudioCategory[" << category->name() << "], already exists!"; + return; + } + m_categories.insert(category->name(), QVariant::fromValue(category)); + if (category->name() == QLatin1String("default")) { + if (!m_complete) { + m_defaultCategory = category; + } else { + qWarning() << "Can not change default category after initializing engine"; + } + } + + category->setEngine(this); +} + +/*! + \qmlmethod QtAudioEngine::AudioEngine::addAttenuationModel(AttenuationModel attenuationModel) + + Adds the given \a attenuationModel to the engine. + This can be used when the AttenuationModelLinear / AttenuationModelInverse is created dynamically: + + \qml + import QtAudioEngine 1.1 + + AudioEngine { + id: engine + + Component.onCompleted: { + var attenuationModel = Qt.createQmlObject('import QtAudioEngine 1.1; AttenuationModelLinear {}', engine); + attenuationModel.name ="linear" + attenuationModel.start = 20 + attenuationModel.end = 180 + engine.addAttenuationModel(attenuationModel); + } + } + \endqml +*/ +void QDeclarativeAudioEngine::addAttenuationModel(QDeclarativeAttenuationModel *attenModel) +{ +#ifdef DEBUG_AUDIOENGINE + qDebug() << "add AttenuationModel[" << attenModel->name() << "]"; +#endif + if (attenModel->name().isEmpty()) { + qWarning("AttenuationModel must have a name!"); + return; + } + + if (m_attenuationModels.contains(attenModel->name())) { + qWarning() << "Failed to add AttenuationModel[" << attenModel->name() << "], already exists!"; + return; + } + m_attenuationModels.insert(attenModel->name(), attenModel); + + if (attenModel->name() == QLatin1String("default")) { + if (!m_complete) { + m_defaultAttenuationModel = attenModel; + } else { + qWarning() << "Can not change default attenuation model after initializing engine"; + } + } + + attenModel->setEngine(this); +} + void QDeclarativeAudioEngine::componentComplete() { #ifdef DEBUG_AUDIOENGINE @@ -231,10 +447,9 @@ void QDeclarativeAudioEngine::componentComplete() qDebug() << "creating default category"; #endif m_defaultCategory = new QDeclarativeAudioCategory(this); - m_defaultCategory->classBegin(); m_defaultCategory->setName(QString::fromLatin1("default")); m_defaultCategory->setVolume(1); - m_defaultCategory->componentComplete(); + m_defaultCategory->setEngine(this); } #ifdef DEBUG_AUDIOENGINE qDebug() << "init samples" << m_samples.keys().count(); @@ -246,7 +461,8 @@ void QDeclarativeAudioEngine::componentComplete() qWarning() << "accessing invalid sample[" << key << "]"; continue; } - sample->init(); + + initAudioSample(sample); } #ifdef DEBUG_AUDIOENGINE @@ -260,35 +476,8 @@ void QDeclarativeAudioEngine::componentComplete() qWarning() << "accessing invalid sound[" << key << "]"; continue; } - QDeclarativeAudioCategory *category = m_defaultCategory; - if (m_categories.contains(sound->category())) { - category = qobject_cast<QDeclarativeAudioCategory*>( - qvariant_cast<QObject*>(m_categories[sound->category()])); - } - sound->setCategoryObject(category); - - QDeclarativeAttenuationModel *attenuationModel = 0; - if (sound->attenuationModel().isEmpty()) { - if (m_defaultAttenuationModel) - attenuationModel = m_defaultAttenuationModel; - } else if (m_attenuationModels.contains(sound->attenuationModel())){ - attenuationModel = m_attenuationModels[sound->attenuationModel()]; - } else { - qWarning() << "Sound[" << sound->name() << "] contains invalid attenuationModel[" - << sound->attenuationModel() << "]"; - } - sound->setAttenuationModelObject(attenuationModel); - - foreach (QDeclarativePlayVariation* playVariation, sound->playlist()) { - if (m_samples.contains(playVariation->sample())) { - playVariation->setSampleObject( - qobject_cast<QDeclarativeAudioSample*>( - qvariant_cast<QObject*>(m_samples[playVariation->sample()]))); - } else { - qWarning() << "Sound[" << sound->name() << "] contains invalid sample[" - << playVariation->sample() << "] for its playVarations"; - } - } + + initSound(sound); } m_complete = true; #ifdef DEBUG_AUDIOENGINE @@ -330,65 +519,30 @@ void QDeclarativeAudioEngine::appendFunction(QQmlListProperty<QObject> *property { QDeclarativeAudioEngine* engine = static_cast<QDeclarativeAudioEngine*>(property->object); if (engine->m_complete) { - qWarning("AudioEngine: cannot add child after initialization!"); return; } QDeclarativeSound *sound = qobject_cast<QDeclarativeSound*>(value); if (sound) { -#ifdef DEBUG_AUDIOENGINE - qDebug() << "add QDeclarativeSound[" << sound->name() << "]"; -#endif - if (engine->m_sounds.contains(sound->name())) { - qWarning() << "Failed to add Sound[" << sound->name() << "], already exists!"; - return; - } - engine->m_sounds.insert(sound->name(), QVariant::fromValue(value)); + engine->addSound(sound); return; } QDeclarativeAudioSample *sample = qobject_cast<QDeclarativeAudioSample*>(value); if (sample) { -#ifdef DEBUG_AUDIOENGINE - qDebug() << "add QDeclarativeAudioSample[" << sample->name() << "]"; -#endif - if (engine->m_samples.contains(sample->name())) { - qWarning() << "Failed to add AudioSample[" << sample->name() << "], already exists!"; - return; - } - engine->m_samples.insert(sample->name(), QVariant::fromValue(value)); + engine->addAudioSample(sample); return; } QDeclarativeAudioCategory *category = qobject_cast<QDeclarativeAudioCategory*>(value); if (category) { -#ifdef DEBUG_AUDIOENGINE - qDebug() << "add QDeclarativeAudioCategory[" << category->name() << "]"; -#endif - if (engine->m_categories.contains(category->name())) { - qWarning() << "Failed to add AudioCategory[" << category->name() << "], already exists!"; - return; - } - engine->m_categories.insert(category->name(), QVariant::fromValue(value)); - if (category->name() == QLatin1String("default")) { - engine->m_defaultCategory = category; - } + engine->addAudioCategory(category); return; } QDeclarativeAttenuationModel *attenModel = qobject_cast<QDeclarativeAttenuationModel*>(value); if (attenModel) { -#ifdef DEBUG_AUDIOENGINE - qDebug() << "add AttenuationModel[" << attenModel->name() << "]"; -#endif - if (attenModel->name() == QLatin1String("default")) { - engine->m_defaultAttenuationModel = attenModel; - } - if (engine->m_attenuationModels.contains(attenModel->name())) { - qWarning() << "Failed to add AttenuationModel[" << attenModel->name() << "], already exists!"; - return; - } - engine->m_attenuationModels.insert(attenModel->name(), attenModel); + engine->addAttenuationModel(attenModel); return; } diff --git a/src/imports/audioengine/qdeclarative_audioengine_p.h b/src/imports/audioengine/qdeclarative_audioengine_p.h index 51090b5dc..7ae6049f0 100644 --- a/src/imports/audioengine/qdeclarative_audioengine_p.h +++ b/src/imports/audioengine/qdeclarative_audioengine_p.h @@ -111,6 +111,11 @@ public: QSoundInstance* newSoundInstance(const QString &name); void releaseSoundInstance(QSoundInstance* instance); + Q_REVISION(1) Q_INVOKABLE void addAudioSample(QDeclarativeAudioSample *); + Q_REVISION(1) Q_INVOKABLE void addSound(QDeclarativeSound *); + Q_REVISION(1) Q_INVOKABLE void addAudioCategory(QDeclarativeAudioCategory *); + Q_REVISION(1) Q_INVOKABLE void addAttenuationModel(QDeclarativeAttenuationModel *); + Q_SIGNALS: void ready(); void liveInstanceCountChanged(); @@ -149,6 +154,9 @@ private: QList<QDeclarativeSoundInstance*> m_managedDeclSoundInstances; QList<QDeclarativeSoundInstance*> m_managedDeclSndInstancePool; void releaseManagedDeclarativeSoundInstance(QDeclarativeSoundInstance* declSndInstance); + + void initAudioSample(QDeclarativeAudioSample *); + void initSound(QDeclarativeSound *); }; QT_END_NAMESPACE diff --git a/src/imports/audioengine/qdeclarative_audiosample_p.cpp b/src/imports/audioengine/qdeclarative_audiosample_p.cpp index 5a9a67b71..297af3b31 100644 --- a/src/imports/audioengine/qdeclarative_audiosample_p.cpp +++ b/src/imports/audioengine/qdeclarative_audiosample_p.cpp @@ -54,7 +54,9 @@ QT_USE_NAMESPACE \c AudioSample is part of the \b{QtAudioEngine 1.0} module. It can be accessed through QtAudioEngine::AudioEngine::samples with its unique - name and must be defined inside AudioEngine. + name and must be defined inside AudioEngine or be added to it using + \l{QtAudioEngine::AudioEngine::addAudioSample()}{AudioEngine.addAudioSample()} + if AudioSample is created dynamically. \qml import QtQuick 2.0 @@ -78,10 +80,10 @@ QT_USE_NAMESPACE */ QDeclarativeAudioSample::QDeclarativeAudioSample(QObject *parent) : QObject(parent) - , m_complete(false) , m_streaming(false) , m_preloaded(false) , m_soundBuffer(0) + , m_engine(0) { } @@ -89,23 +91,6 @@ QDeclarativeAudioSample::~QDeclarativeAudioSample() { } -void QDeclarativeAudioSample::classBegin() -{ - if (!parent() || !parent()->inherits("QDeclarativeAudioEngine")) { - qWarning("AudioSample must be defined inside AudioEngine!"); - return; - } -} - -void QDeclarativeAudioSample::componentComplete() -{ - if (m_name.isEmpty()) { - qWarning("AudioSample must have a name!"); - return; - } - m_complete = true; -} - /*! \qmlproperty url QtAudioEngine::AudioSample::source @@ -118,7 +103,7 @@ QUrl QDeclarativeAudioSample::source() const void QDeclarativeAudioSample::setSource(const QUrl& url) { - if (m_complete) { + if (m_engine) { qWarning("AudioSample: source not changeable after initialization."); return; } @@ -130,6 +115,11 @@ bool QDeclarativeAudioSample::isStreaming() const return m_streaming; } +QDeclarativeAudioEngine *QDeclarativeAudioSample::engine() const +{ + return m_engine; +} + /*! \qmlproperty bool QtAudioEngine::AudioSample::preloaded @@ -173,7 +163,7 @@ void QDeclarativeAudioSample::load() void QDeclarativeAudioSample::setPreloaded(bool preloaded) { - if (m_complete) { + if (m_engine) { qWarning("AudioSample: preloaded not changeable after initialization."); return; } @@ -182,13 +172,22 @@ void QDeclarativeAudioSample::setPreloaded(bool preloaded) void QDeclarativeAudioSample::setStreaming(bool streaming) { - if (m_complete) { + if (m_engine) { qWarning("AudioSample: streaming not changeable after initialization."); return; } m_streaming = streaming; } +void QDeclarativeAudioSample::setEngine(QDeclarativeAudioEngine *engine) +{ + if (m_engine) { + qWarning("AudioSample: engine not changeable after initialization."); + return; + } + m_engine = engine; +} + /*! \qmlproperty string QtAudioEngine::AudioSample::name @@ -202,7 +201,7 @@ QString QDeclarativeAudioSample::name() const void QDeclarativeAudioSample::setName(const QString& name) { - if (m_complete) { + if (m_engine) { qWarning("AudioSample: name not changeable after initialization."); return; } @@ -211,12 +210,13 @@ void QDeclarativeAudioSample::setName(const QString& name) void QDeclarativeAudioSample::init() { + Q_ASSERT(m_engine != 0); + if (m_streaming) { //TODO } else { - m_soundBuffer = - qobject_cast<QDeclarativeAudioEngine*>(parent())->engine()->getStaticSoundBuffer(m_url); + m_soundBuffer = m_engine->engine()->getStaticSoundBuffer(m_url); if (m_soundBuffer->state() == QSoundBuffer::Ready) { emit loadedChanged(); } else { diff --git a/src/imports/audioengine/qdeclarative_audiosample_p.h b/src/imports/audioengine/qdeclarative_audiosample_p.h index 94e1c7e27..5b549e785 100644 --- a/src/imports/audioengine/qdeclarative_audiosample_p.h +++ b/src/imports/audioengine/qdeclarative_audiosample_p.h @@ -35,16 +35,15 @@ #define QDECLARATIVEAUDIOSAMPLE_P_H #include <QtQml/qqml.h> -#include <QtQml/qqmlcomponent.h> QT_BEGIN_NAMESPACE class QSoundBuffer; +class QDeclarativeAudioEngine; -class QDeclarativeAudioSample : public QObject, public QQmlParserStatus +class QDeclarativeAudioSample : public QObject { Q_OBJECT - Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(QUrl source READ source WRITE setSource) Q_PROPERTY(bool preloaded READ isPreloaded WRITE setPreloaded) @@ -55,9 +54,6 @@ public: QDeclarativeAudioSample(QObject *parent = 0); ~QDeclarativeAudioSample(); - void classBegin(); - void componentComplete(); - QString name() const; void setName(const QString& name); @@ -70,6 +66,9 @@ public: bool isPreloaded() const; void setPreloaded(bool preloaded); + QDeclarativeAudioEngine *engine() const; + void setEngine(QDeclarativeAudioEngine *); + bool isLoaded() const; QSoundBuffer* soundBuffer() const; @@ -85,13 +84,12 @@ public Q_SLOTS: private: Q_DISABLE_COPY(QDeclarativeAudioSample); - bool m_complete; QString m_name; QUrl m_url; bool m_streaming; bool m_preloaded; - QSoundBuffer *m_soundBuffer; + QDeclarativeAudioEngine *m_engine; }; QT_END_NAMESPACE diff --git a/src/imports/audioengine/qdeclarative_playvariation_p.cpp b/src/imports/audioengine/qdeclarative_playvariation_p.cpp index 38876c227..156f83f68 100644 --- a/src/imports/audioengine/qdeclarative_playvariation_p.cpp +++ b/src/imports/audioengine/qdeclarative_playvariation_p.cpp @@ -55,7 +55,9 @@ QT_USE_NAMESPACE This type is part of the \b{QtAudioEngine 1.0} module. - PlayVariation must be defined inside a \l Sound. + PlayVariation must be defined inside a \l Sound or be added to it using + \l{QtAudioEngine::Sound::addPlayVariation()}{Sound.addPlayVariation()} + if PlayVariation is created dynamically. \qml import QtQuick 2.0 @@ -100,13 +102,13 @@ QT_USE_NAMESPACE */ QDeclarativePlayVariation::QDeclarativePlayVariation(QObject *parent) : QObject(parent) - , m_complete(false) , m_looping(false) , m_maxGain(1) , m_minGain(1) , m_maxPitch(1) , m_minPitch(1) , m_sampleObject(0) + , m_engine(0) { } @@ -114,15 +116,7 @@ QDeclarativePlayVariation::~QDeclarativePlayVariation() { } -void QDeclarativePlayVariation::classBegin() -{ - if (!parent() || !parent()->inherits("QDeclarativeSound")) { - qWarning("PlayVariation must be defined inside Sound!"); - return; - } -} - -void QDeclarativePlayVariation::componentComplete() +void QDeclarativePlayVariation::setEngine(QDeclarativeAudioEngine *engine) { if (m_maxGain < m_minGain) { qWarning("PlayVariation: maxGain must be no less than minGain"); @@ -132,7 +126,7 @@ void QDeclarativePlayVariation::componentComplete() qWarning("PlayVariation: maxPitch must be no less than minPitch"); qSwap(m_minPitch, m_maxPitch); } - m_complete = true; + m_engine = engine; } /*! @@ -147,7 +141,7 @@ QString QDeclarativePlayVariation::sample() const void QDeclarativePlayVariation::setSample(const QString& sample) { - if (m_complete) { + if (m_engine) { qWarning("PlayVariation: cannot change properties after initialization."); return; } @@ -166,7 +160,7 @@ bool QDeclarativePlayVariation::isLooping() const void QDeclarativePlayVariation::setLooping(bool looping) { - if (m_complete) { + if (m_engine) { qWarning("PlayVariation: cannot change properties after initialization."); return; } @@ -185,7 +179,7 @@ qreal QDeclarativePlayVariation::maxGain() const void QDeclarativePlayVariation::setMaxGain(qreal maxGain) { - if (m_complete) { + if (m_engine) { qWarning("PlayVariation: cannot change properties after initialization."); return; } @@ -208,7 +202,7 @@ qreal QDeclarativePlayVariation::minGain() const void QDeclarativePlayVariation::setMinGain(qreal minGain) { - if (m_complete) { + if (m_engine) { qWarning("PlayVariation: cannot change properties after initialization."); return; } @@ -231,7 +225,7 @@ qreal QDeclarativePlayVariation::maxPitch() const void QDeclarativePlayVariation::setMaxPitch(qreal maxPitch) { - if (m_complete) { + if (m_engine) { qWarning("PlayVariation: cannot change properties after initialization."); return; } @@ -254,7 +248,7 @@ qreal QDeclarativePlayVariation::minPitch() const void QDeclarativePlayVariation::setMinPitch(qreal minPitch) { - if (m_complete) { + if (m_engine) { qWarning("PlayVariation: cannot change properties after initialization."); return; } diff --git a/src/imports/audioengine/qdeclarative_playvariation_p.h b/src/imports/audioengine/qdeclarative_playvariation_p.h index dfe690cef..d0eed0d0a 100644 --- a/src/imports/audioengine/qdeclarative_playvariation_p.h +++ b/src/imports/audioengine/qdeclarative_playvariation_p.h @@ -35,17 +35,16 @@ #define QDECLARATIVEPLAYVARIATION_P_H #include <QtQml/qqml.h> -#include <QtQml/qqmlcomponent.h> QT_BEGIN_NAMESPACE class QDeclarativeAudioSample; class QSoundInstance; +class QDeclarativeAudioEngine; -class QDeclarativePlayVariation : public QObject, public QQmlParserStatus +class QDeclarativePlayVariation : public QObject { Q_OBJECT - Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QString sample READ sample WRITE setSample) Q_PROPERTY(bool looping READ isLooping WRITE setLooping) Q_PROPERTY(qreal maxGain READ maxGain WRITE setMaxGain) @@ -57,9 +56,6 @@ public: QDeclarativePlayVariation(QObject *parent = 0); ~QDeclarativePlayVariation(); - void classBegin(); - void componentComplete(); - QString sample() const; void setSample(const QString& sample); @@ -82,9 +78,10 @@ public: void applyParameters(QSoundInstance *soundInstance); + void setEngine(QDeclarativeAudioEngine *engine); + private: Q_DISABLE_COPY(QDeclarativePlayVariation); - bool m_complete; QString m_sample; bool m_looping; qreal m_maxGain; @@ -92,6 +89,7 @@ private: qreal m_maxPitch; qreal m_minPitch; QDeclarativeAudioSample *m_sampleObject; + QDeclarativeAudioEngine *m_engine; }; QT_END_NAMESPACE diff --git a/src/imports/audioengine/qdeclarative_sound_p.cpp b/src/imports/audioengine/qdeclarative_sound_p.cpp index fcbd76f71..f19b8dbb3 100644 --- a/src/imports/audioengine/qdeclarative_sound_p.cpp +++ b/src/imports/audioengine/qdeclarative_sound_p.cpp @@ -64,8 +64,12 @@ qreal QDeclarativeSoundCone::innerAngle() const void QDeclarativeSoundCone::setInnerAngle(qreal innerAngle) { QDeclarativeSound *s = qobject_cast<QDeclarativeSound*>(parent()); - if (s && s->m_complete) + + if (s && s->m_engine) { + qWarning("SoundCone: innerAngle not changeable after initialization."); return; + } + if (innerAngle < 0 || innerAngle > 360) { qWarning() << "innerAngle should be within[0, 360] degrees"; return; @@ -88,8 +92,12 @@ qreal QDeclarativeSoundCone::outerAngle() const void QDeclarativeSoundCone::setOuterAngle(qreal outerAngle) { QDeclarativeSound *s = qobject_cast<QDeclarativeSound*>(parent()); - if (s && s->m_complete) + + if (s && s->m_engine) { + qWarning("SoundCone: outerAngle not changeable after initialization."); return; + } + if (outerAngle < 0 || outerAngle > 360) { qWarning() << "outerAngle should be within[0, 360] degrees"; return; @@ -112,8 +120,12 @@ qreal QDeclarativeSoundCone::outerGain() const void QDeclarativeSoundCone::setOuterGain(qreal outerGain) { QDeclarativeSound *s = qobject_cast<QDeclarativeSound*>(parent()); - if (s && s->m_complete) + + if (s && s->m_engine) { + qWarning("SoundCone: outerGain not changeable after initialization."); return; + } + if (outerGain < 0 || outerGain > 1) { qWarning() << "outerGain should no less than 0 and no more than 1"; return; @@ -121,11 +133,18 @@ void QDeclarativeSoundCone::setOuterGain(qreal outerGain) m_outerGain = outerGain; } -void QDeclarativeSoundCone::componentComplete() +void QDeclarativeSoundCone::setEngine(QDeclarativeAudioEngine *engine) { + if (m_engine) { + qWarning("SoundCone: engine not changeable after initialization."); + return; + } + if (m_outerAngle < m_innerAngle) { m_outerAngle = m_innerAngle; } + + m_engine = engine; } //////////////////////////////////////////////////////////// @@ -143,7 +162,9 @@ void QDeclarativeSoundCone::componentComplete() This type is part of the \b{QtAudioEngine 1.0} module. Sound can be accessed through QtAudioEngine::AudioEngine::sounds with its unique name - and must be defined inside AudioEngine. + and must be defined inside AudioEngine or be added to it using + \l{QtAudioEngine::AudioEngine::addSound()}{AudioEngine.addSound()} + if \l Sound is created dynamically. \qml import QtQuick 2.0 @@ -194,10 +215,10 @@ void QDeclarativeSoundCone::componentComplete() QDeclarativeSound::QDeclarativeSound(QObject *parent) : QObject(parent) - , m_complete(false) , m_playType(Random) , m_attenuationModelObject(0) , m_categoryObject(0) + , m_engine(0) { m_cone = new QDeclarativeSoundCone(this); } @@ -206,20 +227,6 @@ QDeclarativeSound::~QDeclarativeSound() { } -void QDeclarativeSound::classBegin() -{ - if (!parent() || !parent()->inherits("QDeclarativeAudioEngine")) { - qWarning("Sound must be defined inside AudioEngine!"); - return; - } -} - -void QDeclarativeSound::componentComplete() -{ - m_complete = true; - m_cone->componentComplete(); -} - /*! \qmlproperty enumeration QtAudioEngine::Sound::playType @@ -239,7 +246,7 @@ QDeclarativeSound::PlayType QDeclarativeSound::playType() const void QDeclarativeSound::setPlayType(PlayType playType) { - if (m_complete) { + if (m_engine) { qWarning("Sound: playType not changeable after initialization."); return; } @@ -258,7 +265,7 @@ QString QDeclarativeSound::category() const void QDeclarativeSound::setCategory(const QString& category) { - if (m_complete) { + if (m_engine) { qWarning("Sound: category not changeable after initialization."); return; } @@ -278,7 +285,7 @@ QString QDeclarativeSound::name() const void QDeclarativeSound::setName(const QString& name) { - if (m_complete) { + if (m_engine) { qWarning("Sound: category not changeable after initialization."); return; } @@ -322,13 +329,28 @@ QDeclarativePlayVariation* QDeclarativeSound::getVariation(int index) void QDeclarativeSound::setAttenuationModel(const QString &attenuationModel) { - if (m_complete) { + if (m_engine) { qWarning("Sound: attenuationModel not changeable after initialization."); return; } m_attenuationModel = attenuationModel; } +void QDeclarativeSound::setEngine(QDeclarativeAudioEngine *engine) +{ + if (m_engine) { + qWarning("Sound: engine not changeable after initialization."); + return; + } + m_cone->setEngine(engine); + m_engine = engine; +} + +QDeclarativeAudioEngine *QDeclarativeSound::engine() const +{ + return m_engine; +} + QDeclarativeSoundCone* QDeclarativeSound::cone() const { return m_cone; @@ -367,11 +389,42 @@ QList<QDeclarativePlayVariation*>& QDeclarativeSound::playlist() void QDeclarativeSound::appendFunction(QQmlListProperty<QDeclarativePlayVariation> *property, QDeclarativePlayVariation *value) { QDeclarativeSound *sound = static_cast<QDeclarativeSound*>(property->object); - if (sound->m_complete) { - qWarning("Sound: PlayVariation not addable after initialization."); + if (sound->m_engine) { return; } - sound->m_playlist.append(value); + sound->addPlayVariation(value); +} + +/*! + \qmlmethod QtAudioEngine::Sound::addPlayVariation(PlayVariation playVariation) + + Adds the given \a playVariation to sound. + This can be used when the PlayVariation is created dynamically: + + \qml + import QtAudioEngine 1.1 + + AudioEngine { + id: engine + + Component.onCompleted: { + var playVariation = Qt.createQmlObject('import QtAudioEngine 1.1; PlayVariation {}', engine); + playVariation.sample = "sample"; + playVariation.minPitch = 0.8 + playVariation.maxPitch = 1.1 + + var sound = Qt.createQmlObject('import QtAudioEngine 1.1; Sound {}', engine); + sound.name = "example"; + sound.addPlayVariation(playVariation); + engine.addSound(sound); + } + } + \endqml +*/ +void QDeclarativeSound::addPlayVariation(QDeclarativePlayVariation *value) +{ + m_playlist.append(value); + value->setEngine(m_engine); } /*! @@ -507,7 +560,7 @@ void QDeclarativeSound::play(const QVector3D& position, const QVector3D& velocit */ void QDeclarativeSound::play(const QVector3D& position, const QVector3D& velocity, const QVector3D& direction, qreal gain, qreal pitch) { - if (!m_complete) { + if (!m_engine) { qWarning() << "AudioEngine::play not ready!"; return; } @@ -546,8 +599,13 @@ QDeclarativeSoundInstance* QDeclarativeSound::newInstance() QDeclarativeSoundInstance* QDeclarativeSound::newInstance(bool managed) { + if (!m_engine) { + qWarning("engine attrbiute must be set for Sound object!"); + return NULL; + } + QDeclarativeSoundInstance *instance = - qobject_cast<QDeclarativeAudioEngine*>(this->parent())->newDeclarativeSoundInstance(managed); + m_engine->newDeclarativeSoundInstance(managed); instance->setSound(m_name); return instance; } diff --git a/src/imports/audioengine/qdeclarative_sound_p.h b/src/imports/audioengine/qdeclarative_sound_p.h index 14ebd1039..83b1eb2af 100644 --- a/src/imports/audioengine/qdeclarative_sound_p.h +++ b/src/imports/audioengine/qdeclarative_sound_p.h @@ -35,7 +35,6 @@ #define QDECLARATIVESOUND_P_H #include <QtQml/qqml.h> -#include <QtQml/qqmlcomponent.h> #include <QtCore/qlist.h> #include "qdeclarative_playvariation_p.h" @@ -44,6 +43,7 @@ QT_BEGIN_NAMESPACE class QDeclarativeAudioCategory; class QDeclarativeAttenuationModel; class QDeclarativeSoundInstance; +class QDeclarativeAudioEngine; class QDeclarativeSoundCone : public QObject { @@ -65,21 +65,21 @@ public: qreal outerGain() const; void setOuterGain(qreal outerGain); - void componentComplete(); + void setEngine(QDeclarativeAudioEngine *engine); private: Q_DISABLE_COPY(QDeclarativeSoundCone) qreal m_innerAngle; qreal m_outerAngle; qreal m_outerGain; + QDeclarativeAudioEngine *m_engine; }; -class QDeclarativeSound : public QObject, public QQmlParserStatus +class QDeclarativeSound : public QObject { friend class QDeclarativeSoundCone; Q_OBJECT - Q_INTERFACES(QQmlParserStatus) Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(PlayType playType READ playType WRITE setPlayType) Q_PROPERTY(QString category READ category WRITE setCategory) @@ -99,9 +99,6 @@ public: QDeclarativeSound(QObject *parent = 0); ~QDeclarativeSound(); - void classBegin(); - void componentComplete(); - PlayType playType() const; void setPlayType(PlayType playType); @@ -114,6 +111,9 @@ public: QString attenuationModel() const; void setAttenuationModel(const QString &attenuationModel); + QDeclarativeAudioEngine *engine() const; + void setEngine(QDeclarativeAudioEngine *); + QDeclarativeSoundCone* cone() const; QDeclarativeAttenuationModel* attenuationModelObject() const; @@ -128,6 +128,8 @@ public: QQmlListProperty<QDeclarativePlayVariation> playVariationlist(); QList<QDeclarativePlayVariation*>& playlist(); + Q_INVOKABLE Q_REVISION(1) void addPlayVariation(QDeclarativePlayVariation*); + public Q_SLOTS: void play(); void play(qreal gain); @@ -147,7 +149,6 @@ private: Q_DISABLE_COPY(QDeclarativeSound) QDeclarativeSoundInstance* newInstance(bool managed); static void appendFunction(QQmlListProperty<QDeclarativePlayVariation> *property, QDeclarativePlayVariation *value); - bool m_complete; PlayType m_playType; QString m_name; QString m_category; @@ -157,6 +158,7 @@ private: QDeclarativeAttenuationModel *m_attenuationModelObject; QDeclarativeAudioCategory *m_categoryObject; + QDeclarativeAudioEngine *m_engine; }; QT_END_NAMESPACE |