buffer.c
来自「一个类似windows」· C语言 代码 · 共 1,512 行 · 第 1/3 页
C
1,512 行
} TRACE("Created buffer at %p\n", dsb); dsb->ref = 0; dsb->dsb = 0; dsb->dsound = ds; dsb->lpVtbl = &dsbvt; dsb->iks = NULL; /* size depends on version */ CopyMemory(&dsb->dsbd, dsbd, dsbd->dwSize); /* variable sized struct so calculate size based on format */ if (wfex->wFormatTag == WAVE_FORMAT_PCM) { alloc_size = sizeof(WAVEFORMATEX); cp_size = sizeof(PCMWAVEFORMAT); } else alloc_size = cp_size = sizeof(WAVEFORMATEX) + wfex->cbSize; dsb->pwfx = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,alloc_size); if (dsb->pwfx == NULL) { WARN("out of memory\n"); HeapFree(GetProcessHeap(),0,dsb); *pdsb = NULL; return DSERR_OUTOFMEMORY; } CopyMemory(dsb->pwfx, wfex, cp_size); if (dsbd->dwBufferBytes % dsbd->lpwfxFormat->nBlockAlign) dsb->buflen = dsbd->dwBufferBytes + (dsbd->lpwfxFormat->nBlockAlign - (dsbd->dwBufferBytes % dsbd->lpwfxFormat->nBlockAlign)); else dsb->buflen = dsbd->dwBufferBytes; dsb->freq = dsbd->lpwfxFormat->nSamplesPerSec; dsb->notify = NULL; dsb->notifies = NULL; dsb->nrofnotifies = 0; dsb->hwnotify = 0; /* Check necessary hardware mixing capabilities */ if (wfex->nChannels==2) capf |= DSCAPS_SECONDARYSTEREO; else capf |= DSCAPS_SECONDARYMONO; if (wfex->wBitsPerSample==16) capf |= DSCAPS_SECONDARY16BIT; else capf |= DSCAPS_SECONDARY8BIT; use_hw = (ds->device->drvcaps.dwFlags & capf) == capf; TRACE("use_hw = 0x%08x, capf = 0x%08lx, ds->drvcaps.dwFlags = 0x%08lx\n", use_hw, capf, ds->device->drvcaps.dwFlags); /* FIXME: check hardware sample rate mixing capabilities */ /* FIXME: check app hints for software/hardware buffer (STATIC, LOCHARDWARE, etc) */ /* FIXME: check whether any hardware buffers are left */ /* FIXME: handle DSDHEAP_CREATEHEAP for hardware buffers */ /* Allocate an empty buffer */ dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer))); if (dsb->buffer == NULL) { WARN("out of memory\n"); HeapFree(GetProcessHeap(),0,dsb->pwfx); HeapFree(GetProcessHeap(),0,dsb); *pdsb = NULL; return DSERR_OUTOFMEMORY; } /* Allocate system memory for buffer if applicable */ if ((ds->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) || !use_hw) { dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen); if (dsb->buffer->memory == NULL) { WARN("out of memory\n"); HeapFree(GetProcessHeap(),0,dsb->pwfx); HeapFree(GetProcessHeap(),0,dsb->buffer); HeapFree(GetProcessHeap(),0,dsb); *pdsb = NULL; return DSERR_OUTOFMEMORY; } dsb->buffer->ref = 1; FillMemory(dsb->buffer->memory, dsb->buflen, dsbd->lpwfxFormat->wBitsPerSample == 8 ? 128 : 0); } /* Allocate the hardware buffer */ if (use_hw) { err = IDsDriver_CreateSoundBuffer(ds->device->driver,wfex,dsbd->dwFlags,0, &(dsb->buflen),&(dsb->buffer->memory), (LPVOID*)&(dsb->hwbuf)); /* fall back to software buffer on failure */ if (err != DS_OK) { TRACE("IDsDriver_CreateSoundBuffer failed, falling back to software buffer\n"); use_hw = 0; if (ds->device->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) { dsb->buffer->memory = HeapAlloc(GetProcessHeap(),0,dsb->buflen); if (dsb->buffer->memory == NULL) { WARN("out of memory\n"); HeapFree(GetProcessHeap(),0,dsb->buffer); HeapFree(GetProcessHeap(),0,dsb->pwfx); HeapFree(GetProcessHeap(),0,dsb); *pdsb = NULL; return DSERR_OUTOFMEMORY; } dsb->buffer->ref = 1; FillMemory(dsb->buffer->memory, dsb->buflen, dsbd->lpwfxFormat->wBitsPerSample == 8 ? 128 : 0); } err = DS_OK; } } /* calculate fragment size and write lead */ DSOUND_RecalcFormat(dsb); /* It's not necessary to initialize values to zero since */ /* we allocated this structure with HEAP_ZERO_MEMORY... */ dsb->playpos = 0; dsb->buf_mixpos = 0; dsb->state = STATE_STOPPED; dsb->freqAdjust = (dsb->freq << DSOUND_FREQSHIFT) / ds->device->pwfx->nSamplesPerSec; dsb->nAvgBytesPerSec = dsb->freq * dsbd->lpwfxFormat->nBlockAlign; if (dsb->dsbd.dwFlags & DSBCAPS_CTRL3D) { dsb->ds3db_ds3db.dwSize = sizeof(DS3DBUFFER); dsb->ds3db_ds3db.vPosition.x = 0.0; dsb->ds3db_ds3db.vPosition.y = 0.0; dsb->ds3db_ds3db.vPosition.z = 0.0; dsb->ds3db_ds3db.vVelocity.x = 0.0; dsb->ds3db_ds3db.vVelocity.y = 0.0; dsb->ds3db_ds3db.vVelocity.z = 0.0; dsb->ds3db_ds3db.dwInsideConeAngle = DS3D_DEFAULTCONEANGLE; dsb->ds3db_ds3db.dwOutsideConeAngle = DS3D_DEFAULTCONEANGLE; dsb->ds3db_ds3db.vConeOrientation.x = 0.0; dsb->ds3db_ds3db.vConeOrientation.y = 0.0; dsb->ds3db_ds3db.vConeOrientation.z = 0.0; dsb->ds3db_ds3db.lConeOutsideVolume = DS3D_DEFAULTCONEOUTSIDEVOLUME; dsb->ds3db_ds3db.flMinDistance = DS3D_DEFAULTMINDISTANCE; dsb->ds3db_ds3db.flMaxDistance = DS3D_DEFAULTMAXDISTANCE; dsb->ds3db_ds3db.dwMode = DS3DMODE_NORMAL; dsb->ds3db_need_recalc = FALSE; DSOUND_Calc3DBuffer(dsb); } else DSOUND_RecalcVolPan(&(dsb->volpan)); InitializeCriticalSection(&(dsb->lock)); dsb->lock.DebugInfo->Spare[0] = (DWORD_PTR)"DSOUNDBUFFER_lock"; /* register buffer if not primary */ if (!(dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER)) { err = DSOUND_AddBuffer(ds, dsb); if (err != DS_OK) { HeapFree(GetProcessHeap(),0,dsb->buffer->memory); HeapFree(GetProcessHeap(),0,dsb->buffer); dsb->lock.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&(dsb->lock)); HeapFree(GetProcessHeap(),0,dsb->pwfx); HeapFree(GetProcessHeap(),0,dsb); dsb = NULL; } } *pdsb = dsb; return err;}HRESULT WINAPI IDirectSoundBufferImpl_Destroy( IDirectSoundBufferImpl *pdsb){ TRACE("(%p)\n",pdsb); /* This keeps the *_Destroy functions from possibly deleting * this object until it is ready to be deleted */ IDirectSoundBufferImpl_AddRef((LPDIRECTSOUNDBUFFER8)pdsb); if (pdsb->iks) { WARN("iks not NULL\n"); IKsBufferPropertySetImpl_Destroy(pdsb->iks); pdsb->iks = NULL; } if (pdsb->ds3db) { WARN("ds3db not NULL\n"); IDirectSound3DBufferImpl_Destroy(pdsb->ds3db); pdsb->ds3db = NULL; } if (pdsb->notify) { WARN("notify not NULL\n"); IDirectSoundNotifyImpl_Destroy(pdsb->notify); pdsb->notify = NULL; } if (pdsb->dsb) { WARN("dsb not NULL\n"); SecondaryBufferImpl_Destroy(pdsb->dsb); pdsb->dsb = NULL; } while (IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)pdsb) > 0); return S_OK;}/******************************************************************************* * SecondaryBuffer */static HRESULT WINAPI SecondaryBufferImpl_QueryInterface( LPDIRECTSOUNDBUFFER8 iface,REFIID riid,LPVOID *ppobj){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj); return IDirectSoundBufferImpl_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb,riid,ppobj);}static ULONG WINAPI SecondaryBufferImpl_AddRef(LPDIRECTSOUNDBUFFER8 iface){ IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface; ULONG ref = InterlockedIncrement(&(This->ref)); TRACE("(%p) ref was %ld\n", This, ref - 1); return ref;}static ULONG WINAPI SecondaryBufferImpl_Release(LPDIRECTSOUNDBUFFER8 iface){ IDirectSoundBufferImpl *This = (IDirectSoundBufferImpl *)iface; ULONG ref = InterlockedDecrement(&(This->ref)); TRACE("(%p) ref was %ld\n", This, ref + 1); if (!ref) { This->dsb->dsb = NULL; IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)This->dsb); HeapFree(GetProcessHeap(), 0, This); TRACE("(%p) released\n", This); } return ref;}static HRESULT WINAPI SecondaryBufferImpl_GetCaps( LPDIRECTSOUNDBUFFER8 iface,LPDSBCAPS caps){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p)->(%p)\n",This,caps); return IDirectSoundBufferImpl_GetCaps((LPDIRECTSOUNDBUFFER8)This->dsb,caps);}static HRESULT WINAPI SecondaryBufferImpl_GetCurrentPosition( LPDIRECTSOUNDBUFFER8 iface,LPDWORD playpos,LPDWORD writepos){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%p,%p)\n",This,playpos,writepos); return IDirectSoundBufferImpl_GetCurrentPosition((LPDIRECTSOUNDBUFFER8)This->dsb,playpos,writepos);}static HRESULT WINAPI SecondaryBufferImpl_GetFormat( LPDIRECTSOUNDBUFFER8 iface,LPWAVEFORMATEX lpwf,DWORD wfsize,LPDWORD wfwritten){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%p,%ld,%p)\n",This,lpwf,wfsize,wfwritten); return IDirectSoundBufferImpl_GetFormat((LPDIRECTSOUNDBUFFER8)This->dsb,lpwf,wfsize,wfwritten);}static HRESULT WINAPI SecondaryBufferImpl_GetVolume( LPDIRECTSOUNDBUFFER8 iface,LPLONG vol){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%p)\n",This,vol); return IDirectSoundBufferImpl_GetVolume((LPDIRECTSOUNDBUFFER8)This->dsb,vol);}static HRESULT WINAPI SecondaryBufferImpl_GetPan( LPDIRECTSOUNDBUFFER8 iface,LPLONG pan){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%p)\n",This,pan); return IDirectSoundBufferImpl_GetPan((LPDIRECTSOUNDBUFFER8)This->dsb,pan);}static HRESULT WINAPI SecondaryBufferImpl_GetFrequency( LPDIRECTSOUNDBUFFER8 iface,LPDWORD freq){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%p)\n",This,freq); return IDirectSoundBufferImpl_GetFrequency((LPDIRECTSOUNDBUFFER8)This->dsb,freq);}static HRESULT WINAPI SecondaryBufferImpl_GetStatus( LPDIRECTSOUNDBUFFER8 iface,LPDWORD status){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%p)\n",This,status); return IDirectSoundBufferImpl_GetStatus((LPDIRECTSOUNDBUFFER8)This->dsb,status);}static HRESULT WINAPI SecondaryBufferImpl_Initialize( LPDIRECTSOUNDBUFFER8 iface,LPDIRECTSOUND dsound,LPCDSBUFFERDESC dbsd){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%p,%p)\n",This,dsound,dbsd); return IDirectSoundBufferImpl_Initialize((LPDIRECTSOUNDBUFFER8)This->dsb,dsound,dbsd);}static HRESULT WINAPI SecondaryBufferImpl_Lock( LPDIRECTSOUNDBUFFER8 iface, DWORD writecursor, DWORD writebytes, LPVOID lplpaudioptr1, LPDWORD audiobytes1, LPVOID lplpaudioptr2, LPDWORD audiobytes2, DWORD dwFlags){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%ld,%ld,%p,%p,%p,%p,0x%08lx)\n", This,writecursor,writebytes,lplpaudioptr1,audiobytes1,lplpaudioptr2,audiobytes2,dwFlags); return IDirectSoundBufferImpl_Lock((LPDIRECTSOUNDBUFFER8)This->dsb, writecursor,writebytes,lplpaudioptr1,audiobytes1,lplpaudioptr2,audiobytes2,dwFlags);}static HRESULT WINAPI SecondaryBufferImpl_Play( LPDIRECTSOUNDBUFFER8 iface,DWORD reserved1,DWORD reserved2,DWORD flags){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%08lx,%08lx,%08lx)\n",This,reserved1,reserved2,flags); return IDirectSoundBufferImpl_Play((LPDIRECTSOUNDBUFFER8)This->dsb,reserved1,reserved2,flags);}static HRESULT WINAPI SecondaryBufferImpl_SetCurrentPosition( LPDIRECTSOUNDBUFFER8 iface,DWORD newpos){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%ld)\n",This,newpos); return IDirectSoundBufferImpl_SetCurrentPosition((LPDIRECTSOUNDBUFFER8)This->dsb,newpos);}static HRESULT WINAPI SecondaryBufferImpl_SetFormat( LPDIRECTSOUNDBUFFER8 iface,LPCWAVEFORMATEX wfex){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%p)\n",This,wfex); return IDirectSoundBufferImpl_SetFormat((LPDIRECTSOUNDBUFFER8)This->dsb,wfex);}static HRESULT WINAPI SecondaryBufferImpl_SetVolume( LPDIRECTSOUNDBUFFER8 iface,LONG vol){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%ld)\n",This,vol); return IDirectSoundBufferImpl_SetVolume((LPDIRECTSOUNDBUFFER8)This->dsb,vol);}static HRESULT WINAPI SecondaryBufferImpl_SetPan( LPDIRECTSOUNDBUFFER8 iface,LONG pan){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%ld)\n",This,pan); return IDirectSoundBufferImpl_SetPan((LPDIRECTSOUNDBUFFER8)This->dsb,pan);}static HRESULT WINAPI SecondaryBufferImpl_SetFrequency( LPDIRECTSOUNDBUFFER8 iface,DWORD freq){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%ld)\n",This,freq); return IDirectSoundBufferImpl_SetFrequency((LPDIRECTSOUNDBUFFER8)This->dsb,freq);}static HRESULT WINAPI SecondaryBufferImpl_Stop(LPDIRECTSOUNDBUFFER8 iface){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p)\n",This); return IDirectSoundBufferImpl_Stop((LPDIRECTSOUNDBUFFER8)This->dsb);}static HRESULT WINAPI SecondaryBufferImpl_Unlock( LPDIRECTSOUNDBUFFER8 iface, LPVOID lpvAudioPtr1, DWORD dwAudioBytes1, LPVOID lpvAudioPtr2, DWORD dwAudioBytes2){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%p,%ld,%p,%ld)\n", This, lpvAudioPtr1, dwAudioBytes1, lpvAudioPtr2, dwAudioBytes2); return IDirectSoundBufferImpl_Unlock((LPDIRECTSOUNDBUFFER8)This->dsb, lpvAudioPtr1,dwAudioBytes1,lpvAudioPtr2,dwAudioBytes2);}static HRESULT WINAPI SecondaryBufferImpl_Restore( LPDIRECTSOUNDBUFFER8 iface){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p)\n",This); return IDirectSoundBufferImpl_Restore((LPDIRECTSOUNDBUFFER8)This->dsb);}static HRESULT WINAPI SecondaryBufferImpl_SetFX( LPDIRECTSOUNDBUFFER8 iface,DWORD dwEffectsCount,LPDSEFFECTDESC pDSFXDesc,LPDWORD pdwResultCodes){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%lu,%p,%p)\n",This,dwEffectsCount,pDSFXDesc,pdwResultCodes); return IDirectSoundBufferImpl_SetFX((LPDIRECTSOUNDBUFFER8)This->dsb,dwEffectsCount,pDSFXDesc,pdwResultCodes);}static HRESULT WINAPI SecondaryBufferImpl_AcquireResources( LPDIRECTSOUNDBUFFER8 iface,DWORD dwFlags,DWORD dwEffectsCount,LPDWORD pdwResultCodes){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%08lu,%lu,%p)\n",This,dwFlags,dwEffectsCount,pdwResultCodes); return IDirectSoundBufferImpl_AcquireResources((LPDIRECTSOUNDBUFFER8)This->dsb,dwFlags,dwEffectsCount,pdwResultCodes);}static HRESULT WINAPI SecondaryBufferImpl_GetObjectInPath( LPDIRECTSOUNDBUFFER8 iface,REFGUID rguidObject,DWORD dwIndex,REFGUID rguidInterface,LPVOID* ppObject){ SecondaryBufferImpl *This = (SecondaryBufferImpl *)iface; TRACE("(%p,%s,%lu,%s,%p)\n",This,debugstr_guid(rguidObject),dwIndex,debugstr_guid(rguidInterface),ppObject); return IDirectSoundBufferImpl_GetObjectInPath((LPDIRECTSOUNDBUFFER8)This->dsb,rguidObject,dwIndex,rguidInterface,ppObject);}static const IDirectSoundBuffer8Vtbl sbvt ={ SecondaryBufferImpl_QueryInterface, SecondaryBufferImpl_AddRef, SecondaryBufferImpl_Release, SecondaryBufferImpl_GetCaps, SecondaryBufferImpl_GetCurrentPosition, SecondaryBufferImpl_GetFormat, SecondaryBufferImpl_GetVolume, SecondaryBufferImpl_GetPan, SecondaryBufferImpl_GetFrequency, SecondaryBufferImpl_GetStatus, SecondaryBufferImpl_Initialize, SecondaryBufferImpl_Lock, SecondaryBufferImpl_Play, SecondaryBufferImpl_SetCurrentPosition, SecondaryBufferImpl_SetFormat, SecondaryBufferImpl_SetVolume, SecondaryBufferImpl_SetPan, SecondaryBufferImpl_SetFrequency, SecondaryBufferImpl_Stop, SecondaryBufferImpl_Unlock, SecondaryBufferImpl_Restore, SecondaryBufferImpl_SetFX, SecondaryBufferImpl_AcquireResources, SecondaryBufferImpl_GetObjectInPath};HRESULT WINAPI SecondaryBufferImpl_Create( IDirectSoundBufferImpl *dsb, SecondaryBufferImpl **psb){ SecondaryBufferImpl *sb; TRACE("(%p,%p)\n",dsb,psb); sb = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*sb)); if (sb == 0) { WARN("out of memory\n"); *psb = NULL; return DSERR_OUTOFMEMORY; } sb->ref = 0; sb->dsb = dsb; sb->lpVtbl = &sbvt; IDirectSoundBuffer8_AddRef((LPDIRECTSOUNDBUFFER8)dsb); *psb = sb; return S_OK;}HRESULT WINAPI SecondaryBufferImpl_Destroy( SecondaryBufferImpl *pdsb){ TRACE("(%p)\n",pdsb); while (SecondaryBufferImpl_Release((LPDIRECTSOUNDBUFFER8)pdsb) > 0); return S_OK;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?