summaryrefslogtreecommitdiff
path: root/src/multimedia/audio
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-08-27 20:23:52 +0200
committerLiang Qi <liang.qi@qt.io>2016-08-27 20:23:52 +0200
commitda7d462e315fb101fc9112a294b5ca2e3bd35a75 (patch)
tree843917c14a566949318d1e8e03aa84a6ccc041d4 /src/multimedia/audio
parent820205e604a5f281238c23464638fdff72b969d1 (diff)
parent6d95682d7ff282180655f2f384d8aba69c4f67af (diff)
downloadqtmultimedia-da7d462e315fb101fc9112a294b5ca2e3bd35a75.tar.gz
Merge remote-tracking branch 'origin/5.6' into 5.7
Change-Id: I639d42e78a2b85e939c9f8e9dd5da70cdc058857
Diffstat (limited to 'src/multimedia/audio')
-rw-r--r--src/multimedia/audio/qaudiosystemplugin.cpp2
-rw-r--r--src/multimedia/audio/qsoundeffect_pulse_p.cpp49
-rw-r--r--src/multimedia/audio/qsoundeffect_pulse_p.h10
3 files changed, 50 insertions, 11 deletions
diff --git a/src/multimedia/audio/qaudiosystemplugin.cpp b/src/multimedia/audio/qaudiosystemplugin.cpp
index b4fc0dbca..904cb22e9 100644
--- a/src/multimedia/audio/qaudiosystemplugin.cpp
+++ b/src/multimedia/audio/qaudiosystemplugin.cpp
@@ -72,7 +72,7 @@ QAudioSystemFactoryInterface::~QAudioSystemFactoryInterface()
\sa QAbstractAudioDeviceInfo, QAbstractAudioOutput, QAbstractAudioInput
- Qt supports win32, linux(alsa) and OS X standard (builtin to the
+ Qt supports win32, linux(alsa) and \macos standard (builtin to the
QtMultimedia library at compile time).
You can support other backends other than these predefined ones by
diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp
index 79d1d96ab..6e4aadd0b 100644
--- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp
+++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp
@@ -419,7 +419,13 @@ void QSoundEffectPrivate::setSource(const QUrl &url)
#ifdef QT_PA_DEBUG
qDebug() << this << "setSource =" << url;
#endif
+
+ // Make sure the stream is empty before loading a new source (otherwise whatever is there will
+ // be played before the new source)
+ emptyStream();
+
stop();
+
if (m_sample) {
if (!m_sampleReady) {
disconnect(m_sample, SIGNAL(error()), this, SLOT(decoderError()));
@@ -594,7 +600,7 @@ void QSoundEffectPrivate::playAvailable()
setLoopsRemaining(0);
m_playQueued = true;
Q_ASSERT(m_pulseStream);
- emptyStream();
+ emptyStream(ReloadSampleWhenDone);
return;
}
setLoopsRemaining(m_loopCount);
@@ -604,18 +610,25 @@ void QSoundEffectPrivate::playAvailable()
setPlaying(true);
}
-void QSoundEffectPrivate::emptyStream()
+void QSoundEffectPrivate::emptyStream(EmptyStreamOptions options)
{
#ifdef QT_PA_DEBUG
qDebug() << this << "emptyStream";
#endif
+ if (!m_pulseStream || m_emptying)
+ return;
+
+ const bool reloadSample = options.testFlag(ReloadSampleWhenDone);
+ pa_stream_success_cb_t flushCompleteCb = reloadSample ? stream_flush_reload_callback
+ : stream_flush_callback;
+
m_emptying = true;
pa_stream_set_write_callback(m_pulseStream, 0, 0);
pa_stream_set_underflow_callback(m_pulseStream, 0, 0);
- pa_operation_unref(pa_stream_flush(m_pulseStream, stream_flush_callback, m_ref->getRef()));
+ pa_operation_unref(pa_stream_flush(m_pulseStream, flushCompleteCb, m_ref->getRef()));
}
-void QSoundEffectPrivate::emptyComplete(void *stream)
+void QSoundEffectPrivate::emptyComplete(void *stream, bool reload)
{
PulseDaemonLocker locker;
#ifdef QT_PA_DEBUG
@@ -625,7 +638,7 @@ void QSoundEffectPrivate::emptyComplete(void *stream)
m_emptying = false;
if ((pa_stream *)stream == m_pulseStream)
- pa_operation_unref(pa_stream_cork(m_pulseStream, 1, stream_cork_callback, m_ref->getRef()));
+ pa_operation_unref(pa_stream_cork(m_pulseStream, 1, reload ? stream_cork_callback : 0, m_ref->getRef()));
}
void QSoundEffectPrivate::sampleReady()
@@ -729,6 +742,10 @@ void QSoundEffectPrivate::prepare()
if (!m_pulseStream || !m_sampleReady)
return;
PulseDaemonLocker locker;
+
+ if (pa_stream_get_state(m_pulseStream) != PA_STREAM_READY)
+ return;
+
pa_stream_set_write_callback(m_pulseStream, stream_write_callback, this);
pa_stream_set_underflow_callback(m_pulseStream, stream_underrun_callback, this);
m_stopping = false;
@@ -857,7 +874,7 @@ void QSoundEffectPrivate::stop()
PulseDaemonLocker locker;
m_stopping = true;
if (m_pulseStream) {
- emptyStream();
+ emptyStream(ReloadSampleWhenDone);
if (m_reloadCategory) {
unloadPulseStream(); // upon play we reconnect anyway
}
@@ -1100,10 +1117,26 @@ void QSoundEffectPrivate::stream_flush_callback(pa_stream *s, int success, void
if (!success)
qWarning("QSoundEffect(pulseaudio): faild to drain");
+
+ QMetaObject::invokeMethod(self, "emptyComplete", Qt::QueuedConnection, Q_ARG(void*, s), Q_ARG(bool, false));
+}
+
+void QSoundEffectPrivate::stream_flush_reload_callback(pa_stream *s, int success, void *userdata)
+{
#ifdef QT_PA_DEBUG
- qDebug() << self << "stream_flush_callback";
+ qDebug() << "stream_flush_reload_callback";
#endif
- QMetaObject::invokeMethod(self, "emptyComplete", Qt::QueuedConnection, Q_ARG(void*, s));
+ Q_UNUSED(s);
+ QSoundEffectRef *ref = reinterpret_cast<QSoundEffectRef*>(userdata);
+ QSoundEffectPrivate *self = ref->soundEffect();
+ ref->release();
+ if (!self)
+ return;
+
+ if (!success)
+ qWarning("QSoundEffect(pulseaudio): faild to drain");
+
+ QMetaObject::invokeMethod(self, "emptyComplete", Qt::QueuedConnection, Q_ARG(void*, s), Q_ARG(bool, true));
}
void QSoundEffectPrivate::stream_write_done_callback(void *p)
diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.h b/src/multimedia/audio/qsoundeffect_pulse_p.h
index 6bf2416cf..020aa031a 100644
--- a/src/multimedia/audio/qsoundeffect_pulse_p.h
+++ b/src/multimedia/audio/qsoundeffect_pulse_p.h
@@ -117,7 +117,7 @@ private Q_SLOTS:
void underRun();
void prepare();
void streamReady();
- void emptyComplete(void *stream);
+ void emptyComplete(void *stream, bool reload);
void handleAvailabilityChanged(bool available);
@@ -125,7 +125,12 @@ private:
void playAvailable();
void playSample();
- void emptyStream();
+ enum EmptyStreamOption {
+ ReloadSampleWhenDone = 0x1
+ };
+ Q_DECLARE_FLAGS(EmptyStreamOptions, EmptyStreamOption)
+ void emptyStream(EmptyStreamOptions options = EmptyStreamOptions());
+
void createPulseStream();
void unloadPulseStream();
@@ -140,6 +145,7 @@ private:
static void stream_underrun_callback(pa_stream *s, void *userdata);
static void stream_cork_callback(pa_stream *s, int success, void *userdata);
static void stream_flush_callback(pa_stream *s, int success, void *userdata);
+ static void stream_flush_reload_callback(pa_stream *s, int success, void *userdata);
static void stream_write_done_callback(void *p);
static void stream_adjust_prebuffer_callback(pa_stream *s, int success, void *userdata);
static void stream_reset_buffer_callback(pa_stream *s, int success, void *userdata);