1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
// Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qdarwinaudiodevice_p.h"
#include "qcoreaudioutils_p.h"
#include <private/qcore_mac_p.h>
#if defined(Q_OS_IOS)
#include "qcoreaudiosessionmanager_p.h"
#else
#include "qmacosaudiodatautils_p.h"
#endif
#include <QtCore/QDataStream>
#include <QtCore/QDebug>
#include <QtCore/QSet>
#include <QIODevice>
QT_BEGIN_NAMESPACE
#if defined(Q_OS_MACOS)
QCoreAudioDeviceInfo::QCoreAudioDeviceInfo(AudioDeviceID id, const QByteArray &device, QAudioDevice::Mode mode)
: QAudioDevicePrivate(device, mode),
m_deviceId(id)
#else
QCoreAudioDeviceInfo::QCoreAudioDeviceInfo(const QByteArray &device, QAudioDevice::Mode mode)
: QAudioDevicePrivate(device, mode)
#endif
{
description = getDescription();
getChannelLayout();
preferredFormat = determinePreferredFormat();
minimumSampleRate = 1;
maximumSampleRate = 96000;
minimumChannelCount = 1;
maximumChannelCount = 16;
supportedSampleFormats << QAudioFormat::UInt8 << QAudioFormat::Int16 << QAudioFormat::Int32 << QAudioFormat::Float;
}
QAudioFormat QCoreAudioDeviceInfo::determinePreferredFormat() const
{
QAudioFormat format;
#if defined(Q_OS_MACOS)
const auto audioDevicePropertyStreamsAddress =
makePropertyAddress(kAudioDevicePropertyStreams, mode);
if (auto streamIDs = getAudioData<AudioStreamID>(m_deviceId, audioDevicePropertyStreamsAddress,
"propertyStreams")) {
const auto audioDevicePhysicalFormatPropertyAddress =
makePropertyAddress(kAudioStreamPropertyPhysicalFormat, mode);
for (auto streamID : *streamIDs) {
if (auto streamDescription = getAudioObject<AudioStreamBasicDescription>(
streamID, audioDevicePhysicalFormatPropertyAddress,
"prefferedPhysicalFormat")) {
format = CoreAudioUtils::toQAudioFormat(*streamDescription);
break;
}
}
}
if (!format.isValid())
#endif
{
format.setSampleRate(44100);
format.setSampleFormat(QAudioFormat::Int16);
format.setChannelCount(mode == QAudioDevice::Input ? 1 : 2);
}
format.setChannelConfig(channelConfiguration);
return format;
}
QString QCoreAudioDeviceInfo::getDescription() const
{
#ifdef Q_OS_MACOS
const auto propertyAddress = makePropertyAddress(kAudioObjectPropertyName, mode);
if (auto name =
getAudioObject<CFStringRef>(m_deviceId, propertyAddress, "Device Description")) {
auto deleter = qScopeGuard([&name]() { CFRelease(*name); });
return QString::fromCFString(*name);
}
return {};
#else
return QString::fromUtf8(id);
#endif
}
void QCoreAudioDeviceInfo::getChannelLayout()
{
#ifdef Q_OS_MACOS
const auto propertyAddress =
makePropertyAddress(kAudioDevicePropertyPreferredChannelLayout, mode);
if (auto data = getAudioData<char>(m_deviceId, propertyAddress, "prefferedChannelLayout",
sizeof(AudioChannelLayout))) {
const auto *layout = reinterpret_cast<const AudioChannelLayout *>(data->data());
channelConfiguration = CoreAudioUtils::fromAudioChannelLayout(layout);
}
#else
channelConfiguration = (mode == QAudioDevice::Input) ? QAudioFormat::ChannelConfigMono : QAudioFormat::ChannelConfigStereo;
#endif
}
QT_END_NAMESPACE
|