]> git.tdb.fi Git - ext/openal.git/blob - alc/backends/base.cpp
Import OpenAL Soft 1.23.1 sources
[ext/openal.git] / alc / backends / base.cpp
1
2 #include "config.h"
3
4 #include "base.h"
5
6 #include <algorithm>
7 #include <array>
8 #include <atomic>
9
10 #ifdef _WIN32
11 #define WIN32_LEAN_AND_MEAN
12 #include <windows.h>
13 #include <mmreg.h>
14
15 #include "albit.h"
16 #include "core/logging.h"
17 #include "aloptional.h"
18 #endif
19
20 #include "atomic.h"
21 #include "core/devformat.h"
22
23
24 namespace al {
25
26 backend_exception::backend_exception(backend_error code, const char *msg, ...) : mErrorCode{code}
27 {
28     std::va_list args;
29     va_start(args, msg);
30     setMessage(msg, args);
31     va_end(args);
32 }
33 backend_exception::~backend_exception() = default;
34
35 } // namespace al
36
37
38 bool BackendBase::reset()
39 { throw al::backend_exception{al::backend_error::DeviceError, "Invalid BackendBase call"}; }
40
41 void BackendBase::captureSamples(al::byte*, uint)
42 { }
43
44 uint BackendBase::availableSamples()
45 { return 0; }
46
47 ClockLatency BackendBase::getClockLatency()
48 {
49     ClockLatency ret;
50
51     uint refcount;
52     do {
53         refcount = mDevice->waitForMix();
54         ret.ClockTime = GetDeviceClockTime(mDevice);
55         std::atomic_thread_fence(std::memory_order_acquire);
56     } while(refcount != ReadRef(mDevice->MixCount));
57
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.
61      */
62     ret.Latency = std::max(std::chrono::seconds{mDevice->BufferSize-mDevice->UpdateSize},
63         std::chrono::seconds::zero());
64     ret.Latency /= mDevice->Frequency;
65
66     return ret;
67 }
68
69 void BackendBase::setDefaultWFXChannelOrder()
70 {
71     mDevice->RealOut.ChannelIndex.fill(InvalidChannelIndex);
72
73     switch(mDevice->FmtChans)
74     {
75     case DevFmtMono:
76         mDevice->RealOut.ChannelIndex[FrontCenter] = 0;
77         break;
78     case DevFmtStereo:
79         mDevice->RealOut.ChannelIndex[FrontLeft]  = 0;
80         mDevice->RealOut.ChannelIndex[FrontRight] = 1;
81         break;
82     case DevFmtQuad:
83         mDevice->RealOut.ChannelIndex[FrontLeft]  = 0;
84         mDevice->RealOut.ChannelIndex[FrontRight] = 1;
85         mDevice->RealOut.ChannelIndex[BackLeft]   = 2;
86         mDevice->RealOut.ChannelIndex[BackRight]  = 3;
87         break;
88     case DevFmtX51:
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;
95         break;
96     case DevFmtX61:
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;
104         break;
105     case DevFmtX71:
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         break;
115     case DevFmtX714:
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;
128         break;
129     case DevFmtX3D71:
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;
138         break;
139     case DevFmtAmbi3D:
140         break;
141     }
142 }
143
144 void BackendBase::setDefaultChannelOrder()
145 {
146     mDevice->RealOut.ChannelIndex.fill(InvalidChannelIndex);
147
148     switch(mDevice->FmtChans)
149     {
150     case DevFmtX51:
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;
157         return;
158     case DevFmtX71:
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;
167         return;
168     case DevFmtX714:
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;
181         break;
182     case DevFmtX3D71:
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;
191         return;
192
193     /* Same as WFX order */
194     case DevFmtMono:
195     case DevFmtStereo:
196     case DevFmtQuad:
197     case DevFmtX61:
198     case DevFmtAmbi3D:
199         setDefaultWFXChannelOrder();
200         break;
201     }
202 }