static BOOL AppReadDataFromBuffer(LPDIRECTSOUNDCAPTUREBUFFER 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 = IDirectSoundCaptureBuffer_Lock( lpDsb, dwOffset, dwSoundBytes, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0); if SUCCEEDED(hr) { // Read from pointers. pj_memcpy(lpbSoundData, lpvPtr1, dwBytes1); if (lpvPtr2 != NULL) pj_memcpy(lpbSoundData+dwBytes1, lpvPtr2, dwBytes2); // Release the data back to DirectSound. hr = IDirectSoundCaptureBuffer_Unlock(lpDsb, lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); if SUCCEEDED(hr) return TRUE; } // Lock, Unlock, or Restore failed. return FALSE; }
static int capture_buffer_service(capture_state_t* state) { HRESULT rc; LPVOID ptr1,ptr2; DWORD len1,len2; DWORD capture_pos,read_pos; rc=IDirectSoundCaptureBuffer_GetCurrentPosition(state->dscbo,&capture_pos, &read_pos); ok(rc==DS_OK,"IDirectSoundCaptureBuffer_GetCurrentPosition() failed: %08x\n", rc); if (rc!=DS_OK) return 0; rc=IDirectSoundCaptureBuffer_Lock(state->dscbo,state->offset,state->size, &ptr1,&len1,&ptr2,&len2,0); ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Lock() failed: %08x\n", rc); if (rc!=DS_OK) return 0; rc=IDirectSoundCaptureBuffer_Unlock(state->dscbo,ptr1,len1,ptr2,len2); ok(rc==DS_OK,"IDirectSoundCaptureBuffer_Unlock() failed: %08x\n", rc); if (rc!=DS_OK) return 0; state->offset = (state->offset + state->size) % state->buffer_size; return 1; }
/*minsamples is a hint*/ unsigned int DSOUND_Capture_Update(void *ctx, unsigned char *buffer, unsigned int minbytes, unsigned int maxbytes) { dsndcapture_t *c = ctx; HRESULT hr; LPBYTE lpbuf1 = NULL; LPBYTE lpbuf2 = NULL; DWORD dwsize1 = 0; DWORD dwsize2 = 0; DWORD capturePos; DWORD readPos; long filled; // Query to see how much data is in buffer. hr = IDirectSoundCaptureBuffer_GetCurrentPosition(c->DSCaptureBuffer, &capturePos, &readPos); if (hr != DS_OK) { return 0; } filled = readPos - c->lastreadpos; if (filled < 0) filled += bufferbytes; // unwrap offset if (filled > maxbytes) //figure out how much we need to empty it by, and if that's enough to be worthwhile. filled = maxbytes; else if (filled < minbytes) return 0; // filled /= inputwidth; // filled *= inputwidth; // Lock free space in the DS hr = IDirectSoundCaptureBuffer_Lock(c->DSCaptureBuffer, c->lastreadpos, filled, (void **) &lpbuf1, &dwsize1, (void **) &lpbuf2, &dwsize2, 0); if (hr == DS_OK) { // Copy from DS to the buffer memcpy(buffer, lpbuf1, dwsize1); if(lpbuf2 != NULL) { memcpy(buffer+dwsize1, lpbuf2, dwsize2); } // Update our buffer offset and unlock sound buffer c->lastreadpos = (c->lastreadpos + dwsize1 + dwsize2) % bufferbytes; IDirectSoundCaptureBuffer_Unlock(c->DSCaptureBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2); } else { return 0; } return filled; }
static void *__playback_thread(void *param) { tdav_producer_dsound_t* dsound = (tdav_producer_dsound_t*)param; HRESULT hr; LPVOID lpvAudio1, lpvAudio2; DWORD dwBytesAudio1, dwBytesAudio2; TSK_DEBUG_INFO("__record_thread -- START"); SetPriorityClass(GetCurrentThread(), REALTIME_PRIORITY_CLASS); for(;;){ DWORD dwEvent = WaitForMultipleObjects(sizeof(dsound->notifEvents)/sizeof(HANDLE), dsound->notifEvents, FALSE, INFINITE); if(!dsound->started){ break; } else { // lock if((hr = IDirectSoundCaptureBuffer_Lock(dsound->captureBuffer, (dwEvent * dsound->bytes_per_notif), dsound->bytes_per_notif, &lpvAudio1, &dwBytesAudio1, &lpvAudio2, &dwBytesAudio2, 0)) != DS_OK){ tdav_win32_print_error("IDirectSoundCaptureBuffer_Lock", hr); goto next; } if(TMEDIA_PRODUCER(dsound)->enc_cb.callback){ if(lpvAudio2){ TMEDIA_PRODUCER(dsound)->enc_cb.callback(TMEDIA_PRODUCER(dsound)->enc_cb.callback_data, lpvAudio1, dwBytesAudio1); TMEDIA_PRODUCER(dsound)->enc_cb.callback(TMEDIA_PRODUCER(dsound)->enc_cb.callback_data, lpvAudio2, dwBytesAudio2); } else{ TMEDIA_PRODUCER(dsound)->enc_cb.callback(TMEDIA_PRODUCER(dsound)->enc_cb.callback_data, lpvAudio1, dwBytesAudio1); } } // unlock if((hr = IDirectSoundCaptureBuffer_Unlock(dsound->captureBuffer, lpvAudio1, dwBytesAudio1, lpvAudio2, dwBytesAudio2)) != DS_OK){ tdav_win32_print_error("IDirectSoundCaptureBuffer_Unlock", hr); goto next; } next:; } } TSK_DEBUG_INFO("__record_thread -- STOP"); return tsk_null; }
static ALCuint DSoundAvailableSamples(ALCdevice *pDevice) { DSoundCaptureData *pData = pDevice->ExtraData; DWORD dwRead, dwCursor, dwBufferBytes, dwNumBytes; void *pvAudio1, *pvAudio2; DWORD dwAudioBytes1, dwAudioBytes2; DWORD FrameSize; HRESULT hr; if(!pDevice->Connected) goto done; FrameSize = FrameSizeFromDevFmt(pDevice->FmtChans, pDevice->FmtType); dwBufferBytes = pData->dwBufferBytes; dwCursor = pData->dwCursor; hr = IDirectSoundCaptureBuffer_GetCurrentPosition(pData->DSCbuffer, NULL, &dwRead); if(SUCCEEDED(hr)) { dwNumBytes = (dwBufferBytes + dwRead - dwCursor) % dwBufferBytes; if(dwNumBytes == 0) goto done; hr = IDirectSoundCaptureBuffer_Lock(pData->DSCbuffer, dwCursor, dwNumBytes, &pvAudio1, &dwAudioBytes1, &pvAudio2, &dwAudioBytes2, 0); } if(SUCCEEDED(hr)) { WriteRingBuffer(pData->pRing, pvAudio1, dwAudioBytes1/FrameSize); if(pvAudio2 != NULL) WriteRingBuffer(pData->pRing, pvAudio2, dwAudioBytes2/FrameSize); hr = IDirectSoundCaptureBuffer_Unlock(pData->DSCbuffer, pvAudio1, dwAudioBytes1, pvAudio2, dwAudioBytes2); pData->dwCursor = (dwCursor + dwAudioBytes1 + dwAudioBytes2) % dwBufferBytes; } if(FAILED(hr)) { ERR("update failed: 0x%08lx\n", hr); aluHandleDisconnect(pDevice); } done: return RingBufferSize(pData->pRing); }
static ALCuint DSoundAvailableSamples(ALCdevice *Device) { DSoundCaptureData *data = Device->ExtraData; DWORD ReadCursor, LastCursor, BufferBytes, NumBytes; VOID *ReadPtr1, *ReadPtr2; DWORD ReadCnt1, ReadCnt2; DWORD FrameSize; HRESULT hr; if(!Device->Connected) goto done; FrameSize = FrameSizeFromDevFmt(Device->FmtChans, Device->FmtType); BufferBytes = data->BufferBytes; LastCursor = data->Cursor; hr = IDirectSoundCaptureBuffer_GetCurrentPosition(data->DSCbuffer, NULL, &ReadCursor); if(SUCCEEDED(hr)) { NumBytes = (ReadCursor-LastCursor + BufferBytes) % BufferBytes; if(NumBytes == 0) goto done; hr = IDirectSoundCaptureBuffer_Lock(data->DSCbuffer, LastCursor, NumBytes, &ReadPtr1, &ReadCnt1, &ReadPtr2, &ReadCnt2, 0); } if(SUCCEEDED(hr)) { WriteRingBuffer(data->Ring, ReadPtr1, ReadCnt1/FrameSize); if(ReadPtr2 != NULL) WriteRingBuffer(data->Ring, ReadPtr2, ReadCnt2/FrameSize); hr = IDirectSoundCaptureBuffer_Unlock(data->DSCbuffer, ReadPtr1, ReadCnt1, ReadPtr2, ReadCnt2); data->Cursor = (LastCursor+ReadCnt1+ReadCnt2) % BufferBytes; } if(FAILED(hr)) { ERR("update failed: 0x%08lx\n", hr); aluHandleDisconnect(Device); } done: return RingBufferSize(data->Ring); }
static int DSOUND_CaptureFromDevice(_THIS, void *buffer, int buflen) { struct SDL_PrivateAudioData *h = this->hidden; DWORD junk, cursor, ptr1len, ptr2len; VOID *ptr1, *ptr2; SDL_assert(buflen == this->spec.size); while (SDL_TRUE) { if (SDL_AtomicGet(&this->shutdown)) { /* in case the buffer froze... */ SDL_memset(buffer, this->spec.silence, buflen); return buflen; } if (IDirectSoundCaptureBuffer_GetCurrentPosition(h->capturebuf, &junk, &cursor) != DS_OK) { return -1; } if ((cursor / this->spec.size) == h->lastchunk) { SDL_Delay(1); /* FIXME: find out how much time is left and sleep that long */ } else { break; } } if (IDirectSoundCaptureBuffer_Lock(h->capturebuf, h->lastchunk * this->spec.size, this->spec.size, &ptr1, &ptr1len, &ptr2, &ptr2len, 0) != DS_OK) { return -1; } SDL_assert(ptr1len == this->spec.size); SDL_assert(ptr2 == NULL); SDL_assert(ptr2len == 0); SDL_memcpy(buffer, ptr1, ptr1len); if (IDirectSoundCaptureBuffer_Unlock(h->capturebuf, ptr1, ptr1len, ptr2, ptr2len) != DS_OK) { return -1; } h->lastchunk = (h->lastchunk + 1) % h->num_buffers; return ptr1len; }
static void gst_directsound_src_reset (GstAudioSrc * asrc) { GstDirectSoundSrc *dsoundsrc; LPVOID pLockedBuffer = NULL; DWORD dwSizeBuffer = 0; GST_DEBUG_OBJECT (asrc, "reset directsoundsrc"); dsoundsrc = GST_DIRECTSOUND_SRC (asrc); GST_DSOUND_LOCK (dsoundsrc); dsoundsrc->reset_while_sleeping = TRUE; /* Interrupt read sleep if required */ if (dsoundsrc->read_wait_clock_id != NULL) gst_clock_id_unschedule (dsoundsrc->read_wait_clock_id); if (dsoundsrc->pDSBSecondary) { /*stop capturing */ HRESULT hRes = IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary); /*reset position */ /* hRes = IDirectSoundCaptureBuffer_SetCurrentPosition (dsoundsrc->pDSBSecondary, 0); */ /*reset the buffer */ hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary, dsoundsrc->current_circular_offset, dsoundsrc->buffer_size, pLockedBuffer, &dwSizeBuffer, NULL, NULL, 0L); if (SUCCEEDED (hRes)) { memset (pLockedBuffer, 0, dwSizeBuffer); hRes = IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary, pLockedBuffer, dwSizeBuffer, NULL, 0); } dsoundsrc->current_circular_offset = 0; } GST_DSOUND_UNLOCK (dsoundsrc); }
static void gst_directsound_src_reset (GstAudioSrc * asrc) { GstDirectSoundSrc *dsoundsrc; LPVOID pLockedBuffer = NULL; DWORD dwSizeBuffer = 0; GST_DEBUG_OBJECT (asrc, "reset directsoundsrc"); dsoundsrc = GST_DIRECTSOUND_SRC (asrc); #if 0 IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary); #endif GST_DSOUND_LOCK (dsoundsrc); if (dsoundsrc->pDSBSecondary) { /*stop capturing */ HRESULT hRes = IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary); /*reset position */ /* hRes = IDirectSoundCaptureBuffer_SetCurrentPosition (dsoundsrc->pDSBSecondary, 0); */ /*reset the buffer */ hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary, dsoundsrc->current_circular_offset, dsoundsrc->buffer_size, pLockedBuffer, &dwSizeBuffer, NULL, NULL, 0L); if (SUCCEEDED (hRes)) { memset (pLockedBuffer, 0, dwSizeBuffer); hRes = IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary, pLockedBuffer, dwSizeBuffer, NULL, 0); } dsoundsrc->current_circular_offset = 0; } GST_DSOUND_UNLOCK (dsoundsrc); }
HRESULT DSW_ReadBlock( 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 = IDirectSoundCaptureBuffer_Lock ( dsw->dsw_InputBuffer, dsw->dsw_ReadOffset, numBytes, (void **) &lpbuf1, &dwsize1, (void **) &lpbuf2, &dwsize2, 0); if (hr == DS_OK) { // Copy from DS to the buffer CopyMemory( buf, lpbuf1, dwsize1); if(lpbuf2 != NULL) { CopyMemory( buf+dwsize1, lpbuf2, dwsize2); } // Update our buffer offset and unlock sound buffer dsw->dsw_ReadOffset = (dsw->dsw_ReadOffset + dwsize1 + dwsize2) % dsw->dsw_InputSize; IDirectSoundCaptureBuffer_Unlock ( dsw->dsw_InputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2); } return hr; }
/* return number of readed bytes */ static guint gst_directsound_src_read (GstAudioSrc * asrc, gpointer data, guint length, GstClockTime * timestamp) { GstDirectSoundSrc *dsoundsrc; HRESULT hRes; /* Result for windows functions */ DWORD dwCurrentCaptureCursor = 0; DWORD dwBufferSize = 0; LPVOID pLockedBuffer1 = NULL; LPVOID pLockedBuffer2 = NULL; DWORD dwSizeBuffer1 = 0; DWORD dwSizeBuffer2 = 0; DWORD dwStatus = 0; GST_DEBUG_OBJECT (asrc, "reading directsoundsrc"); dsoundsrc = GST_DIRECTSOUND_SRC (asrc); GST_DSOUND_LOCK (dsoundsrc); /* Get current buffer status */ hRes = IDirectSoundCaptureBuffer_GetStatus (dsoundsrc->pDSBSecondary, &dwStatus); /* Starting capturing if not already */ if (!(dwStatus & DSCBSTATUS_CAPTURING)) { hRes = IDirectSoundCaptureBuffer_Start (dsoundsrc->pDSBSecondary, DSCBSTART_LOOPING); // Sleep (dsoundsrc->latency_time/1000); GST_DEBUG_OBJECT (asrc, "capture started"); } // calculate_buffersize: while (length > dwBufferSize) { Sleep (dsoundsrc->latency_time / 1000); hRes = IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary, &dwCurrentCaptureCursor, NULL); /* calculate the buffer */ if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) { dwBufferSize = dsoundsrc->buffer_size - (dsoundsrc->current_circular_offset - dwCurrentCaptureCursor); } else { dwBufferSize = dwCurrentCaptureCursor - dsoundsrc->current_circular_offset; } } // while (... /* Lock the buffer */ hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary, dsoundsrc->current_circular_offset, length, &pLockedBuffer1, &dwSizeBuffer1, &pLockedBuffer2, &dwSizeBuffer2, 0L); /* Copy buffer data to another buffer */ if (hRes == DS_OK) { memcpy (data, pLockedBuffer1, dwSizeBuffer1); } /* ...and if something is in another buffer */ if (pLockedBuffer2 != NULL) { memcpy (((guchar *) data + dwSizeBuffer1), pLockedBuffer2, dwSizeBuffer2); } dsoundsrc->current_circular_offset += dwSizeBuffer1 + dwSizeBuffer2; dsoundsrc->current_circular_offset %= dsoundsrc->buffer_size; IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary, pLockedBuffer1, dwSizeBuffer1, pLockedBuffer2, dwSizeBuffer2); GST_DSOUND_UNLOCK (dsoundsrc); /* return length (readed data size in bytes) */ return length; }
// //////////////////////////////////////////////////////////////////////// static BOOL sendAudioBuffer(BOOL bNow) { DWORD read; static DWORD lastread=0; HRESULT hr; NETMSG msg; UWORD size=0; LPVOID lpvPtr1,lpvPtr2; DWORD dwBytes1=0,dwBytes2=0; hr = IDirectSoundCaptureBuffer_GetCurrentPosition(lpDirectSoundCaptureBuffer,NULL,&read); if(hr != DS_OK) { return FALSE; } // if buffer is still pretty empty if(lastread <= read) // non wrapped. { size = (UWORD) (read - lastread); } else // wrapped { size = (UWORD) (read + (captureBuff.dwBufferBytes - lastread)); } if(!bNow) { if(size < ((MaxMsgSize*3)/4) ) { return TRUE; } } // send an audio packet if getting near the end of the buffer. if(size > MaxMsgSize) { size = MaxMsgSize; DBPRINTF(("NETPLAY:lost some audio\n")); } // lock an area hr = IDirectSoundCaptureBuffer_Lock(lpDirectSoundCaptureBuffer, //Obtain mem add. of write block. lastread, // start at size, // read this much &lpvPtr1,&dwBytes1, &lpvPtr2,&dwBytes2, 0 //DSCBLOCK_ENTIREBUFFER ); lastread = lastread+size; if(lastread >captureBuff.dwBufferBytes) // wrapped { lastread = lastread - captureBuff.dwBufferBytes; } if(hr != DS_OK) { return FALSE; } // read it out memcpy(msg.body,lpvPtr1,dwBytes1); // copy first part into buffer if (lpvPtr2 != NULL) // second part. { memcpy(((UBYTE *)msg.body)+dwBytes1,lpvPtr2,dwBytes2); // buffer contents } // unlock area. hr = IDirectSoundCaptureBuffer_Unlock(lpDirectSoundCaptureBuffer, lpvPtr1,dwBytes1, lpvPtr2,dwBytes2); if(hr != DS_OK) { return FALSE; } // may want to compress it! //MMRESULT acmFormatSuggest( HACMDRIVER had, LPWAVEFORMATEX pwfxSrc, LPWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest // send the buffer elsewhere msg.type = AUDIOMSG; msg.size = (UWORD)(dwBytes1+dwBytes2); NETbcast(&msg,FALSE); return TRUE; }
/* return number of readed bytes */ static guint gst_directsound_src_read (GstAudioSrc * asrc, gpointer data, guint length, GstClockTime * timestamp) { GstDirectSoundSrc *dsoundsrc; guint64 sleep_time_ms, sleep_until; GstClockID clock_id; HRESULT hRes; /* Result for windows functions */ DWORD dwCurrentCaptureCursor = 0; DWORD dwBufferSize = 0; LPVOID pLockedBuffer1 = NULL; LPVOID pLockedBuffer2 = NULL; DWORD dwSizeBuffer1 = 0; DWORD dwSizeBuffer2 = 0; DWORD dwStatus = 0; GST_DEBUG_OBJECT (asrc, "reading directsoundsrc"); dsoundsrc = GST_DIRECTSOUND_SRC (asrc); GST_DSOUND_LOCK (dsoundsrc); /* Get current buffer status */ hRes = IDirectSoundCaptureBuffer_GetStatus (dsoundsrc->pDSBSecondary, &dwStatus); if (FAILED (hRes)) { GST_DSOUND_UNLOCK (dsoundsrc); return -1; } /* Starting capturing if not already */ if (!(dwStatus & DSCBSTATUS_CAPTURING)) { hRes = IDirectSoundCaptureBuffer_Start (dsoundsrc->pDSBSecondary, DSCBSTART_LOOPING); GST_INFO_OBJECT (asrc, "capture started"); } /* Loop till the source has produced bytes equal to or greater than @length. * * DirectSound has a notification-based API that uses Windows CreateEvent() * + WaitForSingleObject(), but it is completely useless for live streams. * * 1. You must schedule all events before starting capture * 2. The events are all fired exactly once * 3. You cannot schedule new events while a capture is running * 4. You cannot stop/schedule/start either * * This means you cannot use the API while doing live looped capture and we * must resort to this. * * However, this is almost as efficient as event-based capture since it's ok * to consistently overwait by a fixed amount; the extra bytes will just end * up being used in the next call, and the extra latency will be constant. */ while (TRUE) { hRes = IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary, &dwCurrentCaptureCursor, NULL); if (FAILED (hRes)) { GST_DSOUND_UNLOCK (dsoundsrc); return -1; } /* calculate the size of the buffer that's been captured while accounting * for wrap-arounds */ if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) { dwBufferSize = dsoundsrc->buffer_size - (dsoundsrc->current_circular_offset - dwCurrentCaptureCursor); } else { dwBufferSize = dwCurrentCaptureCursor - dsoundsrc->current_circular_offset; } if (dwBufferSize >= length) { /* Yay, we got all the data we need */ break; } else { GST_DEBUG_OBJECT (asrc, "not enough data, got %lu (want at least %u)", dwBufferSize, length); /* If we didn't get enough data, sleep for a proportionate time */ sleep_time_ms = gst_util_uint64_scale (dsoundsrc->latency_time, length - dwBufferSize, length * 1000); /* Make sure we don't run in a tight loop unnecessarily */ sleep_time_ms = MAX (sleep_time_ms, 10); /* Sleep using gst_clock_id_wait() so that we can be interrupted */ sleep_until = gst_clock_get_time (dsoundsrc->system_clock) + sleep_time_ms * GST_MSECOND; /* Setup the clock id wait */ if (G_UNLIKELY (dsoundsrc->read_wait_clock_id == NULL || gst_clock_single_shot_id_reinit (dsoundsrc->system_clock, dsoundsrc->read_wait_clock_id, sleep_until) == FALSE)) { if (dsoundsrc->read_wait_clock_id != NULL) gst_clock_id_unref (dsoundsrc->read_wait_clock_id); dsoundsrc->read_wait_clock_id = gst_clock_new_single_shot_id (dsoundsrc->system_clock, sleep_until); } clock_id = dsoundsrc->read_wait_clock_id; dsoundsrc->reset_while_sleeping = FALSE; GST_DEBUG_OBJECT (asrc, "waiting %" G_GUINT64_FORMAT "ms for more data", sleep_time_ms); GST_DSOUND_UNLOCK (dsoundsrc); gst_clock_id_wait (clock_id, NULL); GST_DSOUND_LOCK (dsoundsrc); if (dsoundsrc->reset_while_sleeping == TRUE) { GST_DEBUG_OBJECT (asrc, "reset while sleeping, cancelled read"); GST_DSOUND_UNLOCK (dsoundsrc); return -1; } } } GST_DEBUG_OBJECT (asrc, "Got enough data: %lu bytes (wanted at least %u)", dwBufferSize, length); /* Lock the buffer and read only the first @length bytes. Keep the rest in * the capture buffer for the next read. */ hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary, dsoundsrc->current_circular_offset, length, &pLockedBuffer1, &dwSizeBuffer1, &pLockedBuffer2, &dwSizeBuffer2, 0L); /* NOTE: We now assume that dwSizeBuffer1 + dwSizeBuffer2 == length since the * API is supposed to guarantee that */ /* Copy buffer data to another buffer */ if (hRes == DS_OK) { memcpy (data, pLockedBuffer1, dwSizeBuffer1); } /* ...and if something is in another buffer */ if (pLockedBuffer2 != NULL) { memcpy (((guchar *) data + dwSizeBuffer1), pLockedBuffer2, dwSizeBuffer2); } dsoundsrc->current_circular_offset += dwSizeBuffer1 + dwSizeBuffer2; dsoundsrc->current_circular_offset %= dsoundsrc->buffer_size; IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary, pLockedBuffer1, dwSizeBuffer1, pLockedBuffer2, dwSizeBuffer2); GST_DSOUND_UNLOCK (dsoundsrc); /* We always read exactly @length data */ return length; }