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
qqnxsndaudiosink_p.h
Go to the documentation of this file.
1// Copyright (C) 2025 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//
5// W A R N I N G
6// -------------
7//
8// This file is not part of the Qt API. It exists for the convenience
9// of other Qt classes. This header file may change from version to
10// version without notice, or even be removed.
11//
12// We mean it.
13//
14
15#ifndef QQNXSNDAUDIOSINK_P_H
16#define QQNXSNDAUDIOSINK_P_H
17
18#include <alsa/asoundlib.h>
19
20#include <QtCore/qiodevice.h>
21#include <QtCore/qthread.h>
22#include <QtCore/qtclasshelpermacros.h>
23#include <QtMultimedia/qaudio.h>
24#include <QtMultimedia/qaudiodevice.h>
25#include <QtMultimedia/private/qaudiosystem_p.h>
26#include <QtMultimedia/private/qaudiosystem_platform_stream_support_p.h>
27#include <QtMultimedia/private/qaudio_platform_implementation_support_p.h>
28
30
31#include <atomic>
32#include <memory>
33#include <optional>
34
35QT_BEGIN_NAMESPACE
36
37class QQnxSndAudioSink;
38
42{
43 using SinkType = QQnxSndAudioSink;
48
53
54 QQnxSndAudioSinkStream(QAudioDevice, const QAudioFormat &,
55 std::optional<qsizetype> ringbufferSize, QQnxSndAudioSink *parent,
56 float volume, std::optional<NativePeriodFrames> nativePeriodFrames,
60
61 bool open();
62
67
68 bool start(QIODevice *);
70 bool start(AudioCallback);
71
72 void suspend();
73 void resume();
74 void stop(ShutdownPolicy);
75
76 void updateStreamIdle(bool) override;
77
78private:
79 bool openPcmDevice();
80 int recoverFromXrun(int err);
81 void startWorker(StreamType);
82 void joinWorkerThread();
83 void runProcessLoop(StreamType);
84 bool processOnePeriod(StreamType);
85 void handleSndPcmError(int err = 0);
86 void closePcmDevice();
87
88 snd_pcm_t *m_handle = nullptr;
89 snd_pcm_uframes_t m_periodFrames = 0;
90 // Device-native sample format chosen at open (best-native + convert); the
91 // host buffer written to io-snd is in this format, converted from the
92 // application format by the base-class process()/runAudioCallback helpers.
93 QAudioHelperInternal::NativeSampleFormat m_nativeFormat =
95
96 std::atomic_bool m_suspended = false;
97 std::atomic<ShutdownPolicy> m_shutdownPolicy = ShutdownPolicy::DiscardRingbuffer;
98 QtPrivate::QAutoResetEvent m_ringbufferDrained;
99
100 std::unique_ptr<QThread> m_workerThread;
101 // Wakes the worker out of poll() for stop/suspend/resume (see runProcessLoop).
102 QnxSndHelpers::WakePipe m_wakePipe;
103 // Optional (matching the source) so the Callback path can guard on it being
104 // set rather than relying on runAudioCallback's Q_PRESUME(valid).
105 std::optional<AudioCallback> m_audioCallback = std::nullopt;
106
107 // Read on the worker thread inside updateStreamIdle and inside lambdas
108 // posted via invokeOnAppThread; written on the app thread from stop().
109 // Atomic to avoid the read/write race; the front class is responsible
110 // for joining the worker before its own destruction so the pointer
111 // cannot become dangling once read.
112 std::atomic<QQnxSndAudioSink *> m_parent{ nullptr };
113};
114
115class QQnxSndAudioSink final
116 : public QtMultimediaPrivate::QPlatformAudioSinkImplementation<QQnxSndAudioSinkStream,
117 QQnxSndAudioSink>
118{
119 using BaseClass = QtMultimediaPrivate::QPlatformAudioSinkImplementation<QQnxSndAudioSinkStream,
120 QQnxSndAudioSink>;
121
122public:
123 QQnxSndAudioSink(QAudioDevice, const QAudioFormat &, QObject *parent);
125};
126
127QT_END_NAMESPACE
128
129#endif // QQNXSNDAUDIOSINK_P_H
QQnxSndAudioSink(QAudioDevice, const QAudioFormat &, QObject *parent)
void setWorkerRealtimePriority(const QLoggingCategory &category)
int startPcm(snd_pcm_t *handle)
int recoverFromXrun(snd_pcm_t *handle, int err)
PollOutcome pollPcm(snd_pcm_t *handle, const WakePipe &wake)
PcmOpenResult openConfiguredPcm(const PcmOpenConfig &config)
QT_BEGIN_NAMESPACE Q_STATIC_LOGGING_CATEGORY(lcSynthesizedIterableAccess, "qt.iterable.synthesized", QtWarningMsg)
bool start(AudioCallback)
QtMultimediaPrivate::QPlatformAudioSinkStream::AudioCallback AudioCallback
void updateStreamIdle(bool) override
void stop(ShutdownPolicy)
QQnxSndAudioSinkStream(QAudioDevice, const QAudioFormat &, std::optional< qsizetype > ringbufferSize, QQnxSndAudioSink *parent, float volume, std::optional< NativePeriodFrames > nativePeriodFrames, AudioEndpointRole)