Example #1
0
static HRESULT test_block_align(LPGUID lpGuid)
{
    HRESULT rc;
    LPDIRECTSOUND dso=NULL;
    LPDIRECTSOUNDBUFFER secondary=NULL;
    DSBUFFERDESC bufdesc;
    DSBCAPS dsbcaps;
    WAVEFORMATEX wfx;
    DWORD pos, pos2;
    int ref;

    /* Create the DirectSound object */
    rc=pDirectSoundCreate(lpGuid,&dso,NULL);
    ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
       "DirectSoundCreate() failed: %08x\n",rc);
    if (rc!=DS_OK)
        return rc;

    init_format(&wfx,WAVE_FORMAT_PCM,11025,16,2);
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
    bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec + 1;
    bufdesc.lpwfxFormat=&wfx;
    rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
    ok(rc==DS_OK,"IDirectSound_CreateSoundBuffer() "
       "should have returned DS_OK, returned: %08x\n", rc);

    if (rc==DS_OK && secondary!=NULL) {
        ZeroMemory(&dsbcaps, sizeof(dsbcaps));
        dsbcaps.dwSize = sizeof(dsbcaps);
        rc=IDirectSoundBuffer_GetCaps(secondary,&dsbcaps);
        ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() should have returned DS_OK, "
           "returned: %08x\n", rc);
        if (rc==DS_OK && wfx.nBlockAlign > 1)
        {
            ok(dsbcaps.dwBufferBytes==(wfx.nAvgBytesPerSec + wfx.nBlockAlign),
               "Buffer size not a multiple of nBlockAlign: requested %d, "
               "got %d, should be %d\n", bufdesc.dwBufferBytes,
               dsbcaps.dwBufferBytes, wfx.nAvgBytesPerSec + wfx.nBlockAlign);

            rc = IDirectSoundBuffer_SetCurrentPosition(secondary, 0);
            ok(rc == DS_OK, "Could not set position to 0: %08x\n", rc);
            rc = IDirectSoundBuffer_GetCurrentPosition(secondary, &pos, NULL);
            ok(rc == DS_OK, "Could not get position: %08x\n", rc);
            rc = IDirectSoundBuffer_SetCurrentPosition(secondary, 1);
            ok(rc == DS_OK, "Could not set position to 1: %08x\n", rc);
            rc = IDirectSoundBuffer_GetCurrentPosition(secondary, &pos2, NULL);
            ok(rc == DS_OK, "Could not get new position: %08x\n", rc);
            ok(pos == pos2, "Positions not the same! Old position: %d, new position: %d\n", pos, pos2);
        }
        ref=IDirectSoundBuffer_Release(secondary);
        ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d references, "
           "should have 0\n",ref);
    }

    ref=IDirectSound_Release(dso);
    ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
    if (ref!=0)
        return DSERR_GENERIC;

    return rc;
}
Example #2
0
static HRESULT WINAPI IDirectMusicPerformance8Impl_CreateStandardAudioPath (LPDIRECTMUSICPERFORMANCE8 iface, DWORD dwType, DWORD dwPChannelCount, BOOL fActivate, IDirectMusicAudioPath** ppNewPath) {
	IDirectMusicAudioPathImpl *default_path;
	IDirectMusicAudioPath *pPath;
	DSBUFFERDESC desc;
	WAVEFORMATEX format;
	LPDIRECTSOUNDBUFFER buffer;
	HRESULT hr = S_OK;

	IDirectMusicPerformance8Impl *This = (IDirectMusicPerformance8Impl *)iface;
	
	FIXME("(%p)->(%d, %d, %d, %p): semi-stub\n", This, dwType, dwPChannelCount, fActivate, ppNewPath);

	if (NULL == ppNewPath) {
	  return E_POINTER;
	}
	
	DMUSIC_CreateDirectMusicAudioPathImpl (&IID_IDirectMusicAudioPath, (LPVOID*)&pPath, NULL);
	default_path = (IDirectMusicAudioPathImpl*)((char*)(pPath) - offsetof(IDirectMusicAudioPathImpl,AudioPathVtbl));
	default_path->pPerf = (IDirectMusicPerformance8*) This;
	
	/* Secondary buffer description */
	memset(&format, 0, sizeof(format));
	format.wFormatTag = WAVE_FORMAT_PCM;
	format.nChannels = 1;
	format.nSamplesPerSec = 44000;
	format.nAvgBytesPerSec = 44000*2;
	format.nBlockAlign = 2;
	format.wBitsPerSample = 16;
	format.cbSize = 0;
	
	memset(&desc, 0, sizeof(desc));
	desc.dwSize = sizeof(desc);
	desc.dwFlags = DSBCAPS_CTRLFX | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS;
	desc.dwBufferBytes = DSBSIZE_MIN;
	desc.dwReserved = 0;
	desc.lpwfxFormat = &format;
	desc.guid3DAlgorithm = GUID_NULL;
	
	switch(dwType) {
	case DMUS_APATH_DYNAMIC_3D:
                desc.dwFlags |= DSBCAPS_CTRL3D | DSBCAPS_CTRLFREQUENCY | DSBCAPS_MUTE3DATMAXDISTANCE;
		break;
	case DMUS_APATH_DYNAMIC_MONO:
	        desc.dwFlags |= DSBCAPS_CTRLFREQUENCY;
		break;
	case DMUS_APATH_SHARED_STEREOPLUSREVERB:
	        /* normally we have to create 2 buffers (one for music other for reverb)
		 * in this case. See msdn
                 */
	case DMUS_APATH_DYNAMIC_STEREO:
		desc.dwFlags |= DSBCAPS_CTRLFREQUENCY;
		format.nChannels = 2;
		format.nBlockAlign *= 2;
		format.nAvgBytesPerSec *=2;
		break;
	default:
	        HeapFree(GetProcessHeap(), 0, default_path); 
	        *ppNewPath = NULL;
	        return E_INVALIDARG;
	}

	/* FIXME: Should we create one secondary buffer for each PChannel? */
	hr = IDirectSound8_CreateSoundBuffer ((LPDIRECTSOUND8) This->pDirectSound, &desc, &buffer, NULL);
	if (FAILED(hr)) {
	        HeapFree(GetProcessHeap(), 0, default_path); 
	        *ppNewPath = NULL;
	        return DSERR_BUFFERLOST;
	}
	default_path->pDSBuffer = buffer;

	/* Update description for creating primary buffer */
	desc.dwFlags |= DSBCAPS_PRIMARYBUFFER;
	desc.dwBufferBytes = 0;
	desc.lpwfxFormat = NULL;

	hr = IDirectSound8_CreateSoundBuffer ((LPDIRECTSOUND8) This->pDirectSound, &desc, &buffer, NULL);
	if (FAILED(hr)) {
                IDirectSoundBuffer_Release(default_path->pDSBuffer);
	        HeapFree(GetProcessHeap(), 0, default_path); 
	        *ppNewPath = NULL;
	        return DSERR_BUFFERLOST;
	}
	default_path->pPrimary = buffer;

	*ppNewPath = pPath;
	
	TRACE(" returning IDirectMusicPerformance interface at %p.\n", *ppNewPath);

	return IDirectMusicAudioPath_Activate(*ppNewPath, fActivate);
}
Example #3
0
HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv)
{
    HRESULT hr;
    DSoundRenderImpl * pDSoundRender;

    TRACE("(%p, %p)\n", pUnkOuter, ppv);

    *ppv = NULL;

    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    pDSoundRender = CoTaskMemAlloc(sizeof(DSoundRenderImpl));
    if (!pDSoundRender)
        return E_OUTOFMEMORY;
    ZeroMemory(pDSoundRender, sizeof(DSoundRenderImpl));

    hr = BaseRenderer_Init(&pDSoundRender->renderer, &DSoundRender_Vtbl, (IUnknown*)pDSoundRender, &CLSID_DSoundRender, (DWORD_PTR)(__FILE__ ": DSoundRenderImpl.csFilter"), &BaseFuncTable);

    BasicAudio_Init(&pDSoundRender->basicAudio,&IBasicAudio_Vtbl);
    pDSoundRender->IReferenceClock_iface.lpVtbl = &IReferenceClock_Vtbl;
    pDSoundRender->IAMDirectSound_iface.lpVtbl = &IAMDirectSound_Vtbl;
    pDSoundRender->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl;

    if (SUCCEEDED(hr))
    {
        hr = DirectSoundCreate8(NULL, &pDSoundRender->dsound, NULL);
        if (FAILED(hr))
            ERR("Cannot create Direct Sound object (%x)\n", hr);
        else
            hr = IDirectSound_SetCooperativeLevel(pDSoundRender->dsound, GetDesktopWindow(), DSSCL_PRIORITY);
        if (SUCCEEDED(hr)) {
            IDirectSoundBuffer *buf;
            DSBUFFERDESC buf_desc;
            memset(&buf_desc,0,sizeof(DSBUFFERDESC));
            buf_desc.dwSize = sizeof(DSBUFFERDESC);
            buf_desc.dwFlags = DSBCAPS_PRIMARYBUFFER;
            hr = IDirectSound_CreateSoundBuffer(pDSoundRender->dsound, &buf_desc, &buf, NULL);
            if (SUCCEEDED(hr)) {
                IDirectSoundBuffer_Play(buf, 0, 0, DSBPLAY_LOOPING);
                IDirectSoundBuffer_Release(buf);
            }
            hr = S_OK;
        }
    }

    if (SUCCEEDED(hr))
    {
        pDSoundRender->blocked = CreateEventW(NULL, TRUE, TRUE, NULL);

        if (!pDSoundRender->blocked || FAILED(hr))
        {
            IBaseFilter_Release(&pDSoundRender->renderer.filter.IBaseFilter_iface);
            return HRESULT_FROM_WIN32(GetLastError());
        }

        *ppv = pDSoundRender;
    }
    else
    {
        BaseRendererImpl_Release(&pDSoundRender->renderer.filter.IBaseFilter_iface);
        CoTaskMemFree(pDSoundRender);
    }

    return hr;
}
Example #4
0
/**************************************************************************
 * 				MCICDA_Play			[internal]
 */
static DWORD MCICDA_Play(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
{
    WINE_MCICDAUDIO*	        wmcda = MCICDA_GetOpenDrv(wDevID);
    DWORD		        ret = 0, start, end;
    HANDLE                      oldcb;
    DWORD                       br;
    CDROM_PLAY_AUDIO_MSF        play;
    CDROM_SUB_Q_DATA_FORMAT     fmt;
    SUB_Q_CHANNEL_DATA          data;
    CDROM_TOC			toc;

    TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);

    if (lpParms == NULL)
	return MCIERR_NULL_PARAMETER_BLOCK;

    if (wmcda == NULL)
	return MCIERR_INVALID_DEVICE_ID;

    if (!DeviceIoControl(wmcda->handle, IOCTL_CDROM_READ_TOC, NULL, 0,
                         &toc, sizeof(toc), &br, NULL)) {
        WARN("error reading TOC !\n");
        return MCICDA_GetError(wmcda);
    }

    if (dwFlags & MCI_FROM) {
	start = MCICDA_CalcFrame(wmcda, lpParms->dwFrom);
	if ( (ret=MCICDA_SkipDataTracks(wmcda, &start)) )
	  return ret;
	TRACE("MCI_FROM=%08X -> %u\n", lpParms->dwFrom, start);
    } else {
        fmt.Format = IOCTL_CDROM_CURRENT_POSITION;
        if (!DeviceIoControl(wmcda->handle, IOCTL_CDROM_READ_Q_CHANNEL, &fmt, sizeof(fmt),
                             &data, sizeof(data), &br, NULL)) {
            return MCICDA_GetError(wmcda);
        }
        start = FRAME_OF_ADDR(data.CurrentPosition.AbsoluteAddress);
	if ( (ret=MCICDA_SkipDataTracks(wmcda, &start)) )
	  return ret;
    }
    if (dwFlags & MCI_TO) {
	end = MCICDA_CalcFrame(wmcda, lpParms->dwTo);
	if ( (ret=MCICDA_SkipDataTracks(wmcda, &end)) )
	  return ret;
	TRACE("MCI_TO=%08X -> %u\n", lpParms->dwTo, end);
    } else {
	end = FRAME_OF_TOC(toc, toc.LastTrack + 1) - 1;
    }
    if (end < start) return MCIERR_OUTOFRANGE;
    TRACE("Playing from %u to %u\n", start, end);

    oldcb = InterlockedExchangePointer(&wmcda->hCallback,
	(dwFlags & MCI_NOTIFY) ? HWND_32(LOWORD(lpParms->dwCallback)) : NULL);
    if (oldcb) mciDriverNotify(oldcb, wmcda->wNotifyDeviceID, MCI_NOTIFY_ABORTED);

    if (start == end || start == FRAME_OF_TOC(toc,toc.LastTrack+1)-1) {
        if (dwFlags & MCI_NOTIFY) {
            oldcb = InterlockedExchangePointer(&wmcda->hCallback, NULL);
            if (oldcb) mciDriverNotify(oldcb, wDevID, MCI_NOTIFY_SUCCESSFUL);
        }
        return MMSYSERR_NOERROR;
    }

    if (wmcda->hThread != 0) {
        SetEvent(wmcda->stopEvent);
        WaitForSingleObject(wmcda->hThread, INFINITE);

        CloseHandle(wmcda->hThread);
        wmcda->hThread = 0;
        CloseHandle(wmcda->stopEvent);
        wmcda->stopEvent = 0;

        IDirectSoundBuffer_Stop(wmcda->dsBuf);
        IDirectSoundBuffer_Release(wmcda->dsBuf);
        wmcda->dsBuf = NULL;
        IDirectSound_Release(wmcda->dsObj);
        wmcda->dsObj = NULL;
    }

    if (pDirectSoundCreate) {
        WAVEFORMATEX format;
        DSBUFFERDESC desc;
        DWORD lockLen;
        void *cdData;
        HRESULT hr;

        hr = pDirectSoundCreate(NULL, &wmcda->dsObj, NULL);
        if (SUCCEEDED(hr)) {
            IDirectSound_SetCooperativeLevel(wmcda->dsObj, GetDesktopWindow(), DSSCL_PRIORITY);

            /* The "raw" frame is relative to the start of the first track */
            wmcda->start = start - FRAME_OF_TOC(toc, toc.FirstTrack);
            wmcda->end = end - FRAME_OF_TOC(toc, toc.FirstTrack);

            memset(&format, 0, sizeof(format));
            format.wFormatTag = WAVE_FORMAT_PCM;
            format.nChannels = 2;
            format.nSamplesPerSec = 44100;
            format.wBitsPerSample = 16;
            format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
            format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
            format.cbSize = 0;

            memset(&desc, 0, sizeof(desc));
            desc.dwSize = sizeof(desc);
            desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
            desc.dwBufferBytes = (CDDA_FRAG_SIZE - (CDDA_FRAG_SIZE%RAW_SECTOR_SIZE)) * CDDA_FRAG_COUNT;
            desc.lpwfxFormat = &format;

            hr = IDirectSound_CreateSoundBuffer(wmcda->dsObj, &desc, &wmcda->dsBuf, NULL);
        }
        if (SUCCEEDED(hr)) {
            hr = IDirectSoundBuffer_Lock(wmcda->dsBuf, 0, 0, &cdData, &lockLen,
                                         NULL, NULL, DSBLOCK_ENTIREBUFFER);
        }
        if (SUCCEEDED(hr)) {
            RAW_READ_INFO rdInfo;
            int readok;

            rdInfo.DiskOffset.QuadPart = wmcda->start<<11;
            rdInfo.SectorCount = min(desc.dwBufferBytes/RAW_SECTOR_SIZE,
                                     wmcda->end-wmcda->start);
            rdInfo.TrackMode = CDDA;

            readok = DeviceIoControl(wmcda->handle, IOCTL_CDROM_RAW_READ,
                                     &rdInfo, sizeof(rdInfo), cdData, lockLen,
                                     &br, NULL);
            IDirectSoundBuffer_Unlock(wmcda->dsBuf, cdData, lockLen, NULL, 0);

            if (readok) {
                wmcda->start += rdInfo.SectorCount;
                wmcda->stopEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
            }
            if (wmcda->stopEvent != 0)
                wmcda->hThread = CreateThread(NULL, 0, MCICDA_playLoop, wmcda, 0, &br);
            if (wmcda->hThread != 0) {
                hr = IDirectSoundBuffer_Play(wmcda->dsBuf, 0, 0, DSBPLAY_LOOPING);
                if (SUCCEEDED(hr)) {
                    /* FIXME: implement MCI_WAIT and send notification only in that case */
                    if (0) {
                        oldcb = InterlockedExchangePointer(&wmcda->hCallback, NULL);
                        if (oldcb) mciDriverNotify(oldcb, wmcda->wNotifyDeviceID,
                            FAILED(hr) ? MCI_NOTIFY_FAILURE : MCI_NOTIFY_SUCCESSFUL);
                    }
                    return ret;
                }

                SetEvent(wmcda->stopEvent);
                WaitForSingleObject(wmcda->hThread, INFINITE);
                CloseHandle(wmcda->hThread);
                wmcda->hThread = 0;
            }
        }

        if (wmcda->stopEvent != 0) {
            CloseHandle(wmcda->stopEvent);
            wmcda->stopEvent = 0;
        }
        if (wmcda->dsBuf) {
            IDirectSoundBuffer_Release(wmcda->dsBuf);
            wmcda->dsBuf = NULL;
        }
        if (wmcda->dsObj) {
            IDirectSound_Release(wmcda->dsObj);
            wmcda->dsObj = NULL;
        }
    }

    play.StartingM = start / CDFRAMES_PERMIN;
    play.StartingS = (start / CDFRAMES_PERSEC) % 60;
    play.StartingF = start % CDFRAMES_PERSEC;
    play.EndingM   = end / CDFRAMES_PERMIN;
    play.EndingS   = (end / CDFRAMES_PERSEC) % 60;
    play.EndingF   = end % CDFRAMES_PERSEC;
    if (!DeviceIoControl(wmcda->handle, IOCTL_CDROM_PLAY_AUDIO_MSF, &play, sizeof(play),
                         NULL, 0, &br, NULL)) {
	wmcda->hCallback = NULL;
	ret = MCIERR_HARDWARE;
    }
    /* The independent CD player has no means to signal MCI_NOTIFY when it's done.
     * Native sends a notification with MCI_WAIT only. */
    return ret;
}
Example #5
0
/*
 * Destroy stream.
 */
PJ_DEF(pj_status_t) pjmedia_snd_stream_close(pjmedia_snd_stream *stream)
{
    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);

    pjmedia_snd_stream_stop(stream);

    if (stream->thread) {
	pj_assert(stream->thread_quit_event);
	SetEvent(stream->thread_quit_event);
	pj_thread_join(stream->thread);
	pj_thread_destroy(stream->thread);
	stream->thread = NULL;
    }

    if (stream->thread_quit_event) {
	CloseHandle(stream->thread_quit_event);
	stream->thread_quit_event = NULL;
    }

    if (stream->play_strm.lpDsNotify) {
	IDirectSoundNotify_Release( stream->play_strm.lpDsNotify );
	stream->play_strm.lpDsNotify = NULL;
    }
    
    if (stream->play_strm.hEvent) {
	CloseHandle(stream->play_strm.hEvent);
	stream->play_strm.hEvent = NULL;
    }

    if (stream->play_strm.ds.play.lpDsBuffer) {
	IDirectSoundBuffer_Release( stream->play_strm.ds.play.lpDsBuffer );
	stream->play_strm.ds.play.lpDsBuffer = NULL;
    }

    if (stream->play_strm.ds.play.lpDs) {
	IDirectSound_Release( stream->play_strm.ds.play.lpDs );
	stream->play_strm.ds.play.lpDs = NULL;
    }

    if (stream->rec_strm.lpDsNotify) {
	IDirectSoundNotify_Release( stream->rec_strm.lpDsNotify );
	stream->rec_strm.lpDsNotify = NULL;
    }
    
    if (stream->rec_strm.hEvent) {
	CloseHandle(stream->rec_strm.hEvent);
	stream->rec_strm.hEvent = NULL;
    }

    if (stream->rec_strm.ds.capture.lpDsBuffer) {
	IDirectSoundCaptureBuffer_Release( stream->rec_strm.ds.capture.lpDsBuffer );
	stream->rec_strm.ds.capture.lpDsBuffer = NULL;
    }

    if (stream->rec_strm.ds.capture.lpDs) {
	IDirectSoundCapture_Release( stream->rec_strm.ds.capture.lpDs );
	stream->rec_strm.ds.capture.lpDs = NULL;
    }


    pj_pool_release(stream->pool);

    return PJ_SUCCESS;
}
Example #6
0
static HRESULT test_frequency(LPGUID lpGuid)
{
    HRESULT rc;
    LPDIRECTSOUND dso=NULL;
    LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
    DSBUFFERDESC bufdesc;
    DSCAPS dscaps;
    WAVEFORMATEX wfx, wfx1;
    DWORD f, r;
    int ref;
    int rates[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
                    48000, 96000 };

    /* Create the DirectSound object */
    rc=DirectSoundCreate(lpGuid,&dso,NULL);
    ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
       "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
    if (rc!=DS_OK)
        return rc;

    /* Get the device capabilities */
    ZeroMemory(&dscaps, sizeof(dscaps));
    dscaps.dwSize=sizeof(dscaps);
    rc=IDirectSound_GetCaps(dso,&dscaps);
    ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
    if (rc!=DS_OK)
        goto EXIT;

    /* We must call SetCooperativeLevel before creating primary buffer */
    /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
    rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
    ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
       DXGetErrorString8(rc));
    if (rc!=DS_OK)
        goto EXIT;

    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
    rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
    ok(rc==DS_OK && primary!=NULL,
       "IDirectSound_CreateSoundBuffer() failed to create a primary buffer "
       "%s\n",DXGetErrorString8(rc));

    if (rc==DS_OK && primary!=NULL) {
        rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
        ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
           DXGetErrorString8(rc));
        if (rc!=DS_OK)
            goto EXIT1;

        for (f=0;f<sizeof(fmts)/sizeof(fmts[0]);f++) {
        for (r=0;r<sizeof(rates)/sizeof(rates[0]);r++) {
            init_format(&wfx,WAVE_FORMAT_PCM,11025,fmts[f].bits,
                        fmts[f].channels);
            secondary=NULL;
            ZeroMemory(&bufdesc, sizeof(bufdesc));
            bufdesc.dwSize=sizeof(bufdesc);
            bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRLFREQUENCY;
            bufdesc.dwBufferBytes=align((wfx.nAvgBytesPerSec*rates[r]/11025)*
                                        BUFFER_LEN/1000,wfx.nBlockAlign);
            bufdesc.lpwfxFormat=&wfx;
            if (winetest_interactive) {
                trace("  Testing a secondary buffer at %ldx%dx%d "
                      "with a primary buffer at %ldx%dx%d\n",
                      wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
                      wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
            }
            rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
            ok(rc==DS_OK && secondary!=NULL,
               "IDirectSound_CreateSoundBuffer() failed to create a secondary "
               "buffer %s\n",DXGetErrorString8(rc));

            if (rc==DS_OK && secondary!=NULL) {
                test_buffer(dso,&secondary,0,FALSE,0,FALSE,0,
                            winetest_interactive,1.0,0,NULL,0,0,TRUE,rates[r]);

                ref=IDirectSoundBuffer_Release(secondary);
                ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
                   "should have 0\n",ref);
            }
        }
        }
EXIT1:
        ref=IDirectSoundBuffer_Release(primary);
        ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
           "should have 0\n",ref);
    }

    /* Set the CooperativeLevel back to normal */
    /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
    rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
    ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
       DXGetErrorString8(rc));

EXIT:
    ref=IDirectSound_Release(dso);
    ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
    if (ref!=0)
        return DSERR_GENERIC;

    return rc;
}
Example #7
0
/*
 * Test the primary buffer at different formats while keeping the
 * secondary buffer at a constant format.
 */
static HRESULT test_primary_secondary8(LPGUID lpGuid)
{
    HRESULT rc;
    LPDIRECTSOUND8 dso=NULL;
    LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
    DSBUFFERDESC bufdesc;
    DSCAPS dscaps;
    WAVEFORMATEX wfx, wfx2;
    int ref;
    unsigned int f;

    /* Create the DirectSound object */
    rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
    ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
       "DirectSoundCreate8() failed: %08x\n",rc);
    if (rc!=DS_OK)
        return rc;

    /* Get the device capabilities */
    ZeroMemory(&dscaps, sizeof(dscaps));
    dscaps.dwSize=sizeof(dscaps);
    rc=IDirectSound8_GetCaps(dso,&dscaps);
    ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc);
    if (rc!=DS_OK)
        goto EXIT;

    /* We must call SetCooperativeLevel before creating primary buffer */
    /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
    rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
    ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
    if (rc!=DS_OK)
        goto EXIT;

    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
    rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
    ok(rc==DS_OK && primary!=NULL,
       "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
       "%08x\n",rc);

    if (rc==DS_OK && primary!=NULL) {
        for (f=0;f<NB_FORMATS;f++) {
            /* We must call SetCooperativeLevel to be allowed to call
             * SetFormat */
            /* DSOUND: Setting DirectSound cooperative level to
             * DSSCL_PRIORITY */
            rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
            ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
            if (rc!=DS_OK)
                goto EXIT;

            init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
                        formats[f][2]);
            wfx2=wfx;
            rc=IDirectSoundBuffer_SetFormat(primary,&wfx);
            ok(rc==DS_OK
               || rc==DSERR_INVALIDPARAM, /* 2003 */
               "IDirectSoundBuffer_SetFormat(%s) failed: %08x\n",
               format_string(&wfx), rc);

            /* There is no guarantee that SetFormat will actually change the
             * format to what we asked for. It depends on what the soundcard
             * supports. So we must re-query the format.
             */
            rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL);
            ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc);
            if (rc==DS_OK &&
                (wfx.wFormatTag!=wfx2.wFormatTag ||
                 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
                 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
                 wfx.nChannels!=wfx2.nChannels)) {
                trace("Requested primary format tag=0x%04x %dx%dx%d "
                      "avg.B/s=%d align=%d\n",
                      wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
                      wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
                trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
                      wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
                      wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
            }

            /* Set the CooperativeLevel back to normal */
            /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
            rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
            ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);

            init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);

            secondary=NULL;
            ZeroMemory(&bufdesc, sizeof(bufdesc));
            bufdesc.dwSize=sizeof(bufdesc);
            bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
            bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
                                        wfx.nBlockAlign);
            bufdesc.lpwfxFormat=&wfx2;
            if (winetest_interactive) {
                trace("  Testing a primary buffer at %dx%dx%d with a "
                      "secondary buffer at %dx%dx%d\n",
                      wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
                      wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels);
            }
            rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
            ok(rc==DS_OK && secondary!=NULL,
               "IDirectSound_CreateSoundBuffer() failed to create a secondary "
               "buffer %08x\n",rc);

            if (rc==DS_OK && secondary!=NULL) {
                test_buffer8(dso,&secondary,0,FALSE,0,FALSE,0,
                             winetest_interactive,1.0,0,NULL,0,0);

                ref=IDirectSoundBuffer_Release(secondary);
                ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
                   "should have 0\n",ref);
            }
        }

        ref=IDirectSoundBuffer_Release(primary);
        ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
           "should have 0\n",ref);
    }

    /* Set the CooperativeLevel back to normal */
    /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
    rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
    ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);

EXIT:
    ref=IDirectSound8_Release(dso);
    ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
    if (ref!=0)
        return DSERR_GENERIC;

    return rc;
}
Example #8
0
int I2_PlaySound(void *data, boolean play3d, sound3d_t *desc, int pan)
{
	sampleheader_t	*header = data;
	byte			*sample = (byte*) data + sizeof(sampleheader_t);
	sndsource_t		*sndbuf;
	void			*writePtr1=NULL, *writePtr2=NULL;
	DWORD			writeBytes1, writeBytes2;
	int				samplelen = header->length, freq = header->frequency, bits = 8;

	// Can we play sounds?
	if(!initOk || data == NULL) return 0;	// Sorry...

	if(snd_Resample != 1 && snd_Resample != 2 && snd_Resample != 4)
	{
		ST_Message("I2_PlaySound: invalid resample factor.\n");
		snd_Resample = 1;
	}

	// Get a buffer that's doing nothing.
	sndbuf = I2_GetFreeSource(play3d);
	sndbuf->startTime = I_GetTime();
	// Prepare the audio data.
	if(snd_Resample == 1 && !snd_16bits) // Play sounds as normal?
	{
		// No resampling necessary.
		sndbuf->freq = header->frequency;
	}
	else
	{
		// Resample the sound.
		sample = I_Resample8bitSound(sample, header->length, freq, 
			snd_Resample, snd_16bits, &samplelen);
		if(snd_16bits) bits = 16;
		freq *= snd_Resample;
		sndbuf->freq = freq;
	}
	if(sndbuf->source)
	{
		// Release the old source.
		I2_KillSource(sndbuf);
	}
	// Create a new source.
	if(FAILED(hr = CreateDSBuffer(play3d? DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY 
		| DSBCAPS_CTRL3D | DSBCAPS_MUTE3DATMAXDISTANCE | DSBCAPS_STATIC 
		: DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY 
		| DSBCAPS_STATIC, 
		header->length * snd_Resample, freq, bits, 1, &sndbuf->source)))
	{
		ST_Message("I2_PlaySound: couldn't create a new buffer (result = %d).\n", hr & 0xffff);
		memset(sndbuf, 0, sizeof(*sndbuf));
		return 0;
	}
	if(play3d)
	{
		// Query the 3D interface.
		if(FAILED(hr = IDirectSoundBuffer_QueryInterface(sndbuf->source, &IID_IDirectSound3DBuffer, 
			&sndbuf->source3D)))
		{
			ST_Message("I2_PlaySound: couldn't get 3D buffer interface (result = %d).\n", hr & 0xffff);
			IDirectSoundBuffer_Release(sndbuf->source);
			memset(sndbuf, 0, sizeof(*sndbuf));
			return 0;
		}
	}

	// Lock the buffer.
	if(FAILED(hr = IDirectSoundBuffer_Lock(sndbuf->source, 0, samplelen, 
		&writePtr1, &writeBytes1, &writePtr2, &writeBytes2, 0)))
	{
		I_Error("I2_PlaySound: couldn't lock source (result = %d).\n", hr & 0xffff);
	}

	// Copy the data over.
	memcpy(writePtr1, sample, writeBytes1);
	if(writePtr2) memcpy(writePtr2, (char*) sample + writeBytes1, writeBytes2);

	// Unlock the buffer.
	if(FAILED(hr = IDirectSoundBuffer_Unlock(sndbuf->source, writePtr1, writeBytes1, 
		writePtr2, writeBytes2)))
	{
		I_Error("I2_PlaySound: couldn't unlock source (result = %d).\n", hr & 0xffff);
		return 0;
	}

	if(play3d)
	{
		// Set the 3D parameters of the source.
		if(desc->flags & DDSOUNDF_VERY_LOUD)
		{
			// You can hear this from very far away (e.g. thunderclap).
			IDirectSound3DBuffer_SetMinDistance(sndbuf->source3D, 10000, DS3D_DEFERRED);
			IDirectSound3DBuffer_SetMaxDistance(sndbuf->source3D, 20000, DS3D_DEFERRED);	
		}
		else
		{
			IDirectSound3DBuffer_SetMinDistance(sndbuf->source3D, 100, DS3D_DEFERRED);
			IDirectSound3DBuffer_SetMaxDistance(sndbuf->source3D, MAX_SND_DIST, DS3D_DEFERRED);
		}
		if(desc->flags & DDSOUNDF_LOCAL)
			IDirectSound3DBuffer_SetMode(sndbuf->source3D, DS3DMODE_DISABLE, DS3D_DEFERRED);
	}
	else
	{
		// If playing in 2D mode, set the pan.
		I2_SetPan(sndbuf, pan/1000.0f);
	}
	I2_UpdateSource(sndbuf, desc);
	// Start playing the buffer.
	if(FAILED(hr = IDirectSoundBuffer_Play(sndbuf->source, 0, 0, 0)))
	{
		I_Error("I2_PlaySound: couldn't start source (result = %d).\n", hr & 0xffff);
		return 0;
	}
	// Return the handle to the sound source.
	return (sndbuf->id = idGen++);
}
Example #9
0
int I2_Init()
{
	DSBUFFERDESC		desc;
	LPDIRECTSOUNDBUFFER	bufTemp;

	if(initOk) return true;	// Don't init a second time.
	if(FAILED(hr = EAXDirectSoundCreate(NULL, &dsound, NULL)))
	{
		// EAX can't be initialized. Use normal DS, then.
		ST_Message("I2_Init: EAX 2 couldn't be initialized (result: %i).\n", hr & 0xffff);
		if(FAILED(hr = DirectSoundCreate(NULL, &dsound, NULL)))
		{
			ST_Message("I2_Init: Couldn't create dsound (result: %i).\n", hr & 0xffff);
			return false;
		}
	}
	// Set the cooperative level.
	if(FAILED(hr = IDirectSound_SetCooperativeLevel(dsound, hWndMain, DSSCL_PRIORITY)))
	{
		ST_Message("I2_Init: Couldn't set dSound cooperative level (result: %i).\n", hr & 0xffff);
		return false;
	}
	// Get the listener.
	memset(&desc, 0, sizeof(desc));
	desc.dwSize = sizeof(desc);
	desc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER;
	if(SUCCEEDED(IDirectSound_CreateSoundBuffer(dsound, &desc, &bufTemp, NULL)))
	{
		// Query the listener interface.
		IDirectSoundBuffer_QueryInterface(bufTemp, &IID_IDirectSound3DListener, &dsListener);
	}
	// Release the primary buffer interface, we won't need it.
	IDirectSoundBuffer_Release(bufTemp);
	
	// Try to get the EAX listener property set. Create a temporary secondary buffer for it.
	if(SUCCEEDED( CreateDSBuffer(DSBCAPS_STATIC | DSBCAPS_CTRL3D, DSBSIZE_MIN, 22050, 8, 1, &bufTemp) ))
	{
		// Now try to get the property set.
		if(SUCCEEDED(hr = IDirectSoundBuffer_QueryInterface(bufTemp, 
			&IID_IKsPropertySet, &eaxListener)))
		{
			DWORD support = 0, revsize = 0;
			// Check for support.
			if(FAILED(hr = IKsPropertySet_QuerySupport(eaxListener,
				&DSPROPSETID_EAX_ListenerProperties,
				DSPROPERTY_EAXLISTENER_ENVIRONMENT,
				&support)) 
				|| ((support & NEEDED_SUPPORT) != NEEDED_SUPPORT))
			{
				ST_Message("I2_Init: Property set acquired, but EAX 2 not supported.\n  Result:%i, support:%x\n", hr&0xffff, support);
				IKsPropertySet_Release(eaxListener);
				eaxListener = NULL;
			}
			else
			{
				// EAX is supported!
				ST_Message("I2_Init: EAX 2 available.\n");
			}
		}
		// Release the temporary buffer interface.
		IDirectSoundBuffer_Release(bufTemp);
	}
		
	// Get the caps.
	dsCaps.dwSize = sizeof(dsCaps);
	IDirectSound_GetCaps(dsound, &dsCaps);
	ST_Message("I2_Init: Number of hardware 3D buffers: %i\n", dsCaps.dwMaxHw3DAllBuffers);

	// Configure the DS3D listener.
	if(dsListener)
	{
		IDirectSound3DListener_SetDistanceFactor(dsListener, 1/36.0f, DS3D_DEFERRED);
		IDirectSound3DListener_SetDopplerFactor(dsListener, 2, DS3D_DEFERRED);
	}

	// Success!
	initOk = true;
	return true;
}
Example #10
0
/* This function tries to create a primary audio buffer, and returns the
   number of audio chunks available in the created buffer.
*/
static int CreatePrimary(LPDIRECTSOUND sndObj, HWND focus, 
	LPDIRECTSOUNDBUFFER *sndbuf, WAVEFORMATEX *wavefmt, Uint32 chunksize)
{
	HRESULT result;
	DSBUFFERDESC format;
	DSBCAPS caps;
	int numchunks;

	/* Try to set primary mixing privileges */
	result = IDirectSound_SetCooperativeLevel(sndObj, focus,
							DSSCL_WRITEPRIMARY);
	if ( result != DS_OK ) {
#ifdef DEBUG_SOUND
		SetDSerror("DirectSound SetCooperativeLevel", result);
#endif
		return(-1);
	}

	/* Try to create the primary buffer */
	memset(&format, 0, sizeof(format));
	format.dwSize = sizeof(format);
	format.dwFlags=(DSBCAPS_PRIMARYBUFFER|DSBCAPS_GETCURRENTPOSITION2);
	format.dwFlags |= DSBCAPS_STICKYFOCUS;
#ifdef USE_POSITION_NOTIFY
	format.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY;
#endif
	result = IDirectSound_CreateSoundBuffer(sndObj, &format, sndbuf, NULL);
	if ( result != DS_OK ) {
#ifdef DEBUG_SOUND
		SetDSerror("DirectSound CreateSoundBuffer", result);
#endif
		return(-1);
	}

	/* Check the size of the fragment buffer */
	memset(&caps, 0, sizeof(caps));
	caps.dwSize = sizeof(caps);
	result = IDirectSoundBuffer_GetCaps(*sndbuf, &caps);
	if ( result != DS_OK ) {
#ifdef DEBUG_SOUND
		SetDSerror("DirectSound GetCaps", result);
#endif
		IDirectSoundBuffer_Release(*sndbuf);
		return(-1);
	}
	if ( (chunksize > caps.dwBufferBytes) ||
				((caps.dwBufferBytes%chunksize) != 0) ) {
		/* The primary buffer size is not a multiple of 'chunksize'
		   -- this hopefully doesn't happen when 'chunksize' is a 
		      power of 2.
		*/
		IDirectSoundBuffer_Release(*sndbuf);
		SDL_SetError(
"Primary buffer size is: %d, cannot break it into chunks of %d bytes\n",
					caps.dwBufferBytes, chunksize);
		return(-1);
	}
	numchunks = (caps.dwBufferBytes/chunksize);

	/* Set the primary audio format */
	result = IDirectSoundBuffer_SetFormat(*sndbuf, wavefmt);
	if ( result != DS_OK ) {
#ifdef DEBUG_SOUND
		SetDSerror("DirectSound SetFormat", result);
#endif
		IDirectSoundBuffer_Release(*sndbuf);
		return(-1);
	}
	return(numchunks);
}
Example #11
0
void I2_KillSource(sndsource_t *src)
{
	if(src->source3D) IDirectSound3DBuffer_Release(src->source3D);
	if(src->source) IDirectSoundBuffer_Release(src->source);
	memset(src, 0, sizeof(*src));	
}
Example #12
0
static ALCboolean DSoundResetPlayback(ALCdevice *device)
{
    DSoundData *pData = (DSoundData*)device->ExtraData;
    DSBUFFERDESC DSBDescription;
    WAVEFORMATEXTENSIBLE OutputType;
    DWORD speakers;
    HRESULT hr;

    memset(&OutputType, 0, sizeof(OutputType));

    switch(device->FmtType)
    {
    case DevFmtByte:
        device->FmtType = DevFmtUByte;
        break;
    case DevFmtUShort:
        device->FmtType = DevFmtShort;
        break;
    case DevFmtUByte:
    case DevFmtShort:
    case DevFmtFloat:
        break;
    }

    hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
    if(SUCCEEDED(hr) && ConfigValueExists(NULL, "format"))
    {
        switch(device->FmtChans)
        {
        case DevFmtMono:
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0);
            break;
        case DevFmtStereo:
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0);
            break;
        case DevFmtQuad:
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0);
            break;
        case DevFmtX51:
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0);
            break;
        case DevFmtX61:
            /* ??? */
            ;
            break;
        case DevFmtX71:
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0);
            break;
        }
    }
    if(SUCCEEDED(hr))
    {
        speakers = DSSPEAKER_CONFIG(speakers);
        if(speakers == DSSPEAKER_MONO)
        {
            device->FmtChans = DevFmtMono;
            OutputType.dwChannelMask = SPEAKER_FRONT_CENTER;
        }
        else if(speakers == DSSPEAKER_STEREO || speakers == DSSPEAKER_HEADPHONE)
        {
            device->FmtChans = DevFmtStereo;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT;
        }
        else if(speakers == DSSPEAKER_QUAD)
        {
            device->FmtChans = DevFmtQuad;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT;
        }
        else if(speakers == DSSPEAKER_5POINT1)
        {
            device->FmtChans = DevFmtX51;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_FRONT_CENTER |
                                       SPEAKER_LOW_FREQUENCY |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT;
        }
        else if(speakers == DSSPEAKER_7POINT1)
        {
            device->FmtChans = DevFmtX71;
            OutputType.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;
        }

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

    if(OutputType.Format.nChannels > 2 || OutputType.Format.wBitsPerSample > 16)
    {
        OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
        OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
        OutputType.Format.cbSize = 22;
        if(OutputType.Format.wBitsPerSample == 32)
            OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
        else
            OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
    }
    else
    {
        if(SUCCEEDED(hr))
        {
            memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
            DSBDescription.dwSize=sizeof(DSBUFFERDESC);
            DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
            hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL);
        }
        if(SUCCEEDED(hr))
            hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType.Format);
    }

    if(SUCCEEDED(hr))
    {
        memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
        DSBDescription.dwSize=sizeof(DSBUFFERDESC);
        DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2;
        DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates *
                                     OutputType.Format.nBlockAlign;
        DSBDescription.lpwfxFormat=&OutputType.Format;
        hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
    }

    if(SUCCEEDED(hr))
    {
        SetDefaultWFXChannelOrder(device);
        pData->thread = StartThread(DSoundProc, device);
        if(!pData->thread)
            hr = E_FAIL;
    }

    if(FAILED(hr))
    {
        if (pData->DSsbuffer)
            IDirectSoundBuffer_Release(pData->DSsbuffer);
        pData->DSsbuffer = NULL;
        if (pData->DSpbuffer)
            IDirectSoundBuffer_Release(pData->DSpbuffer);
        pData->DSpbuffer = NULL;
        return ALC_FALSE;
    }

    return ALC_TRUE;
}
static GstCaps *
gst_directsound_probe_supported_formats (GstDirectSoundSink * dsoundsink,
    const GstCaps * template_caps)
{
  HRESULT hRes;
  DSBUFFERDESC descSecondary;
  WAVEFORMATEX wfx;
  GstCaps *caps;
  GstCaps *tmp, *tmp2;
  LPDIRECTSOUNDBUFFER tmpBuffer;

  caps = gst_caps_copy (template_caps);

  /*
   * Check availability of digital output by trying to create an SPDIF buffer
   */

#ifdef WAVE_FORMAT_DOLBY_AC3_SPDIF
  /* fill the WAVEFORMATEX structure with some standard AC3 over SPDIF params */
  memset (&wfx, 0, sizeof (wfx));
  wfx.cbSize = 0;
  wfx.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF;
  wfx.nChannels = 2;
  wfx.nSamplesPerSec = 48000;
  wfx.wBitsPerSample = 16;
  wfx.nBlockAlign = 4;
  wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;

  // create a secondary directsound buffer
  memset (&descSecondary, 0, sizeof (DSBUFFERDESC));
  descSecondary.dwSize = sizeof (DSBUFFERDESC);
  descSecondary.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
  descSecondary.dwBufferBytes = 6144;
  descSecondary.lpwfxFormat = &wfx;

  hRes = IDirectSound_CreateSoundBuffer (dsoundsink->pDS, &descSecondary,
      &tmpBuffer, NULL);
  if (FAILED (hRes)) {
    GST_INFO_OBJECT (dsoundsink, "AC3 passthrough not supported "
        "(IDirectSound_CreateSoundBuffer returned: %s)\n",
        DXGetErrorString9 (hRes));
    tmp = gst_caps_new_empty_simple ("audio/x-ac3");
    tmp2 = gst_caps_subtract (caps, tmp);
    gst_caps_unref (tmp);
    gst_caps_unref (caps);
    caps = tmp2;
    tmp = gst_caps_new_empty_simple ("audio/x-dts");
    tmp2 = gst_caps_subtract (caps, tmp);
    gst_caps_unref (tmp);
    gst_caps_unref (caps);
    caps = tmp2;
  } else {
    GST_INFO_OBJECT (dsoundsink, "AC3 passthrough supported");
    hRes = IDirectSoundBuffer_Release (tmpBuffer);
    if (FAILED (hRes)) {
      GST_DEBUG_OBJECT (dsoundsink,
          "(IDirectSoundBuffer_Release returned: %s)\n",
          DXGetErrorString9 (hRes));
    }
  }
#else
  tmp = gst_caps_new_empty_simple ("audio/x-ac3");
  tmp2 = gst_caps_subtract (caps, tmp);
  gst_caps_unref (tmp);
  gst_caps_unref (caps);
  caps = tmp2;
  tmp = gst_caps_new_empty_simple ("audio/x-dts");
  tmp2 = gst_caps_subtract (caps, tmp);
  gst_caps_unref (tmp);
  gst_caps_unref (caps);
  caps = tmp2;
#endif

  return caps;
}
Example #14
0
static int DirectSound_start_audio_stream(int stereo)
{
    HRESULT hr;
    
    DSBUFFERDESC dsbd;
    LPDIRECTSOUNDBUFFER primary_buffer;
    WAVEFORMATEX wfx;

    VOID *area1,*area2;
    DWORD len_area1,len_area2;


    is_stereo = stereo;
    stereo_factor = (is_stereo ? 2 : 1);

	/* determine the number of samples per frame */
	samples_per_frame = (double)Machine->sample_rate / (double)Machine->drv->frames_per_second;

	/* compute how many samples to generate this frame */
	samples_left_over = samples_per_frame;
	samples_this_frame = (UINT32)samples_left_over + EXTRA_SAMPLES;
	samples_left_over -= (double)samples_this_frame;

    hr = IDirectSound_SetCooperativeLevel(ds, MAME32App.m_hWnd, DSSCL_PRIORITY);
    if (FAILED(hr))
        ErrorMsg("Unable to set priority cooperative level for sound: %s",DirectXDecodeError(hr));


    memset(&dsbd,0,sizeof(dsbd));
    dsbd.dwSize = sizeof(dsbd);
    dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
    hr = IDirectSound_CreateSoundBuffer(ds,&dsbd,&primary_buffer,NULL);
    if (FAILED(hr))
    {
        ErrorMsg("Unable to create primary sound buffer: %s",DirectXDecodeError(hr));
        return 1;
    }
    
    memset(&wfx,0,sizeof(wfx));
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    wfx.nChannels = (stereo != 0) ? 2 : 1;
    wfx.nSamplesPerSec = Machine->sample_rate;
    wfx.wBitsPerSample = 16;
    wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
    wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
    hr = IDirectSoundBuffer_SetFormat(primary_buffer,&wfx);
    
    if (FAILED(hr))
    {
        ErrorMsg("Unable to set format of primary sound buffer: %s",DirectXDecodeError(hr));
        IDirectSoundBuffer_Release(primary_buffer);
        return 1;
    }
    IDirectSoundBuffer_Play(primary_buffer,0,0,DSBPLAY_LOOPING);
    IDirectSoundBuffer_Release(primary_buffer);
    

    hr = IDirectSound_SetCooperativeLevel(ds,MAME32App.m_hWnd,DSSCL_NORMAL);
    if (FAILED(hr))
        ErrorMsg("Unable to set normal cooperative level for sound: %s",DirectXDecodeError(hr));

    wfx.nChannels = stereo_factor;

    dsb = NULL;
       
    memset(&dsbd,0,sizeof(dsbd));
    dsbd.dwSize = sizeof(dsbd);
    dsbd.dwFlags = DSBCAPS_GETCURRENTPOSITION2   // Always a good idea
       | DSBCAPS_CTRLPAN
       | DSBCAPS_CTRLVOLUME
       | DSBCAPS_GLOBALFOCUS;        // Allows background playing
    
       
    buffer_length = Machine->sample_rate*sizeof(INT16)*stereo_factor*BUFFER_SIZE_MILLIS/1000;
    // sound pukes if it's not aligned to 16 byte length
    buffer_length = (buffer_length + 15) & ~15;

    dsbd.dwBufferBytes = buffer_length;
    dsbd.lpwfxFormat = &wfx; 
       
    hr = IDirectSound_CreateSoundBuffer(ds,&dsbd,&dsb,NULL);
    if (FAILED(hr))
    {
        ErrorMsg("Unable to create secondary sound buffer: %s",DirectXDecodeError(hr));
        dsb = NULL;
        return 0;
    }

    // clear it out, because we start playing it instantly
    hr = IDirectSoundBuffer_Lock(dsb,0,buffer_length,&area1,&len_area1,&area2,&len_area2,0);
    if (FAILED(hr))
    {
        ErrorMsg("Unable to lock secondary sound buffer: %s",DirectXDecodeError(hr));
    }
    else
    {
        memset(area1,0,len_area1);
        memset(area2,0,len_area2);
       
        hr = IDirectSoundBuffer_Unlock(dsb,area1,len_area1,area2,len_area2);
        if (FAILED(hr))
            ErrorMsg("Unable to unlock secondary sound buffer: %s",DirectXDecodeError(hr));
    }

    hr = IDirectSoundBuffer_Play(dsb,0,0,DSBPLAY_LOOPING);
    if (FAILED(hr))
        ErrorMsg("Unable to play secondary sound buffer: %s",DirectXDecodeError(hr));

    voice_pos = 0;

    return samples_this_frame;
}
Example #15
0
static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
                                   LPCSTR lpcstrModule, LPVOID lpContext)
{
    HRESULT rc;
    LPDIRECTSOUND dso=NULL;
    LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
    DSBUFFERDESC bufdesc;
    WAVEFORMATEX wfx;
    int ref;

    trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
    driver_count++;

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

    /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
    /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
    rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
    ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n",
       rc);
    if (rc!=DS_OK)
        goto EXIT;

    /* Testing 3D buffers */
    primary=NULL;
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_LOCHARDWARE|DSBCAPS_CTRL3D;
    rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
    ok((rc==DS_OK&&primary!=NULL)
       || broken(rc==DSERR_INVALIDPARAM),
       "IDirectSound_CreateSoundBuffer() failed to "
       "create a hardware 3D primary buffer: %08x\n",rc);
    if(rc==DSERR_INVALIDPARAM) {
       skip("broken driver\n");
       goto EXIT;
    }
    if (rc==DS_OK&&primary!=NULL) {
        ZeroMemory(&wfx, sizeof(wfx));
        wfx.wFormatTag=WAVE_FORMAT_PCM;
        wfx.nChannels=1;
        wfx.wBitsPerSample=16;
        wfx.nSamplesPerSec=44100;
        wfx.nBlockAlign=wfx.nChannels*wfx.wBitsPerSample/8;
        wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;
        ZeroMemory(&bufdesc, sizeof(bufdesc));
        bufdesc.dwSize=sizeof(bufdesc);
        bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2;
        bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
        bufdesc.lpwfxFormat=&wfx;
        trace("  Testing a secondary buffer at %dx%dx%d\n",
            wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
        rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
        ok((rc==DS_OK && secondary!=NULL) || broken(rc == DSERR_CONTROLUNAVAIL), /* vmware drivers on w2k */
           "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer: %08x\n",rc);
        if (rc==DS_OK&&secondary!=NULL) {
            IKsPropertySet * pPropertySet=NULL;
            rc=IDirectSoundBuffer_QueryInterface(secondary,
                                                 &IID_IKsPropertySet,
                                                 (void **)&pPropertySet);
            /* it's not an error for this to fail */
            if(rc==DS_OK) {
                ULONG ulTypeSupport;
                trace("  Supports property sets\n");
                /* it's not an error for these to fail */
                rc=IKsPropertySet_QuerySupport(pPropertySet,
                                               &DSPROPSETID_VoiceManager,
                                               0,&ulTypeSupport);
                if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
                                                KSPROPERTY_SUPPORT_SET)))
                    trace("    DSPROPSETID_VoiceManager supported\n");
                else
                    trace("    DSPROPSETID_VoiceManager not supported\n");
                rc=IKsPropertySet_QuerySupport(pPropertySet,
                    &DSPROPSETID_EAX20_ListenerProperties,0,&ulTypeSupport);
                if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
                    KSPROPERTY_SUPPORT_SET)))
                    trace("    DSPROPSETID_EAX20_ListenerProperties "
                          "supported\n");
                else
                    trace("    DSPROPSETID_EAX20_ListenerProperties not "
                          "supported\n");
                rc=IKsPropertySet_QuerySupport(pPropertySet,
                    &DSPROPSETID_EAX20_BufferProperties,0,&ulTypeSupport);
                if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
                    KSPROPERTY_SUPPORT_SET)))
                    trace("    DSPROPSETID_EAX20_BufferProperties supported\n");
                else
                    trace("    DSPROPSETID_EAX20_BufferProperties not "
                          "supported\n");
                rc=IKsPropertySet_QuerySupport(pPropertySet,
                    &DSPROPSETID_I3DL2_ListenerProperties,0,&ulTypeSupport);
                if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
                    KSPROPERTY_SUPPORT_SET)))
                    trace("    DSPROPSETID_I3DL2_ListenerProperties "
                          "supported\n");
                else
                    trace("    DSPROPSETID_I3DL2_ListenerProperties not "
                          "supported\n");
                rc=IKsPropertySet_QuerySupport(pPropertySet,
                    &DSPROPSETID_I3DL2_BufferProperties,0,&ulTypeSupport);
                if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
                    KSPROPERTY_SUPPORT_SET)))
                    trace("    DSPROPSETID_I3DL2_BufferProperties supported\n");
                else
                    trace("    DSPROPSETID_I3DL2_BufferProperties not "
                          "supported\n");
                rc=IKsPropertySet_QuerySupport(pPropertySet,
                    &DSPROPSETID_ZOOMFX_BufferProperties,0,&ulTypeSupport);
                if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
                    KSPROPERTY_SUPPORT_SET)))
                    trace("    DSPROPSETID_ZOOMFX_BufferProperties "
                          "supported\n");
                else
                    trace("    DSPROPSETID_ZOOMFX_BufferProperties not "
                          "supported\n");
                ref=IKsPropertySet_Release(pPropertySet);
                /* try a few common ones */
                ok(ref==0,"IKsPropertySet_Release() secondary has %d "
                   "references, should have 0\n",ref);
            } else
                trace("  Doesn't support property sets\n");

            ref=IDirectSoundBuffer_Release(secondary);
            ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d "
               "references, should have 0\n",ref);
        }

        ref=IDirectSoundBuffer_Release(primary);
        ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
           "should have 0\n",ref);
    }

EXIT:
    if (dso!=NULL) {
        ref=IDirectSound_Release(dso);
        ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",
           ref);
    }
    return TRUE;
}
Example #16
0
static ALCboolean DSoundResetPlayback(ALCdevice *device)
{
    DSoundData *pData = (DSoundData*)device->ExtraData;
    DSBUFFERDESC DSBDescription;
    WAVEFORMATEXTENSIBLE OutputType;
    DWORD frameSize = 0;
    ALenum format = 0;
    DWORD speakers;
    HRESULT hr;

    memset(&OutputType, 0, sizeof(OutputType));

    hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
    if(SUCCEEDED(hr) && ConfigValueExists(NULL, "format"))
    {
        if(aluChannelsFromFormat(device->Format) == 1)
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_MONO, 0);
        else if(aluChannelsFromFormat(device->Format) == 2)
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 0);
        else if(aluChannelsFromFormat(device->Format) == 4)
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_QUAD, 0);
        else if(aluChannelsFromFormat(device->Format) == 6)
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_5POINT1, 0);
        else if(aluChannelsFromFormat(device->Format) == 8)
            speakers = DSSPEAKER_COMBINED(DSSPEAKER_7POINT1, 0);
        else
        {
            AL_PRINT("Unknown format: 0x%x\n", device->Format);
            return ALC_FALSE;
        }
    }
    if(SUCCEEDED(hr))
    {
        speakers = DSSPEAKER_CONFIG(speakers);
        if(speakers == DSSPEAKER_MONO)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                format = AL_FORMAT_MONO8;
            else if(aluBytesFromFormat(device->Format) == 2)
                format = AL_FORMAT_MONO16;
            else if(aluBytesFromFormat(device->Format) == 4)
                format = AL_FORMAT_MONO_FLOAT32;
            OutputType.dwChannelMask = SPEAKER_FRONT_CENTER;
        }
        else if(speakers == DSSPEAKER_STEREO)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                format = AL_FORMAT_STEREO8;
            else if(aluBytesFromFormat(device->Format) == 2)
                format = AL_FORMAT_STEREO16;
            else if(aluBytesFromFormat(device->Format) == 4)
                format = AL_FORMAT_STEREO_FLOAT32;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT;
        }
        else if(speakers == DSSPEAKER_QUAD)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                format = AL_FORMAT_QUAD8;
            else if(aluBytesFromFormat(device->Format) == 2)
                format = AL_FORMAT_QUAD16;
            else if(aluBytesFromFormat(device->Format) == 4)
                format = AL_FORMAT_QUAD32;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT;
        }
        else if(speakers == DSSPEAKER_5POINT1)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                format = AL_FORMAT_51CHN8;
            else if(aluBytesFromFormat(device->Format) == 2)
                format = AL_FORMAT_51CHN16;
            else if(aluBytesFromFormat(device->Format) == 4)
                format = AL_FORMAT_51CHN32;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_FRONT_CENTER |
                                       SPEAKER_LOW_FREQUENCY |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT;
        }
        else if(speakers == DSSPEAKER_7POINT1)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                format = AL_FORMAT_71CHN8;
            else if(aluBytesFromFormat(device->Format) == 2)
                format = AL_FORMAT_71CHN16;
            else if(aluBytesFromFormat(device->Format) == 4)
                format = AL_FORMAT_71CHN32;
            OutputType.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;
        }
        else
            format = device->Format;
        frameSize = aluFrameSizeFromFormat(format);

        OutputType.Format.wFormatTag = WAVE_FORMAT_PCM;
        OutputType.Format.nChannels = aluChannelsFromFormat(format);
        OutputType.Format.wBitsPerSample = aluBytesFromFormat(format) * 8;
        OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8;
        OutputType.Format.nSamplesPerSec = device->Frequency;
        OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign;
        OutputType.Format.cbSize = 0;
    }

    if(OutputType.Format.nChannels > 2 || OutputType.Format.wBitsPerSample > 16)
    {
        OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
        OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
        OutputType.Format.cbSize = 22;
        if(OutputType.Format.wBitsPerSample == 32)
            OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
        else
            OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
    }
    else
    {
        if(SUCCEEDED(hr))
        {
            memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
            DSBDescription.dwSize=sizeof(DSBUFFERDESC);
            DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
            hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL);
        }
        if(SUCCEEDED(hr))
            hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType.Format);
    }

    if(SUCCEEDED(hr))
    {
        memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
        DSBDescription.dwSize=sizeof(DSBUFFERDESC);
        DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2;
        DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates * frameSize;
        DSBDescription.lpwfxFormat=&OutputType.Format;
        hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
    }

    if(SUCCEEDED(hr))
        hr = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING);

    if(SUCCEEDED(hr))
    {
        device->Format = format;
        SetDefaultWFXChannelOrder(device);
        pData->thread = StartThread(DSoundProc, device);
        if(!pData->thread)
            hr = E_FAIL;
    }

    if(FAILED(hr))
    {
        if (pData->DSsbuffer)
            IDirectSoundBuffer_Release(pData->DSsbuffer);
        pData->DSsbuffer = NULL;
        if (pData->DSpbuffer)
            IDirectSoundBuffer_Release(pData->DSpbuffer);
        pData->DSpbuffer = NULL;
        return ALC_FALSE;
    }

    return ALC_TRUE;
}
Example #17
0
static int dsound_create_buffers(void)
{
	HRESULT result;
	void *buffer;
	DWORD locked;

	// create a buffer desc for the primary buffer
	primary_desc.dwSize				= sizeof(primary_desc);
	primary_desc.dwFlags			= DSBCAPS_PRIMARYBUFFER |
									  DSBCAPS_GETCURRENTPOSITION2;
	primary_desc.lpwfxFormat		= NULL;

	// create the primary buffer
	result = IDirectSound_CreateSoundBuffer(dsound, &primary_desc, &primary_buffer, NULL);
	if (result != DS_OK)
	{
		fprintf(stderr, "Error creating primary buffer: %08x\n", (UINT32)result);
		goto cant_create_primary;
	}

	// attempt to set the primary format
	result = IDirectSoundBuffer_SetFormat(primary_buffer, &stream_format);
	if (result != DS_OK)
	{
		fprintf(stderr, "Error setting primary format: %08x\n", (UINT32)result);
		goto cant_set_primary_format;
	}

	// get the primary format
	result = IDirectSoundBuffer_GetFormat(primary_buffer, &primary_format, sizeof(primary_format), NULL);
	if (result != DS_OK)
	{
		fprintf(stderr, "Error getting primary format: %08x\n", (UINT32)result);
		goto cant_get_primary_format;
	}
	if (verbose)
		fprintf(stderr, "Primary buffer: %d Hz, %d bits, %d channels\n",
				(int)primary_format.nSamplesPerSec, (int)primary_format.wBitsPerSample, (int)primary_format.nChannels);

	// create a buffer desc for the stream buffer
	stream_desc.dwSize				= sizeof(stream_desc);
	stream_desc.dwFlags				= DSBCAPS_CTRLVOLUME |
									  DSBCAPS_GLOBALFOCUS |
									  DSBCAPS_GETCURRENTPOSITION2;
	stream_desc.dwBufferBytes 		= stream_buffer_size;
	stream_desc.lpwfxFormat			= &stream_format;

	// create the stream buffer
	result = IDirectSound_CreateSoundBuffer(dsound, &stream_desc, &stream_buffer, NULL);
	if (result != DS_OK)
	{
		fprintf(stderr, "Error creating DirectSound buffer: %08x\n", (UINT32)result);
		goto cant_create_buffer;
	}

	// lock the buffer
	result = IDirectSoundBuffer_Lock(stream_buffer, 0, stream_buffer_size, &buffer, &locked, NULL, NULL, 0);
	if (result != DS_OK)
	{
		fprintf(stderr, "Error locking stream buffer: %08x\n", (UINT32)result);
		goto cant_lock_buffer;
	}

	// clear the buffer and unlock it
	memset(buffer, 0, locked);
	IDirectSoundBuffer_Unlock(stream_buffer, buffer, locked, NULL, 0);
	return 0;

	// error handling
cant_lock_buffer:
	IDirectSoundBuffer_Release(stream_buffer);
cant_create_buffer:
	stream_buffer = NULL;
cant_get_primary_format:
cant_set_primary_format:
	IDirectSoundBuffer_Release(primary_buffer);
cant_create_primary:
	primary_buffer = NULL;
	return 0;
}
Example #18
0
/*
====================
SndSys_Shutdown

Stop the sound card, delete "snd_renderbuffer" and free its other resources
====================
*/
void SndSys_Shutdown (void)
{
#ifdef SUPPORTDIRECTX
	if (pDSBuf)
	{
		IDirectSoundBuffer_Stop(pDSBuf);
		IDirectSoundBuffer_Release(pDSBuf);
	}

	// only release primary buffer if it's not also the mixing buffer we just released
	if (pDSPBuf && (pDSBuf != pDSPBuf))
	{
		IDirectSoundBuffer_Release(pDSPBuf);
	}

	if (pDS)
	{
		IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_NORMAL);
		IDirectSound_Release(pDS);
	}
#endif

	if (hWaveOut)
	{
		waveOutReset (hWaveOut);

		if (lpWaveHdr)
		{
			unsigned int i;

			for (i=0 ; i< WAV_BUFFERS ; i++)
				waveOutUnprepareHeader (hWaveOut, lpWaveHdr+i, sizeof(WAVEHDR));
		}

		waveOutClose (hWaveOut);

		if (hWaveHdr)
		{
			GlobalUnlock(hWaveHdr);
			GlobalFree(hWaveHdr);
		}

		if (hData)
		{
			GlobalUnlock(hData);
			GlobalFree(hData);
		}
	}

	if (snd_renderbuffer != NULL)
	{
		Mem_Free(snd_renderbuffer);
		snd_renderbuffer = NULL;
	}

#ifdef SUPPORTDIRECTX
	pDS = NULL;
	pDSBuf = NULL;
	pDSPBuf = NULL;
	dsound_init = false;
#endif
	hWaveOut = 0;
	hData = 0;
	hWaveHdr = 0;
	lpData = NULL;
	lpWaveHdr = NULL;
	wav_init = false;
}
Example #19
0
static HRESULT test_primary8(LPGUID lpGuid)
{
    HRESULT rc;
    LPDIRECTSOUND8 dso=NULL;
    LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
    LPDIRECTSOUNDBUFFER8 pb8 = NULL;
    DSBUFFERDESC bufdesc;
    DSCAPS dscaps;
    WAVEFORMATEX wfx;
    int ref;

    /* Create the DirectSound object */
    rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
    ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
       "DirectSoundCreate8() failed: %08x\n",rc);
    if (rc!=DS_OK)
        return rc;

    /* Get the device capabilities */
    ZeroMemory(&dscaps, sizeof(dscaps));
    dscaps.dwSize=sizeof(dscaps);
    rc=IDirectSound8_GetCaps(dso,&dscaps);
    ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc);
    if (rc!=DS_OK)
        goto EXIT;

    /* DSOUND: Error: Invalid buffer description pointer */
    rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL);
    ok(rc==DSERR_INVALIDPARAM,
       "IDirectSound8_CreateSoundBuffer should have returned "
       "DSERR_INVALIDPARAM, returned: %08x\n",rc);

    /* DSOUND: Error: Invalid buffer description pointer */
    rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL);
    ok(rc==DSERR_INVALIDPARAM && primary==0,
       "IDirectSound8_CreateSoundBuffer() should have returned "
       "DSERR_INVALIDPARAM, returned: rc=%08x,dsbo=%p\n",
       rc,primary);

    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize = sizeof(DSBUFFERDESC);

    /* DSOUND: Error: Invalid dsound buffer interface pointer */
    rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL);
    ok(rc==DSERR_INVALIDPARAM && primary==0,
       "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
       "dsbo=%p\n",rc,primary);

    ZeroMemory(&bufdesc, sizeof(bufdesc));

    /* DSOUND: Error: Invalid size */
    /* DSOUND: Error: Invalid buffer description */
    rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
    ok(rc==DSERR_INVALIDPARAM && primary==0,
       "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x,"
       "primary=%p\n",rc,primary);

    /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
    /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
    rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
    ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
    if (rc!=DS_OK)
        goto EXIT;

    /* Testing the primary buffer */
    primary=NULL;
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
    bufdesc.lpwfxFormat = &wfx;
    init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2);
    rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
    ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have "
       "returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
    if (rc==DS_OK && primary!=NULL)
        IDirectSoundBuffer_Release(primary);

    primary=NULL;
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME;
    rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
    ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL),
       "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: "
       "%08x\n",rc);
    if (rc==DSERR_CONTROLUNAVAIL)
        trace("  No Primary\n");
    else if (rc==DS_OK && primary!=NULL) {
        LONG vol;

        /* Try to create a second primary buffer */
        /* DSOUND: Error: The primary buffer already exists.
         * Any changes made to the buffer description will be ignored. */
        rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL);
        ok(rc==DS_OK && second==primary,
           "IDirectSound8_CreateSoundBuffer() should have returned original "
           "primary buffer: %08x\n",rc);
        ref=IDirectSoundBuffer_Release(second);
        ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, "
           "should have 1\n",ref);

        /* Try to duplicate a primary buffer */
        /* DSOUND: Error: Can't duplicate primary buffers */
        rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third);
        /* rc=0x88780032 */
        ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer "
           "should have failed %08x\n",rc);

        /* Primary buffers don't have an IDirectSoundBuffer8 */
        rc = IDirectSoundBuffer_QueryInterface(primary, &IID_IDirectSoundBuffer8, (LPVOID*)&pb8);
        ok(FAILED(rc), "Primary buffer does have an IDirectSoundBuffer8: %08x\n", rc);

        rc=IDirectSoundBuffer_GetVolume(primary,&vol);
        ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc);

        if (winetest_interactive) {
            trace("Playing a 5 seconds reference tone at the current volume.\n");
            if (rc==DS_OK)
                trace("(the current volume is %d according to DirectSound)\n",
                      vol);
            trace("All subsequent tones should be identical to this one.\n");
            trace("Listen for stutter, changes in pitch, volume, etc.\n");
        }
        test_buffer8(dso,&primary,1,FALSE,0,FALSE,0,winetest_interactive &&
                     !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0);

        ref=IDirectSoundBuffer_Release(primary);
        ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
           "should have 0\n",ref);
    }

    /* Set the CooperativeLevel back to normal */
    /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
    rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
    ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);

EXIT:
    ref=IDirectSound8_Release(dso);
    ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
    if (ref!=0)
        return DSERR_GENERIC;

    return rc;
}
Example #20
0
/**
 * Creates a DirectSound buffer of the required format.
 *
 * This function creates the buffer we'll use to play audio.
 * In DirectSound there are two kinds of buffers:
 * - the primary buffer: which is the actual buffer that the soundcard plays
 * - the secondary buffer(s): these buffers are the one actually used by
 *    applications and DirectSound takes care of mixing them into the primary.
 *
 * Once you create a secondary buffer, you cannot change its format anymore so
 * you have to release the current one and create another.
 */
static HRESULT CreateDSBuffer( vlc_object_t *obj, aout_stream_sys_t *sys,
                               int i_format, int i_channels, int i_nb_channels,
                               int i_rate, bool b_probe )
{
    WAVEFORMATEXTENSIBLE waveformat;
    DSBUFFERDESC         dsbdesc;
    HRESULT              hr;

    /* First set the sound buffer format */
    waveformat.dwChannelMask = 0;
    for( unsigned i = 0; pi_vlc_chan_order_wg4[i]; i++ )
        if( i_channels & pi_vlc_chan_order_wg4[i] )
            waveformat.dwChannelMask |= pi_channels_in[i];

    switch( i_format )
    {
    case VLC_CODEC_SPDIFL:
        i_nb_channels = 2;
        /* To prevent channel re-ordering */
        waveformat.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
        waveformat.Format.wBitsPerSample = 16;
        waveformat.Samples.wValidBitsPerSample =
            waveformat.Format.wBitsPerSample;
        waveformat.Format.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF;
        waveformat.SubFormat = _KSDATAFORMAT_SUBTYPE_DOLBY_AC3_SPDIF;
        break;

    case VLC_CODEC_FL32:
        waveformat.Format.wBitsPerSample = sizeof(float) * 8;
        waveformat.Samples.wValidBitsPerSample =
            waveformat.Format.wBitsPerSample;
        waveformat.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
        waveformat.SubFormat = _KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
        break;

    case VLC_CODEC_S16N:
        waveformat.Format.wBitsPerSample = 16;
        waveformat.Samples.wValidBitsPerSample =
            waveformat.Format.wBitsPerSample;
        waveformat.Format.wFormatTag = WAVE_FORMAT_PCM;
        waveformat.SubFormat = _KSDATAFORMAT_SUBTYPE_PCM;
        break;
    }

    waveformat.Format.nChannels = i_nb_channels;
    waveformat.Format.nSamplesPerSec = i_rate;
    waveformat.Format.nBlockAlign =
        waveformat.Format.wBitsPerSample / 8 * i_nb_channels;
    waveformat.Format.nAvgBytesPerSec =
        waveformat.Format.nSamplesPerSec * waveformat.Format.nBlockAlign;

    sys->i_bytes_per_sample = waveformat.Format.nBlockAlign;
    sys->format = i_format;

    /* Then fill in the direct sound descriptor */
    memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
    dsbdesc.dwSize = sizeof(DSBUFFERDESC);
    dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 /* Better position accuracy */
                    | DSBCAPS_GLOBALFOCUS         /* Allows background playing */
                    | DSBCAPS_CTRLVOLUME          /* Allows volume control */
                    | DSBCAPS_CTRLPOSITIONNOTIFY; /* Allow position notifications */

    /* Only use the new WAVE_FORMAT_EXTENSIBLE format for multichannel audio */
    if( i_nb_channels <= 2 )
    {
        waveformat.Format.cbSize = 0;
    }
    else
    {
        waveformat.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
        waveformat.Format.cbSize =
            sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);

        /* Needed for 5.1 on emu101k */
        dsbdesc.dwFlags |= DSBCAPS_LOCHARDWARE;
    }

    dsbdesc.dwBufferBytes = DS_BUF_SIZE; /* buffer size */
    dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&waveformat;

    /* CreateSoundBuffer doesn't allow volume control for non-PCM buffers */
    if ( i_format == VLC_CODEC_SPDIFL )
        dsbdesc.dwFlags &= ~DSBCAPS_CTRLVOLUME;

    hr = IDirectSound_CreateSoundBuffer( sys->p_dsobject, &dsbdesc,
                                         &sys->p_dsbuffer, NULL );
    if( FAILED(hr) )
    {
        if( !(dsbdesc.dwFlags & DSBCAPS_LOCHARDWARE) )
            return hr;

        /* Try without DSBCAPS_LOCHARDWARE */
        dsbdesc.dwFlags &= ~DSBCAPS_LOCHARDWARE;
        hr = IDirectSound_CreateSoundBuffer( sys->p_dsobject, &dsbdesc,
                                             &sys->p_dsbuffer, NULL );
        if( FAILED(hr) )
            return hr;
        if( !b_probe )
            msg_Dbg( obj, "couldn't use hardware sound buffer" );
    }

    /* Stop here if we were just probing */
    if( b_probe )
    {
        IDirectSoundBuffer_Release( sys->p_dsbuffer );
        sys->p_dsbuffer = NULL;
        return DS_OK;
    }

    sys->i_rate = i_rate;
    sys->i_channel_mask = waveformat.dwChannelMask;
    sys->chans_to_reorder =
        aout_CheckChannelReorder( pi_channels_in, pi_channels_out,
                                  waveformat.dwChannelMask, sys->chan_table );
    if( sys->chans_to_reorder )
        msg_Dbg( obj, "channel reordering needed" );

    hr = IDirectSoundBuffer_QueryInterface( sys->p_dsbuffer,
                                            &IID_IDirectSoundNotify,
                                            (void **) &sys->p_notify );
    if( hr != DS_OK )
    {
        msg_Err( obj, "Couldn't query IDirectSoundNotify" );
        sys->p_notify = NULL;
    }

    FillBuffer( obj, sys, NULL );
    return DS_OK;
}
Example #21
0
static HRESULT test_secondary8(LPGUID lpGuid)
{
    HRESULT rc;
    LPDIRECTSOUND8 dso=NULL;
    LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
    DSBUFFERDESC bufdesc;
    DSCAPS dscaps;
    WAVEFORMATEX wfx, wfx1;
    DWORD f;
    int ref;

    /* Create the DirectSound object */
    rc=pDirectSoundCreate8(lpGuid,&dso,NULL);
    ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
       "DirectSoundCreate8() failed: %08x\n",rc);
    if (rc!=DS_OK)
        return rc;

    /* Get the device capabilities */
    ZeroMemory(&dscaps, sizeof(dscaps));
    dscaps.dwSize=sizeof(dscaps);
    rc=IDirectSound8_GetCaps(dso,&dscaps);
    ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc);
    if (rc!=DS_OK)
        goto EXIT;

    /* We must call SetCooperativeLevel before creating primary buffer */
    /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
    rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
    ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);
    if (rc!=DS_OK)
        goto EXIT;

    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
    rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
    ok(rc==DS_OK && primary!=NULL,
       "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer "
       "%08x\n",rc);

    if (rc==DS_OK && primary!=NULL) {
        rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
        ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc);
        if (rc!=DS_OK)
            goto EXIT1;

        for (f=0;f<NB_FORMATS;f++) {
            WAVEFORMATEXTENSIBLE wfxe;
            init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1],
                        formats[f][2]);
            secondary=NULL;
            ZeroMemory(&bufdesc, sizeof(bufdesc));
            bufdesc.dwSize=sizeof(bufdesc);
            bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
            bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
                                        wfx.nBlockAlign);
            rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
            ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() "
               "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc);
            if (rc==DS_OK && secondary!=NULL)
                IDirectSoundBuffer_Release(secondary);

            secondary=NULL;
            ZeroMemory(&bufdesc, sizeof(bufdesc));
            bufdesc.dwSize=sizeof(bufdesc);
            bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
            bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
                                        wfx.nBlockAlign);
            bufdesc.lpwfxFormat=&wfx;
            rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
            if (wfx.wBitsPerSample != 8 && wfx.wBitsPerSample != 16)
                ok(((rc == DSERR_CONTROLUNAVAIL || rc == DSERR_INVALIDCALL || rc == DSERR_INVALIDPARAM /* 2003 */) && !secondary)
                    || rc == DS_OK, /* driver dependent? */
                    "IDirectSound_CreateSoundBuffer() "
                    "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) "
                    "and NULL, returned: %08x %p\n", rc, secondary);
            else
                ok(rc==DS_OK && secondary!=NULL,
                    "IDirectSound_CreateSoundBuffer() failed to create a secondary "
                    "buffer %08x\n",rc);
            if (secondary)
                IDirectSoundBuffer_Release(secondary);
            secondary = NULL;

            bufdesc.lpwfxFormat=(WAVEFORMATEX*)&wfxe;
            wfxe.Format = wfx;
            wfxe.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
            wfxe.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
            wfxe.Format.cbSize = 1;
            wfxe.Samples.wValidBitsPerSample = wfx.wBitsPerSample;
            wfxe.dwChannelMask = (wfx.nChannels == 1 ? KSAUDIO_SPEAKER_MONO : KSAUDIO_SPEAKER_STEREO);

            rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
            ok(rc==DSERR_INVALIDPARAM && !secondary,
                "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
                rc, secondary);
            if (secondary)
            {
                IDirectSoundBuffer_Release(secondary);
                secondary=NULL;
            }

            wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx) + 1;

            rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
            ok(((rc==DSERR_CONTROLUNAVAIL || DSERR_INVALIDCALL /* 2003 */) && !secondary)
                || rc==DS_OK /* driver dependent? */,
                "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
                rc, secondary);
            if (secondary)
            {
                IDirectSoundBuffer_Release(secondary);
                secondary=NULL;
            }

            wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx);
            wfxe.SubFormat = GUID_NULL;
            rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
            ok((rc==DSERR_INVALIDPARAM || rc==DSERR_INVALIDCALL) && !secondary,
                "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
                rc, secondary);
            if (secondary)
            {
                IDirectSoundBuffer_Release(secondary);
                secondary=NULL;
            }
            wfxe.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;

            ++wfxe.Samples.wValidBitsPerSample;
            rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
            ok(rc==DSERR_INVALIDPARAM && !secondary,
                "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
                rc, secondary);
            if (secondary)
            {
                IDirectSoundBuffer_Release(secondary);
                secondary=NULL;
            }
            --wfxe.Samples.wValidBitsPerSample;

            wfxe.Samples.wValidBitsPerSample = 0;
            rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
            ok(rc==DS_OK && secondary,
                "IDirectSound_CreateSoundBuffer() returned: %08x %p\n",
                rc, secondary);
            if (secondary)
            {
                IDirectSoundBuffer_Release(secondary);
                secondary=NULL;
            }
            wfxe.Samples.wValidBitsPerSample = wfxe.Format.wBitsPerSample;

            rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
            ok(rc==DS_OK && secondary!=NULL,
                "IDirectSound_CreateSoundBuffer() failed to create a secondary "
                "buffer %08x\n",rc);

            if (rc==DS_OK && secondary!=NULL) {
                if (winetest_interactive) {
                    trace("  Testing a secondary buffer at %dx%dx%d "
                        "with a primary buffer at %dx%dx%d\n",
                        wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
                        wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
                }
                test_buffer8(dso,&secondary,0,FALSE,0,FALSE,0,
                             winetest_interactive,1.0,0,NULL,0,0);

                ref=IDirectSoundBuffer_Release(secondary);
                ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
                   "should have 0\n",ref);
            }
        }
EXIT1:
        ref=IDirectSoundBuffer_Release(primary);
        ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
           "should have 0\n",ref);
    }

    /* Set the CooperativeLevel back to normal */
    /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
    rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
    ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc);

EXIT:
    ref=IDirectSound8_Release(dso);
    ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref);
    if (ref!=0)
        return DSERR_GENERIC;

    return rc;
}
Example #22
0
static HRESULT WINAPI DSoundRender_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
{
    InputPin *This = (InputPin *)iface;
    PIN_DIRECTION pindirReceive;
    DSoundRenderImpl *DSImpl;
    HRESULT hr = S_OK;

    TRACE("(%p)->(%p, %p)\n", This, pReceivePin, pmt);
    dump_AM_MEDIA_TYPE(pmt);

    EnterCriticalSection(This->pin.pCritSec);
    {
        DSImpl = (DSoundRenderImpl*)This->pin.pinInfo.pFilter;
        DSImpl->rtLastStop = -1;

        if (This->pin.pConnectedTo)
            hr = VFW_E_ALREADY_CONNECTED;

        if (SUCCEEDED(hr) && This->pin.fnQueryAccept(This->pin.pUserData, pmt) != S_OK)
            hr = VFW_E_TYPE_NOT_ACCEPTED;

        if (SUCCEEDED(hr))
        {
            IPin_QueryDirection(pReceivePin, &pindirReceive);

            if (pindirReceive != PINDIR_OUTPUT)
            {
                ERR("Can't connect from non-output pin\n");
                hr = VFW_E_INVALID_DIRECTION;
            }
        }

        if (SUCCEEDED(hr))
        {
            WAVEFORMATEX *format;
            DSBUFFERDESC buf_desc;

            TRACE("MajorType %s\n", debugstr_guid(&pmt->majortype));
            TRACE("SubType %s\n", debugstr_guid(&pmt->subtype));
            TRACE("Format %s\n", debugstr_guid(&pmt->formattype));
            TRACE("Size %d\n", pmt->cbFormat);

            format = (WAVEFORMATEX*)pmt->pbFormat;

            DSImpl->buf_size = format->nAvgBytesPerSec;

            memset(&buf_desc,0,sizeof(DSBUFFERDESC));
            buf_desc.dwSize = sizeof(DSBUFFERDESC);
            buf_desc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN |
                               DSBCAPS_CTRLFREQUENCY |
                               DSBCAPS_GETCURRENTPOSITION2;
            buf_desc.dwBufferBytes = DSImpl->buf_size;
            buf_desc.lpwfxFormat = format;
            hr = IDirectSound_CreateSoundBuffer(DSImpl->dsound, &buf_desc, &DSImpl->dsbuffer, NULL);
            if (FAILED(hr))
                ERR("Can't create sound buffer (%x)\n", hr);
        }

        if (SUCCEEDED(hr))
        {
            hr = IDirectSoundBuffer_SetVolume(DSImpl->dsbuffer, DSImpl->volume);
            if (FAILED(hr))
                ERR("Can't set volume to %ld (%x)\n", DSImpl->volume, hr);

            hr = IDirectSoundBuffer_SetPan(DSImpl->dsbuffer, DSImpl->pan);
            if (FAILED(hr))
                ERR("Can't set pan to %ld (%x)\n", DSImpl->pan, hr);

            DSImpl->write_pos = 0;
            hr = S_OK;
        }

        if (SUCCEEDED(hr))
        {
            CopyMediaType(&This->pin.mtCurrent, pmt);
            This->pin.pConnectedTo = pReceivePin;
            IPin_AddRef(pReceivePin);
        }
        else if (hr != VFW_E_ALREADY_CONNECTED)
        {
            if (DSImpl->dsbuffer)
                IDirectSoundBuffer_Release(DSImpl->dsbuffer);
            DSImpl->dsbuffer = NULL;
        }
    }
    LeaveCriticalSection(This->pin.pCritSec);

    return hr;
}
Example #23
0
static ALCboolean DSoundResetPlayback(ALCdevice *device)
{
    DSoundPlaybackData *data = (DSoundPlaybackData*)device->ExtraData;
    DSBUFFERDESC DSBDescription;
    WAVEFORMATEXTENSIBLE OutputType;
    DWORD speakers;
    HRESULT hr;

    memset(&OutputType, 0, sizeof(OutputType));

    if(data->DSnotify)
        IDirectSoundNotify_Release(data->DSnotify);
    data->DSnotify = NULL;
    if(data->DSsbuffer)
        IDirectSoundBuffer_Release(data->DSsbuffer);
    data->DSsbuffer = NULL;
    if(data->DSpbuffer != NULL)
        IDirectSoundBuffer_Release(data->DSpbuffer);
    data->DSpbuffer = NULL;

    switch(device->FmtType)
    {
        case DevFmtByte:
            device->FmtType = DevFmtUByte;
            break;
        case DevFmtFloat:
            if((device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
                break;
            /* fall-through */
        case DevFmtUShort:
            device->FmtType = DevFmtShort;
            break;
        case DevFmtUInt:
            device->FmtType = DevFmtInt;
            break;
        case DevFmtUByte:
        case DevFmtShort:
        case DevFmtInt:
            break;
    }

    hr = IDirectSound_GetSpeakerConfig(data->DS, &speakers);
    if(SUCCEEDED(hr))
    {
        if(!(device->Flags&DEVICE_CHANNELS_REQUEST))
        {
            speakers = DSSPEAKER_CONFIG(speakers);
            if(speakers == DSSPEAKER_MONO)
                device->FmtChans = DevFmtMono;
            else if(speakers == DSSPEAKER_STEREO || speakers == DSSPEAKER_HEADPHONE)
                device->FmtChans = DevFmtStereo;
            else if(speakers == DSSPEAKER_QUAD)
                device->FmtChans = DevFmtQuad;
            else if(speakers == DSSPEAKER_5POINT1)
                device->FmtChans = DevFmtX51;
            else if(speakers == DSSPEAKER_7POINT1)
                device->FmtChans = DevFmtX71;
            else
                ERR("Unknown system speaker config: 0x%lx\n", speakers);
        }

        switch(device->FmtChans)
        {
            case DevFmtMono:
                OutputType.dwChannelMask = SPEAKER_FRONT_CENTER;
                break;
            case DevFmtStereo:
                OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                           SPEAKER_FRONT_RIGHT;
                break;
            case DevFmtQuad:
                OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                           SPEAKER_FRONT_RIGHT |
                                           SPEAKER_BACK_LEFT |
                                           SPEAKER_BACK_RIGHT;
                break;
            case DevFmtX51:
                OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                           SPEAKER_FRONT_RIGHT |
                                           SPEAKER_FRONT_CENTER |
                                           SPEAKER_LOW_FREQUENCY |
                                           SPEAKER_BACK_LEFT |
                                           SPEAKER_BACK_RIGHT;
                break;
            case DevFmtX51Side:
                OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                           SPEAKER_FRONT_RIGHT |
                                           SPEAKER_FRONT_CENTER |
                                           SPEAKER_LOW_FREQUENCY |
                                           SPEAKER_SIDE_LEFT |
                                           SPEAKER_SIDE_RIGHT;
                break;
            case DevFmtX61:
                OutputType.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:
                OutputType.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;
        }

retry_open:
        hr = S_OK;
        OutputType.Format.wFormatTag = WAVE_FORMAT_PCM;
        OutputType.Format.nChannels = ChannelsFromDevFmt(device->FmtChans);
        OutputType.Format.wBitsPerSample = BytesFromDevFmt(device->FmtType) * 8;
        OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8;
        OutputType.Format.nSamplesPerSec = device->Frequency;
        OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign;
        OutputType.Format.cbSize = 0;
    }

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

        if(data->DSpbuffer)
            IDirectSoundBuffer_Release(data->DSpbuffer);
        data->DSpbuffer = NULL;
    }
    else
    {
        if(SUCCEEDED(hr))
        {
            memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
            DSBDescription.dwSize=sizeof(DSBUFFERDESC);
            DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
            hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->DSpbuffer, NULL);
        }
        if(SUCCEEDED(hr))
            hr = IDirectSoundBuffer_SetFormat(data->DSpbuffer,&OutputType.Format);
    }

    if(SUCCEEDED(hr))
    {
        if(device->NumUpdates > MAX_UPDATES)
        {
            device->UpdateSize = (device->UpdateSize*device->NumUpdates +
                                  MAX_UPDATES-1) / MAX_UPDATES;
            device->NumUpdates = MAX_UPDATES;
        }

        memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
        DSBDescription.dwSize=sizeof(DSBUFFERDESC);
        DSBDescription.dwFlags=DSBCAPS_CTRLPOSITIONNOTIFY|DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_GLOBALFOCUS;
        DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates *
                                     OutputType.Format.nBlockAlign;
        DSBDescription.lpwfxFormat=&OutputType.Format;
        hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->DSsbuffer, NULL);
        if(FAILED(hr) && device->FmtType == DevFmtFloat)
        {
            device->FmtType = DevFmtShort;
            goto retry_open;
        }
    }

    if(SUCCEEDED(hr))
    {
        hr = IDirectSoundBuffer_QueryInterface(data->DSsbuffer, &IID_IDirectSoundNotify, (LPVOID *)&data->DSnotify);
        if(SUCCEEDED(hr))
        {
            DSBPOSITIONNOTIFY notifies[MAX_UPDATES];
            ALuint i;

            for(i = 0;i < device->NumUpdates;++i)
            {
                notifies[i].dwOffset = i * device->UpdateSize *
                                       OutputType.Format.nBlockAlign;
                notifies[i].hEventNotify = data->NotifyEvent;
            }
            if(IDirectSoundNotify_SetNotificationPositions(data->DSnotify, device->NumUpdates, notifies) != DS_OK)
                hr = E_FAIL;
        }
    }

    if(FAILED(hr))
    {
        if(data->DSnotify != NULL)
            IDirectSoundNotify_Release(data->DSnotify);
        data->DSnotify = NULL;
        if(data->DSsbuffer != NULL)
            IDirectSoundBuffer_Release(data->DSsbuffer);
        data->DSsbuffer = NULL;
        if(data->DSpbuffer != NULL)
            IDirectSoundBuffer_Release(data->DSpbuffer);
        data->DSpbuffer = NULL;
        return ALC_FALSE;
    }

    ResetEvent(data->NotifyEvent);
    SetDefaultWFXChannelOrder(device);

    return ALC_TRUE;
}
Example #24
0
File: dsound.c Project: m64/PEG
static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
{
    DSBUFFERDESC DSBDescription;
    DSoundData *pData = NULL;
    WAVEFORMATEXTENSIBLE OutputType;
    DWORD frameSize = 0;
    LPGUID guid = NULL;
    DWORD speakers;
    HRESULT hr;

    if(deviceName)
    {
        int i;
        for(i = 0;DeviceList[i].name;i++)
        {
            if(strcmp(deviceName, DeviceList[i].name) == 0)
            {
                device->szDeviceName = DeviceList[i].name;
                if(i > 0)
                    guid = &DeviceList[i].guid;
                break;
            }
        }
        if(!DeviceList[i].name)
            return ALC_FALSE;
    }
    else
        device->szDeviceName = DeviceList[0].name;

    memset(&OutputType, 0, sizeof(OutputType));

    //Initialise requested device

    pData = calloc(1, sizeof(DSoundData));
    if(!pData)
    {
        SetALCError(ALC_OUT_OF_MEMORY);
        return ALC_FALSE;
    }

    //DirectSound Init code
    hr = DirectSoundCreate(guid, &pData->lpDS, NULL);
    if(SUCCEEDED(hr))
        hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY);

    if(SUCCEEDED(hr))
        hr = IDirectSound_GetSpeakerConfig(pData->lpDS, &speakers);
    if(SUCCEEDED(hr))
    {
        speakers = DSSPEAKER_CONFIG(speakers);
        if(speakers == DSSPEAKER_MONO)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                device->Format = AL_FORMAT_MONO8;
            else
                device->Format = AL_FORMAT_MONO16;
        }
        else if(speakers == DSSPEAKER_STEREO)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                device->Format = AL_FORMAT_STEREO8;
            else
                device->Format = AL_FORMAT_STEREO16;
        }
        else if(speakers == DSSPEAKER_QUAD)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                device->Format = AL_FORMAT_QUAD8;
            else
                device->Format = AL_FORMAT_QUAD16;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT;
        }
        else if(speakers == DSSPEAKER_5POINT1)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                device->Format = AL_FORMAT_51CHN8;
            else
                device->Format = AL_FORMAT_51CHN16;
            OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
                                       SPEAKER_FRONT_RIGHT |
                                       SPEAKER_FRONT_CENTER |
                                       SPEAKER_LOW_FREQUENCY |
                                       SPEAKER_BACK_LEFT |
                                       SPEAKER_BACK_RIGHT;
        }
        else if(speakers == DSSPEAKER_7POINT1)
        {
            if(aluBytesFromFormat(device->Format) == 1)
                device->Format = AL_FORMAT_71CHN8;
            else
                device->Format = AL_FORMAT_71CHN16;
            OutputType.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;
        }
        frameSize = aluBytesFromFormat(device->Format) *
                    aluChannelsFromFormat(device->Format);

        OutputType.Format.wFormatTag = WAVE_FORMAT_PCM;
        OutputType.Format.nChannels = aluChannelsFromFormat(device->Format);
        OutputType.Format.wBitsPerSample = aluBytesFromFormat(device->Format) * 8;
        OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8;
        OutputType.Format.nSamplesPerSec = device->Frequency;
        OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign;
        OutputType.Format.cbSize = 0;

        device->UpdateSize /= DS_FRAGS;
    }

    if(OutputType.Format.nChannels > 2)
    {
        OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
        OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
        OutputType.Format.cbSize = 22;
        OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
    }
    else
    {
        if(SUCCEEDED(hr))
        {
            memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
            DSBDescription.dwSize=sizeof(DSBUFFERDESC);
            DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
            hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSpbuffer, NULL);
        }
        if(SUCCEEDED(hr))
            hr = IDirectSoundBuffer_SetFormat(pData->DSpbuffer,&OutputType.Format);
    }

    if(SUCCEEDED(hr))
    {
        memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
        DSBDescription.dwSize=sizeof(DSBUFFERDESC);
        DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2;
        DSBDescription.dwBufferBytes=device->UpdateSize * DS_FRAGS * frameSize;
        DSBDescription.lpwfxFormat=&OutputType.Format;
        hr = IDirectSound_CreateSoundBuffer(pData->lpDS, &DSBDescription, &pData->DSsbuffer, NULL);
    }

    if(SUCCEEDED(hr))
        hr = IDirectSoundBuffer_Play(pData->DSsbuffer, 0, 0, DSBPLAY_LOOPING);

    device->ExtraData = pData;
    pData->thread = StartThread(DSoundProc, device);
    if(!pData->thread)
        hr = E_FAIL;

    if(FAILED(hr))
    {
        if (pData->DSsbuffer)
            IDirectSoundBuffer_Release(pData->DSsbuffer);
        if (pData->DSpbuffer)
            IDirectSoundBuffer_Release(pData->DSpbuffer);
        if (pData->lpDS)
            IDirectSound_Release(pData->lpDS);

        free(pData);
        return ALC_FALSE;
    }

    return ALC_TRUE;
}