1 #include "wf_directsound.h"
2 #include "wf_interface.h"
6 #include <winpr/windows.h>
16 #include <freerdp/log.h>
17 #define TAG SERVER_TAG("windows")
19 IDirectSoundCapture8* cap;
20 IDirectSoundCaptureBuffer8* capBuf;
23 wfPeerContext* latestPeer;
25 int wf_rdpsnd_set_latest_peer(wfPeerContext* peer)
31 int wf_directsound_activate(RdpsndServerContext* context)
37 LPDIRECTSOUNDCAPTUREBUFFER pDSCB;
39 wfi = wf_info_get_instance();
42 WLog_ERR(TAG,
"Failed to wfi instance");
45 WLog_DBG(TAG,
"RDPSND (direct sound) Activated");
46 hr = DirectSoundCaptureCreate8(NULL, &cap, NULL);
50 WLog_ERR(TAG,
"Failed to create sound capture device");
54 WLog_INFO(TAG,
"Created sound capture device");
55 dscbd.dwSize =
sizeof(DSCBUFFERDESC);
57 dscbd.dwBufferBytes = wfi->agreed_format->nAvgBytesPerSec;
59 dscbd.lpwfxFormat = wfi->agreed_format;
61 dscbd.lpDSCFXDesc = NULL;
63 hr = cap->lpVtbl->CreateCaptureBuffer(cap, &dscbd, &pDSCB, NULL);
67 WLog_ERR(TAG,
"Failed to create capture buffer");
70 WLog_INFO(TAG,
"Created capture buffer");
71 hr = pDSCB->lpVtbl->QueryInterface(pDSCB, &IID_IDirectSoundCaptureBuffer8, (LPVOID*)&capBuf);
74 WLog_ERR(TAG,
"Failed to QI capture buffer");
76 WLog_INFO(TAG,
"Created IDirectSoundCaptureBuffer8");
77 pDSCB->lpVtbl->Release(pDSCB);
80 if (!(hThread = CreateThread(NULL, 0, wf_rdpsnd_directsound_thread, latestPeer, 0, NULL)))
82 WLog_ERR(TAG,
"Failed to create direct sound thread");
85 (void)CloseHandle(hThread);
90 static DWORD WINAPI wf_rdpsnd_directsound_thread(LPVOID lpParam)
96 wfPeerContext* context;
99 VOID* pbCaptureData = NULL;
100 DWORD dwCaptureLength = 0;
101 VOID* pbCaptureData2 = NULL;
102 DWORD dwCaptureLength2 = 0;
103 VOID* pbPlayData = NULL;
107 wfi = wf_info_get_instance();
110 WLog_ERR(TAG,
"Failed get instance");
114 context = (wfPeerContext*)lpParam;
116 WLog_INFO(TAG,
"Trying to start capture");
117 hr = capBuf->lpVtbl->Start(capBuf, DSCBSTART_LOOPING);
120 WLog_ERR(TAG,
"Failed to start capture");
122 WLog_INFO(TAG,
"Capture started");
127 end = GetTickCount();
135 beg = GetTickCount();
137 if (wf_rdpsnd_lock() > 0)
140 if (wfi->snd_stop == TRUE)
146 hr = capBuf->lpVtbl->GetCurrentPosition(capBuf, NULL, &dwReadPos);
149 WLog_ERR(TAG,
"Failed to get read pos");
154 lLockSize = dwReadPos - lastPos;
156 lLockSize += dscbd.dwBufferBytes;
167 hr = capBuf->lpVtbl->Lock(capBuf, lastPos, lLockSize, &pbCaptureData, &dwCaptureLength,
168 &pbCaptureData2, &dwCaptureLength2, 0L);
171 WLog_ERR(TAG,
"Failed to lock sound capture buffer");
181 context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData, dwCaptureLength / 4,
182 (UINT16)(beg & 0xffff));
183 context->rdpsnd->SendSamples(context->rdpsnd, pbCaptureData2, dwCaptureLength2 / 4,
184 (UINT16)(beg & 0xffff));
186 hr = capBuf->lpVtbl->Unlock(capBuf, pbCaptureData, dwCaptureLength, pbCaptureData2,
190 WLog_ERR(TAG,
"Failed to unlock sound capture buffer");
196 lastPos += dwCaptureLength;
197 lastPos %= dscbd.dwBufferBytes;
198 lastPos += dwCaptureLength2;
199 lastPos %= dscbd.dwBufferBytes;
205 WLog_INFO(TAG,
"Trying to stop sound capture");
206 hr = capBuf->lpVtbl->Stop(capBuf);
209 WLog_ERR(TAG,
"Failed to stop capture");
212 WLog_INFO(TAG,
"Capture stopped");
213 capBuf->lpVtbl->Release(capBuf);
214 cap->lpVtbl->Release(cap);