Пример #1
0
int tdav_consumer_dsound_stop(tmedia_consumer_t* self)
{
	tdav_consumer_dsound_t* dsound = (tdav_consumer_dsound_t*)self;

	HRESULT hr;

	if(!self){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	if(!dsound->started){
		TSK_DEBUG_WARN("Consumer not started");
		return 0;
	}

	/* should be done here */
	dsound->started = tsk_false;

	/* stop thread */
	if(dsound->tid[0]){
		tsk_thread_join(&(dsound->tid[0]));
	}

	if((hr = IDirectSoundBuffer_Stop(dsound->secondaryBuffer)) != DS_OK){
		tdav_win32_print_error("IDirectSoundBuffer_Stop", hr);
	}
	if((hr = IDirectSoundBuffer_SetCurrentPosition(dsound->secondaryBuffer, 0)) != DS_OK){
		tdav_win32_print_error("IDirectSoundBuffer_SetCurrentPosition", hr);
	}

	return 0;
}
Пример #2
0
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);
	}
}
Пример #3
0
// ////////////////////////////////////////////////////////////////////////
// Handle a incoming message that needs to be played
void NETplayIncomingAudio(NETMSG *pMsg)
{	
	if(!NetPlay.bAllowCapturePlay)
	{
		return;
	}
#if 1
	if(pMsg->size ==1)
	{
		stopIncomingAudio();
		NetPlay.bCaptureInUse = FALSE;
	}
	else
	{
		NETqueueIncomingAudio(pMsg->body, pMsg->size,TRUE);		// use the circular buffer...
		NetPlay.bCaptureInUse = TRUE;
	}


#else
	// dont queue. crappy old method.
	stopIncomingAudio();
	IDirectSoundBuffer_SetCurrentPosition(lpDirectSoundBuffer,0);	// reset the play position
	NETqueueIncomingAudio(pMsg->body, pMsg->size,FALSE);		// don't use the circular buffer...
#endif
	
}
Пример #4
0
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;
}
Пример #5
0
void m1sdr_PlayStart(void)
{
	waveLogStart();

	IDirectSound_SetCooperativeLevel(lpDS, GetForegroundWindow(), DSSCL_PRIORITY);
	
	IDirectSoundBuffer_SetCurrentPosition(lpSecB, 0);
	IDirectSoundBuffer_Play(lpSecB, 0, 0, DSBPLAY_LOOPING);
}
Пример #6
0
/**
\brief stop playing and empty buffers (for seeking/pause)
*/
static void reset(struct ao *ao)
{
    struct priv *p = ao->priv;

    IDirectSoundBuffer_Stop(p->hdsbuf);
    // reset directsound buffer
    IDirectSoundBuffer_SetCurrentPosition(p->hdsbuf, 0);
    p->write_offset = 0;
    p->underrun_check = 0;
}
Пример #7
0
void DirectSoundDrv_PCM_StopPlayback(void)
{
    if (!Playing) {
        return;
    }
    
    IDirectSoundBuffer_Stop(lpdsbsec);
    IDirectSoundBuffer_SetCurrentPosition(lpdsbsec, 0);
    
    Playing = 0;
}
Пример #8
0
void I_StopSound(int handle)
{
    sndsource_t *buf = GetSource(handle);

    if(!initOk || !buf) return;
    if(buf->source)
    {
        IDirectSoundBuffer_Stop(buf->source);
        IDirectSoundBuffer_SetCurrentPosition(buf->source, 0);
    }
}
Пример #9
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);
   }
}
Пример #10
0
IDirectSoundBuffer *SndObjGetFreeBuffer(SNDOBJ *pSO)
{
    IDirectSoundBuffer *pDSB;

    if (pSO == NULL)
        return NULL;

    if (pDSB = pSO->Buffers[pSO->iCurrent])
    {
        HRESULT hres;
        DWORD dwStatus;

        hres = IDirectSoundBuffer_GetStatus(pDSB, &dwStatus);

        if (FAILED(hres))
            dwStatus = 0;

        if ((dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
        {
            if (pSO->iAlloc > 1)
            {
                if (++pSO->iCurrent >= pSO->iAlloc)
                    pSO->iCurrent = 0;

                pDSB = pSO->Buffers[pSO->iCurrent];
                hres = IDirectSoundBuffer_GetStatus(pDSB, &dwStatus);

                if (SUCCEEDED(hres) && (dwStatus & DSBSTATUS_PLAYING) == DSBSTATUS_PLAYING)
                {
                    IDirectSoundBuffer_Stop(pDSB);
                    IDirectSoundBuffer_SetCurrentPosition(pDSB, 0);
                }
            }
            else
            {
                pDSB = NULL;
            }
        }

        if (pDSB && (dwStatus & DSBSTATUS_BUFFERLOST))
        {
            if (FAILED(IDirectSoundBuffer_Restore(pDSB)) ||
                !DSFillSoundBuffer(pDSB, pSO->pbWaveData, pSO->cbWaveSize))
            {
                pDSB = NULL;
            }
        }
    }

    return pDSB;
}
Пример #11
0
static HRESULT Flush( aout_stream_sys_t *sys )
{
    HRESULT ret = IDirectSoundBuffer_Stop( sys->p_dsbuffer );
    if( ret == DS_OK )
    {
        vlc_mutex_lock(&sys->lock);
        sys->i_data = 0;
        sys->i_last_read = sys->i_write;
        IDirectSoundBuffer_SetCurrentPosition( sys->p_dsbuffer, sys->i_write);
        sys->b_playing = false;
        vlc_mutex_unlock(&sys->lock);
    }
    return ret;
}
Пример #12
0
BOOL SndObjStop(SNDOBJ *pSO)
{
    int i;

    if (pSO == NULL)
        return FALSE;

    for (i=0; i<pSO->iAlloc; i++)
    {
        IDirectSoundBuffer_Stop(pSO->Buffers[i]);
        IDirectSoundBuffer_SetCurrentPosition(pSO->Buffers[i], 0);
    }

    return TRUE;
}
Пример #13
0
/*
 * バッファの再生を停止する
 */
static VOID StopSoundBuffer(int nBuffer)
{
	assert(pDSBuffer[nBuffer] != NULL);
	assert(nBuffer >= 0 && nBuffer < MIXER_STREAMS);

	/* イベントスレッドと排他制御する */
	EnterCriticalSection(&StreamCritical);
	{
		/* バッファが再生中であれば */
		if(pStream[nBuffer] != NULL)
		{
			/* 再生を停止する */
			IDirectSoundBuffer_Stop(pDSBuffer[nBuffer]);
			IDirectSoundBuffer_SetCurrentPosition(pDSBuffer[nBuffer], 0);

			/* ストリームを停止状態にする */
			pStream[nBuffer] = NULL;
		}
	}
	LeaveCriticalSection(&StreamCritical);
}
Пример #14
0
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;
}
Пример #15
0
/*
 * Start stream.
 */
PJ_DEF(pj_status_t) pjmedia_snd_stream_start(pjmedia_snd_stream *stream)
{
    HRESULT hr;

    if (stream->play_strm.ds.play.lpDsBuffer) {
	hr = IDirectSoundBuffer_SetCurrentPosition(
				stream->play_strm.ds.play.lpDsBuffer, 0);
	if (FAILED(hr))
	    return PJ_RETURN_OS_ERROR(hr);
	
	/* Set the write pointer ahead of the read pointer by latency bytes */
	stream->play_strm.dwBytePos = BYTES_PER_SAMPLE * stream->clock_rate *
		stream->channel_count * stream->play_strm.latency / 1000;

	hr = IDirectSoundBuffer_Play(stream->play_strm.ds.play.lpDsBuffer, 
				     0, 0, DSBPLAY_LOOPING);
	if (FAILED(hr))
	    return PJ_RETURN_OS_ERROR(hr);
	PJ_LOG(5,(THIS_FILE, "DirectSound playback stream started"));
    }
    
    if (stream->rec_strm.ds.capture.lpDsBuffer) {
	hr = IDirectSoundCaptureBuffer_GetCurrentPosition( 
				stream->rec_strm.ds.capture.lpDsBuffer, 
				NULL, &stream->rec_strm.dwBytePos );
	if (FAILED(hr))
	    return PJ_RETURN_OS_ERROR(hr);

	hr = IDirectSoundCaptureBuffer_Start(
				stream->rec_strm.ds.capture.lpDsBuffer,
				DSCBSTART_LOOPING );
	if (FAILED(hr))
	    return PJ_RETURN_OS_ERROR(hr);
	PJ_LOG(5,(THIS_FILE, "DirectSound capture stream started"));
    }

    return PJ_SUCCESS;
}
Пример #16
0
/*
 * 再生位置通知のハンドラ
 */
static VOID OnNotifyPlayPos(int nBuffer)
{
	DWORD dwPlayPos;
	HRESULT hRet;

	// 再生終了領域を再生し終わった場合
	if(nPosCurArea[nBuffer] == nPosEndArea[nBuffer])
	{
		/* 再生を停止する */
		IDirectSoundBuffer_Stop(pDSBuffer[nBuffer]);
		IDirectSoundBuffer_SetCurrentPosition(pDSBuffer[nBuffer], 0);

		/* ストリームを停止状態にする */
		pStream[nBuffer] = NULL;
		return;	// 再生終了
	}

	// 再生位置を取得する
	hRet = IDirectSoundBuffer_GetCurrentPosition(pDSBuffer[nBuffer],
												 &dwPlayPos,
												 NULL);
	if(hRet != DS_OK)
		return;	// 再生位置の取得に失敗した

	/*
	 * 更新する領域上を再生中である場合
	 *  - 初回の通知のときに発生する
	 *  - または、遅延がバッファN周分のとき発生する
	 *  - バッファを更新しないで次の通知を待つ
	 *  - 遅延の場合は同じ音が繰り返し再生される(壊れたCDのように)
	 */
	if(dwPlayPos >= (DWORD)nPosCurArea[nBuffer] * AREA_BYTES &&
	   dwPlayPos < ((DWORD)nPosCurArea[nBuffer] + 1) * AREA_BYTES)
		return;	/* 更新しない */

	// バッファを更新する
	WriteNext(nBuffer);
}
Пример #17
0
static void
gst_directsound_sink_reset (GstAudioSink * asink)
{
  GstDirectSoundSink *dsoundsink;
  LPVOID pLockedBuffer = NULL;
  DWORD dwSizeBuffer = 0;

  dsoundsink = GST_DIRECTSOUND_SINK (asink);

  GST_DSOUND_LOCK (dsoundsink);

  if (dsoundsink->pDSBSecondary) {
    /*stop playing */
    HRESULT hRes = IDirectSoundBuffer_Stop (dsoundsink->pDSBSecondary);

    /*reset position */
    hRes = IDirectSoundBuffer_SetCurrentPosition (dsoundsink->pDSBSecondary, 0);
    dsoundsink->current_circular_offset = 0;

    /*reset the buffer */
    hRes = IDirectSoundBuffer_Lock (dsoundsink->pDSBSecondary,
        dsoundsink->current_circular_offset, dsoundsink->buffer_size,
        &pLockedBuffer, &dwSizeBuffer, NULL, NULL, 0L);

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

      hRes =
          IDirectSoundBuffer_Unlock (dsoundsink->pDSBSecondary, pLockedBuffer,
          dwSizeBuffer, NULL, 0);
    }
  }

  dsoundsink->first_buffer_after_reset = TRUE;

  GST_DSOUND_UNLOCK (dsoundsink);
}
Пример #18
0
// ////////////////////////////////////////////////////////////////////////
static VOID stopIncomingAudio(VOID)
{
	LPVOID	lpvPtr1=NULL; 
    DWORD	dwBytes1=0; 
    HRESULT hr; 

	IDirectSoundBuffer_Stop(lpDirectSoundBuffer);

	hr = IDirectSoundBuffer_Lock(lpDirectSoundBuffer,	// clear out and start again
								0,					
								0,	
								&lpvPtr1,&dwBytes1,
								NULL,NULL,
								DSBLOCK_ENTIREBUFFER); 
	if(DS_OK == hr) 
	{     	
	    ZeroMemory( ((UBYTE *)lpvPtr1),playbackBuff.dwBufferBytes);	// remove old stuff
	
		hr = IDirectSoundBuffer_Unlock(lpDirectSoundBuffer, lpvPtr1, dwBytes1, 0,0);			//clear buffer.
	}

	IDirectSoundBuffer_SetCurrentPosition(lpDirectSoundBuffer,0);								// reset the play position

}
Пример #19
0
HRESULT DSW_StartOutput( DSoundWrapper *dsw )
{
	HRESULT        hr;
	QueryPerformanceCounter( &dsw->dsw_LastPlayTime );
	dsw->dsw_LastPlayCursor = 0;
	dsw->dsw_FramesPlayed = 0;
	hr = IDirectSoundBuffer_SetCurrentPosition( dsw->dsw_OutputBuffer, 0 );
	if( hr != DS_OK )
	{
		return hr;
	}
// Start the buffer playback in a loop.
	if( dsw->dsw_OutputBuffer != NULL )
	{
		hr = IDirectSoundBuffer_Play( dsw->dsw_OutputBuffer, 0, 0, DSBPLAY_LOOPING );
		if( hr != DS_OK )
		{
			return hr;
		}
		dsw->dsw_OutputRunning = TRUE;
	}
	
	return 0;
}
Пример #20
0
static	BOOL	StartSoundChannel( SoundManager *sm, unsigned int Handle, geSound_Cfg *cfg, int loop, unsigned int* sfx)
{
	HRESULT	hres;
	Channel* channel, *dupChannel;
	
	if( Handle == 0 )
		return( FALSE );
	channel = GetChannel( sm, Handle );
	//Clear all non-playing duplicate buffers.
	ClearDupBuffers(channel);
	//If the main buffer is playing and all non-playing dups have been cleared
	//we need a new duplicate.
	if( ChannelPlaying( channel ) )
	{
		if(!DupChannel( sm,channel, &dupChannel ) )
			return( FALSE );
		channel = dupChannel;
	}
	if( !ModifyChannel( channel, cfg ) )
		return( FALSE );
	IDirectSoundBuffer_SetCurrentPosition(channel->buffer, 0);
	hres = IDirectSoundBuffer_Play( channel->buffer,
				  				   0,
				  				   0,
				  				   loop ? DSBPLAY_LOOPING : 0);

	if	(hres == DS_OK)
	{
		if( sfx )
			*sfx = channel->ID;
		return TRUE;
	}
	
	geErrorLog_Add(GE_ERR_DS_ERROR, NULL);
	return FALSE;
}
Пример #21
0
static HRESULT test_block_align(LPGUID lpGuid)
{
    HRESULT rc;
    LPDIRECTSOUND dso=NULL;
    LPDIRECTSOUNDBUFFER secondary=NULL;
    DSBUFFERDESC bufdesc;
    DSBCAPS dsbcaps;
    WAVEFORMATEX wfx;
    DWORD pos, pos2;
    int ref;

    /* Create the DirectSound object */
    rc=pDirectSoundCreate(lpGuid,&dso,NULL);
    ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
       "DirectSoundCreate() failed: %08x\n",rc);
    if (rc!=DS_OK)
        return rc;

    init_format(&wfx,WAVE_FORMAT_PCM,11025,16,2);
    ZeroMemory(&bufdesc, sizeof(bufdesc));
    bufdesc.dwSize=sizeof(bufdesc);
    bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
    bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec + 1;
    bufdesc.lpwfxFormat=&wfx;
    rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
    ok(rc==DS_OK,"IDirectSound_CreateSoundBuffer() "
       "should have returned DS_OK, returned: %08x\n", rc);

    if (rc==DS_OK && secondary!=NULL) {
        ZeroMemory(&dsbcaps, sizeof(dsbcaps));
        dsbcaps.dwSize = sizeof(dsbcaps);
        rc=IDirectSoundBuffer_GetCaps(secondary,&dsbcaps);
        ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() should have returned DS_OK, "
           "returned: %08x\n", rc);
        if (rc==DS_OK && wfx.nBlockAlign > 1)
        {
            ok(dsbcaps.dwBufferBytes==(wfx.nAvgBytesPerSec + wfx.nBlockAlign),
               "Buffer size not a multiple of nBlockAlign: requested %d, "
               "got %d, should be %d\n", bufdesc.dwBufferBytes,
               dsbcaps.dwBufferBytes, wfx.nAvgBytesPerSec + wfx.nBlockAlign);

            rc = IDirectSoundBuffer_SetCurrentPosition(secondary, 0);
            ok(rc == DS_OK, "Could not set position to 0: %08x\n", rc);
            rc = IDirectSoundBuffer_GetCurrentPosition(secondary, &pos, NULL);
            ok(rc == DS_OK, "Could not get position: %08x\n", rc);
            rc = IDirectSoundBuffer_SetCurrentPosition(secondary, 1);
            ok(rc == DS_OK, "Could not set position to 1: %08x\n", rc);
            rc = IDirectSoundBuffer_GetCurrentPosition(secondary, &pos2, NULL);
            ok(rc == DS_OK, "Could not get new position: %08x\n", rc);
            ok(pos == pos2, "Positions not the same! Old position: %d, new position: %d\n", pos, pos2);
        }
        ref=IDirectSoundBuffer_Release(secondary);
        ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d references, "
           "should have 0\n",ref);
    }

    ref=IDirectSound_Release(dso);
    ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
    if (ref!=0)
        return DSERR_GENERIC;

    return rc;
}
Пример #22
0
static void *dsound_init(const char *device, unsigned rate, unsigned latency)
{
   WAVEFORMATEX wfx      = {0};
   DSBUFFERDESC bufdesc  = {0};
   struct dsound_dev dev = {0};
   dsound_t          *ds = (dsound_t*)calloc(1, sizeof(*ds));

   if (!ds)
      goto error;

   InitializeCriticalSection(&ds->crit);

   if (device)
      dev.device = strtoul(device, NULL, 0);

   RARCH_LOG("DirectSound devices:\n");
#ifndef _XBOX
   DirectSoundEnumerate(enumerate_cb, &dev);
#endif

   if (DirectSoundCreate(dev.guid, &ds->ds, NULL) != DS_OK)
      goto error;

#ifndef _XBOX
   if (IDirectSound_SetCooperativeLevel(ds->ds, GetDesktopWindow(), DSSCL_PRIORITY) != DS_OK)
      goto error;
#endif

   wfx.wFormatTag        = WAVE_FORMAT_PCM;
   wfx.nChannels         = 2;
   wfx.nSamplesPerSec    = rate;
   wfx.wBitsPerSample    = 16;
   wfx.nBlockAlign       = 2 * sizeof(int16_t);
   wfx.nAvgBytesPerSec   = rate * 2 * sizeof(int16_t);

   ds->buffer_size       = (latency * wfx.nAvgBytesPerSec) / 1000;
   ds->buffer_size      /= CHUNK_SIZE;
   ds->buffer_size      *= CHUNK_SIZE;
   if (ds->buffer_size < 4 * CHUNK_SIZE)
      ds->buffer_size    = 4 * CHUNK_SIZE;

   RARCH_LOG("[DirectSound]: Setting buffer size of %u bytes\n", ds->buffer_size);
   RARCH_LOG("[DirectSound]: Latency = %u ms\n", (unsigned)((1000 * ds->buffer_size) / wfx.nAvgBytesPerSec));

   bufdesc.dwSize        = sizeof(DSBUFFERDESC);
   bufdesc.dwFlags       = 0;
#ifndef _XBOX
   bufdesc.dwFlags       = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
#endif
   bufdesc.dwBufferBytes = ds->buffer_size;
   bufdesc.lpwfxFormat   = &wfx;

   ds->event = CreateEvent(NULL, false, false, NULL);
   if (!ds->event)
      goto error;

   ds->buffer = fifo_new(4 * 1024);
   if (!ds->buffer)
      goto error;

   if (IDirectSound_CreateSoundBuffer(ds->ds, &bufdesc, &ds->dsb, 0) != DS_OK)
      goto error;

   IDirectSoundBuffer_SetVolume(ds->dsb, DSBVOLUME_MAX);
   IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0);

   dsound_clear_buffer(ds);

   if (IDirectSoundBuffer_Play(ds->dsb, 0, 0, DSBPLAY_LOOPING) != DS_OK)
      goto error;

   if (!dsound_start_thread(ds))
      goto error;

   return ds;

error:
   RARCH_ERR("[DirectSound] Error occured in init.\n");
   dsound_free(ds);
   return NULL;
}
Пример #23
0
/*
 * Initialize DirectSound player device.
 */
static pj_status_t init_player_stream( struct dsound_stream *ds_strm,
				       int dev_id,
				       unsigned clock_rate,
				       unsigned channel_count,
				       unsigned samples_per_frame,
				       unsigned buffer_count)
{
    HRESULT hr;
    HWND hwnd;
    PCMWAVEFORMAT pcmwf; 
    DSBUFFERDESC dsbdesc;
    DSBPOSITIONNOTIFY dsPosNotify[MAX_PACKET_BUFFER_COUNT];
    unsigned bytes_per_frame;
    unsigned max_latency;
    unsigned i;


    PJ_ASSERT_RETURN(buffer_count <= MAX_PACKET_BUFFER_COUNT, PJ_EINVAL);

    /* Check device ID */
    if (dev_id == -1)
	dev_id = 0;

    PJ_ASSERT_RETURN(dev_id>=0 && dev_id < (int)dev_count, PJ_EINVAL);

    /*
     * Create DirectSound device.
     */
    hr = DirectSoundCreate(dev_info[dev_id].lpGuid, &ds_strm->ds.play.lpDs, 
			   NULL);
    if (FAILED(hr))
	return PJ_RETURN_OS_ERROR(hr);

    hwnd = GetForegroundWindow();
    if (hwnd == NULL) {
	hwnd = GetDesktopWindow();
    }    
    hr = IDirectSound_SetCooperativeLevel( ds_strm->ds.play.lpDs, hwnd, 
					   DSSCL_PRIORITY);
    if FAILED(hr)
	return PJ_RETURN_OS_ERROR(hr);
    
    /*
     * Set up wave format structure for initialize DirectSound play
     * buffer. 
     */
    init_waveformatex(&pcmwf, clock_rate, channel_count);
    bytes_per_frame = samples_per_frame * BYTES_PER_SAMPLE;

    /* Set up DSBUFFERDESC structure. */
    pj_bzero(&dsbdesc, sizeof(DSBUFFERDESC)); 
    dsbdesc.dwSize = sizeof(DSBUFFERDESC); 
    dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPOSITIONNOTIFY |
		      DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;

    dsbdesc.dwBufferBytes = buffer_count * bytes_per_frame;
    dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf; 

    /*
     * Create DirectSound playback buffer. 
     */
    hr = IDirectSound_CreateSoundBuffer(ds_strm->ds.play.lpDs, &dsbdesc, 
					&ds_strm->ds.play.lpDsBuffer, NULL); 
    if (FAILED(hr) )
	return PJ_RETURN_OS_ERROR(hr);

    /*
     * Create event for play notification.
     */
    ds_strm->hEvent = CreateEvent( NULL, FALSE, FALSE, NULL);
    if (ds_strm->hEvent == NULL)
	return pj_get_os_error();

    /*
     * Setup notification for play.
     */
    hr = IDirectSoundBuffer_QueryInterface( ds_strm->ds.play.lpDsBuffer, 
					    &IID_IDirectSoundNotify, 
					    (LPVOID *)&ds_strm->lpDsNotify); 
    if (FAILED(hr))
	return PJ_RETURN_OS_ERROR(hr);

    
    for (i=0; i<buffer_count; ++i) {
	dsPosNotify[i].dwOffset = i * bytes_per_frame;
	dsPosNotify[i].hEventNotify = ds_strm->hEvent;
    }
    
    hr = IDirectSoundNotify_SetNotificationPositions( ds_strm->lpDsNotify, 
						      buffer_count, 
						      dsPosNotify);
    if (FAILED(hr))
	return PJ_RETURN_OS_ERROR(hr);


    hr = IDirectSoundBuffer_SetCurrentPosition(ds_strm->ds.play.lpDsBuffer, 0);
    if (FAILED(hr))
	return PJ_RETURN_OS_ERROR(hr);


    ds_strm->dwBytePos = 0;
    ds_strm->dwDsBufferSize = buffer_count * bytes_per_frame;
    ds_strm->timestamp.u64 = 0;
    /*
     * Play latency does not need to be on a frame boundry, it is just how far
     * ahead of the read pointer we set the write pointer.  So we should just
     * use the user configured latency.  However, if the latency measured in
     * bytes causes more buffers than we are allowed, we must cap the latency
     * at the time contained in 1-buffer_count.
     */
    max_latency = (1 - buffer_count) * samples_per_frame * 1000 / clock_rate /
        channel_count;
    ds_strm->latency = PJ_MIN(max_latency, snd_output_latency);

    /* Done setting up play device. */
    PJ_LOG(5,(THIS_FILE, 
	      " DirectSound player \"%s\" initialized (clock_rate=%d, "
	      "channel_count=%d, samples_per_frame=%d (%dms))",
	      dev_info[dev_id].info.name,
	      clock_rate, channel_count, samples_per_frame,
	      samples_per_frame * 1000 / clock_rate));

    return PJ_SUCCESS;
}
Пример #24
0
int I_StartSound(sfxinfo_t *sound, int vol, int sep, int pitch, int pri)
{
  int channel=0;

  // proff 07/04/98: Added for CYGWIN32 compatibility
#ifdef HAVE_LIBDSOUND
  HRESULT error;
  char *snddata;
  int sndlength;

  if (noDSound == true)
    return channel;

  // load sound data if we have not already  

  I_CacheSound(sound);

  // find a free channel

  channel = I_GetFreeChannel();

  // proff 07/26/98: Added volume check
  // proff 10/31/98: Added Stop before updating sound-data

  error = IDirectSoundBuffer_Stop(lpSecondaryDSB[channel]);
  ChannelInfo[channel].playing = false;
  
  if (vol==0)
    return channel;

  snddata = sound->data;

  ChannelInfo[channel].samplerate = (snddata[3] << 8) + snddata[2];
// proff 10/31/98: Use accurate time for this one
  ChannelInfo[channel].endtime = 
    I_GetTime_RealTime() + 
    (sound->length * 35) / ChannelInfo[channel].samplerate + 1;

  // skip past header

  snddata += 8;
  sndlength = sound->length - 8;

  error = IDirectSoundBuffer_SetCurrentPosition(lpSecondaryDSB[channel],0);

  // proff 11/09/98: Added for a slight speedup
  if (sound != ChannelInfo[channel].sfx)
    {
      DWORD *hand1,*hand2;
      DWORD len1,len2;

      ChannelInfo[channel].sfx = sound;
      error = IDirectSoundBuffer_Lock(lpSecondaryDSB[channel],0,65535,
				      &hand1,&len1,&hand2,&len2,
				      DSBLOCK_FROMWRITECURSOR);
      if (len1 >= sndlength) 
	{
	  memset(hand1, 128, len1);
	  memcpy(hand1, snddata , sndlength);
	  memset(hand2, 128, len2);
	}
      else 
	{
	  memcpy(hand1, snddata, len1);
	  memcpy(hand2, &((char *)snddata)[len1], sndlength-len1);
	}
      
      error = IDirectSoundBuffer_Unlock
	(lpSecondaryDSB[channel], hand1, len1, hand2, len2);
    }
  IDirectSoundBuffer_SetVolume(lpSecondaryDSB[channel], VOL(vol));
  IDirectSoundBuffer_SetPan(lpSecondaryDSB[channel], SEP(sep));
  IDirectSoundBuffer_SetFrequency(lpSecondaryDSB[channel], 
				  ChannelInfo[channel].samplerate+PITCH(pitch));
  error = IDirectSoundBuffer_Play(lpSecondaryDSB[channel], 0, 0, 0);
  ChannelInfo[channel].playing = true;

#endif // HAVE_LIBDSOUND
  return channel;
}
Пример #25
0
static int ds_rsd_open(void* data, wav_header_t *w)
{
    ds_t* ds = data;

    if (DirectSoundCreate(NULL, &ds->ds, NULL) != DS_OK)
        return -1;

    if (IDirectSound_SetCooperativeLevel(ds->ds, GetDesktopWindow(), DSSCL_NORMAL) != DS_OK)
        return -1;

    int bits = 16;
    ds->fmt = w->rsd_format;
    ds->conv = converter_fmt_to_s16ne(w->rsd_format);

    ds->rings = 16;
    ds->latency = DEFAULT_CHUNK_SIZE * 2;

    WAVEFORMATEX wfx = {
        .wFormatTag = WAVE_FORMAT_PCM,
        .nChannels = w->numChannels,
        .nSamplesPerSec = w->sampleRate,
        .wBitsPerSample = bits,
        .nBlockAlign = w->numChannels * bits / 8,
        .nAvgBytesPerSec = w->sampleRate * w->numChannels * bits / 8,
    };

    DSBUFFERDESC bufdesc = {
        .dwSize = sizeof(DSBUFFERDESC),
        .dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS,
        .dwBufferBytes = ds->rings * ds->latency,
        .lpwfxFormat = &wfx,
    };

    if (IDirectSound_CreateSoundBuffer(ds->ds, &bufdesc, &ds->dsb, 0) != DS_OK)
        return -1;

    IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0);
    clear_buffers(ds);
    IDirectSoundBuffer_Play(ds->dsb, 0, 0, DSBPLAY_LOOPING);

    return 0;
}

static size_t ds_rsd_write(void *data, const void* inbuf, size_t size)
{
    ds_t *ds = data;

    size_t osize = size;

    uint8_t convbuf[2 * size];
    const uint8_t *buffer_ptr = inbuf;

    if (ds->conv != RSD_NULL)
    {
        if (rsnd_format_to_bytes(ds->fmt) == 1)
            osize = 2 * size;
        else if (rsnd_format_to_bytes(ds->fmt) == 4)
            osize = size / 2;

        memcpy(convbuf, inbuf, size);

        audio_converter(convbuf, ds->fmt, ds->conv, size);
        buffer_ptr = convbuf;
    }

    // With this approach we are prone to underruns which would "ring",
    // but the RSound API does not really encourage letting stuff underrun anyways.
    ds->writering = (ds->writering + 1) % ds->rings;
    for (;;)
    {
        DWORD pos;
        IDirectSoundBuffer_GetCurrentPosition(ds->dsb, &pos, 0);
        unsigned activering = pos / ds->latency;
        if (activering != ds->writering)
            break;

        Sleep(1);
    }

    void *output1, *output2;
    DWORD size1, size2;

    HRESULT res;
    if ((res = IDirectSoundBuffer_Lock(ds->dsb, ds->writering * ds->latency, osize,
                                       &output1, &size1, &output2, &size2, 0)) != DS_OK)
    {
        if (res != DSERR_BUFFERLOST)
            return 0;

        if (IDirectSoundBuffer_Restore(ds->dsb) != DS_OK)
            return 0;

        if (IDirectSoundBuffer_Lock(ds->dsb, ds->writering * ds->latency, osize,
                                    &output1, &size1, &output2, &size2, 0) != DS_OK)
            return 0;
    }

    memcpy(output1, buffer_ptr, size1);
    memcpy(output2, buffer_ptr + size1, size2);

    IDirectSoundBuffer_Unlock(ds->dsb, output1, size1, output2, size2);

    return size;
}

static int ds_rsd_latency(void* data)
{
    ds_t *ds = data;

    DWORD pos;
    IDirectSoundBuffer_GetCurrentPosition(ds->dsb, &pos, 0);
    DWORD next_writepos = ((ds->writering + 1) % ds->rings) * ds->latency;
    if (next_writepos <= pos)
        next_writepos += ds->rings * ds->latency;

    int delta = next_writepos - pos;

    if (rsnd_format_to_bytes(ds->fmt) == 1)
        delta /= 2;
    else if (rsnd_format_to_bytes(ds->fmt) == 4)
        delta *= 2;

    return delta;
}
Пример #26
0
DWORD WINAPI pest_thread_proc( LPVOID jalla ){
	short *buffer1;
	short *buffer2;
	int play_pos;
	DWORD len1;
	DWORD len2;

	ready_to_quit = FALSE;

	if(done) return 0;
	done = FALSE;

	SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);

	IDirectSoundBuffer_Lock( secondary, 0, BUFFER_LEN*4, (void**)&buffer1, &len1, (void**)&buffer2, &len2, DSBLOCK_ENTIREBUFFER);
	bytes_written = fill_buffer( buffer1, len1 );
	if(buffer2) bytes_written+= fill_buffer( buffer2, len2 );

	EnterCriticalSection(&critical);
	last_known = (int)(bytes_written%(BUFFER_LEN*4));
	LeaveCriticalSection(&critical);

	IDirectSoundBuffer_Unlock(secondary,(void*)buffer1,len1,(void*)buffer2,len2);
	IDirectSoundBuffer_SetCurrentPosition(secondary, 0);
	IDirectSoundBuffer_Play(secondary, 0, 0, DSBPLAY_LOOPING);

	playing = TRUE;
	Sleep(100);

	while( !done )
	{
		short buffer[BUFFER_LEN*2];
		int to_write;
		DWORD written;

		IDirectSoundBuffer_GetCurrentPosition( secondary, &play_pos, NULL );

		if( last_known < play_pos ){
			to_write = play_pos - last_known;
			OutputDebugString( "Last known smaller than play pos" );
		}else{
			to_write = (BUFFER_LEN*4)-(last_known-play_pos);
		}

		while( IDirectSoundBuffer_Lock( secondary, last_known, to_write, (void**)&buffer1, &len1, (void**)&buffer2, &len2, 0)!=DS_OK){
			OutputDebugString("Trying to restore");
			IDirectSoundBuffer_Restore( secondary );
			IDirectSoundBuffer_Play( secondary, 0, 0, DSBPLAY_LOOPING);
		}

		written = fill_buffer( (short*)buffer, len1+len2 );
		memcpy(buffer1,buffer,len1);

		if(written>len1) memcpy(buffer2,(char*)buffer+len1,written-len1);

		IDirectSoundBuffer_Unlock( secondary, (void*)buffer1, len1, (void*)buffer2, len2 );

		EnterCriticalSection(&critical);
		bytes_written += written;
		last_known = (int)(bytes_written%(BUFFER_LEN*4));
		LeaveCriticalSection(&critical);
		Sleep(100);
	}

	playing=FALSE;
	ready_to_quit=TRUE;

	DeleteCriticalSection(&critical);

	return 0;
}