Ejemplo n.º 1
0
void SNDDXDeInit()
{
   DWORD status=0;

   if (lpDSB2)
   {
      IDirectSoundBuffer8_GetStatus(lpDSB2, &status);

      if(status == DSBSTATUS_PLAYING)
         IDirectSoundBuffer8_Stop(lpDSB2);

      IDirectSoundBuffer8_Release(lpDSB2);
      lpDSB2 = NULL;
   }

   if (lpDSB)
   {
      IDirectSoundBuffer8_Release(lpDSB);
      lpDSB = NULL;
   }

   if (lpDS8)
   {
      IDirectSound8_Release(lpDS8);
      lpDS8 = NULL;
   }
}
Ejemplo n.º 2
0
void PlayIt()
{
int count=0;
DWORD dwStatus;

	if (!Playing) {
		for (count = 0; count < 3; count ++) {
			if (SndBuffer[count] == Buffer_Full) 
			{
				Playing = TRUE;
				IDirectSoundBuffer8_Play(lpdsbuf, 0, 0, DSBPLAY_LOOPING );
				return;
			}
		}
	} else {
		IDirectSoundBuffer8_GetStatus(lpdsbuf,&dwStatus);
		if ((dwStatus & DSBSTATUS_PLAYING) == 0) {
			IDirectSoundBuffer8_Play(lpdsbuf, 0, 0, DSBPLAY_LOOPING );
		}
	}

}
Ejemplo 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);
}
Ejemplo n.º 4
0
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;
}