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") 
   19IDirectSoundCapture8* cap;
 
   20IDirectSoundCaptureBuffer8* capBuf;
 
   23wfPeerContext* latestPeer;
 
   25int wf_rdpsnd_set_latest_peer(wfPeerContext* peer)
 
   31int 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);
 
   90static 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);