⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 primary.c

📁 一个类似windows
💻 C
📖 第 1 页 / 共 3 页
字号:
        device->pwfx = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,device->pwfx,alloc_size);	nSamplesPerSec = device->pwfx->nSamplesPerSec;        CopyMemory(device->pwfx, wfex, cp_size);	if (device->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMSETFORMAT) {		DWORD flags = CALLBACK_FUNCTION;		if (ds_hw_accel != DS_HW_ACCEL_EMULATION)			flags |= WAVE_DIRECTSOUND;		/* FIXME: check for errors */		DSOUND_PrimaryClose(device);		waveOutClose(device->hwo);		device->hwo = 0;                err = mmErr(waveOutOpen(&(device->hwo), device->drvdesc.dnDevNode,                                        device->pwfx, (DWORD_PTR)DSOUND_callback, (DWORD)device,                                        flags));                if (err == DS_OK) {                    err = DSOUND_PrimaryOpen(device);		    if (err != DS_OK) {			WARN("DSOUND_PrimaryOpen failed\n");			goto done;		    }		} else {			WARN("waveOutOpen failed\n");			goto done;		}	} else if (device->hwbuf) {		err = IDsDriverBuffer_SetFormat(device->hwbuf, device->pwfx);		if (err == DSERR_BUFFERLOST) {			/* Wine-only: the driver wants us to recreate the HW buffer */			IDsDriverBuffer_Release(device->hwbuf);			err = IDsDriver_CreateSoundBuffer(device->driver,device->pwfx,							  DSBCAPS_PRIMARYBUFFER,0,							  &(device->buflen),&(device->buffer),							  (LPVOID)&(device->hwbuf));			if (err != DS_OK) {				WARN("IDsDriver_CreateSoundBuffer failed\n");				goto done;			}			if (device->state == STATE_PLAYING) device->state = STATE_STARTING;			else if (device->state == STATE_STOPPING) device->state = STATE_STOPPED;		} else {			WARN("IDsDriverBuffer_SetFormat failed\n");			goto done;		}                /* FIXME: should we set err back to DS_OK in all cases ? */	}	DSOUND_RecalcPrimary(device);	if (nSamplesPerSec != device->pwfx->nSamplesPerSec) {		IDirectSoundBufferImpl** dsb = device->buffers;		for (i = 0; i < device->nrofbuffers; i++, dsb++) {			/* **** */			EnterCriticalSection(&((*dsb)->lock));			(*dsb)->freqAdjust = ((*dsb)->freq << DSOUND_FREQSHIFT) /				wfex->nSamplesPerSec;			LeaveCriticalSection(&((*dsb)->lock));			/* **** */		}	}done:	LeaveCriticalSection(&(device->mixlock));	RtlReleaseResource(&(device->buffer_list_lock));	/* **** */	return err;}static HRESULT WINAPI PrimaryBufferImpl_SetVolume(	LPDIRECTSOUNDBUFFER8 iface,LONG vol) {	DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->dsound->device;	DWORD ampfactors;	DSVOLUMEPAN volpan;        HRESULT hres = DS_OK;	TRACE("(%p,%ld)\n", iface, vol);	if (!(device->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {		WARN("control unavailable\n");		return DSERR_CONTROLUNAVAIL;	}	if ((vol > DSBVOLUME_MAX) || (vol < DSBVOLUME_MIN)) {		WARN("invalid parameter: vol = %ld\n", vol);		return DSERR_INVALIDPARAM;	}	/* **** */	EnterCriticalSection(&(device->mixlock));        waveOutGetVolume(device->hwo, &ampfactors);        volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;        volpan.dwTotalRightAmpFactor=ampfactors >> 16;        DSOUND_AmpFactorToVolPan(&volpan);        if (vol != volpan.lVolume) {            volpan.lVolume=vol;            DSOUND_RecalcVolPan(&volpan);            if (device->hwbuf) {                hres = IDsDriverBuffer_SetVolumePan(device->hwbuf, &volpan);                if (hres != DS_OK)                    WARN("IDsDriverBuffer_SetVolumePan failed\n");            } else {                ampfactors = (volpan.dwTotalLeftAmpFactor & 0xffff) | (volpan.dwTotalRightAmpFactor << 16);                waveOutSetVolume(device->hwo, ampfactors);            }        }	LeaveCriticalSection(&(device->mixlock));	/* **** */	return hres;}static HRESULT WINAPI PrimaryBufferImpl_GetVolume(	LPDIRECTSOUNDBUFFER8 iface,LPLONG vol) {	DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->dsound->device;	DWORD ampfactors;	DSVOLUMEPAN volpan;	TRACE("(%p,%p)\n", iface, vol);	if (!(device->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {		WARN("control unavailable\n");		return DSERR_CONTROLUNAVAIL;	}	if (vol == NULL) {		WARN("invalid parameter: vol = NULL\n");		return DSERR_INVALIDPARAM;	}	waveOutGetVolume(device->hwo, &ampfactors);	volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;	volpan.dwTotalRightAmpFactor=ampfactors >> 16;	DSOUND_AmpFactorToVolPan(&volpan);	*vol = volpan.lVolume;	return DS_OK;}static HRESULT WINAPI PrimaryBufferImpl_SetFrequency(	LPDIRECTSOUNDBUFFER8 iface,DWORD freq) {	PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;	TRACE("(%p,%ld)\n",This,freq);	/* You cannot set the frequency of the primary buffer */	WARN("control unavailable\n");	return DSERR_CONTROLUNAVAIL;}static HRESULT WINAPI PrimaryBufferImpl_Play(	LPDIRECTSOUNDBUFFER8 iface,DWORD reserved1,DWORD reserved2,DWORD flags) {	DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->dsound->device;	TRACE("(%p,%08lx,%08lx,%08lx)\n", iface, reserved1, reserved2, flags);	if (!(flags & DSBPLAY_LOOPING)) {		WARN("invalid parameter: flags = %08lx\n", flags);		return DSERR_INVALIDPARAM;	}	/* **** */	EnterCriticalSection(&(device->mixlock));	if (device->state == STATE_STOPPED)		device->state = STATE_STARTING;	else if (device->state == STATE_STOPPING)		device->state = STATE_PLAYING;	LeaveCriticalSection(&(device->mixlock));	/* **** */	return DS_OK;}static HRESULT WINAPI PrimaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER8 iface){	DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->dsound->device;	TRACE("(%p)\n", iface);	/* **** */	EnterCriticalSection(&(device->mixlock));	if (device->state == STATE_PLAYING)		device->state = STATE_STOPPING;	else if (device->state == STATE_STARTING)		device->state = STATE_STOPPED;	LeaveCriticalSection(&(device->mixlock));	/* **** */	return DS_OK;}static ULONG WINAPI PrimaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface){    PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;    ULONG ref = InterlockedIncrement(&(This->ref));    TRACE("(%p) ref was %ld\n", This, ref - 1);    return ref;}static ULONG WINAPI PrimaryBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface){    PrimaryBufferImpl *This = (PrimaryBufferImpl *)iface;    DWORD ref = InterlockedDecrement(&(This->ref));    TRACE("(%p) ref was %ld\n", This, ref + 1);    if (!ref) {        This->dsound->device->primary = NULL;        HeapFree(GetProcessHeap(), 0, This);        TRACE("(%p) released\n", This);    }    return ref;}static HRESULT WINAPI PrimaryBufferImpl_GetCurrentPosition(	LPDIRECTSOUNDBUFFER8 iface,LPDWORD playpos,LPDWORD writepos) {	HRESULT	hres;        DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->dsound->device;	TRACE("(%p,%p,%p)\n", iface, playpos, writepos);	hres = DSOUND_PrimaryGetPosition(device, playpos, writepos);	if (hres != DS_OK) {		WARN("DSOUND_PrimaryGetPosition failed\n");		return hres;	}	if (writepos) {		if (device->state != STATE_STOPPED)			/* apply the documented 10ms lead to writepos */			*writepos += device->writelead;		while (*writepos >= device->buflen) *writepos -= device->buflen;	}	TRACE("playpos = %ld, writepos = %ld (%p, time=%ld)\n", playpos?*playpos:0, writepos?*writepos:0, device, GetTickCount());	return DS_OK;}static HRESULT WINAPI PrimaryBufferImpl_GetStatus(	LPDIRECTSOUNDBUFFER8 iface,LPDWORD status) {        DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->dsound->device;	TRACE("(%p,%p)\n", iface, status);	if (status == NULL) {		WARN("invalid parameter: status == NULL\n");		return DSERR_INVALIDPARAM;	}	*status = 0;	if ((device->state == STATE_STARTING) ||	    (device->state == STATE_PLAYING))		*status |= DSBSTATUS_PLAYING | DSBSTATUS_LOOPING;	TRACE("status=%lx\n", *status);	return DS_OK;}static HRESULT WINAPI PrimaryBufferImpl_GetFormat(    LPDIRECTSOUNDBUFFER8 iface,    LPWAVEFORMATEX lpwf,    DWORD wfsize,    LPDWORD wfwritten){    DWORD size;    DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->dsound->device;    TRACE("(%p,%p,%ld,%p)\n", iface, lpwf, wfsize, wfwritten);    size = sizeof(WAVEFORMATEX) + device->pwfx->cbSize;    if (lpwf) {	/* NULL is valid */        if (wfsize >= size) {            CopyMemory(lpwf,device->pwfx,size);            if (wfwritten)                *wfwritten = size;        } else {            WARN("invalid parameter: wfsize too small\n");            if (wfwritten)                *wfwritten = 0;            return DSERR_INVALIDPARAM;        }    } else {        if (wfwritten)            *wfwritten = sizeof(WAVEFORMATEX) + device->pwfx->cbSize;        else {            WARN("invalid parameter: wfwritten == NULL\n");            return DSERR_INVALIDPARAM;        }    }    return DS_OK;}static HRESULT WINAPI PrimaryBufferImpl_Lock(	LPDIRECTSOUNDBUFFER8 iface,DWORD writecursor,DWORD writebytes,LPVOID lplpaudioptr1,LPDWORD audiobytes1,LPVOID lplpaudioptr2,LPDWORD audiobytes2,DWORD flags) {        DirectSoundDevice *device = ((PrimaryBufferImpl *)iface)->dsound->device;	TRACE("(%p,%ld,%ld,%p,%p,%p,%p,0x%08lx) at %ld\n",		iface,		writecursor,		writebytes,		lplpaudioptr1,		audiobytes1,		lplpaudioptr2,		audiobytes2,		flags,		GetTickCount()	);	if (device->priolevel != DSSCL_WRITEPRIMARY) {		WARN("failed priority check!\n");		return DSERR_PRIOLEVELNEEDED;	}	if (flags & DSBLOCK_FROMWRITECURSOR) {		DWORD writepos;		HRESULT hres;		/* GetCurrentPosition does too much magic to duplicate here */		hres = IDirectSoundBuffer_GetCurrentPosition(iface, NULL, &writepos);		if (hres != DS_OK) {			WARN("IDirectSoundBuffer_GetCurrentPosition failed\n");			return hres;		}		writecursor += writepos;	}	while (writecursor >= device->buflen)		writecursor -= device->buflen;	if (flags & DSBLOCK_ENTIREBUFFER)		writebytes = device->buflen;	if (writebytes > device->buflen)		writebytes = device->buflen;	if (!(device->drvdesc.dwFlags & DSDDESC_DONTNEEDPRIMARYLOCK) && device->hwbuf) {		HRESULT hres;		hres = IDsDriverBuffer_Lock(device->hwbuf,					    lplpaudioptr1, audiobytes1,					    lplpaudioptr2, audiobytes2,					    writecursor, writebytes,					    0);		if (hres != DS_OK) {			WARN("IDsDriverBuffer_Lock failed\n");			return hres;		}	} else {		if (writecursor+writebytes <= device->buflen) {			*(LPBYTE*)lplpaudioptr1 = device->buffer+writecursor;			*audiobytes1 = writebytes;			if (lplpaudioptr2)				*(LPBYTE*)lplpaudioptr2 = NULL;			if (audiobytes2)				*audiobytes2 = 0;			TRACE("->%ld.0\n",writebytes);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -