0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

QtAdvent Calendar 2024

Day 14

QtMultimedia にパッチを送ってみました 2

Posted at

はじめに

これは Qt Advent Calendar 2024 14日目の記事です。

昨日書いた QtMultimedia にパッチを送ってみました と前提の部分が共通なので、まずはそちらを読んでいただければと思います。

マイクから音声データを読み込む処理のコードを読んでみよう

qtmultimedia/src/multimedia/pulseaudio/qpulseaudiosource.cpp
qint64 QPulseAudioSource::read(char *data, qint64 len)
{
    using namespace QPulseAudioInternal;

    Q_ASSERT(data != nullptr || len == 0);

    m_stateMachine.updateActiveOrIdle(true, QAudio::NoError);
    int readBytes = 0;

    if (!m_pullMode && !m_tempBuffer.isEmpty()) {
        readBytes = qMin(static_cast<int>(len), m_tempBuffer.size());
        if (readBytes)
            memcpy(data, m_tempBuffer.constData(), readBytes);
        m_totalTimeValue += readBytes;

        if (readBytes < m_tempBuffer.size()) {
            m_tempBuffer.remove(0, readBytes);
            return readBytes;
        }

        m_tempBuffer.clear();
    }

    while (pa_stream_readable_size(m_stream) > 0) {
        ...
    }
    ...
}

ここの処理はざっと以下のような感じになっています。

  • Pull Mode ではなかったら m_tempBuffer に保持しているものを先に処理する
  • while 文内で、PulseAudio からデータを取得する

bytesAvailable() の処理を読んでみよう

qtmultimedia/src/multimedia/pulseaudio/qpulseaudiosource.cpp
qsizetype QPulseAudioSource::bytesReady() const
{
    using namespace QPulseAudioInternal;

    if (!m_stateMachine.isActiveOrIdle())
        return 0;

    std::lock_guard lock(*QPulseAudioEngine::instance());

    int bytes = pa_stream_readable_size(m_stream);
    if (bytes < 0) {
        qWarning() << "pa_stream_readable_size() failed:" << currentError(m_stream);
        return 0;
    }

    return static_cast<qsizetype>(bytes);
}

基本的には前述の read と同じ構成であるべきなのですが、

  • Pull Mode ではなかったら m_tempBuffer に保持しているものを先に処理する

の部分が見当たりません。

修正してみました

diff --git a/src/multimedia/pulseaudio/qpulseaudiosource.cpp b/src/multimedia/pulseaudio/qpulseaudiosource.cpp
index 87bba24..5a75ac2 100644
--- a/src/multimedia/pulseaudio/qpulseaudiosource.cpp
+++ b/src/multimedia/pulseaudio/qpulseaudiosource.cpp
@@ -320,13 +320,17 @@
 
     std::lock_guard lock(*QPulseAudioEngine::instance());
 
+    qsizetype tempBufferSize = 0;
+    if (!m_pullMode && !m_tempBuffer.isEmpty()) {
+        tempBufferSize = m_tempBuffer.size();
+    }
     int bytes = pa_stream_readable_size(m_stream);
     if (bytes < 0) {
         qWarning() << "pa_stream_readable_size() failed:" << currentError(m_stream);
-        return 0;
+        return tempBufferSize;
     }
 
-    return static_cast<qsizetype>(bytes);
+    return static_cast<qsizetype>(bytes) + tempBufferSize;
 }
 
 qint64 QPulseAudioSource::read(char *data, qint64 len)

read に合わせて、Push Mode の際には m_tempBuffer を考慮するようにしました。

PulseAudio: fix bytesAavailable of QAudioSource in push mode にて Qt 本体へ取り込んでもらうためのレビューを今行っています。

QAudioSource クラスは単体テストも存在しないので(実デバイスとの兼ね合いで難しい)、上記の変更そのままです。

おわりに

QAudioSource を使って遊んでいたら見つけたバグの修正を昨日して、今日はその周辺で見つけたバグの修正をしました。
Qt 自体のビルドも最近は簡単なので、Qt のバグを見つけたら直して、本体に取り込んでもらえるようにしてみましょう。

明日は @hermit4 さんが、なにか書いてくれるようです。お楽しみに!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?