-
Notifications
You must be signed in to change notification settings - Fork 0
/
SFBCAChannelLayout.hpp
192 lines (141 loc) · 5.4 KB
/
SFBCAChannelLayout.hpp
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
//
// Copyright (c) 2013 - 2024 Stephen F. Booth <me@sbooth.org>
// Part of https://github.com/sbooth/CXXAudioUtilities
// MIT license
//
#pragma once
#import <vector>
#import <CoreAudioTypes/CoreAudioTypes.h>
#ifdef __OBJC__
#import <AVFAudio/AVFAudio.h>
#endif /* __OBJC__ */
#import "SFBCFWrapper.hpp"
namespace SFB {
/// Returns the size of an @c AudioChannelLayout struct
/// @param channelLayout A pointer to an @c AudioChannelLayout struct
/// @return The size of @c channelLayout in bytes
size_t AudioChannelLayoutSize(const AudioChannelLayout * _Nullable channelLayout) noexcept;
/// A class wrapping a Core Audio @c AudioChannelLayout
class CAChannelLayout
{
public:
/// Mono layout
static const CAChannelLayout Mono;
/// Stereo layout
static const CAChannelLayout Stereo;
#pragma mark Factory Methods
/// Creates a @c CAChannelLayout
/// @param channelBitmap The channel bitmap for the channel layout
/// @return A @c CAChannelLayout
static CAChannelLayout ChannelLayoutWithBitmap(UInt32 channelBitmap);
#pragma mark Creation and Destruction
/// Creates an empty @c CAChannelLayout
CAChannelLayout() noexcept = default;
/// Copy constructor
CAChannelLayout(const CAChannelLayout& rhs);
/// Assignment operator
CAChannelLayout& operator=(const CAChannelLayout& rhs);
/// Destroys the @c CAChannelLayout and release all associated resources.
inline ~CAChannelLayout()
{
Reset();
}
/// Move constructor
CAChannelLayout(CAChannelLayout&& rhs) noexcept
: mChannelLayout{rhs.Release()}
{}
/// Move assignment operator
CAChannelLayout& operator=(CAChannelLayout&& rhs) noexcept
{
if(this != &rhs)
Reset(rhs.Release());
return *this;
}
/// Creates a @c CAChannelLayout
/// @param layoutTag The layout tag for the channel layout
CAChannelLayout(AudioChannelLayoutTag layoutTag);
/// Creates a @c CAChannelLayout
/// @param channelLabels A @c std::vector of the desired channel labels
CAChannelLayout(std::vector<AudioChannelLabel> channelLabels);
// Native overloads
/// Creates a new @c CAChannelLayout by performing a deep copy of @c rhs
CAChannelLayout(const AudioChannelLayout * _Nullable rhs);
/// Performs a deep copy of @c rhs
CAChannelLayout& operator=(const AudioChannelLayout * _Nullable rhs);
#pragma mark Comparison
/// Returns @c true if @c rhs is equal to @c this
bool operator==(const CAChannelLayout& rhs) const noexcept;
/// Returns @c true if @c rhs is not equal to @c this
inline bool operator!=(const CAChannelLayout& rhs) const noexcept
{
return !operator==(rhs);
}
#pragma mark Functionality
/// Returns the number of channels contained in this channel layout
size_t ChannelCount() const noexcept;
/// Creates a channel map for remapping audio from this channel layout
/// @param outputLayout The output channel layout
/// @param channelMap A @c std::vector to receive the channel map on success
/// @return @c true on success, @c false otherwise
bool MapToLayout(const CAChannelLayout& outputLayout, std::vector<SInt32>& channelMap) const;
#pragma mark AudioChannelLayout access
/// Returns the size in bytes of this object's internal @c AudioChannelLayout
inline size_t Size() const noexcept
{
return AudioChannelLayoutSize(mChannelLayout);
}
/// Releases ownership of the object's internal @c AudioChannelLayout and returns it
/// @note The caller assumes responsiblity for deallocating the returned @c AudioChannelLayout using @c std::free
AudioChannelLayout * _Nullable Release() noexcept
{
auto channelLayout = mChannelLayout;
mChannelLayout = nullptr;
return channelLayout;
}
/// Replaces the object's internal @c AudioChannelLayout with @c channelLayout and then deallocates it
/// @note The object assumes responsiblity for deallocating the passed @c AudioChannelLayout using @c std::free
void Reset(AudioChannelLayout * _Nullable channelLayout = nullptr) noexcept
{
auto oldChannelLayout = mChannelLayout;
mChannelLayout = channelLayout;
std::free(oldChannelLayout);
}
/// Retrieves a const pointer to this object's internal @c AudioChannelLayout
inline const AudioChannelLayout * _Nullable ChannelLayout() const noexcept
{
return mChannelLayout;
}
/// Returns @c true if this object's internal @c AudioChannelLayout is not @c nullptr
inline explicit operator bool() const noexcept
{
return mChannelLayout != nullptr;
}
/// Returns @c true if this object's internal @c AudioChannelLayout is @c nullptr
inline bool operator!() const noexcept
{
return !operator bool();
}
/// Retrieve a const pointer to this object's internal @c AudioChannelLayout
inline const AudioChannelLayout * _Nullable operator->() const noexcept
{
return mChannelLayout;
}
/// Retrieve a const pointer to this object's internal @c AudioChannelLayout
inline operator const AudioChannelLayout * const _Nullable () const noexcept
{
return mChannelLayout;
}
/// Returns a string representation of this channel layout suitable for logging
CFString Description(const char * const _Nullable prefix = nullptr) const noexcept;
#ifdef __OBJC__
/// Returns an @c AVAudioChannelLayout object initialized with this object's internal @c AudioChannelLayout
inline operator AVAudioChannelLayout * _Nullable () const noexcept
{
return [[AVAudioChannelLayout alloc] initWithLayout:mChannelLayout];
}
#endif /* __OBJC__ */
private:
/// The underlying @c AudioChannelLayout struct
AudioChannelLayout * _Nullable mChannelLayout = nullptr;
};
} // namespace SFB