Enable proper full C++ exception handling on MSVC
[openal-soft.git] / alc / backends / base.cpp
blob4f90fef1f543770bd0090fb9c987e93b42c7c0b7
2 #include "config.h"
4 #include "base.h"
6 #include <algorithm>
7 #include <array>
8 #include <atomic>
10 #include "core/devformat.h"
13 namespace al {
15 backend_exception::backend_exception(backend_error code, const char *msg, ...) : mErrorCode{code}
17 /* NOLINTBEGIN(*-array-to-pointer-decay) */
18 std::va_list args;
19 va_start(args, msg);
20 setMessage(msg, args);
21 va_end(args);
22 /* NOLINTEND(*-array-to-pointer-decay) */
24 backend_exception::~backend_exception() = default;
26 } // namespace al
29 bool BackendBase::reset()
30 { throw al::backend_exception{al::backend_error::DeviceError, "Invalid BackendBase call"}; }
32 void BackendBase::captureSamples(std::byte*, uint)
33 { }
35 uint BackendBase::availableSamples()
36 { return 0; }
38 ClockLatency BackendBase::getClockLatency()
40 ClockLatency ret{};
42 uint refcount;
43 do {
44 refcount = mDevice->waitForMix();
45 ret.ClockTime = mDevice->getClockTime();
46 std::atomic_thread_fence(std::memory_order_acquire);
47 } while(refcount != mDevice->mMixCount.load(std::memory_order_relaxed));
49 /* NOTE: The device will generally have about all but one periods filled at
50 * any given time during playback. Without a more accurate measurement from
51 * the output, this is an okay approximation.
53 ret.Latency = std::chrono::seconds{mDevice->BufferSize - mDevice->UpdateSize};
54 ret.Latency /= mDevice->Frequency;
56 return ret;
59 void BackendBase::setDefaultWFXChannelOrder() const
61 mDevice->RealOut.ChannelIndex.fill(InvalidChannelIndex);
63 switch(mDevice->FmtChans)
65 case DevFmtMono:
66 mDevice->RealOut.ChannelIndex[FrontCenter] = 0;
67 break;
68 case DevFmtStereo:
69 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
70 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
71 break;
72 case DevFmtQuad:
73 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
74 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
75 mDevice->RealOut.ChannelIndex[BackLeft] = 2;
76 mDevice->RealOut.ChannelIndex[BackRight] = 3;
77 break;
78 case DevFmtX51:
79 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
80 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
81 mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
82 mDevice->RealOut.ChannelIndex[LFE] = 3;
83 mDevice->RealOut.ChannelIndex[SideLeft] = 4;
84 mDevice->RealOut.ChannelIndex[SideRight] = 5;
85 break;
86 case DevFmtX61:
87 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
88 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
89 mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
90 mDevice->RealOut.ChannelIndex[LFE] = 3;
91 mDevice->RealOut.ChannelIndex[BackCenter] = 4;
92 mDevice->RealOut.ChannelIndex[SideLeft] = 5;
93 mDevice->RealOut.ChannelIndex[SideRight] = 6;
94 break;
95 case DevFmtX71:
96 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
97 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
98 mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
99 mDevice->RealOut.ChannelIndex[LFE] = 3;
100 mDevice->RealOut.ChannelIndex[BackLeft] = 4;
101 mDevice->RealOut.ChannelIndex[BackRight] = 5;
102 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
103 mDevice->RealOut.ChannelIndex[SideRight] = 7;
104 break;
105 case DevFmtX714:
106 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
107 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
108 mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
109 mDevice->RealOut.ChannelIndex[LFE] = 3;
110 mDevice->RealOut.ChannelIndex[BackLeft] = 4;
111 mDevice->RealOut.ChannelIndex[BackRight] = 5;
112 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
113 mDevice->RealOut.ChannelIndex[SideRight] = 7;
114 mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
115 mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
116 mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
117 mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
118 break;
119 case DevFmtX7144:
120 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
121 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
122 mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
123 mDevice->RealOut.ChannelIndex[LFE] = 3;
124 mDevice->RealOut.ChannelIndex[BackLeft] = 4;
125 mDevice->RealOut.ChannelIndex[BackRight] = 5;
126 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
127 mDevice->RealOut.ChannelIndex[SideRight] = 7;
128 mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
129 mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
130 mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
131 mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
132 mDevice->RealOut.ChannelIndex[BottomFrontLeft] = 12;
133 mDevice->RealOut.ChannelIndex[BottomFrontRight] = 13;
134 mDevice->RealOut.ChannelIndex[BottomBackLeft] = 14;
135 mDevice->RealOut.ChannelIndex[BottomBackRight] = 15;
136 break;
137 case DevFmtX3D71:
138 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
139 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
140 mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
141 mDevice->RealOut.ChannelIndex[LFE] = 3;
142 mDevice->RealOut.ChannelIndex[Aux0] = 4;
143 mDevice->RealOut.ChannelIndex[Aux1] = 5;
144 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
145 mDevice->RealOut.ChannelIndex[SideRight] = 7;
146 break;
147 case DevFmtAmbi3D:
148 break;
152 void BackendBase::setDefaultChannelOrder() const
154 mDevice->RealOut.ChannelIndex.fill(InvalidChannelIndex);
156 switch(mDevice->FmtChans)
158 case DevFmtX51:
159 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
160 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
161 mDevice->RealOut.ChannelIndex[SideLeft] = 2;
162 mDevice->RealOut.ChannelIndex[SideRight] = 3;
163 mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
164 mDevice->RealOut.ChannelIndex[LFE] = 5;
165 return;
166 case DevFmtX71:
167 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
168 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
169 mDevice->RealOut.ChannelIndex[BackLeft] = 2;
170 mDevice->RealOut.ChannelIndex[BackRight] = 3;
171 mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
172 mDevice->RealOut.ChannelIndex[LFE] = 5;
173 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
174 mDevice->RealOut.ChannelIndex[SideRight] = 7;
175 return;
176 case DevFmtX714:
177 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
178 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
179 mDevice->RealOut.ChannelIndex[BackLeft] = 2;
180 mDevice->RealOut.ChannelIndex[BackRight] = 3;
181 mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
182 mDevice->RealOut.ChannelIndex[LFE] = 5;
183 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
184 mDevice->RealOut.ChannelIndex[SideRight] = 7;
185 mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
186 mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
187 mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
188 mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
189 break;
190 case DevFmtX7144:
191 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
192 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
193 mDevice->RealOut.ChannelIndex[BackLeft] = 2;
194 mDevice->RealOut.ChannelIndex[BackRight] = 3;
195 mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
196 mDevice->RealOut.ChannelIndex[LFE] = 5;
197 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
198 mDevice->RealOut.ChannelIndex[SideRight] = 7;
199 mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
200 mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
201 mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
202 mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
203 mDevice->RealOut.ChannelIndex[BottomFrontLeft] = 12;
204 mDevice->RealOut.ChannelIndex[BottomFrontRight] = 13;
205 mDevice->RealOut.ChannelIndex[BottomBackLeft] = 14;
206 mDevice->RealOut.ChannelIndex[BottomBackRight] = 15;
207 break;
208 case DevFmtX3D71:
209 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
210 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
211 mDevice->RealOut.ChannelIndex[Aux0] = 2;
212 mDevice->RealOut.ChannelIndex[Aux1] = 3;
213 mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
214 mDevice->RealOut.ChannelIndex[LFE] = 5;
215 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
216 mDevice->RealOut.ChannelIndex[SideRight] = 7;
217 return;
219 /* Same as WFX order */
220 case DevFmtMono:
221 case DevFmtStereo:
222 case DevFmtQuad:
223 case DevFmtX61:
224 case DevFmtAmbi3D:
225 setDefaultWFXChannelOrder();
226 break;