static void DS_Update(void) { LPVOID block; DWORD bBytes; /* Do first update in DS_Update() to be consistent with other non threaded drivers. */ if (do_update && pSoundBuffer) { do_update = 0; if (IDirectSoundBuffer_Lock(pSoundBuffer, 0, fragsize, &block, &bBytes, NULL, NULL, 0) == DSERR_BUFFERLOST) { IDirectSoundBuffer_Restore (pSoundBuffer); IDirectSoundBuffer_Lock (pSoundBuffer, 0, fragsize, &block, &bBytes, NULL, NULL, 0); } if (Player_Paused_internal()) { VC_SilenceBytes ((SBYTE *)block, (ULONG)bBytes); } else { VC_WriteBytes ((SBYTE *)block, (ULONG)bBytes); } IDirectSoundBuffer_Unlock (pSoundBuffer, block, bBytes, NULL, 0); IDirectSoundBuffer_SetCurrentPosition(pSoundBuffer, 0); IDirectSoundBuffer_Play(pSoundBuffer, 0, 0, DSBPLAY_LOOPING); threadInUse=1; ResumeThread (updateBufferHandle); } }
static BOOL AppWriteDataToBuffer(LPDIRECTSOUNDBUFFER lpDsb, // The buffer. DWORD dwOffset, // Our own write cursor. LPBYTE lpbSoundData, // Start of our data. DWORD dwSoundBytes) // Size of block to copy. { LPVOID lpvPtr1; DWORD dwBytes1; LPVOID lpvPtr2; DWORD dwBytes2; HRESULT hr; // Obtain memory address of write block. This will be in two parts // if the block wraps around. hr = IDirectSoundBuffer_Lock( lpDsb, dwOffset, dwSoundBytes, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); // If the buffer was lost, restore and retry lock. if (DSERR_BUFFERLOST == hr) { IDirectSoundBuffer_Restore(lpDsb); hr = IDirectSoundBuffer_Lock( lpDsb, dwOffset, dwSoundBytes, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); } if SUCCEEDED(hr) { pj_memcpy(lpvPtr1, lpbSoundData, dwBytes1); if (NULL != lpvPtr2) pj_memcpy(lpvPtr2, lpbSoundData+dwBytes1, dwBytes2); hr = IDirectSoundBuffer_Unlock(lpDsb, lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); if SUCCEEDED(hr) return TRUE; } return FALSE; }
static Uint8 * DSOUND_GetDeviceBuf(_THIS) { DWORD cursor = 0; DWORD junk = 0; HRESULT result = DS_OK; DWORD rawlen = 0; /* Figure out which blocks to fill next */ this->hidden->locked_buf = NULL; result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf, &junk, &cursor); if (result == DSERR_BUFFERLOST) { IDirectSoundBuffer_Restore(this->hidden->mixbuf); result = IDirectSoundBuffer_GetCurrentPosition(this->hidden->mixbuf, &junk, &cursor); } if (result != DS_OK) { SetDSerror("DirectSound GetCurrentPosition", result); return (NULL); } cursor /= this->hidden->mixlen; #ifdef DEBUG_SOUND /* Detect audio dropouts */ { DWORD spot = cursor; if (spot < this->hidden->lastchunk) { spot += this->hidden->num_buffers; } if (spot > this->hidden->lastchunk + 1) { fprintf(stderr, "Audio dropout, missed %d fragments\n", (spot - (this->hidden->lastchunk + 1))); } } #endif this->hidden->lastchunk = cursor; cursor = (cursor + 1) % this->hidden->num_buffers; cursor *= this->hidden->mixlen; /* Lock the audio buffer */ result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor, this->hidden->mixlen, (LPVOID *) & this->hidden->locked_buf, &rawlen, NULL, &junk, 0); if (result == DSERR_BUFFERLOST) { IDirectSoundBuffer_Restore(this->hidden->mixbuf); result = IDirectSoundBuffer_Lock(this->hidden->mixbuf, cursor, this->hidden->mixlen, (LPVOID *) & this-> hidden->locked_buf, &rawlen, NULL, &junk, 0); } if (result != DS_OK) { SetDSerror("DirectSound Lock", result); return (NULL); } return (this->hidden->locked_buf); }
/** \brief fill sound buffer \param data pointer to the sound data to copy \param len length of the data to copy in bytes \return number of copyed bytes */ static int write_buffer(struct ao *ao, unsigned char *data, int len) { struct priv *p = ao->priv; HRESULT res; LPVOID lpvPtr1; DWORD dwBytes1; LPVOID lpvPtr2; DWORD dwBytes2; p->underrun_check = 0; // Lock the buffer res = IDirectSoundBuffer_Lock(p->hdsbuf, p->write_offset, len, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); // If the buffer was lost, restore and retry lock. if (DSERR_BUFFERLOST == res) { IDirectSoundBuffer_Restore(p->hdsbuf); res = IDirectSoundBuffer_Lock(p->hdsbuf, p->write_offset, len, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); } if (SUCCEEDED(res)) { if (!AF_FORMAT_IS_AC3(ao->format)) { memcpy(lpvPtr1, data, dwBytes1); if (lpvPtr2 != NULL) memcpy(lpvPtr2, (char *)data + dwBytes1, dwBytes2); p->write_offset += dwBytes1 + dwBytes2; if (p->write_offset >= p->buffer_size) p->write_offset = dwBytes2; } else { // Write to pointers without reordering. memcpy(lpvPtr1, data, dwBytes1); if (NULL != lpvPtr2) memcpy(lpvPtr2, data + dwBytes1, dwBytes2); p->write_offset += dwBytes1 + dwBytes2; if (p->write_offset >= p->buffer_size) p->write_offset = dwBytes2; } // Release the data back to DirectSound. res = IDirectSoundBuffer_Unlock(p->hdsbuf, lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); if (SUCCEEDED(res)) { // Success. DWORD status; IDirectSoundBuffer_GetStatus(p->hdsbuf, &status); if (!(status & DSBSTATUS_PLAYING)) res = IDirectSoundBuffer_Play(p->hdsbuf, 0, 0, DSBPLAY_LOOPING); return dwBytes1 + dwBytes2; } } // Lock, Unlock, or Restore failed. return 0; }
static Uint8 *DX5_GetAudioBuf(_THIS) { DWORD cursor, junk; HRESULT result; DWORD rawlen; /* Figure out which blocks to fill next */ locked_buf = NULL; result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor); if ( result == DSERR_BUFFERLOST ) { IDirectSoundBuffer_Restore(mixbuf); result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &junk, &cursor); } if ( result != DS_OK ) { SetDSerror("DirectSound GetCurrentPosition", result); return(NULL); } cursor /= mixlen; #ifdef DEBUG_SOUND /* Detect audio dropouts */ { DWORD spot = cursor; if ( spot < lastchunk ) { spot += NUM_BUFFERS; } if ( spot > lastchunk+1 ) { fprintf(stderr, "Audio dropout, missed %d fragments\n", (spot - (lastchunk+1))); } } #endif lastchunk = cursor; cursor = (cursor+1)%NUM_BUFFERS; cursor *= mixlen; /* Lock the audio buffer */ result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, (LPVOID *)&locked_buf, &rawlen, NULL, &junk, 0); if ( result == DSERR_BUFFERLOST ) { IDirectSoundBuffer_Restore(mixbuf); result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, (LPVOID *)&locked_buf, &rawlen, NULL, &junk, 0); } if ( result != DS_OK ) { SetDSerror("DirectSound Lock", result); return(NULL); } return(locked_buf); }
HRESULT DSW_ZeroEmptySpace( DSoundWrapper *dsw ) { HRESULT hr; LPBYTE lpbuf1 = NULL; LPBYTE lpbuf2 = NULL; DWORD dwsize1 = 0; DWORD dwsize2 = 0; long bytesEmpty; hr = DSW_QueryOutputSpace( dsw, &bytesEmpty ); // updates dsw_FramesPlayed if (hr != DS_OK) return hr; if( bytesEmpty == 0 ) return DS_OK; // Lock free space in the DS hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, bytesEmpty, (void **) &lpbuf1, &dwsize1, (void **) &lpbuf2, &dwsize2, 0); if (hr == DS_OK) { // Copy the buffer into the DS ZeroMemory(lpbuf1, dwsize1); if(lpbuf2 != NULL) { ZeroMemory(lpbuf2, dwsize2); } // Update our buffer offset and unlock sound buffer dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize; IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2); dsw->dsw_FramesWritten += bytesEmpty / dsw->dsw_BytesPerFrame; } return hr; }
HRESULT DSW_WriteBlock( DSoundWrapper *dsw, char *buf, long numBytes ) { HRESULT hr; LPBYTE lpbuf1 = NULL; LPBYTE lpbuf2 = NULL; DWORD dwsize1 = 0; DWORD dwsize2 = 0; // Lock free space in the DS hr = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, dsw->dsw_WriteOffset, numBytes, (void **) &lpbuf1, &dwsize1, (void **) &lpbuf2, &dwsize2, 0); if (hr == DS_OK) { // Copy the buffer into the DS CopyMemory(lpbuf1, buf, dwsize1); if(lpbuf2 != NULL) { CopyMemory(lpbuf2, buf+dwsize1, dwsize2); } // Update our buffer offset and unlock sound buffer dsw->dsw_WriteOffset = (dsw->dsw_WriteOffset + dwsize1 + dwsize2) % dsw->dsw_OutputSize; IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2); dsw->dsw_FramesWritten += numBytes / dsw->dsw_BytesPerFrame; } return hr; }
static void dx_clear(void) { LPVOID lpvPtr1; DWORD dwBytes1; LPVOID lpvPtr2; DWORD dwBytes2; HRESULT result; result = IDirectSoundBuffer_Lock(buffer, 0, buffer_size, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); if (result == DSERR_BUFFERLOST) { IDirectSoundBuffer_Restore(buffer); } else { if (is16bit) { memset(lpvPtr1, 0, dwBytes1); if (lpvPtr2) memset(lpvPtr2, 0, dwBytes2); } else { memset(lpvPtr1, 0x80, dwBytes1); if (lpvPtr2) memset(lpvPtr2, 0x80, dwBytes2); } result = IDirectSoundBuffer_Unlock(buffer, lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); } }
void m1sdr_TimeCheck(void) { int nPlaySeg=0, nFollowingSeg=0; DWORD nPlay=0, nWrite=0; int nRet=0; if (!lpDS) return; // We should do nothing until nPlay has left nDSoundNextSeg IDirectSoundBuffer_GetCurrentPosition(lpSecB, &nPlay, &nWrite); nPlaySeg=nPlay/(nDSoundSegLen<<2); if (nPlaySeg>nDSoundSegCount-1) nPlaySeg=nDSoundSegCount-1; if (nPlaySeg<0) nPlaySeg=0; // important to ensure nPlaySeg clipped for below if (nDSoundNextSeg == nPlaySeg) { Sleep(200); // Don't need to do anything for a bit goto End; } // work out which seg we will fill next nFollowingSeg = nDSoundNextSeg; WRAP_INC(nFollowingSeg) while (nDSoundNextSeg != nPlaySeg) { void *pData=NULL,*pData2=NULL; DWORD cbLen=0,cbLen2=0; // fill nNextSeg // Lock the relevant seg of the loop buffer nRet = IDirectSoundBuffer_Lock(lpSecB, nDSoundNextSeg*(nDSoundSegLen<<2), nDSoundSegLen<<2, &pData, &cbLen, &pData2, &cbLen2, 0); if (nRet>=0 && pData!=NULL) { // Locked the seg okay - write the sound we calculated last time memcpy(pData, samples, nDSoundSegLen<<2); } // Unlock (2nd 0 is because we wrote nothing to second part) if (nRet>=0) IDirectSoundBuffer_Unlock(lpSecB, pData, cbLen, pData2, 0); // generate more samples if (m1sdr_Callback) { m1sdr_Callback(nDSoundSegLen, samples); playtime++; } else { memset(samples, 0, nDSoundSegLen*4); } nDSoundNextSeg = nFollowingSeg; WRAP_INC(nFollowingSeg) } End: return; }
static HRESULT WINAPI DSoundRender_InputPin_BeginFlush(IPin * iface) { InputPin *This = (InputPin *)iface; DSoundRenderImpl *pFilter = (DSoundRenderImpl *)This->pin.pinInfo.pFilter; HRESULT hr; LPBYTE buffer; DWORD size; TRACE("\n"); EnterCriticalSection(This->pin.pCritSec); hr = InputPin_BeginFlush(iface); if (pFilter->dsbuffer) { IDirectSoundBuffer_Stop(pFilter->dsbuffer); /* Force a reset */ IDirectSoundBuffer_SetCurrentPosition(pFilter->dsbuffer, 0); pFilter->write_pos = pFilter->last_play_pos = 0; ++pFilter->play_loops; pFilter->write_loops = pFilter->play_loops; IDirectSoundBuffer_Lock(pFilter->dsbuffer, 0, 0, (LPVOID *)&buffer, &size, NULL, NULL, DSBLOCK_ENTIREBUFFER); memset(buffer, 0, size); IDirectSoundBuffer_Unlock(pFilter->dsbuffer, buffer, size, NULL, 0); } if (pFilter->state == State_Paused) SetEvent(pFilter->blocked); LeaveCriticalSection(This->pin.pCritSec); return hr; }
static DWORD WINAPI updateBufferProc(LPVOID lpParameter) { LPVOID pBlock1 = NULL, pBlock2 = NULL; DWORD soundBufferCurrentPosition, blockBytes1, blockBytes2; DWORD start; while (threadInUse) { if (WaitForSingleObject(notifyUpdateHandle,INFINITE)==WAIT_OBJECT_0) { if (!threadInUse) break; IDirectSoundBuffer_GetCurrentPosition (pSoundBuffer,&soundBufferCurrentPosition,NULL); if (soundBufferCurrentPosition < fragsize) start = fragsize; else start = 0; if (IDirectSoundBuffer_Lock (pSoundBuffer,start,fragsize,&pBlock1,&blockBytes1, &pBlock2,&blockBytes2,0)==DSERR_BUFFERLOST) { IDirectSoundBuffer_Restore(pSoundBuffer); IDirectSoundBuffer_Lock (pSoundBuffer,start,fragsize,&pBlock1,&blockBytes1, &pBlock2,&blockBytes2,0); } MUTEX_LOCK(vars); if (Player_Paused_internal()) { VC_SilenceBytes((SBYTE*)pBlock1,(ULONG)blockBytes1); if (pBlock2) VC_SilenceBytes((SBYTE*)pBlock2,(ULONG)blockBytes2); } else { VC_WriteBytes((SBYTE*)pBlock1,(ULONG)blockBytes1); if (pBlock2) VC_WriteBytes((SBYTE*)pBlock2,(ULONG)blockBytes2); } MUTEX_UNLOCK(vars); IDirectSoundBuffer_Unlock (pSoundBuffer,pBlock1,blockBytes1,pBlock2,blockBytes2); } } return 0; }
static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, const BYTE *data, DWORD size) { HRESULT hr = S_OK; LPBYTE lpbuf1 = NULL; LPBYTE lpbuf2 = NULL; DWORD dwsize1 = 0; DWORD dwsize2 = 0; DWORD size2; DWORD play_pos,buf_free; do { hr = DSoundRender_GetPos(This, &play_pos, NULL); if (hr != DS_OK) { ERR("GetPos returned error: %x\n", hr); break; } if (This->write_pos <= play_pos) buf_free = play_pos-This->write_pos; else buf_free = This->buf_size - This->write_pos + play_pos; /* Wait for enough of the buffer to empty before filling it */ if(buf_free < This->buf_size/4) { Sleep(50); continue; } size2 = min(buf_free, size); hr = IDirectSoundBuffer_Lock(This->dsbuffer, This->write_pos, size2, (LPVOID *)&lpbuf1, &dwsize1, (LPVOID *)&lpbuf2, &dwsize2, 0); if (hr != DS_OK) { ERR("Unable to lock sound buffer! (%x)\n", hr); break; } /* TRACE("write_pos=%d, size=%d, sz1=%d, sz2=%d\n", This->write_pos, size2, dwsize1, dwsize2); */ memcpy(lpbuf1, data, dwsize1); if (dwsize2) memcpy(lpbuf2, data + dwsize1, dwsize2); hr = IDirectSoundBuffer_Unlock(This->dsbuffer, lpbuf1, dwsize1, lpbuf2, dwsize2); if (hr != DS_OK) ERR("Unable to unlock sound buffer! (%x)\n", hr); size -= dwsize1 + dwsize2; data += dwsize1 + dwsize2; This->write_pos += dwsize1 + dwsize2; if (This->write_pos >= This->buf_size) { This->write_pos -= This->buf_size; This->write_loops++; } } while (size && This->state == State_Running); return hr; }
void DSSoundFeedVoiceData(unsigned char* pSound,long lBytes) { LPVOID lpvPtr1, lpvPtr2; unsigned long dwBytes1,dwBytes2; unsigned long *lpSS, *lpSD; unsigned long dw,cplay,cwrite; HRESULT hr; unsigned long status; IDirectSoundBuffer_GetStatus(lpDSBSECONDARY1,&status); if (status & DSBSTATUS_BUFFERLOST) { if (IDirectSoundBuffer_Restore(lpDSBSECONDARY1) != DS_OK) return; IDirectSoundBuffer_Play(lpDSBSECONDARY1,0,0,DSBPLAY_LOOPING); } IDirectSoundBuffer_GetCurrentPosition(lpDSBSECONDARY1,&cplay,&cwrite); if(LastWrite == 0xffffffff) LastWrite=cwrite; hr = IDirectSoundBuffer_Lock(lpDSBSECONDARY1,LastWrite,lBytes, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); if (hr != DS_OK) { LastWrite=0xffffffff; return; } lpSS = (unsigned long *)pSound; lpSD = (unsigned long *)lpvPtr1; dw = dwBytes1 >> 2; while(dw) { *lpSD++=*lpSS++; dw--; } if (lpvPtr2) { lpSD = (unsigned long *)lpvPtr2; dw = dwBytes2 >> 2; while(dw) { *lpSD++ = *lpSS++; dw--; } } IDirectSoundBuffer_Unlock(lpDSBSECONDARY1,lpvPtr1,dwBytes1,lpvPtr2,dwBytes2); LastWrite += lBytes; if(LastWrite >= SOUNDSIZE) LastWrite -= SOUNDSIZE; LastPlay = cplay; }
static inline bool grab_region(dsound_t *ds, DWORD write_ptr, struct audio_lock *region) { HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, ®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0); if (res == DSERR_BUFFERLOST) { res = IDirectSoundBuffer_Restore(ds->dsb); if (res != DS_OK) return false; res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, ®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0); if (res != DS_OK) return false; } const char *err; switch (res) { case DSERR_BUFFERLOST: err = "DSERR_BUFFERLOST"; break; case DSERR_INVALIDCALL: err = "DSERR_INVALIDCALL"; break; case DSERR_INVALIDPARAM: err = "DSERR_INVALIDPARAM"; break; case DSERR_PRIOLEVELNEEDED: err = "DSERR_PRIOLEVELNEEDED"; break; default: err = NULL; } if (err) { RARCH_WARN("[DirectSound error]: %s\n", err); return false; } return true; }
static void clear_buffers(ds_t *ds) { ds->writering = ds->rings - 1; DWORD size; void *output; if (IDirectSoundBuffer_Lock(ds->dsb, 0, 0, &output, &size, 0, 0, DSBLOCK_ENTIREBUFFER) == DS_OK) { memset(output, 0, size); IDirectSoundBuffer_Unlock(ds->dsb, output, size, 0, 0); } }
static void dsound_clear_buffer(dsound_t *ds) { IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0); void *ptr; DWORD size; if (IDirectSoundBuffer_Lock(ds->dsb, 0, 0, &ptr, &size, NULL, NULL, DSBLOCK_ENTIREBUFFER) == DS_OK) { memset(ptr, 0, size); IDirectSoundBuffer_Unlock(ds->dsb, ptr, size, NULL, 0); } }
int DSOUND_UpdatePlayback(soundplay_t *sp, int samplechunks, char *buffer) { int ret; dsplay_t *dsp = (dsplay_t*)sp; char *sbuf; int sbufsize; int writable; int remaining = samplechunks; if (!samplechunks) return 0; IDirectSoundBuffer_GetCurrentPosition(dsp->dsbuf, &dsp->readpos, NULL); dsp->readpos /= dsp->sampbytes; while (ret = IDirectSoundBuffer_Lock(dsp->dsbuf, 0, dsp->buffersize*dsp->sampbytes, (void**)&sbuf, &sbufsize, NULL, NULL, 0)) { if (!FAILED(ret)) break; if (ret == DSERR_BUFFERLOST) printf("Buffer lost\n"); else break; // if (FAILED(IDirectSoundBuffer_Resore(dsp->dsbuf))) // return 0; } //memset(sbuf, 0, sbufsize); writable = remaining; if (writable > sbufsize/dsp->sampbytes - dsp->writepos) writable = sbufsize/dsp->sampbytes - dsp->writepos; memcpy(sbuf+dsp->writepos*dsp->sampbytes, buffer, writable*dsp->sampbytes); remaining -= writable; buffer += writable*dsp->sampbytes; dsp->writepos += writable; dsp->writepos %= dsp->buffersize; if (samplechunks > 0) { writable = remaining; if (writable > dsp->readpos) writable = dsp->readpos; memcpy(sbuf, buffer, writable*dsp->sampbytes); remaining -= writable; dsp->writepos += writable; dsp->writepos %= dsp->buffersize; } IDirectSoundBuffer_Unlock(dsp->dsbuf, sbuf, sbufsize, NULL, 0); printf("%i %i\n", 100*dsp->readpos / dsp->buffersize, 100*dsp->writepos / dsp->buffersize); return samplechunks - remaining; }
static HRESULT DSoundRender_SendSampleData(DSoundRenderImpl* This, REFERENCE_TIME tStart, REFERENCE_TIME tStop, const BYTE *data, DWORD size) { HRESULT hr; while (size && This->renderer.filter.state != State_Stopped) { DWORD writepos, skip = 0, free, size1, size2, ret; BYTE *buf1, *buf2; if (This->renderer.filter.state == State_Running) hr = DSoundRender_GetWritePos(This, &writepos, tStart, &free, &skip); else hr = S_FALSE; if (hr != S_OK) { This->in_loop = 1; LeaveCriticalSection(&This->renderer.csRenderLock); ret = WaitForSingleObject(This->blocked, 10); EnterCriticalSection(&This->renderer.csRenderLock); This->in_loop = 0; if (This->renderer.pInputPin->flushing || This->renderer.filter.state == State_Stopped) { return This->renderer.filter.state == State_Paused ? S_OK : VFW_E_WRONG_STATE; } if (ret != WAIT_TIMEOUT) ERR("%x\n", ret); continue; } tStart = -1; if (skip) FIXME("Sample dropped %u of %u bytes\n", skip, size); if (skip >= size) return S_OK; data += skip; size -= skip; hr = IDirectSoundBuffer_Lock(This->dsbuffer, writepos, min(free, size), (void**)&buf1, &size1, (void**)&buf2, &size2, 0); if (hr != DS_OK) { ERR("Unable to lock sound buffer! (%x)\n", hr); break; } memcpy(buf1, data, size1); if (size2) memcpy(buf2, data+size1, size2); IDirectSoundBuffer_Unlock(This->dsbuffer, buf1, size1, buf2, size2); This->writepos = (writepos + size1 + size2) % This->buf_size; TRACE("Wrote %u bytes at %u, next at %u - (%u/%u)\n", size1+size2, writepos, This->writepos, free, size); data += size1 + size2; size -= size1 + size2; } return S_OK; }
/* ==================== SndSys_LockRenderBuffer Get the exclusive lock on "snd_renderbuffer" ==================== */ qboolean SndSys_LockRenderBuffer (void) { #ifdef SUPPORTDIRECTX int reps; HRESULT hresult; DWORD dwStatus; if (pDSBuf) { // if the buffer was lost or stopped, restore it and/or restart it if (IDirectSoundBuffer_GetStatus (pDSBuf, &dwStatus) != DS_OK) Con_Print("Couldn't get sound buffer status\n"); if (dwStatus & DSBSTATUS_BUFFERLOST) { Con_Print("DSound buffer is lost!!\n"); IDirectSoundBuffer_Restore (pDSBuf); } if (!(dwStatus & DSBSTATUS_PLAYING)) IDirectSoundBuffer_Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); reps = 0; while ((hresult = IDirectSoundBuffer_Lock(pDSBuf, 0, gSndBufSize, (LPVOID*)&dsound_pbuf, &dsound_dwSize, (LPVOID*)&dsound_pbuf2, &dsound_dwSize2, 0)) != DS_OK) { if (hresult != DSERR_BUFFERLOST) { Con_Print("S_LockBuffer: DS: Lock Sound Buffer Failed\n"); S_Shutdown (); S_Startup (); return false; } if (++reps > 10000) { Con_Print("S_LockBuffer: DS: couldn't restore buffer\n"); S_Shutdown (); S_Startup (); return false; } } if ((void*)dsound_pbuf != snd_renderbuffer->ring) Sys_Error("SndSys_LockRenderBuffer: the ring address has changed!!!\n"); return true; } #endif return wav_init; }
static Uint8 *DX5_GetAudioBuf(_THIS) { DWORD cursor, junk; HRESULT result; DWORD rawlen; /* Figure out which blocks to fill next */ locked_buf = NULL; result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk); if ( result == DSERR_BUFFERLOST ) { IDirectSoundBuffer_Restore(mixbuf); result = IDirectSoundBuffer_GetCurrentPosition(mixbuf, &cursor, &junk); } if ( result != DS_OK ) { SetDSerror("DirectSound GetCurrentPosition", result); return(NULL); } cursor /= mixlen; playing = cursor; cursor = (cursor+1)%NUM_BUFFERS; cursor *= mixlen; /* Lock the audio buffer */ result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, (LPVOID *)&locked_buf, &rawlen, NULL, &junk, 0); if ( result == DSERR_BUFFERLOST ) { IDirectSoundBuffer_Restore(mixbuf); result = IDirectSoundBuffer_Lock(mixbuf, cursor, mixlen, (LPVOID *)&locked_buf, &rawlen, NULL, &junk, 0); } if ( result != DS_OK ) { SetDSerror("DirectSound Lock", result); return(NULL); } return(locked_buf); }
static int RawWrite(void *data, uint32_t len) { // uint32_t cw; //printf("Pre: %d\n",SexyALI_DSound_RawCanWrite(device)); //fflush(stdout); CheckDStatus(); /* In this block, we write as much data as we can, then we write the rest of it in >=1ms chunks. */ while(len) { VOID *LockPtr[2]={0,0}; DWORD LockLen[2]={0,0}; int32_t curlen; while(!(curlen=RawCanWrite())) { Sleep(1); } if(curlen>len) curlen=len; if(DS_OK == IDirectSoundBuffer_Lock(ppbufw,ToWritePos,curlen,&LockPtr[0],&LockLen[0],&LockPtr[1],&LockLen[1],0)) { } if(LockPtr[1] != 0 && LockPtr[1] != LockPtr[0]) { memcpy(LockPtr[0],data,LockLen[0]); memcpy(LockPtr[1],data+LockLen[0],len-LockLen[0]); } else if(LockPtr[0]) { memcpy(LockPtr[0],data,curlen); } IDirectSoundBuffer_Unlock(ppbufw,LockPtr[0],LockLen[0],LockPtr[1],LockLen[1]); ToWritePos=(ToWritePos+curlen)%DSBufferSize; len-=curlen; data = (void *)((uint8_t *)data + curlen); if(len) Sleep(1); } // end while(len) loop return(1); }
/* SB_Poll performs DMA transfers and fills the Direct Sound Buffer */ static DWORD CALLBACK SB_Poll( void *dummy ) { HRESULT result; LPBYTE lpbuf1 = NULL; LPBYTE lpbuf2 = NULL; DWORD dwsize1 = 0; DWORD dwsize2 = 0; DWORD dwbyteswritten1 = 0; DWORD dwbyteswritten2 = 0; int size; /* FIXME: this loop must be improved */ while(!end_sound_loop) { Sleep(10); if (dma_enable) { size = DMA_Transfer(SB_DMA,min(DMATRFSIZE,SamplesCount),dma_buffer); } else continue; result = IDirectSoundBuffer_Lock(lpdsbuf,buf_off,size,(LPVOID *)&lpbuf1,&dwsize1,(LPVOID *)&lpbuf2,&dwsize2,0); if (result != DS_OK) { ERR("Unable to lock sound buffer !\n"); continue; } dwbyteswritten1 = min(size,dwsize1); memcpy(lpbuf1,dma_buffer,dwbyteswritten1); if (size>dwsize1) { dwbyteswritten2 = min(size - dwbyteswritten1,dwsize2); memcpy(lpbuf2,dma_buffer+dwbyteswritten1,dwbyteswritten2); } buf_off = (buf_off + dwbyteswritten1 + dwbyteswritten2) % DSBUFLEN; result = IDirectSoundBuffer_Unlock(lpdsbuf,lpbuf1,dwbyteswritten1,lpbuf2,dwbyteswritten2); if (result!=DS_OK) ERR("Unable to unlock sound buffer !\n"); SamplesCount -= size; if (!SamplesCount) { DOSVM_QueueEvent(SB_IRQ,SB_IRQ_PRI,NULL,NULL); dma_enable = 0; } } return 0; }
int FillDSBufer(LPDIRECTSOUNDBUFFER pDSB,void* buffer, int ndata) { LPVOID pMem1, pMem2; DWORD dwSize1, dwSize2; if (SUCCEEDED(IDirectSoundBuffer_Lock(pDSB, 0, ndata, &pMem1, &dwSize1, &pMem2, &dwSize2, 0))) { CopyMemory(pMem1, buffer, dwSize1); if ( 0 != dwSize2 ) CopyMemory(pMem2, ((unsigned char*)buffer)+dwSize1, dwSize2); IDirectSoundBuffer_Unlock(pDSB, pMem1, dwSize1, pMem2, dwSize2); return 1; } return 0; }
DWORD * DSOUND_LockBuffer(qboolean lockit) { int reps; static DWORD dwSize; static DWORD dwSize2; static DWORD *pbuf1; static DWORD *pbuf2; HRESULT hresult; if (!pDSBuf) return NULL; if (lockit) { reps = 0; while ((hresult = IDirectSoundBuffer_Lock (pDSBuf, 0, gSndBufSize, (LPVOID *) & pbuf1, &dwSize, (LPVOID *) & pbuf2, &dwSize2,0)) != DS_OK) { if (hresult != DSERR_BUFFERLOST) { Con_Printf ("S_TransferStereo16: DS::Lock Sound Buffer Failed\n"); S_Shutdown (); S_Startup (); return NULL; } if (++reps > 10000) { Con_Printf ("S_TransferStereo16: DS: couldn't restore buffer\n"); S_Shutdown (); S_Startup (); return NULL; } } } else { IDirectSoundBuffer_Unlock (pDSBuf, pbuf1, dwSize, NULL, 0); pbuf1=NULL; pbuf2=NULL; dwSize=0; dwSize2=0; } return(pbuf1); }
static void FillBuffer(int32_t bufnum) { HRESULT err; LPVOID ptr, ptr2; DWORD remaining, remaining2; int32_t retries = 1; //initprintf( "DirectSound FillBuffer: filling %d\n", bufnum); do { err = IDirectSoundBuffer_Lock(lpdsbsec, notifyPositions[bufnum].dwOffset, notifyPositions[1].dwOffset, &ptr, &remaining, &ptr2, &remaining2, 0); if (FAILED(err)) { if (err == DSERR_BUFFERLOST) { err = IDirectSoundBuffer_Restore(lpdsbsec); if (FAILED(err)) { return; } if (retries-- > 0) { continue; } } if (MV_Printf) MV_Printf("DirectSound FillBuffer: err %x\n", (uint32_t) err); return; } break; } while (1); if (ptr) { FillBufferPortion((char *) ptr, remaining); } if (ptr2) { FillBufferPortion((char *) ptr2, remaining2); } IDirectSoundBuffer_Unlock(lpdsbsec, ptr, remaining, ptr2, remaining2); }
void m1sdr_PlayStop(void) { DSBUFFERDESC dsbuf; WAVEFORMATEX format; waveLogStop(); IDirectSoundBuffer_Stop(lpSecB); // this is a bit cheezity-hacky IDirectSoundBuffer_Release(lpSecB); memset(&format, 0, sizeof(format)); format.wFormatTag = WAVE_FORMAT_PCM; format.nChannels = 2; format.wBitsPerSample = 16; format.nSamplesPerSec = nDSoundSamRate; format.nBlockAlign = 4; // stereo 16-bit format.cbSize = 0; format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; memset(&dsbuf, 0, sizeof(DSBUFFERDESC)); dsbuf.dwSize = sizeof(DSBUFFERDESC); // we'll take default controls for this one dsbuf.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY; dsbuf.dwBufferBytes = cbLoopLen; dsbuf.lpwfxFormat = (LPWAVEFORMATEX)&format; if (DS_OK != IDirectSound_CreateSoundBuffer(lpDS, &dsbuf, &lpSecB, NULL)) { printf("Unable to create secondary buffer\n"); return; } // zero out the buffer { LPVOID ptr; DWORD len; IDirectSoundBuffer_Lock(lpSecB, 0, 0, &ptr, &len, NULL, NULL, DSBLOCK_ENTIREBUFFER); ZeroMemory(ptr, len); IDirectSoundBuffer_Unlock(lpSecB, ptr, len, 0, 0); } }
//-------------------------------------------------------------------------- // Fill a DS buffer with the sample BOOL DSFillSoundBuffer(IDirectSoundBuffer *pDSB, BYTE *pbWaveData, DWORD cbWaveSize) { if (pDSB && pbWaveData && cbWaveSize) { LPVOID pMem1, pMem2; DWORD dwSize1, dwSize2; HRESULT hr; if (SUCCEEDED(hr=IDirectSoundBuffer_Lock(pDSB, 0, cbWaveSize, &pMem1, &dwSize1, &pMem2, &dwSize2, 0))) { CopyMemory(pMem1, pbWaveData, dwSize1); if ( 0 != dwSize2 ) CopyMemory(pMem2, pbWaveData+dwSize1, dwSize2); hr=IDirectSoundBuffer_Unlock(pDSB, pMem1, dwSize1, pMem2, dwSize2); return TRUE; } else DEBUGMYERROR(DSTAB,hr); } return FALSE; }
BOOL DSFillSoundBufferByte(IDirectSoundBuffer *pDSB, BYTE value, DWORD cbWaveSize) { if (pDSB && cbWaveSize) { LPVOID pMem1, pMem2; DWORD dwSize1, dwSize2; HRESULT hr; if (SUCCEEDED(hr=IDirectSoundBuffer_Lock(pDSB, 0, cbWaveSize, &pMem1, &dwSize1, &pMem2, &dwSize2, 0))) { FillMemory(pMem1, dwSize1,value); if ( 0 != dwSize2 ) FillMemory(pMem2, dwSize2,value); hr=IDirectSoundBuffer_Unlock(pDSB, pMem1, dwSize1, pMem2, dwSize2); return TRUE; } else DEBUGMYERROR(DSTAB,hr); } return FALSE; }
static HRESULT WINAPI DSoundRender_InputPin_EndFlush(IPin * iface) { BaseInputPin *This = (BaseInputPin *)iface; DSoundRenderImpl *pFilter = (DSoundRenderImpl *)This->pin.pinInfo.pFilter; HRESULT hr; TRACE("\n"); EnterCriticalSection(This->pin.pCritSec); if (pFilter->in_loop) { ResetEvent(pFilter->state_change); LeaveCriticalSection(This->pin.pCritSec); WaitForSingleObject(pFilter->state_change, -1); EnterCriticalSection(This->pin.pCritSec); } if (pFilter->filter.state != State_Stopped) ResetEvent(pFilter->blocked); if (pFilter->dsbuffer) { LPBYTE buffer; DWORD size; IDirectSoundBuffer_Stop(pFilter->dsbuffer); /* Force a reset */ IDirectSoundBuffer_SetCurrentPosition(pFilter->dsbuffer, 0); pFilter->write_pos = pFilter->last_play_pos = 0; ++pFilter->play_loops; pFilter->write_loops = pFilter->play_loops; IDirectSoundBuffer_Lock(pFilter->dsbuffer, 0, 0, (LPVOID *)&buffer, &size, NULL, NULL, DSBLOCK_ENTIREBUFFER); memset(buffer, 0, size); IDirectSoundBuffer_Unlock(pFilter->dsbuffer, buffer, size, NULL, 0); } hr = BaseInputPinImpl_EndFlush(iface); LeaveCriticalSection(This->pin.pCritSec); MediaSeekingPassThru_ResetMediaTime(pFilter->seekthru_unk); return hr; }
BOOL DSFillSoundBuffer(IDirectSoundBuffer *pDSB, BYTE *pbWaveData, DWORD cbWaveSize) { if (pDSB && pbWaveData && cbWaveSize) { LPVOID pMem1, pMem2; DWORD dwSize1, dwSize2; if (SUCCEEDED(IDirectSoundBuffer_Lock(pDSB, 0, cbWaveSize, &pMem1, &dwSize1, &pMem2, &dwSize2, 0))) { CopyMemory(pMem1, pbWaveData, dwSize1); if ( 0 != dwSize2 ) CopyMemory(pMem2, pbWaveData+dwSize1, dwSize2); IDirectSoundBuffer_Unlock(pDSB, pMem1, dwSize1, pMem2, dwSize2); return TRUE; } } return FALSE; }