6#include <mach/mach_time.h>
10double CoreAudioUtils::sFrequency = 0.0;
11bool CoreAudioUtils::sIsInitialized =
false;
13void CoreAudioUtils::initialize()
15 struct mach_timebase_info timeBaseInfo;
16 mach_timebase_info(&timeBaseInfo);
17 sFrequency =
static_cast<double>(timeBaseInfo.denom) /
static_cast<double>(timeBaseInfo.numer);
18 sFrequency *= 1000000000.0;
20 sIsInitialized =
true;
26 return mach_absolute_time();
45 switch (sf.mBitsPerChannel) {
47 if ((sf.mFormatFlags & kAudioFormatFlagIsSignedInteger) == 0)
51 if ((sf.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0)
55 if ((sf.mFormatFlags & kAudioFormatFlagIsSignedInteger) != 0)
57 else if ((sf.mFormatFlags & kAudioFormatFlagIsFloat) != 0)
73 AudioStreamBasicDescription sf;
75 sf.mFormatFlags = kAudioFormatFlagIsPacked;
77 sf.mFramesPerPacket = 1;
81 sf.mBytesPerPacket = sf.mFramesPerPacket * sf.mBytesPerFrame;
82 sf.mFormatID = kAudioFormatLinearPCM;
87 sf.mFormatFlags |= kAudioFormatFlagIsSignedInteger;
90 sf.mFormatFlags |= kAudioFormatFlagIsFloat;
103static constexpr struct {
137 auto *
layout =
static_cast<AudioChannelLayout *
>(malloc(*
size));
139 layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
143 layout->mChannelDescriptions[
layout->mNumberChannelDescriptions++].mChannelLabel =
m.label;
147 auto &desc =
layout->mChannelDescriptions[
layout->mNumberChannelDescriptions++];
148 desc.mChannelLabel = kAudioChannelLabel_UseCoordinates;
149 desc.mChannelFlags = kAudioChannelFlags_SphericalCoordinates;
150 desc.mCoordinates[kAudioChannelCoordinates_Azimuth] = 0.f;
151 desc.mCoordinates[kAudioChannelCoordinates_Elevation] = -20.;
152 desc.mCoordinates[kAudioChannelCoordinates_Distance] = 1.f;
155 auto &desc =
layout->mChannelDescriptions[
layout->mNumberChannelDescriptions++];
156 desc.mChannelLabel = kAudioChannelLabel_UseCoordinates;
157 desc.mChannelFlags = kAudioChannelFlags_SphericalCoordinates;
158 desc.mCoordinates[kAudioChannelCoordinates_Azimuth] = -45.f;
159 desc.mCoordinates[kAudioChannelCoordinates_Elevation] = -20.;
160 desc.mCoordinates[kAudioChannelCoordinates_Distance] = 1.f;
163 auto &desc =
layout->mChannelDescriptions[
layout->mNumberChannelDescriptions++];
164 desc.mChannelLabel = kAudioChannelLabel_UseCoordinates;
165 desc.mChannelFlags = kAudioChannelFlags_SphericalCoordinates;
166 desc.mCoordinates[kAudioChannelCoordinates_Azimuth] = 45.f;
167 desc.mCoordinates[kAudioChannelCoordinates_Elevation] = -20.;
168 desc.mCoordinates[kAudioChannelCoordinates_Distance] = 1.f;
171 return std::unique_ptr<AudioChannelLayout>(
layout);
174static constexpr struct {
175 AudioChannelLayoutTag
tag;
220 if (
m.tag ==
layout->mChannelLayoutTag)
221 return m.channelConfig;
225 if (
layout->mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions) {
227 if (
layout->mNumberChannelDescriptions == 1
228 && (
layout->mChannelDescriptions[0].mChannelLabel == kAudioChannelLabel_Unknown
229 ||
layout->mChannelDescriptions[0].mChannelLabel == kAudioChannelLabel_Mono))
231 if (
layout->mNumberChannelDescriptions == 2 &&
232 layout->mChannelDescriptions[0].mChannelLabel == kAudioChannelLabel_Unknown &&
233 layout->mChannelDescriptions[1].mChannelLabel == kAudioChannelLabel_Unknown)
236 for (
uint i = 0;
i <
layout->mNumberChannelDescriptions; ++
i) {
237 const auto channelLabel =
layout->mChannelDescriptions[
i].mChannelLabel;
238 if (channelLabel == kAudioChannelLabel_Unknown) {
245 [channelLabel](
const auto &labelWithPos) {
246 return labelWithPos.label == channelLabel;
250 qWarning() <<
"audio device has unrecognized channel, index:" <<
i
251 <<
"label:" << channelLabel;
256 qWarning() <<
"Channel layout uses unimplemented format, channelLayoutTag:"
257 <<
layout->mChannelLayoutTag;
264 m_bufferSize(bufferSize)
266 m_buffer =
new char[m_bufferSize];
282 return readSize > 0 ?
Region(m_buffer + m_readPos, readSize) :
Region(0, 0);
290 m_readPos = (m_readPos + region.second) % m_bufferSize;
307#ifdef QT_DEBUG_COREAUDIO
314 m_writePos = (m_writePos + region.second) % m_bufferSize;
317#ifdef QT_DEBUG_COREAUDIO
318 qDebug(
"releaseWriteRegion(%p,%d): m_writePos:%d", region.first, region.second, m_writePos);
void releaseWriteRegion(Region const ®ion)
Region acquireWriteRegion(int size)
Region acquireReadRegion(int size)
void releaseReadRegion(Region const ®ion)
QPair< char *, int > Region
CoreAudioRingBuffer(int bufferSize)
static Q_MULTIMEDIA_EXPORT QAudioFormat toQAudioFormat(const AudioStreamBasicDescription &streamFormat)
static AudioStreamBasicDescription toAudioStreamBasicDescription(QAudioFormat const &audioFormat)
static Q_MULTIMEDIA_EXPORT std::unique_ptr< AudioChannelLayout > toAudioChannelLayout(const QAudioFormat &format, UInt32 *size)
static double frequency()
static QAudioFormat::ChannelConfig fromAudioChannelLayout(const AudioChannelLayout *layout)
static quint64 currentTime()
T fetchAndAddAcquire(T valueToAdd) noexcept
void storeRelaxed(T newValue) noexcept
T fetchAndAddRelease(T valueToAdd) noexcept
T loadRelaxed() const noexcept
Combined button and popup list for selecting options.
static constexpr struct @722 layoutTagMap[]
static constexpr struct @721 channelMap[]
QAudioFormat::ChannelConfig channelConfig
AudioChannelLayoutTag tag
constexpr const T & qMin(const T &a, const T &b)
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint GLsizei const GLchar * label
[43]
GLint GLsizei GLsizei GLenum format
unsigned long long quint64
QT_BEGIN_NAMESPACE typedef uchar * output