Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qqnxsndhelpers_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
#
ifndef
QQNXSNDHELPERS_P_H
5
#
define
QQNXSNDHELPERS_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 for the convenience
12
// of other Qt classes. 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
<
alsa
/
asoundlib
.
h
>
19
20
#
include
<
QtCore
/
qbytearray
.
h
>
21
#
include
<
QtCore
/
qloggingcategory
.
h
>
22
#
include
<
QtMultimedia
/
qaudioformat
.
h
>
23
#
include
<
QtMultimedia
/
private
/
qaudiohelpers_p
.
h
>
24
25
#
include
<
chrono
>
26
#
include
<
cstddef
>
27
#
include
<
cstdint
>
28
#
include
<
memory
>
29
#
include
<
optional
>
30
31
QT_BEGIN_NAMESPACE
32
33
namespace
QnxSndHelpers
{
34
35
// snd_pcm_resume retries before falling back to snd_pcm_prepare.
36
inline
constexpr
int
kSuspendResumeRetryLimit
= 5;
37
// Per-retry delay during suspend/resume recovery (ALSA cookbook idiom).
38
inline
constexpr
std
::chrono::milliseconds
kSuspendResumeRetryDelay
{ 100 };
39
// Number of periods (chunks) per ALSA buffer: buffer = period * chunks. 2 is
40
// double-buffering, 3 gives a little more slack; overridable via env var.
41
inline
constexpr
unsigned
kDefaultPeriodCount
= 3;
42
// Acceptable env-var override range for the period count.
43
inline
constexpr
unsigned
kMinPeriodCount
= 2;
44
inline
constexpr
unsigned
kMaxPeriodCount
= 16;
45
// Default ALSA period size in frames, used unless the caller passes a
46
// NativePeriodFrames override. ~21 ms at 48 kHz.
47
inline
constexpr
snd_pcm_uframes_t
kDefaultPeriodFrames
= 1024;
48
// Worker-thread real-time priority band. io-snd runs its own data/helper threads
49
// at SCHED_RR 24/25 (mixer/irq higher); we stay strictly below 24 so we never
50
// preempt them (raising into that band REPLY-block-wedges the driver), but above
51
// the default application priority (10) so a busy app thread cannot preempt the
52
// audio worker. Overridable within the band via QT_QNXSND_WORKER_PRIO.
53
inline
constexpr
int
kMinWorkerPriority
= 11;
54
inline
constexpr
int
kMaxWorkerPriority
= 23;
55
inline
constexpr
int
kDefaultWorkerPriority
= 20;
56
// Self-pipe to wake a worker blocked in poll() on a PCM fd: the worker adds
57
// readFd() to its poll set; another thread calls wake() to return the poll().
58
// RAII closes both fds. wake()/drain() are const (they touch the pipe, not the
59
// object's own state).
60
class
WakePipe
61
{
62
public
:
63
WakePipe
() =
default
;
64
~
WakePipe
();
65
Q_DISABLE_COPY_MOVE
(
WakePipe
)
66
67
bool
open
();
// create a non-blocking pipe; false on failure
68
void
close
()
noexcept
;
69
void
wake
()
const
noexcept
;
// write one byte (no-op if a wake is pending)
70
void
drain
()
const
noexcept
;
// discard all pending wake bytes
71
void
waitForWake
()
const
noexcept
;
// block until wake() fires, then drain
72
int
readFd
()
const
noexcept
{
return
m_fds[0]; }
73
bool
isOpen
()
const
noexcept
{
return
m_fds[0] >= 0; }
74
75
private
:
76
int
m_fds[2] = { -1, -1 };
77
};
78
79
// Block until the PCM handle is ready for I/O (POLLOUT for playback / POLLIN for
80
// capture, as set by snd_pcm_poll_descriptors) or the wake pipe is signalled:
81
// Ready - the PCM reported its I/O revent; the caller may write/read a period
82
// Woken - the wake pipe fired (re-check stop/suspend); the pipe is drained
83
// Error - poll() failed or the PCM reported POLLERR/POLLHUP/POLLNVAL
84
enum
class
PollOutcome
{
Ready
,
Woken
,
Error
};
85
PollOutcome
pollPcm
(snd_pcm_t *handle,
const
WakePipe
&wake);
86
87
// RAII guard for the void** array returned by snd_device_name_hint.
88
struct
HintsDeleter
89
{
90
void
operator
()(
void
**h)
const
noexcept
91
{
92
if
(h)
93
snd_device_name_free_hint(h);
94
}
95
};
96
using
HintsGuard
=
std
::unique_ptr<
void
*,
HintsDeleter
>;
97
98
// Map a QAudioFormat::SampleFormat to the corresponding ALSA PCM format.
99
// Returns SND_PCM_FORMAT_UNKNOWN for Unknown / NSampleFormats / unhandled.
100
snd_pcm_format_t
mapSampleFormat
(
QAudioFormat
::
SampleFormat
)
noexcept
;
101
102
// Recover from xrun / suspend states; returns the resulting errno.
103
int
recoverFromXrun
(snd_pcm_t *handle,
int
err);
104
105
// Start a prepared PCM. No-op (returns 0) if it already left PREPARED, so a
106
// caller can prefill-then-start without racing the device's auto-start.
107
// Returns the snd_pcm_start errno otherwise.
108
int
startPcm
(snd_pcm_t *handle);
109
110
// Raise the *calling* (worker) thread to SCHED_FIFO at a priority in the
111
// [kMinWorkerPriority, kMaxWorkerPriority] band, overridable via the
112
// QT_QNXSND_WORKER_PRIO environment variable. On failure, logs via the supplied
113
// category and leaves the thread's inherited scheduling unchanged.
114
void
setWorkerRealtimePriority
(
const
QLoggingCategory &category);
115
116
// Inputs for openConfiguredPcm: everything that differs between the
117
// playback and capture paths.
118
struct
PcmOpenConfig
119
{
120
snd_pcm_stream_t
direction
;
// SND_PCM_STREAM_PLAYBACK / _CAPTURE
121
QByteArray
deviceId
;
122
QAudioFormat
format
;
123
const
QLoggingCategory
&
category
;
124
const
char
*
streamLabel
;
// "Playback" or "Capture", embedded in log strings
125
const
char
*
periodCountEnvVar
;
// e.g. "QT_QNXSND_OUTPUT_PERIODS"; chunk-count override
126
std
::optional<uint32_t>
periodFrames
;
// NativePeriodFrames override; nullopt -> kDefaultPeriodFrames
127
};
128
129
// Outputs from openConfiguredPcm. handle is null on failure (use operator bool).
130
struct
PcmOpenResult
131
{
132
snd_pcm_t *
handle
=
nullptr
;
133
snd_pcm_uframes_t
periodFrames
= 0;
134
snd_pcm_uframes_t
bufferFrames
= 0;
135
qsizetype
periodBytes
= 0;
136
// The device's chosen native sample format (may be a 24-bit format that
137
// QAudioFormat cannot express). The stream converts between this and the
138
// application format via the base-class process()/runAudioCallback helpers.
139
QAudioHelperInternal
::
NativeSampleFormat
nativeFormat
=
140
QAudioHelperInternal
::
NativeSampleFormat
::
int16_t
;
141
142
explicit
operator
bool
()
const
noexcept
{
return
handle
!=
nullptr
; }
143
};
144
145
// Open a PCM device, configure hw/sw params and prepare it. The stream is left
146
// PREPARED but NOT started — the worker thread starts it (see startPcm), after
147
// prefilling the first period on the playback side. Returns a populated
148
// PcmOpenResult on success; on failure the handle is closed internally and the
149
// result evaluates to false.
150
PcmOpenResult
openConfiguredPcm
(
const
PcmOpenConfig
&config);
151
152
}
// namespace QnxSndHelpers
153
154
QT_END_NAMESPACE
155
156
#
endif
// QQNXSNDHELPERS_P_H
QQnxSndAudioDeviceInfo
Definition
qqnxsndaudiodevice_p.h:31
QnxSndHelpers::WakePipe
Definition
qqnxsndhelpers_p.h:61
QnxSndHelpers::WakePipe::WakePipe
WakePipe()=default
QnxSndHelpers::WakePipe::isOpen
bool isOpen() const noexcept
Definition
qqnxsndhelpers_p.h:73
QnxSndHelpers::WakePipe::drain
void drain() const noexcept
Definition
qqnxsndhelpers.cpp:59
QnxSndHelpers::WakePipe::~WakePipe
~WakePipe()
Definition
qqnxsndhelpers.cpp:23
QnxSndHelpers::WakePipe::open
bool open()
Definition
qqnxsndhelpers.cpp:28
QnxSndHelpers::WakePipe::readFd
int readFd() const noexcept
Definition
qqnxsndhelpers_p.h:72
QnxSndHelpers::WakePipe::close
void close() noexcept
Definition
qqnxsndhelpers.cpp:40
QnxSndHelpers::WakePipe::waitForWake
void waitForWake() const noexcept
Definition
qqnxsndhelpers.cpp:67
QnxSndHelpers::WakePipe::wake
void wake() const noexcept
Definition
qqnxsndhelpers.cpp:49
QT_BEGIN_NAMESPACE::defaultDeviceFormat
QAudioDevicePrivate::AudioDeviceFormat defaultDeviceFormat(QAudioDevice::Mode mode)
Definition
qqnxsndaudiodevice.cpp:27
QT_BEGIN_NAMESPACE::probeDeviceFormat
QAudioDevicePrivate::AudioDeviceFormat probeDeviceFormat(const QByteArray &dev, QAudioDevice::Mode mode)
Definition
qqnxsndaudiodevice.cpp:56
QnxSndHelpers
Definition
qqnxsndhelpers_p.h:33
QnxSndHelpers::kDefaultPeriodCount
constexpr unsigned kDefaultPeriodCount
Definition
qqnxsndhelpers_p.h:41
QnxSndHelpers::setWorkerRealtimePriority
void setWorkerRealtimePriority(const QLoggingCategory &category)
Definition
qqnxsndhelpers.cpp:256
QnxSndHelpers::kMaxPeriodCount
constexpr unsigned kMaxPeriodCount
Definition
qqnxsndhelpers_p.h:44
QnxSndHelpers::kDefaultWorkerPriority
constexpr int kDefaultWorkerPriority
Definition
qqnxsndhelpers_p.h:55
QnxSndHelpers::startPcm
int startPcm(snd_pcm_t *handle)
Definition
qqnxsndhelpers.cpp:245
QnxSndHelpers::mapSampleFormat
snd_pcm_format_t mapSampleFormat(QAudioFormat::SampleFormat) noexcept
Definition
qqnxsndhelpers.cpp:121
QnxSndHelpers::PollOutcome
PollOutcome
Definition
qqnxsndhelpers_p.h:84
QnxSndHelpers::PollOutcome::Woken
@ Woken
Definition
qqnxsndhelpers_p.h:84
QnxSndHelpers::PollOutcome::Error
@ Error
Definition
qqnxsndhelpers_p.h:84
QnxSndHelpers::PollOutcome::Ready
@ Ready
Definition
qqnxsndhelpers_p.h:84
QnxSndHelpers::kSuspendResumeRetryLimit
constexpr int kSuspendResumeRetryLimit
Definition
qqnxsndhelpers_p.h:36
QnxSndHelpers::kDefaultPeriodFrames
constexpr snd_pcm_uframes_t kDefaultPeriodFrames
Definition
qqnxsndhelpers_p.h:47
QnxSndHelpers::recoverFromXrun
int recoverFromXrun(snd_pcm_t *handle, int err)
Definition
qqnxsndhelpers.cpp:203
QnxSndHelpers::kMaxWorkerPriority
constexpr int kMaxWorkerPriority
Definition
qqnxsndhelpers_p.h:54
QnxSndHelpers::pollPcm
PollOutcome pollPcm(snd_pcm_t *handle, const WakePipe &wake)
Definition
qqnxsndhelpers.cpp:78
QnxSndHelpers::HintsGuard
std::unique_ptr< void *, HintsDeleter > HintsGuard
Definition
qqnxsndhelpers_p.h:96
QnxSndHelpers::kMinPeriodCount
constexpr unsigned kMinPeriodCount
Definition
qqnxsndhelpers_p.h:43
QnxSndHelpers::kSuspendResumeRetryDelay
constexpr std::chrono::milliseconds kSuspendResumeRetryDelay
Definition
qqnxsndhelpers_p.h:38
QnxSndHelpers::kMinWorkerPriority
constexpr int kMinWorkerPriority
Definition
qqnxsndhelpers_p.h:53
QnxSndHelpers::openConfiguredPcm
PcmOpenResult openConfiguredPcm(const PcmOpenConfig &config)
Definition
qqnxsndhelpers.cpp:284
std
[33]
Definition
src_corelib_tools_qhash.cpp:421
Q_DECLARE_LOGGING_CATEGORY
QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQIORing)
QnxSndHelpers::HintsDeleter
Definition
qqnxsndhelpers_p.h:89
QnxSndHelpers::HintsDeleter::operator()
void operator()(void **h) const noexcept
Definition
qqnxsndhelpers_p.h:90
QnxSndHelpers::PcmOpenConfig
Definition
qqnxsndhelpers_p.h:119
QnxSndHelpers::PcmOpenConfig::streamLabel
const char * streamLabel
Definition
qqnxsndhelpers_p.h:124
QnxSndHelpers::PcmOpenConfig::format
QAudioFormat format
Definition
qqnxsndhelpers_p.h:122
QnxSndHelpers::PcmOpenConfig::periodFrames
std::optional< uint32_t > periodFrames
Definition
qqnxsndhelpers_p.h:126
QnxSndHelpers::PcmOpenConfig::deviceId
QByteArray deviceId
Definition
qqnxsndhelpers_p.h:121
QnxSndHelpers::PcmOpenConfig::direction
snd_pcm_stream_t direction
Definition
qqnxsndhelpers_p.h:120
QnxSndHelpers::PcmOpenConfig::category
const QLoggingCategory & category
Definition
qqnxsndhelpers_p.h:123
QnxSndHelpers::PcmOpenConfig::periodCountEnvVar
const char * periodCountEnvVar
Definition
qqnxsndhelpers_p.h:125
QnxSndHelpers::PcmOpenResult
Definition
qqnxsndhelpers_p.h:131
QnxSndHelpers::PcmOpenResult::operator bool
operator bool() const noexcept
Definition
qqnxsndhelpers_p.h:142
QnxSndHelpers::PcmOpenResult::handle
snd_pcm_t * handle
Definition
qqnxsndhelpers_p.h:132
QnxSndHelpers::PcmOpenResult::bufferFrames
snd_pcm_uframes_t bufferFrames
Definition
qqnxsndhelpers_p.h:134
QnxSndHelpers::PcmOpenResult::periodFrames
snd_pcm_uframes_t periodFrames
Definition
qqnxsndhelpers_p.h:133
QnxSndHelpers::PcmOpenResult::nativeFormat
QAudioHelperInternal::NativeSampleFormat nativeFormat
Definition
qqnxsndhelpers_p.h:139
QnxSndHelpers::PcmOpenResult::periodBytes
qsizetype periodBytes
Definition
qqnxsndhelpers_p.h:135
qtmultimedia
src
multimedia
qnx-iosnd
qqnxsndhelpers_p.h
Generated on
for Qt by
1.18.0