Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwasmwebaudiosource_p.h
Go to the documentation of this file.
1// Copyright (C) 2026 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QWASMWEBAUDIOSOURCE_P_H
5#define QWASMWEBAUDIOSOURCE_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <private/qaudiosystem_p.h>
19#include <QElapsedTimer>
20#include <QHash>
21
22#include <emscripten/val.h>
23
24#include "qwasmjs_p.h"
25
26#if QT_CONFIG(thread)
27# include <atomic>
28#endif
29
31
33
35{
37
38public:
41
42 void start(QIODevice *device) override;
43 QIODevice *start() override;
44 void stop() override;
45 void reset() override;
46 void suspend() override;
47 void resume() override;
48 qsizetype bytesReady() const override;
49 void setBufferSize(qsizetype value) override;
50 qsizetype bufferSize() const override;
51 qint64 processedUSecs() const override;
52 QAudio::State state() const override;
53 void setVolume(float volume) override;
54
55 qint64 readFromBuffer(char *data, qint64 maxlen);
56
57 static void workletReadyCallback(int callbackId);
58 static void audioDataCallback(int callbackId);
59
60private:
61 void start(bool pullMode);
62 void connectMediaStreamIfReady();
63 void deliverBufferedData();
64 void teardownPipeline();
65
66#if QT_CONFIG(thread)
67 // Threaded path: JS AudioWorklet writes directly into the WASM heap
68 // (SharedArrayBuffer) via the SPSC ring buffer.
70
72 std::atomic<int> m_writePos{0};
73 std::atomic<int> m_readPos{0};
74 std::atomic<bool> m_running{false};
75 std::atomic<float> m_volumeAtomic{1.0f};
76
77#else // QT_CONFIG(thread)
78
79 // Single-threaded path: JS AudioWorklet + MessagePort.
80 // No SharedArrayBuffer — frames arrive via postMessage into a JS-side queue,
81 // drained by postMessage callbacks into m_pendingData (main-thread only).
82 emscripten::val m_workletNode = emscripten::val::undefined();
83 QByteArray m_pendingData;
84 bool m_running = false;
85
86#endif // QT_CONFIG(thread)
87
88 // Common to both paths
89 emscripten::val m_audioContext = emscripten::val::undefined();
90 static int s_nextId;
91 int m_callbackId = 0;
92
93 JsMediaInputStream *m_inputStream = nullptr;
94 emscripten::val m_mediaStream = emscripten::val::undefined();
95 bool m_streamReady = false;
96 bool m_workletReady = false;
97
98 QIODevice *m_device = nullptr;
99 bool m_pullMode = false;
100 bool m_suspended = false;
101 quint64 m_processed = 0;
102 qsizetype m_bufferSize = 0;
103 QElapsedTimer m_elapsedTimer;
104
106};
107
108QT_END_NAMESPACE
109
110#endif // QWASMWEBAUDIOSOURCE_P_H
The QAudioDevice class provides an information about audio devices and their functionality.
The QCameraDevice class provides general information about camera devices.
QPlatformAudioSink * createAudioSink(const QAudioDevice &, const QAudioFormat &, QObject *parent) override
QList< QAudioDevice > findAudioOutputs() const override
QList< QAudioDevice > findAudioInputs() const override
QPlatformAudioSource * createAudioSource(const QAudioDevice &, const QAudioFormat &, QObject *parent) override
void connectNotify(const QMetaMethod &signal) override
QLatin1String backendName() const override
static void workletReadyCallback(int callbackId)
qint64 processedUSecs() const override
QAudio::State state() const override
QIODevice * start() override
qsizetype bufferSize() const override
void setBufferSize(qsizetype value) override
void start(QIODevice *device) override
void setVolume(float volume) override
qint64 readFromBuffer(char *data, qint64 maxlen)
static void audioDataCallback(int callbackId)
qsizetype bytesReady() const override
void connectNotify(const QMetaMethod &signal) override
QList< QCameraDevice > findVideoInputs() const override
QList< QCameraDevice > videoInputs() const
static QWasmMediaDevices * instance()
QList< QAudioDevice > audioOutputs() const
QList< QAudioDevice > audioInputs() const
State
Definition qaudio.h:32
Combined button and popup list for selecting options.
EM_JS(void, setupAudioOutputSelector,(), { const overlay=document.createElement('div');overlay.style.cssText='position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0, 0, 0, 0.5);z-index:9999;display:flex;align-items:center;justify-content:center;';const dialog=document.createElement('div');dialog.style.cssText='background:white;padding:24px;border-radius:8px;text-align:center;font-family:sans-serif;min-width:240px;';const message=document.createElement('p');message.textContent='Select an audio output device to continue.';message.style.cssText='margin:0 0 16px 0;font-size:14px;';const button=document.createElement('button');button.textContent='Select Audio Output';button.style.cssText='padding:8px 16px;font-size:14px;cursor:pointer;';button.addEventListener('click', async()=> { document.body.removeChild(overlay);try { const deviceInfo=await navigator.mediaDevices.selectAudioOutput();console.log("Selected device: ", deviceInfo.label);Module._qtMediaDevicesOnAudioOutputSelected();} catch(err) { console.error(err);} }, { once:true });dialog.appendChild(message);dialog.appendChild(button);overlay.appendChild(dialog);document.body.appendChild(overlay);})
EMSCRIPTEN_KEEPALIVE void qtMediaDevicesOnAudioOutputSelected()
bool isFirefox()