Esempio n. 1
0
HRESULT DSW_InitInputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate, int nChannels, int bytesPerBuffer )
{
	DSCBUFFERDESC  captureDesc;
	WAVEFORMATEX   wfFormat;
	HRESULT        result;
// Define the buffer format
	wfFormat.wFormatTag      = WAVE_FORMAT_PCM;
	wfFormat.nChannels       = nChannels;
	wfFormat.nSamplesPerSec  = nFrameRate;
	wfFormat.wBitsPerSample  = 8 * sizeof(short);
	wfFormat.nBlockAlign     = wfFormat.nChannels * (wfFormat.wBitsPerSample / 8);
	wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
	wfFormat.cbSize          = 0;   /* No extended format info. */
	dsw->dsw_InputSize = bytesPerBuffer;
// ----------------------------------------------------------------------
// Setup the secondary buffer description
	ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC));
	captureDesc.dwSize = sizeof(DSCBUFFERDESC);
	captureDesc.dwFlags =  0;
	captureDesc.dwBufferBytes = bytesPerBuffer;
	captureDesc.lpwfxFormat = &wfFormat;
	// Create the capture buffer
	if ((result = IDirectSoundCapture_CreateCaptureBuffer( dsw->dsw_pDirectSoundCapture,
		&captureDesc, &dsw->dsw_InputBuffer, NULL)) != DS_OK) return result;
	dsw->dsw_ReadOffset = 0;  // reset last read position to start of buffer
	return DS_OK;
}
Esempio n. 2
0
static HRESULT WINAPI IDirectSoundFullDuplex_IDirectSoundCapture_CreateCaptureBuffer(
    LPDIRECTSOUNDCAPTURE iface,
    LPCDSCBUFFERDESC lpcDSCBufferDesc,
    LPDIRECTSOUNDCAPTUREBUFFER* lplpDSCaptureBuffer,
    LPUNKNOWN pUnk)
{
    IDirectSoundFullDuplex_IDirectSoundCapture *This = (IDirectSoundFullDuplex_IDirectSoundCapture *)iface;
    TRACE("(%p,%p,%p,%p)\n",This,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
    return IDirectSoundCapture_CreateCaptureBuffer(This->pdsfd->capture_device,lpcDSCBufferDesc,lplpDSCaptureBuffer,pUnk);
}
Esempio n. 3
0
/* ============ Media Producer Interface ================= */
int tdav_producer_dsound_prepare(tmedia_producer_t* self, const tmedia_codec_t* codec)
{
	HRESULT hr;

	WAVEFORMATEX wfx = {0};
	DSCBUFFERDESC dsbd = {0};

	tdav_producer_dsound_t* dsound = (tdav_producer_dsound_t*)self;

	if(!dsound || !codec){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	if(dsound->device || dsound->captureBuffer){
		TSK_DEBUG_ERROR("Producer already prepared");
		return -2;
	}

	TDAV_PRODUCER_AUDIO(dsound)->channels = codec->plugin->audio.channels;
	TDAV_PRODUCER_AUDIO(dsound)->rate = codec->plugin->rate;

	/* Create capture device */
	if((hr = DirectSoundCaptureCreate(NULL, &dsound->device, NULL) != DS_OK)){
		tdav_win32_print_error("DirectSoundCaptureCreate", hr);
		return -3;
	}

	/* Creates the capture buffer */
	wfx.wFormatTag = WAVE_FORMAT_PCM;
	wfx.nChannels = TDAV_PRODUCER_AUDIO(dsound)->channels;
	wfx.nSamplesPerSec = TDAV_PRODUCER_AUDIO(dsound)->rate;
	wfx.wBitsPerSample = TDAV_PRODUCER_AUDIO(dsound)->bits_per_sample;
	wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample/8);
	wfx.nAvgBytesPerSec = (wfx.nSamplesPerSec * wfx.nBlockAlign);

	/* Average bytes (count) for each notification */
	dsound->bytes_per_notif = ((wfx.nAvgBytesPerSec * TDAV_PRODUCER_AUDIO(dsound)->ptime)/1000);

	dsbd.dwSize = sizeof(DSCBUFFERDESC);
	dsbd.dwBufferBytes = (TDAV_DSOUNS_PRODUCER_NOTIF_POS_COUNT * dsound->bytes_per_notif);
	dsbd.lpwfxFormat = &wfx;

	if((hr = IDirectSoundCapture_CreateCaptureBuffer(dsound->device, &dsbd, &dsound->captureBuffer, NULL)) != DS_OK){
		tdav_win32_print_error("IDirectSoundCapture_CreateCaptureBuffer", hr);
		return -4;
	}	

	return 0;
}
Esempio n. 4
0
void *DSOUND_Capture_Init (int rate)
{
	dsndcapture_t *result;
	DSCBUFFERDESC bufdesc = {0};
	WAVEFORMATEX  wfxFormat = {0};

	Com_DPrintf("DSOUND_Capture_Init: rate %d\n", rate);

	wfxFormat.wFormatTag = WAVE_FORMAT_PCM;
    wfxFormat.nChannels = 1;
    wfxFormat.nSamplesPerSec = rate;
	wfxFormat.wBitsPerSample = 8*inputwidth;
    wfxFormat.nBlockAlign = wfxFormat.nChannels * (wfxFormat.wBitsPerSample / 8);
	wfxFormat.nAvgBytesPerSec = wfxFormat.nSamplesPerSec * wfxFormat.nBlockAlign;
    wfxFormat.cbSize = 0;

	bufdesc.dwSize = sizeof(bufdesc);
	bufdesc.dwBufferBytes = bufferbytes;
	bufdesc.dwFlags = 0;
	bufdesc.dwReserved = 0;
	bufdesc.lpwfxFormat = &wfxFormat;

	result = Z_Malloc(sizeof(*result));
	if (FAILED(DirectSoundCaptureCreate(NULL, &result->DSCapture, NULL)))
	{
		Com_Printf_State (PRINT_FAIL, "DirectSound: Couldn't create a capture device\n");
	}
	else if (FAILED(IDirectSoundCapture_CreateCaptureBuffer(result->DSCapture, &bufdesc, &result->DSCaptureBuffer, NULL)))
	{
		Com_Printf_State (PRINT_FAIL, "DirectSound: Couldn't create a capture buffer\n");	
	}
	else
	{
		Com_DPrintf("DSOUND_Capture_Init: OK\n");
		return result;	
	}

	// failure, lets clean up.

	if (result->DSCapture)
	{
		IDirectSoundCapture_Release(result->DSCapture);	
	}

	Z_Free(result);

	return NULL;
}
Esempio n. 5
0
/* This function tries to create a capture buffer, and returns the
   number of audio chunks available in the created buffer. This is for
   capture devices, not playback.
*/
static int
CreateCaptureBuffer(_THIS, const DWORD bufsize, WAVEFORMATEX *wfmt)
{
    LPDIRECTSOUNDCAPTURE capture = this->hidden->capture;
    LPDIRECTSOUNDCAPTUREBUFFER *capturebuf = &this->hidden->capturebuf;
    DSCBUFFERDESC format;
//    DWORD junk, cursor;
    HRESULT result;

    SDL_zero(format);
    format.dwSize = sizeof (format);
    format.dwFlags = DSCBCAPS_WAVEMAPPED;
    format.dwBufferBytes = bufsize;
    format.lpwfxFormat = wfmt;

    result = IDirectSoundCapture_CreateCaptureBuffer(capture, &format, capturebuf, NULL);
    if (result != DS_OK) {
        return SetDSerror("DirectSound CreateCaptureBuffer", result);
    }

    result = IDirectSoundCaptureBuffer_Start(*capturebuf, DSCBSTART_LOOPING);
    if (result != DS_OK) {
        IDirectSoundCaptureBuffer_Release(*capturebuf);
        return SetDSerror("DirectSound Start", result);
    }

#if 0
    /* presumably this starts at zero, but just in case... */
    result = IDirectSoundCaptureBuffer_GetCurrentPosition(*capturebuf, &junk, &cursor);
    if (result != DS_OK) {
        IDirectSoundCaptureBuffer_Stop(*capturebuf);
        IDirectSoundCaptureBuffer_Release(*capturebuf);
        return SetDSerror("DirectSound GetCurrentPosition", result);
    }

    this->hidden->lastchunk = cursor / this->spec.size;
#endif

    return 0;
}
static gboolean
gst_directsound_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
{
  GstDirectSoundSrc *dsoundsrc;
  WAVEFORMATEX wfx;             /* Wave format structure */
  HRESULT hRes;                 /* Result for windows functions */
  DSCBUFFERDESC descSecondary;  /* Capturebuffer description */

  dsoundsrc = GST_DIRECTSOUND_SRC (asrc);

  GST_DEBUG_OBJECT (asrc, "preparing directsoundsrc");

  /* Define buffer */
  memset (&wfx, 0, sizeof (WAVEFORMATEX));
  wfx.wFormatTag = WAVE_FORMAT_PCM;
  wfx.nChannels = GST_AUDIO_INFO_CHANNELS (&spec->info);
  wfx.nSamplesPerSec = GST_AUDIO_INFO_RATE (&spec->info);
  wfx.wBitsPerSample = GST_AUDIO_INFO_BPF (&spec->info) * 8 / wfx.nChannels;
  wfx.nBlockAlign = GST_AUDIO_INFO_BPF (&spec->info);
  wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
  /* Ignored for WAVE_FORMAT_PCM. */
  wfx.cbSize = 0;

  if (wfx.wBitsPerSample != 16 && wfx.wBitsPerSample != 8)
    goto dodgy_width;

  /* Set the buffer size to two seconds. 
     This should never reached. 
   */
  dsoundsrc->buffer_size = wfx.nAvgBytesPerSec * 2;

  GST_DEBUG_OBJECT (asrc, "Buffer size: %d", dsoundsrc->buffer_size);

  /* Init secondary buffer desciption */
  memset (&descSecondary, 0, sizeof (DSCBUFFERDESC));
  descSecondary.dwSize = sizeof (DSCBUFFERDESC);
  descSecondary.dwFlags = 0;
  descSecondary.dwReserved = 0;

  /* This is not primary buffer so have to set size  */
  descSecondary.dwBufferBytes = dsoundsrc->buffer_size;
  descSecondary.lpwfxFormat = &wfx;

  /* Create buffer */
  hRes = IDirectSoundCapture_CreateCaptureBuffer (dsoundsrc->pDSC,
      &descSecondary, &dsoundsrc->pDSBSecondary, NULL);
  if (hRes != DS_OK)
    goto capture_buffer;

  dsoundsrc->bytes_per_sample = GST_AUDIO_INFO_BPF (&spec->info);

  GST_DEBUG ("latency time: %" G_GUINT64_FORMAT " - buffer time: %"
      G_GUINT64_FORMAT, spec->latency_time, spec->buffer_time);

  /* Buffer-time should be always more than 2*latency */
  if (spec->buffer_time < spec->latency_time * 2) {
    spec->buffer_time = spec->latency_time * 2;
    GST_WARNING ("buffer-time was less than latency");
  }

  /* Save the times */
  dsoundsrc->buffer_time = spec->buffer_time;
  dsoundsrc->latency_time = spec->latency_time;

  dsoundsrc->latency_size = (gint) wfx.nAvgBytesPerSec *
      dsoundsrc->latency_time / 1000000.0;

  spec->segsize = (guint) (((double) spec->buffer_time / 1000000.0) *
      wfx.nAvgBytesPerSec);

  /* just in case */
  if (spec->segsize < 1)
    spec->segsize = 1;

  spec->segtotal = GST_AUDIO_INFO_BPF (&spec->info) * 8 *
      (wfx.nAvgBytesPerSec / spec->segsize);

  GST_DEBUG_OBJECT (asrc,
      "bytes/sec: %lu, buffer size: %d, segsize: %d, segtotal: %d",
      wfx.nAvgBytesPerSec, dsoundsrc->buffer_size, spec->segsize,
      spec->segtotal);

  /* Not read anything yet */
  dsoundsrc->current_circular_offset = 0;

  GST_DEBUG_OBJECT (asrc, "channels: %d, rate: %d, bytes_per_sample: %d"
      " WAVEFORMATEX.nSamplesPerSec: %ld, WAVEFORMATEX.wBitsPerSample: %d,"
      " WAVEFORMATEX.nBlockAlign: %d, WAVEFORMATEX.nAvgBytesPerSec: %ld",
      GST_AUDIO_INFO_CHANNELS (&spec->info), GST_AUDIO_INFO_RATE (&spec->info),
      GST_AUDIO_INFO_BPF (&spec->info), wfx.nSamplesPerSec, wfx.wBitsPerSample,
      wfx.nBlockAlign, wfx.nAvgBytesPerSec);

  return TRUE;

capture_buffer:
  {
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unable to create capturebuffer"), (NULL));
    return FALSE;
  }
dodgy_width:
  {
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unexpected width %d", wfx.wBitsPerSample), (NULL));
    return FALSE;
  }
}
Esempio n. 7
0
static ALCenum DSoundOpenCapture(ALCdevice *device, const ALCchar *deviceName)
{
    DSoundCaptureData *data = NULL;
    WAVEFORMATEXTENSIBLE InputType;
    DSCBUFFERDESC DSCBDescription;
    LPGUID guid = NULL;
    HRESULT hr, hrcom;
    ALuint samples;

    if(!CaptureDeviceList)
    {
        /* Initialize COM to prevent name truncation */
        hrcom = CoInitialize(NULL);
        hr = DirectSoundCaptureEnumerateA(DSoundEnumCaptureDevices, NULL);
        if(FAILED(hr))
            ERR("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr);
        if(SUCCEEDED(hrcom))
            CoUninitialize();
    }

    if(!deviceName && NumCaptureDevices > 0)
    {
        deviceName = CaptureDeviceList[0].name;
        guid = &CaptureDeviceList[0].guid;
    }
    else
    {
        ALuint i;

        for(i = 0;i < NumCaptureDevices;i++)
        {
            if(strcmp(deviceName, CaptureDeviceList[i].name) == 0)
            {
                guid = &CaptureDeviceList[i].guid;
                break;
            }
        }
        if(i == NumCaptureDevices)
            return ALC_INVALID_VALUE;
    }

    switch(device->FmtType)
    {
        case DevFmtByte:
        case DevFmtUShort:
        case DevFmtUInt:
            WARN("%s capture samples not supported\n", DevFmtTypeString(device->FmtType));
            return ALC_INVALID_ENUM;

        case DevFmtUByte:
        case DevFmtShort:
        case DevFmtInt:
        case DevFmtFloat:
            break;
    }

    //Initialise requested device
    data = calloc(1, sizeof(DSoundCaptureData));
    if(!data)
        return ALC_OUT_OF_MEMORY;

    hr = DS_OK;

    //DirectSoundCapture Init code
    if(SUCCEEDED(hr))
        hr = DirectSoundCaptureCreate(guid, &data->DSC, NULL);
    if(SUCCEEDED(hr))
    {
        memset(&InputType, 0, sizeof(InputType));

        switch(device->FmtChans)
        {
            case DevFmtMono:
                InputType.dwChannelMask = SPEAKER_FRONT_CENTER;
                break;
            case DevFmtStereo:
                InputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                          SPEAKER_FRONT_RIGHT;
                break;
            case DevFmtQuad:
                InputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                          SPEAKER_FRONT_RIGHT |
                                          SPEAKER_BACK_LEFT |
                                          SPEAKER_BACK_RIGHT;
                break;
            case DevFmtX51:
                InputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                          SPEAKER_FRONT_RIGHT |
                                          SPEAKER_FRONT_CENTER |
                                          SPEAKER_LOW_FREQUENCY |
                                          SPEAKER_BACK_LEFT |
                                          SPEAKER_BACK_RIGHT;
                break;
            case DevFmtX51Side:
                InputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                          SPEAKER_FRONT_RIGHT |
                                          SPEAKER_FRONT_CENTER |
                                          SPEAKER_LOW_FREQUENCY |
                                          SPEAKER_SIDE_LEFT |
                                          SPEAKER_SIDE_RIGHT;
                break;
            case DevFmtX61:
                InputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                          SPEAKER_FRONT_RIGHT |
                                          SPEAKER_FRONT_CENTER |
                                          SPEAKER_LOW_FREQUENCY |
                                          SPEAKER_BACK_CENTER |
                                          SPEAKER_SIDE_LEFT |
                                          SPEAKER_SIDE_RIGHT;
                break;
            case DevFmtX71:
                InputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                          SPEAKER_FRONT_RIGHT |
                                          SPEAKER_FRONT_CENTER |
                                          SPEAKER_LOW_FREQUENCY |
                                          SPEAKER_BACK_LEFT |
                                          SPEAKER_BACK_RIGHT |
                                          SPEAKER_SIDE_LEFT |
                                          SPEAKER_SIDE_RIGHT;
                break;
        }

        InputType.Format.wFormatTag = WAVE_FORMAT_PCM;
        InputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans);
        InputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8;
        InputType.Format.nBlockAlign = InputType.Format.nChannels*InputType.Format.wBitsPerSample/8;
        InputType.Format.nSamplesPerSec = device->Frequency;
        InputType.Format.nAvgBytesPerSec = InputType.Format.nSamplesPerSec*InputType.Format.nBlockAlign;
        InputType.Format.cbSize = 0;

        if(InputType.Format.nChannels > 2 || device->FmtType == DevFmtFloat)
        {
            InputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
            InputType.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
            InputType.Samples.wValidBitsPerSample = InputType.Format.wBitsPerSample;
            if(device->FmtType == DevFmtFloat)
                InputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
            else
                InputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
        }

        samples = device->UpdateSize * device->NumUpdates;
        samples = maxu(samples, 100 * device->Frequency / 1000);

        memset(&DSCBDescription, 0, sizeof(DSCBUFFERDESC));
        DSCBDescription.dwSize = sizeof(DSCBUFFERDESC);
        DSCBDescription.dwFlags = 0;
        DSCBDescription.dwBufferBytes = samples * InputType.Format.nBlockAlign;
        DSCBDescription.lpwfxFormat = &InputType.Format;

        hr = IDirectSoundCapture_CreateCaptureBuffer(data->DSC, &DSCBDescription, &data->DSCbuffer, NULL);
    }
    if(SUCCEEDED(hr))
    {
         data->Ring = CreateRingBuffer(InputType.Format.nBlockAlign, device->UpdateSize * device->NumUpdates);
         if(data->Ring == NULL)
             hr = DSERR_OUTOFMEMORY;
    }

    if(FAILED(hr))
    {
        ERR("Device init failed: 0x%08lx\n", hr);

        DestroyRingBuffer(data->Ring);
        data->Ring = NULL;
        if(data->DSCbuffer != NULL)
            IDirectSoundCaptureBuffer_Release(data->DSCbuffer);
        data->DSCbuffer = NULL;
        if(data->DSC)
            IDirectSoundCapture_Release(data->DSC);
        data->DSC = NULL;

        free(data);
        return ALC_INVALID_VALUE;
    }

    data->BufferBytes = DSCBDescription.dwBufferBytes;
    SetDefaultWFXChannelOrder(device);

    device->DeviceName = strdup(deviceName);
    device->ExtraData = data;

    return ALC_NO_ERROR;
}
Esempio n. 8
0
static void test_COM(void)
{
    IDirectSoundCapture *dsc = (IDirectSoundCapture*)0xdeadbeef;
    IDirectSoundCaptureBuffer *buffer = (IDirectSoundCaptureBuffer*)0xdeadbeef;
    IDirectSoundNotify *notify;
    DSCBUFFERDESC bufdesc;
    WAVEFORMATEX wfx;
    HRESULT hr;
    ULONG refcount;

    hr = pDirectSoundCaptureCreate(NULL, &dsc, (IUnknown*)0xdeadbeef);
    ok(hr == DSERR_NOAGGREGATION,
       "DirectSoundCaptureCreate failed: %08x, expected DSERR_NOAGGREGATION\n", hr);
    ok(dsc == (IDirectSoundCapture*)0xdeadbeef, "dsc = %p\n", dsc);

    hr = pDirectSoundCaptureCreate(NULL, &dsc, NULL);
    if (hr == DSERR_NODRIVER) {
        skip("No driver\n");
        return;
    }
    ok(hr == DS_OK, "DirectSoundCaptureCreate failed: %08x, expected DS_OK\n", hr);

    init_format(&wfx, WAVE_FORMAT_PCM, 44100, 16, 1);
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize = sizeof(bufdesc);
    bufdesc.dwBufferBytes = wfx.nAvgBytesPerSec;
    bufdesc.lpwfxFormat = &wfx;

    hr = IDirectSoundCapture_CreateCaptureBuffer(dsc, &bufdesc, &buffer, (IUnknown*)0xdeadbeef);
    if (hr == E_INVALIDARG) {
        /* Old DirectX has only the 1st version of the DSCBUFFERDESC struct */
        bufdesc.dwSize = sizeof(DSCBUFFERDESC1);
        hr = IDirectSoundCapture_CreateCaptureBuffer(dsc, &bufdesc, &buffer, (IUnknown*)0xdeadbeef);
    }
    ok(hr == DSERR_NOAGGREGATION,
       "IDirectSoundCapture_CreateCaptureBuffer failed: %08x, expected DSERR_NOAGGREGATION\n", hr);
    ok(buffer == (IDirectSoundCaptureBuffer*)0xdeadbeef || !buffer /* Win2k without DirectX9 */,
       "buffer = %p\n", buffer);

    hr = IDirectSoundCapture_CreateCaptureBuffer(dsc, &bufdesc, &buffer, NULL);
    ok(hr == DS_OK, "IDirectSoundCapture_CreateCaptureBuffer failed: %08x, expected DS_OK\n", hr);

    /* IDirectSoundCaptureBuffer and IDirectSoundNotify have separate refcounts */
    IDirectSoundCaptureBuffer_AddRef(buffer);
    refcount = IDirectSoundCaptureBuffer_AddRef(buffer);
    ok(refcount == 3, "IDirectSoundCaptureBuffer refcount is %u, expected 3\n", refcount);
    hr = IDirectSoundCaptureBuffer_QueryInterface(buffer, &IID_IDirectSoundNotify, (void**)&notify);
    ok(hr == DS_OK, "IDirectSoundCapture_QueryInterface failed: %08x, expected DS_OK\n", hr);
    refcount = IDirectSoundNotify_AddRef(notify);
    ok(refcount == 2, "IDirectSoundNotify refcount is %u, expected 2\n", refcount);
    IDirectSoundCaptureBuffer_AddRef(buffer);
    refcount = IDirectSoundCaptureBuffer_Release(buffer);
    ok(refcount == 3, "IDirectSoundCaptureBuffer refcount is %u, expected 3\n", refcount);

    /* Release IDirectSoundCaptureBuffer while keeping IDirectSoundNotify alive */
    while (IDirectSoundCaptureBuffer_Release(buffer) > 0);
    refcount = IDirectSoundNotify_AddRef(notify);
    ok(refcount == 3, "IDirectSoundNotify refcount is %u, expected 3\n", refcount);
    refcount = IDirectSoundCaptureBuffer_AddRef(buffer);
    ok(refcount == 1, "IDirectSoundCaptureBuffer refcount is %u, expected 1\n", refcount);

    while (IDirectSoundNotify_Release(notify) > 0);
    refcount = IDirectSoundCaptureBuffer_Release(buffer);
    ok(refcount == 0, "IDirectSoundCaptureBuffer refcount is %u, expected 0\n", refcount);
    refcount = IDirectSoundCapture_Release(dsc);
    ok(refcount == 0, "IDirectSoundCapture refcount is %u, expected 0\n", refcount);
}
Esempio n. 9
0
static BOOL WINAPI dscenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
				    LPCSTR lpcstrModule, LPVOID lpContext)
{
    HRESULT rc;
    LPDIRECTSOUNDCAPTURE dsco=NULL;
    LPDIRECTSOUNDCAPTUREBUFFER dscbo=NULL;
    DSCBUFFERDESC bufdesc;
    WAVEFORMATEX wfx;
    DSCCAPS dsccaps;
    DWORD f;
    int ref;

    /* Private dsound.dll: Error: Invalid interface buffer */
    trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
    rc=pDirectSoundCaptureCreate(lpGuid,NULL,NULL);
    ok(rc==DSERR_INVALIDPARAM,"DirectSoundCaptureCreate() should have "
       "returned DSERR_INVALIDPARAM, returned: %08x\n",rc);

    rc=pDirectSoundCaptureCreate(lpGuid,&dsco,NULL);
    ok((rc==DS_OK)||(rc==DSERR_NODRIVER)||(rc==E_FAIL)||(rc==DSERR_ALLOCATED),
       "DirectSoundCaptureCreate() failed: %08x\n",rc);
    if (rc!=DS_OK) {
        if (rc==DSERR_NODRIVER)
            trace("  No Driver\n");
        else if (rc==E_FAIL)
            trace("  No Device\n");
        else if (rc==DSERR_ALLOCATED)
            trace("  Already In Use\n");
	goto EXIT;
    }

    /* Private dsound.dll: Error: Invalid caps buffer */
    rc=IDirectSoundCapture_GetCaps(dsco,NULL);
    ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
       "returned DSERR_INVALIDPARAM, returned: %08x\n",rc);

    /* Private dsound.dll: Error: Invalid caps buffer */
    dsccaps.dwSize=0;
    rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
    ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_GetCaps() should have "
       "returned DSERR_INVALIDPARAM, returned: %08x\n",rc);

    dsccaps.dwSize=sizeof(dsccaps);
    rc=IDirectSoundCapture_GetCaps(dsco,&dsccaps);
    ok(rc==DS_OK,"IDirectSoundCapture_GetCaps() failed: %08x\n", rc);
    if (rc==DS_OK && winetest_debug > 1) {
	trace("  Caps: size=%d flags=0x%08x formats=%05x channels=%d\n",
	      dsccaps.dwSize,dsccaps.dwFlags,dsccaps.dwFormats,
              dsccaps.dwChannels);
    }

    /* Private dsound.dll: Error: Invalid size */
    /* Private dsound.dll: Error: Invalid capture buffer description */
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=0;
    bufdesc.dwFlags=0;
    bufdesc.dwBufferBytes=0;
    bufdesc.dwReserved=0;
    bufdesc.lpwfxFormat=NULL;
    rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
    ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
       "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
    if (rc==DS_OK) {
	ref=IDirectSoundCaptureBuffer_Release(dscbo);
	ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
           "should have 0\n",ref);
    }

    /* Private dsound.dll: Error: Invalid buffer size */
    /* Private dsound.dll: Error: Invalid capture buffer description */
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=0;
    bufdesc.dwBufferBytes=0;
    bufdesc.dwReserved=0;
    bufdesc.lpwfxFormat=NULL;
    rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
    ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
       "should have returned DSERR_INVALIDPARAM, returned %08x\n", rc);
    if (rc==DS_OK) {
	ref=IDirectSoundCaptureBuffer_Release(dscbo);
	ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
           "should have 0\n",ref);
    }

    /* Private dsound.dll: Error: Invalid buffer size */
    /* Private dsound.dll: Error: Invalid capture buffer description */
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    ZeroMemory(&wfx, sizeof(wfx));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=0;
    bufdesc.dwBufferBytes=0;
    bufdesc.dwReserved=0;
    bufdesc.lpwfxFormat=&wfx;
    rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
    ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
       "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
    if (rc==DS_OK) {
	ref=IDirectSoundCaptureBuffer_Release(dscbo);
	ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
           "should have 0\n",ref);
    }

    /* Private dsound.dll: Error: Invalid buffer size */
    /* Private dsound.dll: Error: Invalid capture buffer description */
    init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1);
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=0;
    bufdesc.dwBufferBytes=0;
    bufdesc.dwReserved=0;
    bufdesc.lpwfxFormat=&wfx;
    rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
    ok(rc==DSERR_INVALIDPARAM,"IDirectSoundCapture_CreateCaptureBuffer() "
       "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
    if (rc==DS_OK) {
	ref=IDirectSoundCaptureBuffer_Release(dscbo);
	ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
           "should have 0\n",ref);
    }

    for (f=0;f<NB_FORMATS;f++) {
	dscbo=NULL;
	init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
                    formats[f][2]);
	ZeroMemory(&bufdesc, sizeof(bufdesc));
	bufdesc.dwSize=sizeof(bufdesc);
	bufdesc.dwFlags=0;
	bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
	bufdesc.dwReserved=0;
	bufdesc.lpwfxFormat=&wfx;
        if (winetest_interactive)
	    trace("  Testing the capture buffer at %s\n", format_string(&wfx));
	rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
	ok(((rc==DS_OK)&&(dscbo!=NULL))
           || rc==DSERR_BADFORMAT || rc==DSERR_INVALIDCALL || rc==DSERR_NODRIVER
           || rc==DSERR_ALLOCATED || rc==E_INVALIDARG || rc==E_FAIL,
           "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
           "%s capture buffer: %08x\n",format_string(&wfx),rc);
	if (rc==DS_OK) {
	    test_capture_buffer(dsco, dscbo, winetest_interactive);
	    ref=IDirectSoundCaptureBuffer_Release(dscbo);
	    ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
               "should have 0\n",ref);
	} else if (rc==DSERR_BADFORMAT) {
            ok(!(dsccaps.dwFormats & formats[f][3]),
               "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
               "capture buffer: format listed as supported but using it failed\n");
            if (!(dsccaps.dwFormats & formats[f][3]))
                trace("  Format not supported: %s\n", format_string(&wfx));
        } else if (rc==DSERR_NODRIVER) {
            trace("  No Driver\n");
        } else if (rc==DSERR_ALLOCATED) {
            trace("  Already In Use\n");
        } else if (rc==E_INVALIDARG) { /* try the old version struct */
            DSCBUFFERDESC1 bufdesc1;
	    ZeroMemory(&bufdesc1, sizeof(bufdesc1));
	    bufdesc1.dwSize=sizeof(bufdesc1);
	    bufdesc1.dwFlags=0;
	    bufdesc1.dwBufferBytes=wfx.nAvgBytesPerSec;
	    bufdesc1.dwReserved=0;
	    bufdesc1.lpwfxFormat=&wfx;
	    rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,
                (DSCBUFFERDESC*)&bufdesc1,&dscbo,NULL);
            ok(rc==DS_OK || broken(rc==DSERR_INVALIDPARAM),
               "IDirectSoundCapture_CreateCaptureBuffer() failed to create a "
               "%s capture buffer: %08x\n",format_string(&wfx), rc);
            if (rc==DSERR_INVALIDPARAM) {
                skip("broken driver\n");
                goto EXIT;
            }
            if (rc==DS_OK) {
	        test_capture_buffer(dsco, dscbo, winetest_interactive);
	        ref=IDirectSoundCaptureBuffer_Release(dscbo);
	        ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d "
                   "references, should have 0\n",ref);
            }
        } else if (rc==E_FAIL) {
            /* WAVE_FORMAT_PCM only allows 8 and 16 bits per sample, so only
             * report a failure if the bits per sample is 8 or 16
             */
            if (wfx.wBitsPerSample == 8 || wfx.wBitsPerSample == 16)
                ok(FALSE,"Should not fail for 8 or 16 bits per sample\n");
        }
    }

    /* try a non PCM format */
    if (0)
    {
    /* FIXME: Why is this commented out? */
    init_format(&wfx,WAVE_FORMAT_MULAW,8000,8,1);
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
    bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
    bufdesc.dwReserved=0;
    bufdesc.lpwfxFormat=&wfx;
    if (winetest_interactive)
        trace("  Testing the capture buffer at %s\n", format_string(&wfx));
    rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
    ok((rc==DS_OK)&&(dscbo!=NULL),"IDirectSoundCapture_CreateCaptureBuffer() "
       "failed to create a capture buffer: %08x\n",rc);
    if ((rc==DS_OK)&&(dscbo!=NULL)) {
	test_capture_buffer(dsco, dscbo, winetest_interactive);
	ref=IDirectSoundCaptureBuffer_Release(dscbo);
	ok(ref==0,"IDirectSoundCaptureBuffer_Release() has %d references, "
           "should have 0\n",ref);
    }
    }

    /* Try an invalid format to test error handling */
    if (0)
    {
    /* FIXME: Remove this test altogether? */
    init_format(&wfx,WAVE_FORMAT_PCM,2000000,16,2);
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=DSCBCAPS_WAVEMAPPED;
    bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
    bufdesc.dwReserved=0;
    bufdesc.lpwfxFormat=&wfx;
    if (winetest_interactive)
        trace("  Testing the capture buffer at %s\n", format_string(&wfx));
    rc=IDirectSoundCapture_CreateCaptureBuffer(dsco,&bufdesc,&dscbo,NULL);
    ok(rc!=DS_OK,"IDirectSoundCapture_CreateCaptureBuffer() should have failed "
       "at 2 MHz %08x\n",rc);
    }

EXIT:
    if (dsco!=NULL) {
	ref=IDirectSoundCapture_Release(dsco);
	ok(ref==0,"IDirectSoundCapture_Release() has %d references, should "
           "have 0\n",ref);
    }

    return TRUE;
}
Esempio n. 10
0
static HRESULT WINAPI
IDirectSoundFullDuplexImpl_Initialize(
    LPDIRECTSOUNDFULLDUPLEX iface,
    LPCGUID pCaptureGuid,
    LPCGUID pRendererGuid,
    LPCDSCBUFFERDESC lpDscBufferDesc,
    LPCDSBUFFERDESC lpDsBufferDesc,
    HWND hWnd,
    DWORD dwLevel,
    LPLPDIRECTSOUNDCAPTUREBUFFER8 lplpDirectSoundCaptureBuffer8,
    LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer8 )
{
    HRESULT hr;
    IDirectSoundFullDuplexImpl *This = (IDirectSoundFullDuplexImpl *)iface;

    TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This,
        debugstr_guid(pCaptureGuid), debugstr_guid(pRendererGuid),
        lpDscBufferDesc, lpDsBufferDesc, hWnd, dwLevel,
        lplpDirectSoundCaptureBuffer8, lplpDirectSoundBuffer8);

    if (This->renderer_device != NULL || This->capture_device != NULL) {
        WARN("already initialized\n");
        *lplpDirectSoundCaptureBuffer8 = NULL;
        *lplpDirectSoundBuffer8 = NULL;
        return DSERR_ALREADYINITIALIZED;
    }

    hr = DSOUND_Create8(&IID_IDirectSound8, &This->renderer_device);
    if (SUCCEEDED(hr))
        hr = IDirectSound_Initialize(This->renderer_device, pRendererGuid);
    if (hr != DS_OK) {
        WARN("DirectSoundDevice_Initialize() failed\n");
        *lplpDirectSoundCaptureBuffer8 = NULL;
        *lplpDirectSoundBuffer8 = NULL;
        return hr;
    }

    IDirectSound8_SetCooperativeLevel(This->renderer_device, hWnd, dwLevel);

    hr = IDirectSound8_CreateSoundBuffer(This->renderer_device, lpDsBufferDesc,
        (IDirectSoundBuffer**)lplpDirectSoundBuffer8, NULL);
    if (hr != DS_OK) {
        WARN("IDirectSoundBufferImpl_Create() failed\n");
        *lplpDirectSoundCaptureBuffer8 = NULL;
        *lplpDirectSoundBuffer8 = NULL;
        return hr;
    }

    hr = DSOUND_CaptureCreate8(&IID_IDirectSoundCapture8, &This->capture_device);
    if (SUCCEEDED(hr))
        hr = IDirectSoundCapture_Initialize(This->capture_device, pCaptureGuid);
    if (hr != DS_OK) {
        WARN("DirectSoundCaptureDevice_Initialize() failed\n");
        *lplpDirectSoundCaptureBuffer8 = NULL;
        *lplpDirectSoundBuffer8 = NULL;
        return hr;
    }

    hr = IDirectSoundCapture_CreateCaptureBuffer(This->capture_device,
        lpDscBufferDesc,
        (IDirectSoundCaptureBuffer**)lplpDirectSoundCaptureBuffer8,
        NULL);
    if (hr != DS_OK) {
        WARN("IDirectSoundCaptureBufferImpl_Create() failed\n");
        *lplpDirectSoundCaptureBuffer8 = NULL;
        *lplpDirectSoundBuffer8 = NULL;
        return hr;
    }

    return hr;
}
Esempio n. 11
0
// ////////////////////////////////////////////////////////////////////////
BOOL NETinitAudioCapture(VOID)
{
	HRESULT				hr;
	WAVEFORMATEX        wfx;

	NetPlay.bAllowCaptureRecord = FALSE;

	hr = DirectSoundCaptureCreate(	NULL,&lpDirectSoundCapture,	NULL);
	if(hr != DS_OK)
	{
		DBPRINTF(("NETPLAY:Failed to create capture interface."));
		if(hr == DSERR_NOAGGREGATION)
		{
			DBPRINTF(("DSERR_NOAGGREGATION"));
		}
		if(hr == DSERR_OUTOFMEMORY)
		{
			DBPRINTF(("DSERR_OUTOFMEMORY"));
		}
		if(hr == DSERR_INVALIDPARAM)
		{
			DBPRINTF(("DSERR_INVALIDPARAM"));
		}
		return FALSE;
	}
	
	ZeroMemory(&captureBuff, sizeof(captureBuff));
	lpDirectSoundCaptureBuffer = NULL;
 
	wfx.wFormatTag			= WAVE_FORMAT_PCM; 	//set audio format
	wfx.nChannels			= AUDIOCHANNELS;
	wfx.nSamplesPerSec		= SAMPLERATE;			
	wfx.nAvgBytesPerSec		= SAMPLERATE * (BITSPERSAMPLE /8) * AUDIOCHANNELS  ;	
	wfx.nBlockAlign			= (AUDIOCHANNELS * BITSPERSAMPLE) / 8 ; 
	wfx.wBitsPerSample		= BITSPERSAMPLE;	
	wfx.cbSize				= 0;	

	captureBuff.dwSize		= sizeof(DSCBUFFERDESC);
	captureBuff.dwFlags		= DSCBCAPS_WAVEMAPPED;
	captureBuff.dwBufferBytes= SAMPLETIME * wfx.nAvgBytesPerSec;		// SAMPLETIME second’s worth of audio
	captureBuff.lpwfxFormat =  &wfx;
 
	hr = IDirectSoundCapture_CreateCaptureBuffer(lpDirectSoundCapture,
												&captureBuff,
												&lpDirectSoundCaptureBuffer,
												NULL);	
	if(hr != DS_OK)
	{
		if( hr == DSERR_INVALIDPARAM)
		{DBPRINTF(("NETPLAY:no capturebuffer,inv param"));
		}
		if( hr == DSERR_BADFORMAT)
		{DBPRINTF(("NETPLAY:no capturebuffer,badformat"));
		}
		if( hr == DSERR_GENERIC)
		{DBPRINTF(("NETPLAY:no capturebuffer,generic"));
		}
		if( hr == DSERR_NODRIVER)
		{DBPRINTF(("NETPLAY:no capturebuffer,nodriver"));
		}
		if( hr == DSERR_OUTOFMEMORY)
		{DBPRINTF(("NETPLAY:no capturebuffer,memory"));	
		}
		if( hr == DSERR_UNINITIALIZED)
		{DBPRINTF(("NETPLAY:no capturebuffer,uninit"));
		}
		return FALSE;
	}

	NetPlay.bAllowCaptureRecord = TRUE;
//	allowCapture = TRUE;
	return(TRUE);
}
Esempio n. 12
0
File: duplex.c Progetto: Jactry/wine
static HRESULT WINAPI IDirectSoundFullDuplexImpl_Initialize(IDirectSoundFullDuplex *iface,
        const GUID *capture_dev, const GUID *render_dev, const DSCBUFFERDESC *cbufdesc,
        const DSBUFFERDESC *bufdesc, HWND hwnd, DWORD level, IDirectSoundCaptureBuffer8 **dscb8,
        IDirectSoundBuffer8 **dsb8)
{
    IDirectSoundFullDuplexImpl *This = impl_from_IDirectSoundFullDuplex(iface);
    IDirectSound8 *ds8 = NULL;
    IDirectSoundCapture8 *dsc8 = NULL;
    HRESULT hr;

    TRACE("(%p,%s,%s,%p,%p,%p,%x,%p,%p)\n", This, debugstr_guid(capture_dev),
            debugstr_guid(render_dev), cbufdesc, bufdesc, hwnd, level, dscb8, dsb8);

    if (!dscb8 || !dsb8)
        return E_INVALIDARG;

    *dscb8 = NULL;
    *dsb8 = NULL;

    if (This->ds8_unk || This->dsc8_unk) {
        WARN("already initialized\n");
        return DSERR_ALREADYINITIALIZED;
    }

    hr = IDirectSoundImpl_Create(&This->IUnknown_iface, &IID_IUnknown, (void**)&This->ds8_unk,
            TRUE);
    if (SUCCEEDED(hr)) {
        IUnknown_QueryInterface(This->ds8_unk, &IID_IDirectSound8, (void**)&ds8);
        hr = IDirectSound8_Initialize(ds8, render_dev);
    }
    if (hr != DS_OK) {
        WARN("Creating/initializing IDirectSound8 failed\n");
        goto error;
    }

    IDirectSound8_SetCooperativeLevel(ds8, hwnd, level);

    hr = IDirectSound8_CreateSoundBuffer(ds8, bufdesc, (IDirectSoundBuffer**)dsb8, NULL);
    if (hr != DS_OK) {
        WARN("IDirectSoundBuffer_Create() failed\n");
        goto error;
    }

    hr = IDirectSoundCaptureImpl_Create(&This->IUnknown_iface, &IID_IUnknown,
            (void**)&This->dsc8_unk, TRUE);
    if (SUCCEEDED(hr)) {
        IUnknown_QueryInterface(This->dsc8_unk, &IID_IDirectSoundCapture8, (void**)&dsc8);
        hr = IDirectSoundCapture_Initialize(dsc8, capture_dev);
    }
    if (hr != DS_OK) {
        WARN("Creating/initializing IDirectSoundCapture8 failed\n");
        goto error;
    }

    hr = IDirectSoundCapture_CreateCaptureBuffer(dsc8, cbufdesc,
            (IDirectSoundCaptureBuffer**)dscb8, NULL);
    if (hr != DS_OK) {
        WARN("IDirectSoundCapture_CreateCaptureBuffer() failed\n");
        goto error;
    }

    IDirectSound8_Release(ds8);
    IDirectSoundCapture_Release(dsc8);
    return DS_OK;

error:
    if (*dsb8) {
        IDirectSoundBuffer8_Release(*dsb8);
        *dsb8 = NULL;
    }
    if (ds8)
        IDirectSound8_Release(ds8);
    if (This->ds8_unk) {
        IUnknown_Release(This->ds8_unk);
        This->ds8_unk = NULL;
    }
    if (*dscb8) {
        IDirectSoundCaptureBuffer8_Release(*dscb8);
        *dscb8 = NULL;
    }
    if (dsc8)
        IDirectSoundCapture_Release(dsc8);
    if (This->dsc8_unk) {
        IUnknown_Release(This->dsc8_unk);
        This->dsc8_unk = NULL;
    }
    return hr;
}
Esempio n. 13
0
static gboolean
gst_directsound_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
{
  GstDirectSoundSrc *dsoundsrc;
  WAVEFORMATEX wfx;             /* Wave format structure */
  HRESULT hRes;                 /* Result for windows functions */
  DSCBUFFERDESC descSecondary;  /* Capturebuffer description */

  dsoundsrc = GST_DIRECTSOUND_SRC (asrc);

  GST_DEBUG_OBJECT (asrc, "preparing directsoundsrc");

  /* Define buffer */
  memset (&wfx, 0, sizeof (WAVEFORMATEX));
  wfx.wFormatTag = WAVE_FORMAT_PCM;
  wfx.nChannels = GST_AUDIO_INFO_CHANNELS (&spec->info);
  wfx.nSamplesPerSec = GST_AUDIO_INFO_RATE (&spec->info);
  wfx.wBitsPerSample = GST_AUDIO_INFO_BPF (&spec->info) * 8 / wfx.nChannels;
  wfx.nBlockAlign = GST_AUDIO_INFO_BPF (&spec->info);
  wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
  /* Ignored for WAVE_FORMAT_PCM. */
  wfx.cbSize = 0;

  if (wfx.wBitsPerSample != 16 && wfx.wBitsPerSample != 8)
    goto dodgy_width;

  GST_INFO_OBJECT (asrc, "latency time: %" G_GUINT64_FORMAT " - buffer time: %"
      G_GUINT64_FORMAT, spec->latency_time, spec->buffer_time);

  /* Buffer-time should always be >= 2*latency */
  if (spec->buffer_time < spec->latency_time * 2) {
    spec->buffer_time = spec->latency_time * 2;
    GST_WARNING ("buffer-time was less than 2*latency-time, clamping");
  }

  /* Set the buffer size from our configured buffer time (in microsecs) */
  dsoundsrc->buffer_size =
      gst_util_uint64_scale_int (spec->buffer_time, wfx.nAvgBytesPerSec,
      GST_SECOND / GST_USECOND);

  GST_INFO_OBJECT (asrc, "Buffer size: %d", dsoundsrc->buffer_size);

  spec->segsize =
      gst_util_uint64_scale (spec->latency_time, wfx.nAvgBytesPerSec,
      GST_SECOND / GST_USECOND);

  /* Sanitized segsize */
  if (spec->segsize < GST_AUDIO_INFO_BPF (&spec->info))
    spec->segsize = GST_AUDIO_INFO_BPF (&spec->info);
  else if (spec->segsize % GST_AUDIO_INFO_BPF (&spec->info) != 0)
    spec->segsize =
        ((spec->segsize + GST_AUDIO_INFO_BPF (&spec->info) -
            1) / GST_AUDIO_INFO_BPF (&spec->info)) *
        GST_AUDIO_INFO_BPF (&spec->info);
  spec->segtotal = dsoundsrc->buffer_size / spec->segsize;
  /* The device usually takes time = 1-2 segments to start producing buffers */
  spec->seglatency = spec->segtotal + 2;

  /* Fetch and set the actual latency time that will be used */
  dsoundsrc->latency_time =
      gst_util_uint64_scale (spec->segsize, GST_SECOND / GST_USECOND,
      GST_AUDIO_INFO_BPF (&spec->info) * GST_AUDIO_INFO_RATE (&spec->info));

  GST_INFO_OBJECT (asrc, "actual latency time: %" G_GUINT64_FORMAT,
      spec->latency_time);

  /* Init secondary buffer desciption */
  memset (&descSecondary, 0, sizeof (DSCBUFFERDESC));
  descSecondary.dwSize = sizeof (DSCBUFFERDESC);
  descSecondary.dwFlags = 0;
  descSecondary.dwReserved = 0;

  /* This is not primary buffer so have to set size  */
  descSecondary.dwBufferBytes = dsoundsrc->buffer_size;
  descSecondary.lpwfxFormat = &wfx;

  /* Create buffer */
  hRes = IDirectSoundCapture_CreateCaptureBuffer (dsoundsrc->pDSC,
      &descSecondary, &dsoundsrc->pDSBSecondary, NULL);
  if (hRes != DS_OK)
    goto capture_buffer;

  dsoundsrc->bytes_per_sample = GST_AUDIO_INFO_BPF (&spec->info);

  GST_INFO_OBJECT (asrc,
      "bytes/sec: %lu, buffer size: %d, segsize: %d, segtotal: %d",
      wfx.nAvgBytesPerSec, dsoundsrc->buffer_size, spec->segsize,
      spec->segtotal);

  /* Not read anything yet */
  dsoundsrc->current_circular_offset = 0;

  GST_INFO_OBJECT (asrc, "channels: %d, rate: %d, bytes_per_sample: %d"
      " WAVEFORMATEX.nSamplesPerSec: %ld, WAVEFORMATEX.wBitsPerSample: %d,"
      " WAVEFORMATEX.nBlockAlign: %d, WAVEFORMATEX.nAvgBytesPerSec: %ld",
      GST_AUDIO_INFO_CHANNELS (&spec->info), GST_AUDIO_INFO_RATE (&spec->info),
      GST_AUDIO_INFO_BPF (&spec->info), wfx.nSamplesPerSec, wfx.wBitsPerSample,
      wfx.nBlockAlign, wfx.nAvgBytesPerSec);

  return TRUE;

capture_buffer:
  {
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unable to create capturebuffer"), (NULL));
    return FALSE;
  }
dodgy_width:
  {
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unexpected width %d", wfx.wBitsPerSample), (NULL));
    return FALSE;
  }
}
Esempio n. 14
0
/*
 * Initialize DirectSound recorder device
 */
static pj_status_t init_capture_stream( struct dsound_stream *ds_strm,
				        int dev_id,
				        unsigned clock_rate,
				        unsigned channel_count,
				        unsigned samples_per_frame,
				        unsigned buffer_count)
{
    HRESULT hr;
    PCMWAVEFORMAT pcmwf; 
    DSCBUFFERDESC dscbdesc;
    DSBPOSITIONNOTIFY dsPosNotify[MAX_PACKET_BUFFER_COUNT];
    unsigned bytes_per_frame;
    unsigned i;


    PJ_ASSERT_RETURN(buffer_count <= MAX_PACKET_BUFFER_COUNT, PJ_EINVAL);


    /* Check device id */
    if (dev_id == -1)
	dev_id = 0;

    PJ_ASSERT_RETURN(dev_id>=0 && dev_id < (int)dev_count, PJ_EINVAL);

    /*
     * Creating recorder device.
     */
    hr = DirectSoundCaptureCreate(dev_info[dev_id].lpGuid, 
				  &ds_strm->ds.capture.lpDs, NULL);
    if (FAILED(hr))
	return PJ_RETURN_OS_ERROR(hr);


    /* Init wave format to initialize buffer */
    init_waveformatex( &pcmwf, clock_rate, channel_count);
    bytes_per_frame = samples_per_frame * BYTES_PER_SAMPLE;

    /* 
     * Setup capture buffer using sound buffer structure that was passed
     * to play buffer creation earlier.
     */
    pj_bzero(&dscbdesc, sizeof(DSCBUFFERDESC));
    dscbdesc.dwSize = sizeof(DSCBUFFERDESC); 
    dscbdesc.dwFlags = DSCBCAPS_WAVEMAPPED ;
    dscbdesc.dwBufferBytes = buffer_count * bytes_per_frame; 
    dscbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf; 

    hr = IDirectSoundCapture_CreateCaptureBuffer( ds_strm->ds.capture.lpDs,
						  &dscbdesc, 
						  &ds_strm->ds.capture.lpDsBuffer,
						  NULL);
    if (FAILED(hr))
	return PJ_RETURN_OS_ERROR(hr);

    /*
     * Create event for play notification.
     */
    ds_strm->hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
    if (ds_strm->hEvent == NULL)
	return pj_get_os_error();

    /*
     * Setup notifications for recording.
     */
    hr = IDirectSoundCaptureBuffer_QueryInterface( ds_strm->ds.capture.lpDsBuffer, 
						   &IID_IDirectSoundNotify, 
						   (LPVOID *)&ds_strm->lpDsNotify); 
    if (FAILED(hr))
	return PJ_RETURN_OS_ERROR(hr);

    
    for (i=0; i<buffer_count; ++i) {
	dsPosNotify[i].dwOffset = i * bytes_per_frame;
	dsPosNotify[i].hEventNotify = ds_strm->hEvent;
    }
    
    hr = IDirectSoundNotify_SetNotificationPositions( ds_strm->lpDsNotify, 
						      buffer_count, 
						      dsPosNotify);
    if (FAILED(hr))
	return PJ_RETURN_OS_ERROR(hr);

    hr = IDirectSoundCaptureBuffer_GetCurrentPosition( ds_strm->ds.capture.lpDsBuffer, 
						       NULL, &ds_strm->dwBytePos );
    if (FAILED(hr))
	return PJ_RETURN_OS_ERROR(hr);

    ds_strm->timestamp.u64 = 0;
    ds_strm->dwDsBufferSize = buffer_count * bytes_per_frame;
    /*
     * Capture latency must always be on a frame boundry,
     * so compute it based off the calculated buffer_count.
     */
    ds_strm->latency = buffer_count * samples_per_frame * 1000 / clock_rate / 
		       channel_count;

    /* Done setting up recorder device. */
    PJ_LOG(5,(THIS_FILE, 
	      " DirectSound capture \"%s\" initialized (clock_rate=%d, "
	      "channel_count=%d, samples_per_frame=%d (%dms))",
	      dev_info[dev_id].info.name,
	      clock_rate, channel_count, samples_per_frame,
	      samples_per_frame * 1000 / clock_rate));

    return PJ_SUCCESS;
}