4#ifndef QMACOSAUDIODATAUTILS_P_H
5#define QMACOSAUDIODATAUTILS_P_H
18#include <CoreAudio/AudioHardware.h>
20#include <QtMultimedia/qaudiodevice.h>
21#include <QtMultimedia/private/qcoreaudioutils_p.h>
22#include <QtCore/qdebug.h>
23#include <QtCore/qspan.h>
24#include <QtCore/private/qcore_mac_p.h>
47[[
nodiscard]] std::optional<AudioDeviceID> findAudioDeviceId(
const QAudioDevice &device);
49template<
typename... Args>
53 auto warn = qWarning();
54 warn <<
"Unable to read property" << QCoreAudioUtils::audioPropertySelectorToString(address.mSelector)
55 <<
"for object" << objectID <<
", scope" << QCoreAudioUtils::audioPropertyScopeToString(address.mScope) <<
";";
56 (warn << ... << args);
57 warn <<
"\n If the warning is unexpected use test_audio_config to get comprehensive audio info and report a bug";
62 AudioObjectPropertySelector selector,
63 QAudioDevice::Mode mode,
67 AudioObjectID objectID,
68 const AudioObjectPropertyAddress &address,
69 QSpan<std::byte> destination,
70 bool warnIfMissing =
true);
74 const AudioObjectPropertyAddress &address,
75 bool warnIfMissing =
true)
77 static_assert(
std::is_trivial_v<T>,
"A trivial type is expected");
80 const auto res = AudioObjectGetPropertyDataSize(objectID, &address, 0,
nullptr, &size);
84 printUnableToReadWarning(objectID, address,
85 "AudioObjectGetPropertyDataSize failed, Err:", res);
87 std::vector<T> data(size /
sizeof(T));
88 if (getAudioPropertyRaw(objectID, address, as_writable_bytes(QSpan{data})))
97 bool warnIfMissing =
false)
99 if constexpr(std::is_same_v<T, QCFString>) {
100 const std::optional<CFStringRef> string = getAudioProperty<CFStringRef>(
101 objectID, address, warnIfMissing);
103 return QCFString{*string};
107 static_assert(
std::is_trivial_v<T>,
"A trivial type is expected");
110 if (getAudioPropertyRaw(objectID, address, as_writable_bytes(QSpan(&object, 1)), warnIfMissing))
120 bool warnIfMissing =
false)
122 static_assert(
std::is_trivial_v<T>,
"A trivial type is expected");
125 const auto res = AudioObjectGetPropertyDataSize(objectID, &address, 0,
nullptr, &size);
128 printUnableToReadWarning(objectID, address,
129 "AudioObjectGetPropertyDataSize failed, Err:", res);
132 if (size <
sizeof(T)) {
133 printUnableToReadWarning(objectID, address,
"Data size is too small:", size,
"VS",
139 std::unique_ptr<std::byte, QFreeDeleter> region {
140 reinterpret_cast<
std::byte*>(::malloc(size))
143 if (getAudioPropertyRaw(objectID, address,
144 QSpan(region.get(), size), warnIfMissing))
145 return std::unique_ptr<T, QFreeDeleter>{
146 reinterpret_cast<T*>(region.release())
QDarwinAudioSink SinkType
void stop(ShutdownPolicy policy)
bool start(AudioCallback cb)
bool start(QIODevice *device)
void stopStreamWhenBufferDrained()
void updateStreamIdle(bool arg) override
QDarwinAudioSource SourceType
bool start(AudioCallback &&)
void stop(ShutdownPolicy)
void updateStreamIdle(bool idle) override
QLatin1String backendName() const override
QList< QAudioDevice > findAudioOutputs() const override
QPlatformAudioSource * createAudioSource(const QAudioDevice &, const QAudioFormat &, QObject *parent) override
QPlatformAudioSink * createAudioSink(const QAudioDevice &, const QAudioFormat &, QObject *parent) override
QList< QAudioDevice > findAudioInputs() const override
~QDarwinAudioDevices() override
void resumeStreamIfNecessary()
void resumeStreamIfNecessary()
std::unique_ptr< T, QCoreAudioUtils::QFreeDeleter > getAudioPropertyWithFlexibleArrayMember(AudioObjectID objectID, const AudioObjectPropertyAddress &address, bool warnIfMissing=false)
std::optional< T > getAudioProperty(AudioObjectID objectID, const AudioObjectPropertyAddress &address, bool warnIfMissing=false)
QStringView audioPropertySelectorToString(AudioObjectPropertySelector selector)
QStringView audioPropertyElementToString(AudioObjectPropertyElement element)
void printUnableToReadWarning(AudioObjectID objectID, const AudioObjectPropertyAddress &address, Args &&...args)
AudioObjectPropertyAddress makePropertyAddress(AudioObjectPropertySelector selector, QAudioDevice::Mode mode, AudioObjectPropertyElement element=kAudioObjectPropertyElementMain)
QByteArray readPersistentDeviceId(AudioDeviceID, QAudioDevice::Mode)
std::optional< std::vector< T > > getAudioPropertyList(AudioObjectID objectID, const AudioObjectPropertyAddress &address, bool warnIfMissing=true)
bool getAudioPropertyRaw(AudioObjectID objectID, const AudioObjectPropertyAddress &address, QSpan< std::byte > destination, bool warnIfMissing=true)
std::optional< AudioDeviceID > findAudioDeviceId(const QByteArray &id, QAudioDevice::Mode)
QStringView audioPropertyScopeToString(AudioObjectPropertyScope scope)