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
qqnxaudioutils.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Research In Motion
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
7
8namespace QnxAudioUtils
9{
10
11snd_pcm_channel_params_t formatToChannelParams(const QAudioFormat &format, QAudioDevice::Mode mode, int fragmentSize)
12{
13 snd_pcm_channel_params_t params;
14 memset(&params, 0, sizeof(params));
15 params.channel = (mode == QAudioDevice::Output) ? SND_PCM_CHANNEL_PLAYBACK : SND_PCM_CHANNEL_CAPTURE;
16 params.mode = SND_PCM_MODE_BLOCK;
17 params.start_mode = SND_PCM_START_DATA;
18 params.stop_mode = SND_PCM_STOP_ROLLOVER;
19 params.buf.block.frag_size = fragmentSize;
20 params.buf.block.frags_min = 1;
21 params.buf.block.frags_max = 1;
22 strcpy(params.sw_mixer_subchn_name, "QAudio Channel");
23
24 params.format.interleave = 1;
25 params.format.rate = format.sampleRate();
26 params.format.voices = format.channelCount();
27
28 switch (format.sampleFormat()) {
29 case QAudioFormat::UInt8:
30 params.format.format = SND_PCM_SFMT_U8;
31 break;
32 default:
33 // fall through
34 case QAudioFormat::Int16:
35#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
36 params.format.format = SND_PCM_SFMT_S16_LE;
37#else
38 params.format.format = SND_PCM_SFMT_S16_BE;
39#endif
40 break;
41 case QAudioFormat::Int32:
42#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
43 params.format.format = SND_PCM_SFMT_S32_LE;
44#else
45 params.format.format = SND_PCM_SFMT_S32_BE;
46#endif
47 break;
48 case QAudioFormat::Float:
49#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
50 params.format.format = SND_PCM_SFMT_FLOAT_LE;
51#else
52 params.format.format = SND_PCM_SFMT_FLOAT_BE;
53#endif
54 break;
55 }
56
57 return params;
58}
59
60
61HandleUniquePtr openPcmDevice(const QByteArray &id, QAudioDevice::Mode mode)
62{
63 const int pcmMode = mode == QAudioDevice::Output
64 ? SND_PCM_OPEN_PLAYBACK
65 : SND_PCM_OPEN_CAPTURE;
66
67 snd_pcm_t *handle;
68
69 const int errorCode = snd_pcm_open_name(&handle, id.constData(), pcmMode);
70
71 if (errorCode != 0) {
72 qWarning("Unable to open PCM device %s (0x%x)", id.constData(), -errorCode);
73 return {};
74 }
75
76 return HandleUniquePtr { handle };
77}
78
79template <typename T, typename Func>
80std::optional<T> pcmChannelGetStruct(snd_pcm_t *handle, QAudioDevice::Mode mode, Func &&func)
81{
82 // initialize in-place to prevent an extra copy when returning
83 std::optional<T> t = { T{} };
84
85 t->channel = mode == QAudioDevice::Output
86 ? SND_PCM_CHANNEL_PLAYBACK
87 : SND_PCM_CHANNEL_CAPTURE;
88
89 const int errorCode = func(handle, &(*t));
90
91 if (errorCode != 0) {
92 qWarning("QAudioDevice: couldn't get channel info (0x%x)", -errorCode);
93 return {};
94 }
95
96 return t;
97}
98
99template <typename T, typename Func>
100std::optional<T> pcmChannelGetStruct(const QByteArray &device,
101 QAudioDevice::Mode mode, Func &&func)
102{
103 const HandleUniquePtr handle = openPcmDevice(device, mode);
104
105 if (!handle)
106 return {};
107
108 return pcmChannelGetStruct<T>(handle.get(), mode, std::forward<Func>(func));
109}
110
111
112std::optional<snd_pcm_channel_info_t> pcmChannelInfo(snd_pcm_t *handle, QAudioDevice::Mode mode)
113{
114 return pcmChannelGetStruct<snd_pcm_channel_info_t>(handle, mode, snd_pcm_plugin_info);
115}
116
118 QAudioDevice::Mode mode)
119{
120 return pcmChannelGetStruct<snd_pcm_channel_info_t>(device, mode, snd_pcm_plugin_info);
121}
122
123std::optional<snd_pcm_channel_setup_t> pcmChannelSetup(snd_pcm_t *handle, QAudioDevice::Mode mode)
124{
125 return pcmChannelGetStruct<snd_pcm_channel_setup_t>(handle, mode, snd_pcm_plugin_setup);
126}
127
129 QAudioDevice::Mode mode)
130{
131 return pcmChannelGetStruct<snd_pcm_channel_setup_t>(device, mode, snd_pcm_plugin_setup);
132}
133
134std::optional<snd_pcm_channel_status_t> pcmChannelStatus(snd_pcm_t *handle, QAudioDevice::Mode mode)
135{
136 return pcmChannelGetStruct<snd_pcm_channel_status_t>(handle, mode, snd_pcm_plugin_status);
137}
138
140 QAudioDevice::Mode mode)
141{
142 return pcmChannelGetStruct<snd_pcm_channel_status_t>(device, mode, snd_pcm_plugin_status);
143}
144
145
146} // namespace QnxAudioUtils
147
148QT_END_NAMESPACE
std::optional< T > pcmChannelGetStruct(snd_pcm_t *handle, QAudioDevice::Mode mode, Func &&func)
std::optional< snd_pcm_channel_setup_t > pcmChannelSetup(const QByteArray &device, QAudioDevice::Mode mode)
std::optional< snd_pcm_channel_info_t > pcmChannelInfo(snd_pcm_t *handle, QAudioDevice::Mode mode)
std::unique_ptr< snd_pcm_t, HandleDeleter > HandleUniquePtr
std::optional< snd_pcm_channel_setup_t > pcmChannelSetup(snd_pcm_t *handle, QAudioDevice::Mode mode)
HandleUniquePtr openPcmDevice(const QByteArray &id, QAudioDevice::Mode mode)
std::optional< snd_pcm_channel_status_t > pcmChannelStatus(const QByteArray &device, QAudioDevice::Mode mode)
std::optional< snd_pcm_channel_info_t > pcmChannelInfo(const QByteArray &device, QAudioDevice::Mode mode)
std::optional< snd_pcm_channel_status_t > pcmChannelStatus(snd_pcm_t *handle, QAudioDevice::Mode mode)
std::optional< T > pcmChannelGetStruct(const QByteArray &device, QAudioDevice::Mode mode, Func &&func)
snd_pcm_channel_params_t formatToChannelParams(const QAudioFormat &format, QAudioDevice::Mode mode, int fragmentSize)