Esempio n. 1
0
void FillSectionWithSilence( int buffer ) {
    DWORD dwBytesLocked;
    VOID *lpvData;

	if (FAILED( IDirectSoundBuffer8_Lock(lpdsbuf, BufferSize * buffer,BufferSize, &lpvData, &dwBytesLocked,
		NULL, NULL, 0  ) ) )
	{
		IDirectSoundBuffer8_Unlock(lpdsbuf, lpvData, dwBytesLocked, NULL, 0 );
		//DisplayError("IDirectSoundBuffer8_Unlock");
		return;
	}
    FillMemory( lpvData, dwBytesLocked, 0 );
	IDirectSoundBuffer8_Unlock(lpdsbuf, lpvData, dwBytesLocked, NULL, 0 );
}
Esempio n. 2
0
BOOL FillBufferWithSilence( LPDIRECTSOUNDBUFFER lpDsb ) {
    WAVEFORMATEX    wfx;
    DWORD           dwSizeWritten;

    PBYTE   pb1;
    DWORD   cb1;

    if ( FAILED( IDirectSoundBuffer8_GetFormat(lpDsb, &wfx, sizeof( WAVEFORMATEX ), &dwSizeWritten ) ) ) {
        return FALSE;
	}

    if ( SUCCEEDED( IDirectSoundBuffer8_Lock(lpDsb,0,0,(LPVOID*)&pb1,&cb1,NULL,NULL,DSBLOCK_ENTIREBUFFER))) {
        FillMemory( pb1, cb1, ( wfx.wBitsPerSample == 8 ) ? 128 : 0 );

        IDirectSoundBuffer8_Unlock(lpDsb, pb1, cb1, NULL, 0 );
        return TRUE;
    }

    return FALSE;
}
Esempio n. 3
0
void SNDDXUpdateAudio(s16 *buffer, u32 num_samples)
{
   LPVOID buffer1;
   LPVOID buffer2;
   DWORD buffer1_size, buffer2_size;
   DWORD status;

   IDirectSoundBuffer8_GetStatus(lpDSB2, &status);

   if (status & DSBSTATUS_BUFFERLOST)
      return; // fix me

   IDirectSoundBuffer8_Lock(lpDSB2, soundoffset, num_samples * sizeof(s16) * 2, &buffer1, &buffer1_size, &buffer2, &buffer2_size, 0);

   memcpy(buffer1, buffer, buffer1_size);
   if (buffer2)
      memcpy(buffer2, ((u8 *)buffer)+buffer1_size, buffer2_size);

   soundoffset += buffer1_size + buffer2_size;
   soundoffset %= soundbufsize;

   IDirectSoundBuffer8_Unlock(lpDSB2, buffer1, buffer1_size, buffer2, buffer2_size);
}
Esempio n. 4
0
static gboolean
gst_directsound_src_event (GstBaseSrc * bsrc, GstEvent * event)
{
  HRESULT hr;
  DWORD dwStatus;
  //DWORD dwSizeBuffer = 0;
  //LPVOID pLockedBuffer = NULL;

  GstDirectSoundSrc * dsoundsrc;

  dsoundsrc = GST_DIRECTSOUND_SRC (bsrc);

  GST_BASE_SRC_CLASS (parent_class)->event (bsrc, event);

  /* no buffer, no event to process */
  if (!dsoundsrc->dsoundbuffer)
    return TRUE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
      GST_DSOUND_LOCK (dsoundsrc->dsoundbuffer);
      dsoundsrc->dsoundbuffer->flushing = TRUE;
      GST_DSOUND_UNLOCK (dsoundsrc->dsoundbuffer);
      break;
    case GST_EVENT_FLUSH_STOP:
      GST_DSOUND_LOCK (dsoundsrc->dsoundbuffer);
      dsoundsrc->dsoundbuffer->flushing = FALSE;

      if (dsoundsrc->dsoundbuffer->pDSCB8) {
        hr = IDirectSoundCaptureBuffer8_GetStatus (dsoundsrc->dsoundbuffer->pDSCB8, &dwStatus);

        if (FAILED(hr)) {
          GST_DSOUND_UNLOCK (dsoundsrc->dsoundbuffer);
          GST_WARNING("gst_directsound_src_event: IDirectSoundCaptureBuffer8_GetStatus, hr = %X", (unsigned int) hr);
          return FALSE;
        }

        if (!(dwStatus & DSCBSTATUS_CAPTURING)) {
          // ###: capture api doesn't support _SetCurrentPosition.  commenting
          //   out for now.
#if 0
          /* reset position */
          hr = IDirectSoundBuffer8_SetCurrentPosition (dsoundsink->dsoundbuffer->pDSB8, 0);
          dsoundsink->dsoundbuffer->buffer_circular_offset = 0;

          /* reset the buffer */
          hr = IDirectSoundBuffer8_Lock (dsoundsink->dsoundbuffer->pDSB8,
              dsoundsink->dsoundbuffer->buffer_circular_offset, 0L,
              &pLockedBuffer, &dwSizeBuffer, NULL, NULL, DSBLOCK_ENTIREBUFFER);

          if (SUCCEEDED (hr)) {
            memset (pLockedBuffer, 0, dwSizeBuffer);

            hr =
                IDirectSoundBuffer8_Unlock (dsoundsink->dsoundbuffer->pDSB8, pLockedBuffer,
                dwSizeBuffer, NULL, 0);

            if (FAILED(hr)) {
              GST_DSOUND_UNLOCK (dsoundsink->dsoundbuffer);
              GST_WARNING("gst_directsound_sink_event: IDirectSoundBuffer8_Unlock, hr = %X", (unsigned int) hr);
              return FALSE;
            }
          }
          else {
            GST_DSOUND_UNLOCK (dsoundsink->dsoundbuffer);
            GST_WARNING ( "gst_directsound_sink_event: IDirectSoundBuffer8_Lock, hr = %X", (unsigned int) hr);
            return FALSE;
          }
#endif
        }
      }
      GST_DSOUND_UNLOCK (dsoundsrc->dsoundbuffer);
      break;
    default:
      break;
  }

  return TRUE;
}
Esempio n. 5
0
static b32
punp_win32_sound_init(void)
{
    HRESULT hr;
    HMODULE dsound_lib;
    DirectSoundCreate8F DirectSoundCreate8;
    DSBUFFERDESC primary_buffer_description = {sizeof(primary_buffer_description)};
    LPDIRECTSOUNDBUFFER primary_buffer;


    dsound_lib = LoadLibraryA("dsound.dll");
    if (!dsound_lib) {
        printf("LoadLibrary(dsound.dll) failed.\n");
        return 0;
    }

    DirectSoundCreate8 = (DirectSoundCreate8F)GetProcAddress(dsound_lib, "DirectSoundCreate8");
    if (!DirectSoundCreate8) {
        printf("GetProcAddress(DirectSoundCreate8) failed.\n");
        return 0;
    }

    hr = DirectSoundCreate8(0, &punp_win32_direct_sound, 0);
    if (hr != DS_OK) {
        printf("DirectSoundCreate failed.\n");
        return 0;
    }

    hr = IDirectSound8_SetCooperativeLevel(punp_win32_direct_sound, punp_win32_window, DSSCL_PRIORITY);
    if (hr != DS_OK) {
        printf("punp_win32_direct_sound->SetCooperativeLevel failed.\n");
        return 0;
    }

    primary_buffer_description.dwFlags = DSBCAPS_PRIMARYBUFFER;

    hr = IDirectSound8_CreateSoundBuffer(punp_win32_direct_sound, &primary_buffer_description, &primary_buffer, 0);
    if (hr != DS_OK) {
        printf("punp_win32_direct_sound->CreateSoundBuffer for primary buffer failed.\n");
        return 0;
    }

    punp_win32_audio_format.wFormatTag = WAVE_FORMAT_PCM;
    punp_win32_audio_format.nChannels = PUNP_SOUND_CHANNELS;
    punp_win32_audio_format.nSamplesPerSec = SOUND_SAMPLE_RATE;
    punp_win32_audio_format.wBitsPerSample = 16;
    punp_win32_audio_format.nBlockAlign = (punp_win32_audio_format.nChannels * punp_win32_audio_format.wBitsPerSample) / 8;
    punp_win32_audio_format.nAvgBytesPerSec = punp_win32_audio_format.nSamplesPerSec * punp_win32_audio_format.nBlockAlign;
    punp_win32_audio_format.cbSize = 0;

    hr = IDirectSoundBuffer8_SetFormat(primary_buffer, &punp_win32_audio_format);
    if (hr != DS_OK) {
        printf("primary_buffer->SetFormat failed.");
        return 0;
    }

    // DSBSIZE_MIN DSBSIZE_MAX

    punp_win32_audio_buffer_description.dwSize = sizeof(punp_win32_audio_buffer_description);
    // 2 seconds.
    punp_win32_audio_buffer_description.dwBufferBytes = PUNP_SOUND_BUFFER_BYTES;
    punp_win32_audio_buffer_description.lpwfxFormat = &punp_win32_audio_format;
    // dicates that IDirectSoundBuffer::GetCurrentPosition should use the new behavior of the play cursor.
    // In DirectSound in DirectX 1, the play cursor was significantly ahead of the actual playing sound on
    // emulated sound cards; it was directly behind the write cursor.
    // Now, if the DSBCAPS_GETCURRENTPOSITION2 flag is specified, the application can get a more accurate
    // play position. If this flag is not specified, the old behavior is preserved for compatibility.
    // Note that this flag affects only emulated sound cards; if a DirectSound driver is present, the play
    // cursor is accurate for DirectSound in all versions of DirectX.
    punp_win32_audio_buffer_description.dwFlags = DSBCAPS_GETCURRENTPOSITION2;

    hr = IDirectSound8_CreateSoundBuffer(punp_win32_direct_sound,
                                         &punp_win32_audio_buffer_description,
                                         &punp_win32_audio_buffer,
                                         0);
    if (hr != DS_OK)
    {
        printf("punp_win32_direct_sound->CreateSoundBuffer for secondary buffer failed.\n");
        return 0;
    }

    // IDirectSoundBuffer8_SetFormat(punp_win32_audio_buffer, &punp_win32_audio_format);

    // Clear the initial buffer.

    {
        LPVOID region1, region2;
        DWORD region1_size, region2_size;

        hr = IDirectSoundBuffer8_Lock(punp_win32_audio_buffer,
                                      0, punp_win32_audio_buffer_description.dwBufferBytes,
                                      (LPVOID *)&region1, &region1_size,
                                      (LPVOID *)&region2, &region2_size,
                                      DSBLOCK_ENTIREBUFFER);

        if (hr == DS_OK)
        {
            memset(region1, 0, region1_size);
            IDirectSoundBuffer8_Unlock(punp_win32_audio_buffer,
                                       region1, region1_size,
                                       region2, region2_size);
        }
    }

    hr = IDirectSoundBuffer8_Play(punp_win32_audio_buffer, 0, 0, DSBPLAY_LOOPING);

    if (hr != DS_OK)
    {
        ASSERT(0);
    }
    return 1;
}
Esempio n. 6
0
static void
punp_win32_sound_step(void)
{
    HRESULT hr;
    DWORD cursor_play, cursor_write;
    isize chunk_size, chunk;
    DWORD lock_cursor, lock_size;
    VOID *range1, *range2;
    DWORD range1_size, range2_size;

    hr = IDirectSoundBuffer8_GetCurrentPosition(punp_win32_audio_buffer,
                                                &cursor_play, &cursor_write);

    if (FAILED(hr)) {
        printf("IDirectSoundBuffer8_GetCurrentPosition failed.\n");
        return;
    }

    chunk_size = PUNP_SOUND_SAMPLES_TO_BYTES(PUNP_SOUND_BUFFER_CHUNK_SAMPLES);
    chunk = cursor_write / chunk_size;

    lock_cursor = ((chunk+1) * chunk_size) % PUNP_SOUND_BUFFER_BYTES;
    lock_size = chunk_size;

    if (lock_cursor == punp_win32_audio_cursor) {
        return;
    }


    hr = IDirectSoundBuffer8_Lock(punp_win32_audio_buffer,
                                  lock_cursor,
                                  lock_size,
                                  &range1, &range1_size,
                                  &range2, &range2_size,
                                  0);
    if (hr != DS_OK) {
        printf("IDirectSoundBuffer8_Lock failed.\n");
        return;
    }

    punp_sound_mix((i16 *)range1, PUNP_SOUND_BYTES_TO_SAMPLES(range1_size));
#if PUNP_SOUND_DEBUG_FILE
    punp_win32_write_audio_buf("range1", range1, range1_size);
#endif
    if (range2) {
        punp_sound_mix((i16 *)range2, PUNP_SOUND_BYTES_TO_SAMPLES(range2_size));
#if PUNP_SOUND_DEBUG_FILE
        punp_win32_write_audio_buf("range2", range2, range2_size);
#endif
    }

    IDirectSoundBuffer8_Unlock(punp_win32_audio_buffer,
                               range1, range1_size,
                               range2, range2_size);

    punp_win32_audio_cursor = lock_cursor;

//  static playing = 0;
//  if (playing == 0) {
//      IDirectSoundBuffer8_Play(punp_win32_audio_buffer, 0, 0, DSBPLAY_LOOPING);
//      playing = 1;
//  }
}
Esempio n. 7
0
void FillBuffer ( int buffer ) {
	//void AddToBuffer (void *sndptr, DWORD sndlen);
    DWORD dwBytesLocked;
    VOID *lpvData;

	if (!audioIsPlaying)
		StartAudio();


	if (gUcode != 4)
	if (Snd1Len == 0) { 
		
		*AudioInfo.AI_STATUS_REG &= ~AI_STATUS_FIFO_FULL;
		*AudioInfo.MI_INTR_REG |= MI_INTR_AI;
		AudioInfo.CheckInterrupts();

		return; }
	if (SndBuffer[buffer] == Buffer_Empty) {
		if (Snd1Len >= BufferSize) {
			if (FAILED( IDirectSoundBuffer8_Lock(lpdsbuf, BufferSize * buffer,BufferSize, &lpvData, &dwBytesLocked,
				NULL, NULL, 0  ) ) )
			{
				IDirectSoundBuffer8_Unlock(lpdsbuf, lpvData, dwBytesLocked, NULL, 0 );
				//DisplayError("FAILED lock");
				return;
			}
			Soundmemcpy(lpvData,Snd1ReadPos,dwBytesLocked);
			//AddToBuffer (lpvData, dwBytesLocked);
			SndBuffer[buffer] = Buffer_Full;
			Snd1ReadPos += dwBytesLocked;
			Snd1Len -= dwBytesLocked;
			IDirectSoundBuffer8_Unlock(lpdsbuf, lpvData, dwBytesLocked, NULL, 0 );
		} else {
			if (FAILED( IDirectSoundBuffer8_Lock(lpdsbuf, BufferSize * buffer,Snd1Len, &lpvData, &dwBytesLocked,
				NULL, NULL, 0  ) ) )
			{
				IDirectSoundBuffer8_Unlock(lpdsbuf, lpvData, dwBytesLocked, NULL, 0 );
				//DisplayError("FAILED lock");
				return;
			}
			Soundmemcpy(lpvData,Snd1ReadPos,dwBytesLocked);
			//AddToBuffer (lpvData, dwBytesLocked);
			SndBuffer[buffer] = Buffer_HalfFull;
			Snd1ReadPos += dwBytesLocked;
			SpaceLeft = BufferSize - Snd1Len;
			Snd1Len = 0;
			IDirectSoundBuffer8_Unlock(lpdsbuf, lpvData, dwBytesLocked, NULL, 0 );
		}
	} else if (SndBuffer[buffer] == Buffer_HalfFull) {
		if (Snd1Len >= SpaceLeft) {
			if (FAILED( IDirectSoundBuffer8_Lock(lpdsbuf, (BufferSize * (buffer + 1)) - SpaceLeft ,SpaceLeft, &lpvData,
				&dwBytesLocked, NULL, NULL, 0  ) ) )
			{
				IDirectSoundBuffer8_Unlock(lpdsbuf, lpvData, dwBytesLocked, NULL, 0 );
				//DisplayError("FAILED lock");
				return;
			}
			Soundmemcpy(lpvData,Snd1ReadPos,dwBytesLocked);
			//AddToBuffer (lpvData, dwBytesLocked);
			SndBuffer[buffer] = Buffer_Full;
			Snd1ReadPos += dwBytesLocked;
			Snd1Len -= dwBytesLocked;
			IDirectSoundBuffer8_Unlock(lpdsbuf, lpvData, dwBytesLocked, NULL, 0 );
		} else {
			if (FAILED( IDirectSoundBuffer8_Lock(lpdsbuf, (BufferSize * (buffer + 1)) - SpaceLeft,Snd1Len, &lpvData, &dwBytesLocked,
				NULL, NULL, 0  ) ) )
			{
				IDirectSoundBuffer8_Unlock(lpdsbuf, lpvData, dwBytesLocked, NULL, 0 );
				//DisplayError("FAILED lock");
				return;
			}
			Soundmemcpy(lpvData,Snd1ReadPos,dwBytesLocked);
			//AddToBuffer (lpvData, dwBytesLocked);
			SndBuffer[buffer] = Buffer_HalfFull;
			Snd1ReadPos += dwBytesLocked;
			SpaceLeft = SpaceLeft - Snd1Len;
			Snd1Len = 0;
			IDirectSoundBuffer8_Unlock(lpdsbuf, lpvData, dwBytesLocked, NULL, 0 );
		}
	}

	if (gUcode != 4)
	if ((Snd1Len == 0) /*&& (gUcode != UNDEFINED_UCODE)*/) {
		*AudioInfo.AI_STATUS_REG &= ~AI_STATUS_FIFO_FULL;
		*AudioInfo.MI_INTR_REG |= MI_INTR_AI;
		AudioInfo.CheckInterrupts();
	}
}
static DWORD WINAPI
gst_directsound_write_proc (LPVOID lpParameter)
{
  GstRingBuffer * buf;
  GstDirectSoundRingBuffer * dsoundbuffer;

  HRESULT hr;
  DWORD dwStatus;
  LPVOID pLockedBuffer1 = NULL, pLockedBuffer2 = NULL;
  DWORD dwSizeBuffer1 = 0, dwSizeBuffer2 = 0;
  DWORD dwCurrentPlayCursor = 0;

  gint64 freeBufferSize = 0;

  guint8 * readptr = NULL;
  gint readseg = 0;
  guint len = 0;
  gint retries = 0;

  gboolean flushing = FALSE;
  gboolean should_run = TRUE;
  gboolean error = FALSE;

  buf = (GstRingBuffer *) lpParameter;
  dsoundbuffer = GST_DIRECTSOUND_RING_BUFFER (buf);

  do {
    GST_DSOUND_LOCK (dsoundbuffer);

    if (dsoundbuffer->flushing || !dsoundbuffer->pDSB8) {
      GST_DSOUND_UNLOCK (dsoundbuffer);
      goto complete;
    }

    GST_DSOUND_UNLOCK (dsoundbuffer);

  restore_buffer:
    /* get current buffer status */
    GST_DSOUND_LOCK (dsoundbuffer);
    hr = IDirectSoundBuffer8_GetStatus (dsoundbuffer->pDSB8, &dwStatus);
    GST_DSOUND_UNLOCK (dsoundbuffer);

    if (dwStatus & DSBSTATUS_BUFFERLOST) {
      GST_DEBUG ("Buffer was lost, attempting to restore");

      GST_DSOUND_LOCK (dsoundbuffer);
      hr = IDirectSoundBuffer8_Restore (dsoundbuffer->pDSB8);
      GST_DSOUND_UNLOCK (dsoundbuffer);

      /* restore may fail again, ensure we restore the 
       * buffer before we continue */
      if (FAILED(hr) && hr == DSERR_BUFFERLOST) {
        if (retries++ < MAX_LOST_RETRIES) {
          GST_DEBUG ("Unable to restore, trying again");
          goto restore_buffer;
        }
        else {
          GST_ELEMENT_ERROR (dsoundbuffer->dsoundsink, RESOURCE, FAILED,
             ("%ls.", DXGetErrorDescription9W(hr)),
             ("gst_directsound_write_proc: IDirectSoundBuffer8_Restore, hr = %X", (unsigned int) hr));
          goto complete;
        }
      }
    }

    /* get current play cursor and write cursor positions */
    GST_DSOUND_LOCK (dsoundbuffer);
    hr = IDirectSoundBuffer8_GetCurrentPosition (dsoundbuffer->pDSB8,
        &dwCurrentPlayCursor, NULL);
    GST_DSOUND_UNLOCK (dsoundbuffer);

    if (G_UNLIKELY (FAILED(hr))) {
      /* try and reopen the default directsound device */
      if (hr == DIRECTSOUND_ERROR_DEVICE_RECONFIGURED) {
        /* we have to wait a while for the sound device removal to actually
         * be processed before attempting to reopen the device. Yes, this sucks */
        Sleep (2000);

        GST_DSOUND_LOCK (dsoundbuffer);
        IDirectSoundBuffer8_Release (dsoundbuffer->pDSB8);
        dsoundbuffer->pDSB8 = NULL;
        GST_DSOUND_UNLOCK (dsoundbuffer);

        if (gst_directsound_ring_buffer_close_device (buf) &&
            gst_directsound_ring_buffer_open_device (buf) &&
            gst_directsound_create_buffer (buf) ) {
          dsoundbuffer->buffer_write_offset = 0;
          goto restore_buffer;
        }
      }

      /* only trigger an error if we're not already in an error state */
      if (FAILED(hr) && !error) {
        GST_ELEMENT_ERROR (dsoundbuffer->dsoundsink, RESOURCE, FAILED,
           ("%ls.", DXGetErrorDescription9W(hr)),
           ("gst_directsound_write_proc: IDirectSoundBuffer8_GetCurrentPosition, hr = %X", (unsigned int) hr));
        error = TRUE;
        goto complete;
      }
    }

    GST_LOG ("Current Play Cursor: %u Current Write Offset: %d",
             (unsigned int) dwCurrentPlayCursor,
             dsoundbuffer->buffer_write_offset);

    /* calculate the free size of the circular buffer */
    GST_DSOUND_LOCK (dsoundbuffer);
    if (dwCurrentPlayCursor <= dsoundbuffer->buffer_write_offset)
      freeBufferSize = dsoundbuffer->buffer_size -
        (dsoundbuffer->buffer_write_offset - dwCurrentPlayCursor);
    else
      freeBufferSize = dwCurrentPlayCursor - dsoundbuffer->buffer_write_offset;
    GST_DSOUND_UNLOCK (dsoundbuffer);

    if (!gst_ring_buffer_prepare_read (buf, &readseg, &readptr, &len))
      goto complete;

    len -= dsoundbuffer->segoffset;

    GST_LOG ("Size of segment to write: %d Free buffer size: %lld",
             len, freeBufferSize);

    /* If we can't write this into directsound because we don't have enough 
     * space, then start playback if we're currently paused. Then, sleep
     * for a little while to wait until space is available */
    if (len >= freeBufferSize) {
      if (!(dwStatus & DSBSTATUS_PLAYING)) {
        GST_DSOUND_LOCK (dsoundbuffer);
        hr = IDirectSoundBuffer8_Play (dsoundbuffer->pDSB8, 0, 0, DSBPLAY_LOOPING);
        GST_DSOUND_UNLOCK (dsoundbuffer);

        if (FAILED(hr)) {
          GST_WARNING ("gst_directsound_write_proc: IDirectSoundBuffer8_Play, hr = %X", (unsigned int) hr);
        }
      }

      goto complete;
    }

    /* lock it */
    GST_DSOUND_LOCK (dsoundbuffer);
    hr = IDirectSoundBuffer8_Lock (dsoundbuffer->pDSB8,
        dsoundbuffer->buffer_write_offset, len, &pLockedBuffer1,
        &dwSizeBuffer1, &pLockedBuffer2, &dwSizeBuffer2, 0L);

    /* copy chunks */
    if (SUCCEEDED (hr)) {
      if (len <= dwSizeBuffer1) {
        memcpy (pLockedBuffer1, (LPBYTE) readptr + dsoundbuffer->segoffset, len);
      }
      else {
        memcpy (pLockedBuffer1, (LPBYTE) readptr + dsoundbuffer->segoffset, dwSizeBuffer1);
        memcpy (pLockedBuffer2, (LPBYTE) readptr + dsoundbuffer->segoffset + dwSizeBuffer1, len - dwSizeBuffer1);
      }

      IDirectSoundBuffer8_Unlock (dsoundbuffer->pDSB8, pLockedBuffer1,
         dwSizeBuffer1, pLockedBuffer2, dwSizeBuffer2);
    }
    else {
      GST_WARNING ("gst_directsound_write_proc: IDirectSoundBuffer8_Lock, hr = %X", (unsigned int) hr);
    }

    /* update tracking data */
    dsoundbuffer->segoffset += dwSizeBuffer1 + (len - dwSizeBuffer1);

    dsoundbuffer->buffer_write_offset += dwSizeBuffer1 + (len - dwSizeBuffer1);
    dsoundbuffer->buffer_write_offset %= dsoundbuffer->buffer_size;
    GST_DSOUND_UNLOCK (dsoundbuffer);

    freeBufferSize -= dwSizeBuffer1 + (len - dwSizeBuffer1);

    GST_LOG ("DirectSound Buffer1 Data Size: %u DirectSound Buffer2 Data Size: %u",
        (unsigned int) dwSizeBuffer1, (unsigned int) dwSizeBuffer2);
    GST_LOG ("Free buffer size: %lld", freeBufferSize);

    /* check if we read a whole segment */
    GST_DSOUND_LOCK (dsoundbuffer);
    if (dsoundbuffer->segoffset == dsoundbuffer->segsize) {
      GST_DSOUND_UNLOCK (dsoundbuffer);

      /* advance to next segment */
      gst_ring_buffer_clear (buf, readseg);
      gst_ring_buffer_advance (buf, 1);

      GST_DSOUND_LOCK (dsoundbuffer);
      dsoundbuffer->segoffset = 0;
    }
    GST_DSOUND_UNLOCK (dsoundbuffer);

  complete:
    GST_DSOUND_LOCK (dsoundbuffer);

    should_run = dsoundbuffer->should_run;
    flushing = dsoundbuffer->flushing;
    retries = 0;

    GST_DSOUND_UNLOCK (dsoundbuffer);

    /* it's extremely important to sleep in without the lock! */
    if (len >= freeBufferSize || flushing || error)
      Sleep (dsoundbuffer->min_sleep_time);
  }
  while(should_run);

  return 0;
}