| 1145 | |
| 1146 | |
| 1147 | struct WasapiCapture final : public BackendBase, WasapiProxy { |
| 1148 | WasapiCapture(ALCdevice *device) noexcept : BackendBase{device} { } |
| 1149 | ~WasapiCapture() override; |
| 1150 | |
| 1151 | int recordProc(); |
| 1152 | |
| 1153 | void open(const ALCchar *name) override; |
| 1154 | HRESULT openProxy() override; |
| 1155 | void closeProxy() override; |
| 1156 | |
| 1157 | HRESULT resetProxy() override; |
| 1158 | bool start() override; |
| 1159 | HRESULT startProxy() override; |
| 1160 | void stop() override; |
| 1161 | void stopProxy() override; |
| 1162 | |
| 1163 | ALCenum captureSamples(al::byte *buffer, ALCuint samples) override; |
| 1164 | ALCuint availableSamples() override; |
| 1165 | |
| 1166 | std::wstring mDevId; |
| 1167 | |
| 1168 | IMMDevice *mMMDev{nullptr}; |
| 1169 | IAudioClient *mClient{nullptr}; |
| 1170 | IAudioCaptureClient *mCapture{nullptr}; |
| 1171 | HANDLE mNotifyEvent{nullptr}; |
| 1172 | |
| 1173 | ChannelConverter mChannelConv{}; |
| 1174 | SampleConverterPtr mSampleConv; |
| 1175 | RingBufferPtr mRing; |
| 1176 | |
| 1177 | std::atomic<bool> mKillNow{true}; |
| 1178 | std::thread mThread; |
| 1179 | |
| 1180 | DEF_NEWDEL(WasapiCapture) |
| 1181 | }; |
| 1182 | |
| 1183 | WasapiCapture::~WasapiCapture() |
| 1184 | { |
| 1185 | pushMessage(MsgType::CloseDevice).wait(); |
| 1186 | |
| 1187 | if(mNotifyEvent != nullptr) |
| 1188 | CloseHandle(mNotifyEvent); |
| 1189 | mNotifyEvent = nullptr; |
| 1190 | } |
| 1191 | |
| 1192 | |
| 1193 | FORCE_ALIGN int WasapiCapture::recordProc() |
| 1194 | { |
| 1195 | HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); |
| 1196 | if(FAILED(hr)) |
| 1197 | { |
| 1198 | ERR("CoInitializeEx(nullptr, COINIT_MULTITHREADED) failed: 0x%08lx\n", hr); |
| 1199 | aluHandleDisconnect(mDevice, "COM init failed: 0x%08lx", hr); |
| 1200 | return 1; |
| 1201 | } |
| 1202 | |
| 1203 | althrd_setname(RECORD_THREAD_NAME); |
| 1204 |
nothing calls this directly
no test coverage detected