6#include <QtCore/qdebug.h>
8#include <pipewire/version.h>
9#include <spa/pod/parser.h>
10#include <spa/param/format.h>
13# include <spa/param/audio/raw-utils.h>
15# include <QtMultimedia/private/qpipewire_spa_compat_p.h>
18#if PW_CHECK_VERSION
(0
, 3
, 44
)
19# include <spa/param/audio/iec958.h>
21# include <QtMultimedia/private/qpipewire_spa_compat_p.h>
32std::optional<std::variant<spa_audio_format, SpaEnum<spa_audio_format>>>
33parseSampleFormat(
const spa_pod &pod)
35 std::optional<spa_audio_format> format = spaParsePodPropertyScalar<spa_audio_format>(
36 pod, SPA_TYPE_OBJECT_Format, SPA_FORMAT_AUDIO_format);
40 std::optional<SpaEnum<spa_audio_format>> choice =
41 spaParsePodPropertyChoice<spa_audio_format, SPA_CHOICE_Enum>(
42 pod, SPA_TYPE_OBJECT_Format, SPA_FORMAT_AUDIO_format);
48std::optional<std::variant<SpaRange<
int>,
int>> parseSamplingRates(
const spa_pod &pod)
50 std::optional<
int> rate =
51 spaParsePodPropertyScalar<
int>(pod, SPA_TYPE_OBJECT_Format, SPA_FORMAT_AUDIO_rate);
55 std::optional<SpaRange<
int>> choice = spaParsePodPropertyChoice<
int, SPA_CHOICE_Range>(
56 pod, SPA_TYPE_OBJECT_Format, SPA_FORMAT_AUDIO_rate);
62bool isIec958Device(
const spa_pod &pod)
64 return spaParsePodPropertyScalar<spa_media_subtype>(pod, SPA_TYPE_OBJECT_Format,
65 SPA_FORMAT_mediaSubtype)
66 == SPA_MEDIA_SUBTYPE_iec958;
69bool isIec958PCMDevice(
const spa_pod &pod)
71 std::optional<spa_audio_iec958_codec> codec = spaParsePodPropertyScalar<spa_audio_iec958_codec>(
72 pod, SPA_TYPE_OBJECT_Format, SPA_FORMAT_AUDIO_iec958Codec);
74 return codec == spa_audio_iec958_codec::SPA_AUDIO_IEC958_CODEC_PCM;
76 std::optional<SpaEnum<spa_audio_iec958_codec>> choice =
77 spaParsePodPropertyChoice<spa_audio_iec958_codec, SPA_CHOICE_Enum>(
78 pod, SPA_TYPE_OBJECT_Format, SPA_FORMAT_AUDIO_iec958Codec);
80 return choice->defaultValue() == spa_audio_iec958_codec::SPA_AUDIO_IEC958_CODEC_PCM;
154spa_audio_format toSpaAudioFormat(QAudioFormat::SampleFormat fmt)
157 case QAudioFormat::Int16:
158 return SPA_AUDIO_FORMAT_S16;
159 case QAudioFormat::Int32:
160 return SPA_AUDIO_FORMAT_S32;
161 case QAudioFormat::UInt8:
162 return SPA_AUDIO_FORMAT_U8;
163 case QAudioFormat::Float:
164 return SPA_AUDIO_FORMAT_F32;
166 return SPA_AUDIO_FORMAT_UNKNOWN;
170void initializeChannelPositions(spa_audio_info_raw &info,
const QAudioFormat &fmt)
172 using ChannelConfig = QAudioFormat::ChannelConfig;
173 const ChannelConfig cfg = fmt.channelConfig();
175 auto fillPositions = [&](QSpan<
const spa_audio_channel> positions) {
176 std::copy(positions.begin(), positions.end(), std::begin(info.position));
180 case ChannelConfig::ChannelConfigMono:
181 return fillPositions(channelPositionsMono);
183 case ChannelConfig::ChannelConfigStereo:
184 return fillPositions(channelPositionsStereo);
185 case ChannelConfig::ChannelConfig2Dot1:
186 return fillPositions(channelPositions2Dot1);
187 case ChannelConfig::ChannelConfig3Dot0:
188 return fillPositions(channelPositions3Dot0);
189 case ChannelConfig::ChannelConfig3Dot1:
190 return fillPositions(channelPositions3Dot1);
191 case ChannelConfig::ChannelConfigSurround5Dot0:
192 return fillPositions(channelPositions5Dot0);
193 case ChannelConfig::ChannelConfigSurround5Dot1:
194 return fillPositions(channelPositions5Dot1);
195 case ChannelConfig::ChannelConfigSurround7Dot0:
196 return fillPositions(channelPositions7Dot0);
197 case ChannelConfig::ChannelConfigSurround7Dot1:
198 return fillPositions(channelPositions7Dot1);
199 case ChannelConfig::ChannelConfigUnknown:
201#if !PW_CHECK_VERSION
(0
, 3
, 33
)
202 uint32_t SPA_AUDIO_CHANNEL_START_Aux = 0x1000;
210 std::iota(info.position, info.position + fmt.channelCount(),
211 uint32_t(SPA_AUDIO_CHANNEL_START_Aux));
221 spa_audio_info_raw ret{
222 .format = toSpaAudioFormat(fmt.sampleFormat()),
224 .rate = uint32_t(fmt.sampleRate()),
225 .channels = uint32_t(fmt.channelCount()),
229 initializeChannelPositions(ret, fmt);
spa_audio_info_raw asSpaAudioInfoRaw(const QAudioFormat &fmt)
static constexpr spa_media_subtype SPA_MEDIA_SUBTYPE_iec958
static constexpr spa_format SPA_FORMAT_AUDIO_iec958Codec