diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-09 14:05:20 (GMT) |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-09 14:05:20 (GMT) |
commit | f5c9262ab59bdb4e35e7d26ea52b72d65b178cf2 (patch) | |
tree | 56b9e94aea9571cda947dca8ca5bfc000c6effed /src/multimedia/effects | |
parent | d85b149a5c7f3532f8e1a593a79298c9ae38a95f (diff) | |
parent | bb966fe9dd8be25530da5a66727c7fe2123fafbb (diff) | |
download | Qt-f5c9262ab59bdb4e35e7d26ea52b72d65b178cf2.zip Qt-f5c9262ab59bdb4e35e7d26ea52b72d65b178cf2.tar.gz Qt-f5c9262ab59bdb4e35e7d26ea52b72d65b178cf2.tar.bz2 |
Merge branch '4.7' of git@scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7
Diffstat (limited to 'src/multimedia/effects')
-rw-r--r-- | src/multimedia/effects/effects.pri | 25 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect.cpp | 202 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect_p.h | 109 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect_pulse_p.cpp | 474 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect_pulse_p.h | 133 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect_qmedia_p.cpp | 134 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect_qmedia_p.h | 103 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect_qsound_p.cpp | 131 | ||||
-rw-r--r-- | src/multimedia/effects/qsoundeffect_qsound_p.h | 102 | ||||
-rw-r--r-- | src/multimedia/effects/wavedecoder_p.cpp | 151 | ||||
-rw-r--r-- | src/multimedia/effects/wavedecoder_p.h | 133 |
11 files changed, 1697 insertions, 0 deletions
diff --git a/src/multimedia/effects/effects.pri b/src/multimedia/effects/effects.pri new file mode 100644 index 0000000..be2b696 --- /dev/null +++ b/src/multimedia/effects/effects.pri @@ -0,0 +1,25 @@ + + +unix:!mac { + contains(QT_CONFIG, pulseaudio) { + DEFINES += QT_MULTIMEDIA_PULSEAUDIO + HEADERS += $$PWD/qsoundeffect_pulse_p.h + SOURCES += $$PWD/qsoundeffect_pulse_p.cpp + LIBS += -lpulse + } else { + DEFINES += QT_MULTIMEDIA_QMEDIAPLAYER + HEADERS += $$PWD/qsoundeffect_qmedia_p.h + SOURCES += $$PWD/qsoundeffect_qmedia_p.cpp + } +} else { + HEADERS += $$PWD/qsoundeffect_qsound_p.h + SOURCES += $$PWD/qsoundeffect_qsound_p.cpp +} + +HEADERS += \ + $$PWD/qsoundeffect_p.h \ + $$PWD/wavedecoder_p.h + +SOURCES += \ + $$PWD/qsoundeffect.cpp \ + $$PWD/wavedecoder_p.cpp diff --git a/src/multimedia/effects/qsoundeffect.cpp b/src/multimedia/effects/qsoundeffect.cpp new file mode 100644 index 0000000..f64d9ee --- /dev/null +++ b/src/multimedia/effects/qsoundeffect.cpp @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsoundeffect_p.h" + +#if defined(QT_MULTIMEDIA_PULSEAUDIO) +#include "qsoundeffect_pulse_p.h" +#elif(QT_MULTIMEDIA_QMEDIAPLAYER) +#include "qsoundeffect_qmedia_p.h" +#else +#include "qsoundeffect_qsound_p.h" +#endif + +QT_BEGIN_NAMESPACE + +/*! + \qmlclass SoundEffect QSoundEffect + \since 4.7 + \brief The SoundEffect element provides a way to play sound effects in qml. + + The following example plays a wav file on mouse click. + + \qml + SoundEffect { + id: playSound + source: "test.wav" + } + MouseArea { + id: playArea + anchors.fill: parent + onPressed: { + playSound.play() + } + } + \endqml + + \sa SoundEffect +*/ + +/*! + \qmlproperty QUrl SoundEffect::source + + This property provides a way to control the sound to play. +*/ + +/*! + \qmlproperty int SoundEffect::loopCount + + This property provides a way to control the number of times to repeat the sound on each play(). +*/ + +/*! + \qmlproperty int SoundEffect::volume + + This property provides a way to control the volume for playback. +*/ + +/*! + \qmlproperty bool SoundEffect::muted + + This property provides a way to control muting. +*/ + +/*! + \qmlsignal SoundEffect::sourceChanged() + + This handler is called when the source has changed. +*/ + +/*! + \qmlsignal SoundEffect::loopCountChanged() + + This handler is called when the number of loops has changes. +*/ + +/*! + \qmlsignal SoundEffect::volumeChanged() + + This handler is called when the volume has changed. +*/ + +/*! + \qmlsignal SoundEffect::mutedChanged() + + This handler is called when the mute state has changed. +*/ + + +QSoundEffect::QSoundEffect(QObject *parent) : + QObject(parent) +{ + d = new QSoundEffectPrivate(this); + connect(d, SIGNAL(volumeChanged()), SIGNAL(volumeChanged())); + connect(d, SIGNAL(mutedChanged()), SIGNAL(mutedChanged())); +} + +QSoundEffect::~QSoundEffect() +{ + delete d; +} + +QUrl QSoundEffect::source() const +{ + return d->source(); +} + +void QSoundEffect::setSource(const QUrl &url) +{ + if (d->source() == url) + return; + + d->setSource(url); + + emit sourceChanged(); +} + +int QSoundEffect::loopCount() const +{ + return d->loopCount(); +} + +void QSoundEffect::setLoopCount(int loopCount) +{ + if (d->loopCount() == loopCount) + return; + + d->setLoopCount(loopCount); + emit loopCountChanged(); +} + +int QSoundEffect::volume() const +{ + return d->volume(); +} + +void QSoundEffect::setVolume(int volume) +{ + if (d->volume() == volume) + return; + + d->setVolume(volume); + emit volumeChanged(); +} + +bool QSoundEffect::isMuted() const +{ + return d->isMuted(); +} + +void QSoundEffect::setMuted(bool muted) +{ + if (d->isMuted() == muted) + return; + + d->setMuted(muted); + emit mutedChanged(); +} + +void QSoundEffect::play() +{ + d->play(); +} + +QT_END_NAMESPACE diff --git a/src/multimedia/effects/qsoundeffect_p.h b/src/multimedia/effects/qsoundeffect_p.h new file mode 100644 index 0000000..ec6a2f7 --- /dev/null +++ b/src/multimedia/effects/qsoundeffect_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSOUNDEFFECT_H +#define QSOUNDEFFECT_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include <QtCore/qobject.h> +#include <QtCore/qurl.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QSoundEffectPrivate; +class Q_MULTIMEDIA_EXPORT QSoundEffect : public QObject +{ + Q_OBJECT + Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount NOTIFY loopCountChanged) + Q_PROPERTY(int volume READ volume WRITE setVolume NOTIFY volumeChanged) + Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) + +public: + explicit QSoundEffect(QObject *parent = 0); + ~QSoundEffect(); + + QUrl source() const; + void setSource(const QUrl &url); + + int loopCount() const; + void setLoopCount(int loopCount); + + int volume() const; + void setVolume(int volume); + + bool isMuted() const; + void setMuted(bool muted); + +Q_SIGNALS: + void sourceChanged(); + void loopCountChanged(); + void volumeChanged(); + void mutedChanged(); + +public Q_SLOTS: + void play(); + +private: + Q_DISABLE_COPY(QSoundEffect) + QSoundEffectPrivate* d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + + +#endif // QSOUNDEFFECT_H diff --git a/src/multimedia/effects/qsoundeffect_pulse_p.cpp b/src/multimedia/effects/qsoundeffect_pulse_p.cpp new file mode 100644 index 0000000..c322722 --- /dev/null +++ b/src/multimedia/effects/qsoundeffect_pulse_p.cpp @@ -0,0 +1,474 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qcoreapplication.h> +#include <QtMultimedia/qaudioformat.h> +#include <QtNetwork> +#include <QTime> + +#include "wavedecoder_p.h" + +#include "qsoundeffect_pulse_p.h" + +#if defined(Q_WS_MAEMO_5) +#include <pulse/ext-stream-restore.h> +#endif + +#include <unistd.h> + +// Less than ideal +#define PA_SCACHE_ENTRY_SIZE_MAX (1024*1024*16) + +QT_BEGIN_NAMESPACE + +namespace +{ +inline pa_sample_spec audioFormatToSampleSpec(const QAudioFormat &format) +{ + pa_sample_spec spec; + + spec.rate = format.frequency(); + spec.channels = format.channels(); + + if (format.sampleSize() == 8) + spec.format = PA_SAMPLE_U8; + else if (format.sampleSize() == 16) { + switch (format.byteOrder()) { + case QAudioFormat::BigEndian: spec.format = PA_SAMPLE_S16BE; break; + case QAudioFormat::LittleEndian: spec.format = PA_SAMPLE_S16LE; break; + } + } + else if (format.sampleSize() == 32) { + switch (format.byteOrder()) { + case QAudioFormat::BigEndian: spec.format = PA_SAMPLE_S32BE; break; + case QAudioFormat::LittleEndian: spec.format = PA_SAMPLE_S32LE; break; + } + } + + return spec; +} + +class PulseDaemon +{ +public: + PulseDaemon():m_prepared(false) + { + prepare(); + } + + ~PulseDaemon() + { + if (m_prepared) + release(); + } + + inline void lock() + { + pa_threaded_mainloop_lock(m_mainLoop); + } + + inline void unlock() + { + pa_threaded_mainloop_unlock(m_mainLoop); + } + + inline pa_context *context() const + { + return m_context; + } + + int volume() + { + return m_vol; + } + +private: + void prepare() + { + m_vol = 100; + + m_mainLoop = pa_threaded_mainloop_new(); + if (m_mainLoop == 0) { + qWarning("PulseAudioService: unable to create pulseaudio mainloop"); + return; + } + + if (pa_threaded_mainloop_start(m_mainLoop) != 0) { + qWarning("PulseAudioService: unable to start pulseaudio mainloop"); + pa_threaded_mainloop_free(m_mainLoop); + return; + } + + m_mainLoopApi = pa_threaded_mainloop_get_api(m_mainLoop); + + lock(); + m_context = pa_context_new(m_mainLoopApi, QString(QLatin1String("QtPulseAudio:%1")).arg(::getpid()).toAscii().constData()); + +#if defined(Q_WS_MAEMO_5) + pa_context_set_state_callback(m_context, context_state_callback, this); +#endif + if (m_context == 0) { + qWarning("PulseAudioService: Unable to create new pulseaudio context"); + pa_threaded_mainloop_free(m_mainLoop); + return; + } + + if (pa_context_connect(m_context, NULL, (pa_context_flags_t)0, NULL) < 0) { + qWarning("PulseAudioService: pa_context_connect() failed"); + pa_context_unref(m_context); + pa_threaded_mainloop_free(m_mainLoop); + return; + } + unlock(); + + m_prepared = true; + } + + void release() + { + if (!m_prepared) return; + pa_threaded_mainloop_stop(m_mainLoop); + pa_threaded_mainloop_free(m_mainLoop); + m_prepared = false; + } + +#if defined(Q_WS_MAEMO_5) + static void context_state_callback(pa_context *c, void *userdata) + { + PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata); + switch (pa_context_get_state(c)) { + case PA_CONTEXT_CONNECTING: + case PA_CONTEXT_AUTHORIZING: + case PA_CONTEXT_SETTING_NAME: + break; + case PA_CONTEXT_READY: + pa_ext_stream_restore_set_subscribe_cb(c, &stream_restore_monitor_callback, self); + pa_ext_stream_restore_subscribe(c, 1, NULL, self); + break; + default: + break; + } + } + static void stream_restore_monitor_callback(pa_context *c, void *userdata) + { + PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata); + pa_ext_stream_restore2_read(c, &stream_restore_info_callback, self); + } + static void stream_restore_info_callback(pa_context *c, const pa_ext_stream_restore2_info *info, + int eol, void *userdata) + { + Q_UNUSED(c) + + PulseDaemon *self = reinterpret_cast<PulseDaemon*>(userdata); + + if (!eol) { + if (QString(info->name).startsWith(QLatin1String("sink-input-by-media-role:x-maemo"))) { + const unsigned str_length = 256; + char str[str_length]; + pa_cvolume_snprint(str, str_length, &info->volume); + self->m_vol = QString(str).replace(" ","").replace("%","").mid(2).toInt(); + } + } + } +#endif + + int m_vol; + bool m_prepared; + pa_context *m_context; + pa_threaded_mainloop *m_mainLoop; + pa_mainloop_api *m_mainLoopApi; +}; +} + +Q_GLOBAL_STATIC(PulseDaemon, daemon) + + +QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): + QObject(parent), + m_muted(false), + m_playQueued(false), + m_sampleLoaded(false), + m_volume(100), + m_duration(0), + m_dataUploaded(0), + m_loopCount(1), + m_runningCount(0), + m_reply(0), + m_stream(0), + m_networkAccessManager(0) +{ +} + +QSoundEffectPrivate::~QSoundEffectPrivate() +{ + delete m_reply; + unloadSample(); +} + +QUrl QSoundEffectPrivate::source() const +{ + return m_source; +} + +void QSoundEffectPrivate::setSource(const QUrl &url) +{ + if (url.isEmpty()) { + m_source = QUrl(); + unloadSample(); + return; + } + + m_source = url; + + if (m_networkAccessManager == 0) + m_networkAccessManager = new QNetworkAccessManager(this); + + m_stream = m_networkAccessManager->get(QNetworkRequest(m_source)); + + unloadSample(); + loadSample(); +} + +int QSoundEffectPrivate::loopCount() const +{ + return m_loopCount; +} + +void QSoundEffectPrivate::setLoopCount(int loopCount) +{ + m_loopCount = loopCount; +} + +int QSoundEffectPrivate::volume() const +{ + return m_volume; +} + +void QSoundEffectPrivate::setVolume(int volume) +{ + m_volume = volume; +} + +bool QSoundEffectPrivate::isMuted() const +{ + return m_muted; +} + +void QSoundEffectPrivate::setMuted(bool muted) +{ + m_muted = muted; +} + +void QSoundEffectPrivate::play() +{ + if (!m_sampleLoaded) { + m_playQueued = true; + return; + } + + m_runningCount += m_loopCount; + + playSample(); +} + +void QSoundEffectPrivate::decoderReady() +{ + if (m_waveDecoder->size() >= PA_SCACHE_ENTRY_SIZE_MAX) { + m_waveDecoder->deleteLater(); + qWarning("QSoundEffect(pulseaudio): Attempting to load to large a sample"); + return; + } + + if (m_name.isNull()) + m_name = QString(QLatin1String("QtPulseSample-%1-%2")).arg(::getpid()).arg(quintptr(this)).toUtf8(); + + pa_sample_spec spec = audioFormatToSampleSpec(m_waveDecoder->audioFormat()); + + daemon()->lock(); + pa_stream *stream = pa_stream_new(daemon()->context(), m_name.constData(), &spec, 0); + pa_stream_set_state_callback(stream, stream_state_callback, this); + pa_stream_set_write_callback(stream, stream_write_callback, this); + pa_stream_connect_upload(stream, (size_t)m_waveDecoder->size()); + daemon()->unlock(); +} + +void QSoundEffectPrivate::decoderError() +{ + qWarning("QSoundEffect(pulseaudio): Error decoding source"); +} + +void QSoundEffectPrivate::checkPlayTime() +{ + int elapsed = m_playbackTime.elapsed(); + + if (elapsed < m_duration) + startTimer(m_duration - elapsed); +} + +void QSoundEffectPrivate::loadSample() +{ + m_sampleLoaded = false; + m_dataUploaded = 0; + m_waveDecoder = new WaveDecoder(m_stream); + connect(m_waveDecoder, SIGNAL(formatKnown()), SLOT(decoderReady())); + connect(m_waveDecoder, SIGNAL(invalidFormat()), SLOT(decoderError())); +} + +void QSoundEffectPrivate::unloadSample() +{ + if (!m_sampleLoaded) + return; + + daemon()->lock(); + pa_context_remove_sample(daemon()->context(), m_name.constData(), NULL, NULL); + daemon()->unlock(); + + m_duration = 0; + m_dataUploaded = 0; + m_sampleLoaded = false; +} + +void QSoundEffectPrivate::playSample() +{ + pa_volume_t volume = PA_VOLUME_NORM; + + daemon()->lock(); +#ifdef Q_WS_MAEMO_5 + volume = PA_VOLUME_NORM / 100 * ((daemon()->volume() + m_volume) / 2); +#endif + pa_operation_unref( + pa_context_play_sample(daemon()->context(), + m_name.constData(), + 0, + volume, + play_callback, + this) + ); + daemon()->unlock(); + + m_playbackTime.start(); +} + +void QSoundEffectPrivate::timerEvent(QTimerEvent *event) +{ + if (m_runningCount > 0) + playSample(); + + killTimer(event->timerId()); +} + +void QSoundEffectPrivate::stream_write_callback(pa_stream *s, size_t length, void *userdata) +{ + Q_UNUSED(length); + + QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata); + + size_t bufferSize = qMin(pa_stream_writable_size(s), + size_t(self->m_waveDecoder->bytesAvailable())); + char buffer[bufferSize]; + + size_t len = 0; + while (len < length) { + qint64 read = self->m_waveDecoder->read(buffer, qMin(bufferSize, length -len)); + if (read > 0) { + if (pa_stream_write(s, buffer, size_t(read), 0, 0, PA_SEEK_RELATIVE) == 0) + len += size_t(read); + else + break; + } + } + self->m_dataUploaded += len; + + if (self->m_waveDecoder->size() == self->m_dataUploaded) { + pa_stream_finish_upload(s); + + self->m_duration = self->m_waveDecoder->duration(); + + self->m_waveDecoder->deleteLater(); + self->m_stream->deleteLater(); + + self->m_sampleLoaded = true; + if (self->m_playQueued) { + self->m_playQueued = false; + QMetaObject::invokeMethod(self, "play"); + } + } +} + +void QSoundEffectPrivate::stream_state_callback(pa_stream *s, void *userdata) +{ + switch (pa_stream_get_state(s)) { + case PA_STREAM_CREATING: + case PA_STREAM_READY: + case PA_STREAM_TERMINATED: + break; + + case PA_STREAM_FAILED: + default: + qWarning("QSoundEffect(pulseaudio): Error in pulse audio stream"); + break; + } +} + +void QSoundEffectPrivate::play_callback(pa_context *c, int success, void *userdata) +{ + Q_UNUSED(c); + + QSoundEffectPrivate *self = reinterpret_cast<QSoundEffectPrivate*>(userdata); + + if (success == 1) { + self->m_runningCount--; + QMetaObject::invokeMethod(self, "checkPlayTime", Qt::QueuedConnection); + } +} + +QT_END_NAMESPACE diff --git a/src/multimedia/effects/qsoundeffect_pulse_p.h b/src/multimedia/effects/qsoundeffect_pulse_p.h new file mode 100644 index 0000000..3aed018 --- /dev/null +++ b/src/multimedia/effects/qsoundeffect_pulse_p.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSOUNDEFFECT_PULSE_H +#define QSOUNDEFFECT_PULSE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include "qsoundeffect_p.h" + +#include <QtCore/qobject.h> +#include <QtCore/qdatetime.h> +#include <QtMultimedia/qmediaplayer.h> +#include <pulse/pulseaudio.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QNetworkReply; +class QNetworkAccessManager; +class WaveDecoder; + +class QSoundEffectPrivate : public QObject +{ + Q_OBJECT +public: + explicit QSoundEffectPrivate(QObject* parent); + ~QSoundEffectPrivate(); + + QUrl source() const; + void setSource(const QUrl &url); + int loopCount() const; + void setLoopCount(int loopCount); + int volume() const; + void setVolume(int volume); + bool isMuted() const; + void setMuted(bool muted); + +public Q_SLOTS: + void play(); + +Q_SIGNALS: + void volumeChanged(); + void mutedChanged(); + +private Q_SLOTS: + void decoderReady(); + void decoderError(); + void checkPlayTime(); + +private: + void loadSample(); + void unloadSample(); + void playSample(); + + void timerEvent(QTimerEvent *event); + + static void stream_write_callback(pa_stream *s, size_t length, void *userdata); + static void stream_state_callback(pa_stream *s, void *userdata); + static void play_callback(pa_context *c, int success, void *userdata); + + bool m_muted; + bool m_playQueued; + bool m_sampleLoaded; + int m_volume; + int m_duration; + int m_dataUploaded; + int m_loopCount; + int m_runningCount; + QUrl m_source; + QTime m_playbackTime; + QByteArray m_name; + QNetworkReply *m_reply; + WaveDecoder *m_waveDecoder; + QIODevice *m_stream; + QNetworkAccessManager *m_networkAccessManager; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSOUNDEFFECT_PULSE_H diff --git a/src/multimedia/effects/qsoundeffect_qmedia_p.cpp b/src/multimedia/effects/qsoundeffect_qmedia_p.cpp new file mode 100644 index 0000000..43ba22f --- /dev/null +++ b/src/multimedia/effects/qsoundeffect_qmedia_p.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qsoundeffect_qmedia_p.h" + +#include <QtCore/qcoreapplication.h> + +#include <QtMultimedia/qmediacontent.h> +#include <QtMultimedia/qmediaplayer.h> + + +QT_BEGIN_NAMESPACE + +QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): + QObject(parent), + m_loopCount(1), + m_runningCount(0), + m_player(0) +{ + m_player = new QMediaPlayer(this, QMediaPlayer::LowLatency); + connect(m_player, SIGNAL(volumeChanged(int)), SIGNAL(volumeChanged())); + connect(m_player, SIGNAL(mutedChanged(bool)), SIGNAL(mutedChanged())); + connect(m_player, SIGNAL(stateChanged(QMediaPlayer::State)), SLOT(stateChanged(QMediaPlayer::State))); +} + +QSoundEffectPrivate::~QSoundEffectPrivate() +{ +} + +QUrl QSoundEffectPrivate::source() const +{ + return m_player->media().canonicalUrl(); +} + +void QSoundEffectPrivate::setSource(const QUrl &url) +{ + m_player->setMedia(url); +} + +int QSoundEffectPrivate::loopCount() const +{ + return m_loopCount; +} + +void QSoundEffectPrivate::setLoopCount(int loopCount) +{ + m_loopCount = loopCount; +} + +int QSoundEffectPrivate::volume() const +{ + return m_player->volume(); +} + +void QSoundEffectPrivate::setVolume(int volume) +{ + m_player->setVolume(volume); +} + +bool QSoundEffectPrivate::isMuted() const +{ + return m_player->isMuted(); +} + +void QSoundEffectPrivate::setMuted(bool muted) +{ + m_player->setMuted(muted); +} + +void QSoundEffectPrivate::play() +{ + m_runningCount += m_loopCount; + m_player->play(); +} + +void QSoundEffectPrivate::stateChanged(QMediaPlayer::State state) +{ + if (state == QMediaPlayer::StoppedState) { + if (--m_runningCount > 0) + m_player->play(); + } +} + +QT_END_NAMESPACE + diff --git a/src/multimedia/effects/qsoundeffect_qmedia_p.h b/src/multimedia/effects/qsoundeffect_qmedia_p.h new file mode 100644 index 0000000..6ad9d79 --- /dev/null +++ b/src/multimedia/effects/qsoundeffect_qmedia_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSOUNDEFFECT_QMEDIA_H +#define QSOUNDEFFECT_QMEDIA_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include <QtCore/qobject.h> +#include <QtCore/qurl.h> +#include <QtMultimedia/qmediaplayer.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + + +class QSoundEffectPrivate : public QObject +{ + Q_OBJECT +public: + explicit QSoundEffectPrivate(QObject* parent); + ~QSoundEffectPrivate(); + + QUrl source() const; + void setSource(const QUrl &url); + int loopCount() const; + void setLoopCount(int loopCount); + int volume() const; + void setVolume(int volume); + bool isMuted() const; + void setMuted(bool muted); + +public Q_SLOTS: + void play(); + +Q_SIGNALS: + void volumeChanged(); + void mutedChanged(); + +private Q_SLOTS: + void stateChanged(QMediaPlayer::State); + +private: + int m_loopCount; + int m_runningCount; + QMediaPlayer *m_player; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSOUNDEFFECT_QMEDIA_H diff --git a/src/multimedia/effects/qsoundeffect_qsound_p.cpp b/src/multimedia/effects/qsoundeffect_qsound_p.cpp new file mode 100644 index 0000000..ff30f67 --- /dev/null +++ b/src/multimedia/effects/qsoundeffect_qsound_p.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qsoundeffect_qsound_p.h" + +#include <QtCore/qcoreapplication.h> +#include <QtGui/qsound.h> + + +QT_BEGIN_NAMESPACE + +QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): + QObject(parent), + m_muted(false), + m_loopCount(1), + m_volume(100), + m_sound(0) +{ +} + +QSoundEffectPrivate::~QSoundEffectPrivate() +{ +} + +QUrl QSoundEffectPrivate::source() const +{ + return m_source; +} + +void QSoundEffectPrivate::setSource(const QUrl &url) +{ + if (url.isEmpty() || url.scheme() != QLatin1String("file")) { + m_source = QUrl(); + return; + } + + if (m_sound != 0) + delete m_sound; + + m_source = url; + m_sound = new QSound(m_source.toLocalFile(), this); + m_sound->setLoops(m_loopCount); +} + +int QSoundEffectPrivate::loopCount() const +{ + return m_loopCount; +} + +void QSoundEffectPrivate::setLoopCount(int lc) +{ + m_loopCount = lc; + if (m_sound) + m_sound->setLoops(lc); +} + +int QSoundEffectPrivate::volume() const +{ + return m_volume; +} + +void QSoundEffectPrivate::setVolume(int v) +{ + m_volume = v; +} + +bool QSoundEffectPrivate::isMuted() const +{ + return m_muted; +} + +void QSoundEffectPrivate::setMuted(bool muted) +{ + m_muted = muted; +} + +void QSoundEffectPrivate::play() +{ + m_sound->play(); +} + +QT_END_NAMESPACE diff --git a/src/multimedia/effects/qsoundeffect_qsound_p.h b/src/multimedia/effects/qsoundeffect_qsound_p.h new file mode 100644 index 0000000..6fb3cfa --- /dev/null +++ b/src/multimedia/effects/qsoundeffect_qsound_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSOUNDEFFECT_QSOUND_H +#define QSOUNDEFFECT_QSOUND_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + + +#include <QtCore/qobject.h> +#include <QtCore/qurl.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QSound; + +class QSoundEffectPrivate : public QObject +{ + Q_OBJECT +public: + explicit QSoundEffectPrivate(QObject* parent); + ~QSoundEffectPrivate(); + + QUrl source() const; + void setSource(const QUrl &url); + int loopCount() const; + void setLoopCount(int loopCount); + int volume() const; + void setVolume(int volume); + bool isMuted() const; + void setMuted(bool muted); + +public Q_SLOTS: + void play(); + +Q_SIGNALS: + void volumeChanged(); + void mutedChanged(); + +private: + bool m_muted; + int m_loopCount; + int m_volume; + QSound *m_sound; + QUrl m_source; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QSOUNDEFFECT_QSOUND_H diff --git a/src/multimedia/effects/wavedecoder_p.cpp b/src/multimedia/effects/wavedecoder_p.cpp new file mode 100644 index 0000000..b534ded --- /dev/null +++ b/src/multimedia/effects/wavedecoder_p.cpp @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "wavedecoder_p.h" + +#include <QtCore/qtimer.h> +#include <QtCore/qendian.h> + +QT_BEGIN_NAMESPACE + +WaveDecoder::WaveDecoder(QIODevice *s, QObject *parent): + QIODevice(parent), + haveFormat(false), + dataSize(0), + remaining(0), + source(s) +{ + open(QIODevice::ReadOnly | QIODevice::Unbuffered); + + if (source->bytesAvailable() >= qint64(sizeof(CombinedHeader) + sizeof(DATAHeader) + sizeof(quint16))) + QTimer::singleShot(0, this, SLOT(handleData())); + else + connect(source, SIGNAL(readyRead()), SLOT(handleData())); +} + +WaveDecoder::~WaveDecoder() +{ +} + +QAudioFormat WaveDecoder::audioFormat() const +{ + return format; +} + +int WaveDecoder::duration() const +{ + return size() * 1000 / (format.sampleSize() / 8) / format.channels() / format.frequency(); +} + +qint64 WaveDecoder::size() const +{ + return haveFormat ? dataSize : 0; +} + +bool WaveDecoder::isSequential() const +{ + return source->isSequential(); +} + +qint64 WaveDecoder::bytesAvailable() const +{ + return haveFormat ? source->bytesAvailable() : 0; +} + +qint64 WaveDecoder::readData(char *data, qint64 maxlen) +{ + return haveFormat ? source->read(data, maxlen) : 0; +} + +qint64 WaveDecoder::writeData(const char *data, qint64 len) +{ + Q_UNUSED(data); + Q_UNUSED(len); + + return -1; +} + +void WaveDecoder::handleData() +{ + if (source->bytesAvailable() < qint64(sizeof(CombinedHeader) + sizeof(DATAHeader) + sizeof(quint16))) + return; + + source->disconnect(SIGNAL(readyRead()), this, SLOT(handleData())); + source->read((char*)&header, sizeof(CombinedHeader)); + + if (qstrncmp(header.riff.descriptor.id, "RIFF", 4) != 0 || + qstrncmp(header.riff.type, "WAVE", 4) != 0 || + qstrncmp(header.wave.descriptor.id, "fmt ", 4) != 0 || + (header.wave.audioFormat != 0 && header.wave.audioFormat != 1)) { + + emit invalidFormat(); + } + else { + DATAHeader dataHeader; + + if (qFromLittleEndian<quint32>(header.wave.descriptor.size) > sizeof(WAVEHeader)) { + // Extended data available + quint16 extraFormatBytes; + source->peek((char*)&extraFormatBytes, sizeof(quint16)); + extraFormatBytes = qFromLittleEndian<quint16>(extraFormatBytes); + source->read(sizeof(quint16) + extraFormatBytes); // dump it all + } + + source->read((char*)&dataHeader, sizeof(DATAHeader)); + + int bps = qFromLittleEndian<quint16>(header.wave.bitsPerSample); + + format.setCodec(QLatin1String("audio/pcm")); + format.setSampleType(bps == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt); + format.setByteOrder(QAudioFormat::LittleEndian); + format.setFrequency(qFromLittleEndian<quint32>(header.wave.sampleRate)); + format.setSampleSize(bps); + format.setChannels(qFromLittleEndian<quint16>(header.wave.numChannels)); + + dataSize = qFromLittleEndian<quint32>(dataHeader.descriptor.size); + + haveFormat = true; + connect(source, SIGNAL(readyRead()), SIGNAL(readyRead())); + emit formatKnown(); + } +} + +QT_END_NAMESPACE diff --git a/src/multimedia/effects/wavedecoder_p.h b/src/multimedia/effects/wavedecoder_p.h new file mode 100644 index 0000000..c1892bb --- /dev/null +++ b/src/multimedia/effects/wavedecoder_p.h @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtMultimedia module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WAVEDECODER_H +#define WAVEDECODER_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qiodevice.h> +#include <QtMultimedia/qaudioformat.h> + + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + + +class WaveDecoder : public QIODevice +{ + Q_OBJECT + +public: + explicit WaveDecoder(QIODevice *source, QObject *parent = 0); + ~WaveDecoder(); + + QAudioFormat audioFormat() const; + int duration() const; + + qint64 size() const; + bool isSequential() const; + qint64 bytesAvailable() const; + +Q_SIGNALS: + void formatKnown(); + void invalidFormat(); + +private Q_SLOTS: + void handleData(); + +private: + qint64 readData(char *data, qint64 maxlen); + qint64 writeData(const char *data, qint64 len); + + struct chunk + { + char id[4]; + quint32 size; + }; + struct RIFFHeader + { + chunk descriptor; + char type[4]; + }; + struct WAVEHeader + { + chunk descriptor; + quint16 audioFormat; + quint16 numChannels; + quint32 sampleRate; + quint32 byteRate; + quint16 blockAlign; + quint16 bitsPerSample; + }; + struct DATAHeader + { + chunk descriptor; + }; + struct CombinedHeader + { + RIFFHeader riff; + WAVEHeader wave; + }; + + bool haveFormat; + qint64 dataSize; + qint64 remaining; + QAudioFormat format; + QIODevice *source; + CombinedHeader header; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // WAVEDECODER_H |