11 #define WIN32_LEAN_AND_MEAN
16 #include "core/logging.h"
17 #include "aloptional.h"
21 #include "core/devformat.h"
26 backend_exception::backend_exception(backend_error code, const char *msg, ...) : mErrorCode{code}
30 setMessage(msg, args);
33 backend_exception::~backend_exception() = default;
38 bool BackendBase::reset()
39 { throw al::backend_exception{al::backend_error::DeviceError, "Invalid BackendBase call"}; }
41 void BackendBase::captureSamples(al::byte*, uint)
44 uint BackendBase::availableSamples()
47 ClockLatency BackendBase::getClockLatency()
53 refcount = mDevice->waitForMix();
54 ret.ClockTime = GetDeviceClockTime(mDevice);
55 std::atomic_thread_fence(std::memory_order_acquire);
56 } while(refcount != ReadRef(mDevice->MixCount));
58 /* NOTE: The device will generally have about all but one periods filled at
59 * any given time during playback. Without a more accurate measurement from
60 * the output, this is an okay approximation.
62 ret.Latency = std::max(std::chrono::seconds{mDevice->BufferSize-mDevice->UpdateSize},
63 std::chrono::seconds::zero());
64 ret.Latency /= mDevice->Frequency;
69 void BackendBase::setDefaultWFXChannelOrder()
71 mDevice->RealOut.ChannelIndex.fill(InvalidChannelIndex);
73 switch(mDevice->FmtChans)
76 mDevice->RealOut.ChannelIndex[FrontCenter] = 0;
79 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
80 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
83 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
84 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
85 mDevice->RealOut.ChannelIndex[BackLeft] = 2;
86 mDevice->RealOut.ChannelIndex[BackRight] = 3;
89 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
90 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
91 mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
92 mDevice->RealOut.ChannelIndex[LFE] = 3;
93 mDevice->RealOut.ChannelIndex[SideLeft] = 4;
94 mDevice->RealOut.ChannelIndex[SideRight] = 5;
97 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
98 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
99 mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
100 mDevice->RealOut.ChannelIndex[LFE] = 3;
101 mDevice->RealOut.ChannelIndex[BackCenter] = 4;
102 mDevice->RealOut.ChannelIndex[SideLeft] = 5;
103 mDevice->RealOut.ChannelIndex[SideRight] = 6;
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;
116 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
117 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
118 mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
119 mDevice->RealOut.ChannelIndex[LFE] = 3;
120 mDevice->RealOut.ChannelIndex[BackLeft] = 4;
121 mDevice->RealOut.ChannelIndex[BackRight] = 5;
122 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
123 mDevice->RealOut.ChannelIndex[SideRight] = 7;
124 mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
125 mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
126 mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
127 mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
130 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
131 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
132 mDevice->RealOut.ChannelIndex[FrontCenter] = 2;
133 mDevice->RealOut.ChannelIndex[LFE] = 3;
134 mDevice->RealOut.ChannelIndex[Aux0] = 4;
135 mDevice->RealOut.ChannelIndex[Aux1] = 5;
136 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
137 mDevice->RealOut.ChannelIndex[SideRight] = 7;
144 void BackendBase::setDefaultChannelOrder()
146 mDevice->RealOut.ChannelIndex.fill(InvalidChannelIndex);
148 switch(mDevice->FmtChans)
151 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
152 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
153 mDevice->RealOut.ChannelIndex[SideLeft] = 2;
154 mDevice->RealOut.ChannelIndex[SideRight] = 3;
155 mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
156 mDevice->RealOut.ChannelIndex[LFE] = 5;
159 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
160 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
161 mDevice->RealOut.ChannelIndex[BackLeft] = 2;
162 mDevice->RealOut.ChannelIndex[BackRight] = 3;
163 mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
164 mDevice->RealOut.ChannelIndex[LFE] = 5;
165 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
166 mDevice->RealOut.ChannelIndex[SideRight] = 7;
169 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
170 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
171 mDevice->RealOut.ChannelIndex[BackLeft] = 2;
172 mDevice->RealOut.ChannelIndex[BackRight] = 3;
173 mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
174 mDevice->RealOut.ChannelIndex[LFE] = 5;
175 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
176 mDevice->RealOut.ChannelIndex[SideRight] = 7;
177 mDevice->RealOut.ChannelIndex[TopFrontLeft] = 8;
178 mDevice->RealOut.ChannelIndex[TopFrontRight] = 9;
179 mDevice->RealOut.ChannelIndex[TopBackLeft] = 10;
180 mDevice->RealOut.ChannelIndex[TopBackRight] = 11;
183 mDevice->RealOut.ChannelIndex[FrontLeft] = 0;
184 mDevice->RealOut.ChannelIndex[FrontRight] = 1;
185 mDevice->RealOut.ChannelIndex[Aux0] = 2;
186 mDevice->RealOut.ChannelIndex[Aux1] = 3;
187 mDevice->RealOut.ChannelIndex[FrontCenter] = 4;
188 mDevice->RealOut.ChannelIndex[LFE] = 5;
189 mDevice->RealOut.ChannelIndex[SideLeft] = 6;
190 mDevice->RealOut.ChannelIndex[SideRight] = 7;
193 /* Same as WFX order */
199 setDefaultWFXChannelOrder();