Exemple #1
0
void S_Update_(void) {
	unsigned        endtime;
	int				samps;
	static			float	lastTime = 0.0f;
	float			ma, op;
	float			thisTime, sane;
	static			int ot = -1;

	if ( !s_soundStarted || s_soundMuted ) {
		return;
	}

	thisTime = Com_Milliseconds();

	// Updates s_soundtime
	S_GetSoundtime();

	if (s_soundtime == ot) {
		return;
	}
	ot = s_soundtime;

	// clear any sound effects that end before the current time,
	// and start any new sounds
	S_ScanChannelStarts();

	sane = thisTime - lastTime;
	if (sane<11) {
		sane = 11;			// 85hz
	}

	ma = s_mixahead->value * dma.speed;
	op = s_mixPreStep->value + sane*dma.speed*0.01;

	if (op < ma) {
		ma = op;
	}

	// mix ahead of current position
	endtime = s_soundtime + ma;

	// mix to an even submission block size
	endtime = (endtime + dma.submission_chunk-1)
		& ~(dma.submission_chunk-1);

	// never mix more than the complete buffer
	samps = dma.samples >> (dma.channels-1);
	if (endtime - s_soundtime > samps)
		endtime = s_soundtime + samps;



	SNDDMA_BeginPainting ();

	S_PaintChannels (endtime);

	SNDDMA_Submit ();

	lastTime = thisTime;
}
Exemple #2
0
/*
==================
S_ClearSoundBuffer

If we are about to perform file access, clear the buffer
so sound doesn't stutter.
==================
*/
void S_Base_ClearSoundBuffer( void ) {
	int		clear;
		
	if (!s_soundStarted)
		return;

	// stop looping sounds
	Com_Memset(loopSounds, 0, MAX_GENTITIES*sizeof(loopSound_t));
	Com_Memset(loop_channels, 0, MAX_CHANNELS*sizeof(channel_t));
	numLoopChannels = 0;

	S_ChannelSetup();

	Com_Memset(s_rawend, '\0', sizeof (s_rawend));

	if (dma.samplebits == 8)
		clear = 0x80;
	else
		clear = 0;

	SNDDMA_BeginPainting ();
	if (dma.buffer)
		Com_Memset(dma.buffer, clear, dma.samples * dma.samplebits/8);
	SNDDMA_Submit ();
}
Exemple #3
0
/*
==================
SNDDMA_Init

Initialize direct sound
Returns false if failed
==================
*/
qboolean SNDDMA_Init(void) {

	memset ((void *)&dma, 0, sizeof (dma));

	// create the secondary buffer we'll actually work with
	dma.channels = 2;
	dma.samplebits = 16;

	if (s_khz->integer == 44)
		dma.speed = 44100;
	else if (s_khz->integer == 22)
		dma.speed = 22050;
	else
		dma.speed = 11025;
	
	SNDDMA_BeginPainting ();
	if (dma.buffer)
		memset(dma.buffer, 0, dma.samples * dma.samplebits/8);
	SNDDMA_Submit ();

	// Hack !!
	dma.samples = 32768;
	dma.submission_chunk = 1;

	dma.buffer = new byte[dma.samples * 2];

	Com_DPrintf("Completed successfully\n" );

    return qtrue;
}
Exemple #4
0
void S_Update_()
{
	guard(S_Update_);

	if (!sound_started) return;

	SNDDMA_BeginPainting();

	if (!dma.buffer) return;

	// Updates DMA time
	GetSoundtime();

	// check to make sure that we haven't overshot
	if (paintedtime < soundtime)
	{
		Com_DPrintf("S_Update_ : overflow\n");
		paintedtime = soundtime;
	}

	// mix ahead of current position
	unsigned endtime = soundtime + appRound(s_mixahead->value * dma.speed);

	// mix to an even submission block size
	endtime = Align(endtime, dma.submission_chunk);
	int samps = dma.samples >> (dma.channels-1);
	if (endtime - soundtime > samps)
		endtime = soundtime + samps;

	S_PaintChannels(endtime);

	SNDDMA_Submit();
	unguard;
}
Exemple #5
0
/*
==================
S_ClearSoundBuffer

If we are about to perform file access, clear the buffer
so sound doesn't stutter.
==================
*/
void S_ClearSoundBuffer( void ) {
	int		clear;
		
	if (!s_soundStarted)
		return;

	// stop looping sounds
	Com_Memset(loopSounds, 0, MAX_GENTITIES*sizeof(loopSound_t));
	Com_Memset(loop_channels, 0, MAX_CHANNELS*sizeof(channel_t));
	numLoopChannels = 0;

	S_ChannelSetup();

	s_rawend = 0;

	if (dma.samplebits == 8)
		clear = 0x80;
	else
		clear = 0;

	SNDDMA_BeginPainting ();
	if (dma.buffer)
    // TTimo: due to a particular bug workaround in linux sound code,
    //   have to optionally use a custom C implementation of Com_Memset
    //   not affecting win32, we have #define Snd_Memset Com_Memset
    // https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=371
		Snd_Memset(dma.buffer, clear, dma.samples * dma.samplebits/8);
	SNDDMA_Submit ();
}
Exemple #6
0
/*
==================
S_ClearBuffer
==================
*/
static void S_ClearBuffer (void)
{
	int		clear;
		
	if (!sound_started)
		return;

#ifdef USE_OPENAL
	if (alSound)
		return;
#endif

	s_rawend = 0;

	if (dma.samplebits == 8)
		clear = 0x80;
	else
		clear = 0;

	SNDDMA_BeginPainting ();

	if (dma.buffer)
		Snd_Memset(dma.buffer, clear, dma.samples * dma.samplebits/8);

	SNDDMA_Submit ();
}
Exemple #7
0
void S_ClearBuffer()
{
	if (!sound_started)
		return;

	s_rawend = 0;

	int clear;
	if (dma.samplebits == 8)
		clear = 0x80;
	else
		clear = 0;

	SNDDMA_BeginPainting();
	if (dma.buffer)
		memset(dma.buffer, clear, dma.samples * dma.samplebits/8);
	SNDDMA_Submit();
}
Exemple #8
0
/*
* S_Clear
*/
static void S_Clear( void )
{
	int clear;

	num_loopsfx = 0;

	S_ClearRawSounds();

	if( dma.samplebits == 8 )
		clear = 0x80;
	else
		clear = 0;

	SNDDMA_BeginPainting();
	if( dma.buffer )
		memset( dma.buffer, clear, dma.samples * dma.samplebits/8 );
	SNDDMA_Submit();
}
Exemple #9
0
void S_DMAClearBuffer( void ) {
	int		clear;
		
	if (!dmaInit)
		return;

	/* Clear the active channels and loops */
	Com_Memset( dmaLoops, 0, sizeof( dmaLoops ));
	Com_Memset( dmaChannels, 0, sizeof( dmaChannels ));
	Com_Memset( &dmaEffect, 0, sizeof( &dmaEffect ));

	if (dma.samplebits == 8)
		clear = 0x80;
	else
		clear = 0;

	/* Fill the dma buffer */
	SNDDMA_BeginPainting ();
	if (dma.buffer)
		Snd_Memset(dma.buffer, clear, dma.samples * dma.samplebits/8);
	SNDDMA_Submit ();
}
void S_Update_(void)
{
	unsigned        endtime;
	int				samps;

	if (!sound_started)
		return;

	SNDDMA_BeginPainting ();

	if (!dma.buffer)
		return;

// Updates DMA time
	GetSoundtime();

// check to make sure that we haven't overshot
	if (paintedtime < soundtime)
	{
		Com_DPrintf ("S_Update_ : overflow\n");
		paintedtime = soundtime;
	}

// mix ahead of current position
	endtime = soundtime + s_mixahead->value * dma.speed;
//endtime = (soundtime + 4096) & ~4095;

	// mix to an even submission block size
	endtime = (endtime + dma.submission_chunk-1)
		& ~(dma.submission_chunk-1);
	samps = dma.samples >> (dma.channels-1);
	if (endtime - soundtime > samps)
		endtime = soundtime + samps;

	S_PaintChannels (endtime);

	SNDDMA_Submit ();
}
Exemple #11
0
void S_Base_ClearSounds(qboolean clearStreaming, qboolean clearMusic)
{
	if (!s_soundStarted)
	{
		return;
	}

	// stop looping sounds
	Com_Memset(loopSounds, 0, MAX_LOOP_SOUNDS * sizeof(loopSound_t));
	Com_Memset(loop_channels, 0, MAX_CHANNELS * sizeof(channel_t));
	numLoopChannels = 0;
	numLoopSounds   = 0;

	// moved this up so streaming sounds dont get updated with the music, below,
	// and leave us with a snippet off streaming sounds after we reload
	if (clearStreaming)
	{
		int              i;
		streamingSound_t *ss;
		channel_t        *ch;

		for (i = 0, ss = streamingSounds; i < MAX_STREAMING_SOUNDS; i++, ss++)
		{
			if (i > 0 || clearMusic)
			{
				S_StopStreamingSound(i);
			}
		}

		// we should also kill all channels, since we are killing streaming sounds anyway
		// (fixes siren in forest playing after a map_restart/loadgame
		ch = s_channels;
		for (i = 0; i < MAX_CHANNELS; i++, ch++)
		{
			if (ch->thesfx)
			{
				S_ChannelFree(ch);
			}
		}
	}

	if (!clearMusic)
	{
		S_UpdateStreamingSounds();
	}

	if (clearStreaming && clearMusic)
	{
		int clear;

		if (dma.samplebits == 8)
		{
			clear = 0x80;
		}
		else
		{
			clear = 0;
		}

		SNDDMA_BeginPainting();
		if (dma.buffer)
		{
			Com_Memset(dma.buffer, clear, dma.samples * dma.samplebits / 8);
		}
		SNDDMA_Submit();

		// clear out channels so they don't finish playing when audio restarts
		S_ChannelSetup();
	}
}
Exemple #12
0
static int SNDDMA_InitDS ()
{
	HRESULT			hresult;
	qboolean		pauseTried;
	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	WAVEFORMATEX	format;

	Com_Printf( "Initializing DirectSound\n");

	if ( !hInstDS ) {
		Com_DPrintf( "...loading dsound.dll: " );

		hInstDS = LoadLibrary("dsound.dll");
		
		if ( hInstDS == NULL ) {
			Com_Printf ("failed\n");
			return 0;
		}

		Com_DPrintf ("ok\n");
		pDirectSoundCreate = (long (__stdcall *)(struct _GUID *,struct IDirectSound ** ,struct IUnknown *))
			GetProcAddress(hInstDS,"DirectSoundCreate");

		if ( !pDirectSoundCreate ) {
			Com_Printf ("*** couldn't get DS proc addr ***\n");
			return 0;
		}
	}

	Com_DPrintf( "...creating DS object: " );
	pauseTried = qfalse;
	while ( ( hresult = iDirectSoundCreate( NULL, &pDS, NULL ) ) != DS_OK ) {
		if ( hresult != DSERR_ALLOCATED ) {
			Com_Printf( "failed\n" );
			return 0;
		}

		if ( pauseTried ) {
			Com_Printf ("failed, hardware already in use\n" );
			return 0;
		}
		// first try just waiting five seconds and trying again
		// this will handle the case of a sysyem beep playing when the
		// game starts
		Com_DPrintf ("retrying...\n");
		Sleep( 3000 );
		pauseTried = qtrue;
	}
	Com_DPrintf( "ok\n" );

	Com_DPrintf("...setting DSSCL_PRIORITY coop level: " );

	if ( DS_OK != pDS->SetCooperativeLevel( g_wv.hWnd, DSSCL_PRIORITY ) )	{
		Com_Printf ("failed\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	Com_DPrintf("ok\n" );


	// create the secondary buffer we'll actually work with
	dma.channels = 2;
	dma.samplebits = 16;

	if (s_khz->integer == 44)
		dma.speed = 44100;
	else if (s_khz->integer == 22)
		dma.speed = 22050;
	else
		dma.speed = 11025;

	memset (&format, 0, sizeof(format));
	format.wFormatTag = WAVE_FORMAT_PCM;
    format.nChannels = dma.channels;
    format.wBitsPerSample = dma.samplebits;
    format.nSamplesPerSec = dma.speed;
    format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
    format.cbSize = 0;
    format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; 

	memset (&dsbuf, 0, sizeof(dsbuf));
	dsbuf.dwSize = sizeof(DSBUFFERDESC);

#define idDSBCAPS_GETCURRENTPOSITION2 0x00010000

	dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCHARDWARE | idDSBCAPS_GETCURRENTPOSITION2;
	dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
	dsbuf.lpwfxFormat = &format;
	
	Com_DPrintf( "...creating secondary buffer: " );
	if (DS_OK != pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) {
		dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY;
		hresult = pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL);
		if (hresult != DS_OK) {			
			Com_Printf( "failed to create secondary buffer - %s\n", DSoundError( hresult ) );
			SNDDMA_Shutdown ();
			return qfalse;
		}
	}
	Com_Printf( "locked hardware.  ok\n" );
		
	// Make sure mixer is active
	if ( DS_OK != pDSBuf->Play(0, 0, DSBPLAY_LOOPING) ) {
		Com_Printf ("*** Looped sound play failed ***\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}

	memset(&dsbcaps, 0, sizeof(dsbcaps));
	dsbcaps.dwSize = sizeof(dsbcaps);
	// get the returned buffer size
	if ( DS_OK != pDSBuf->GetCaps (&dsbcaps) ) {
		Com_Printf ("*** GetCaps failed ***\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	
	gSndBufSize = dsbcaps.dwBufferBytes;

	dma.channels = format.nChannels;
	dma.samplebits = format.wBitsPerSample;
	dma.speed = format.nSamplesPerSec;
	dma.samples = gSndBufSize/(dma.samplebits/8);
	dma.submission_chunk = 1;
	dma.buffer = NULL;			// must be locked first

	sample16 = (dma.samplebits/8) - 1;

	SNDDMA_BeginPainting ();
	if (dma.buffer)
		memset(dma.buffer, 0, dma.samples * dma.samplebits/8);
	SNDDMA_Submit ();
	return 1;
}
Exemple #13
0
int SNDDMA_InitDS ()
{
	HRESULT			hresult;
	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	WAVEFORMATEX	format;
	int				use8;
	
	// Match/Choose output directsound device
	SNDDMAHD_DSEnumSoundDevices(qfalse);

	Com_Printf( "Initializing DirectSound\n");

	use8 = 1;
    // Create IDirectSound using the primary sound device
    if( FAILED( hresult = CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void **)&pDS))) {
		use8 = 0;
	    if( FAILED( hresult = CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void **)&pDS))) {
			Com_Printf ("failed\n");
			SNDDMA_Shutdown ();
			return qfalse;
		}
	}

	hresult = pDS->lpVtbl->Initialize( pDS, g_dsguid);

	Com_DPrintf( "ok\n" );

	Com_DPrintf("...setting DSSCL_PRIORITY coop level: " );

	if ( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, g_wv.hWnd, DSSCL_PRIORITY ) )	{
		Com_Printf ("failed\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	Com_DPrintf("ok\n" );


	// create the secondary buffer we'll actually work with
	dma.channels = 2;
	dma.samplebits = 16;

	if (s_khz->integer >= 44) dma.speed = 44100;
	else if (s_khz->integer >= 32) dma.speed = 32000;
	else if (s_khz->integer >= 24) dma.speed = 24000;
	else if (s_khz->integer >= 22) dma.speed = 22050;
	else dma.speed = 11025;

#ifndef NO_DMAHD
	if (dmaHD_Enabled()) 
	{
		// p5yc0runn3r - Fix dmaHD sound to 44KHz, Stereo and 16 bits per sample.
		dma.speed = 44100;
		dma.channels = 2;
		dma.samplebits = 16;
	}
#endif		
	
	memset (&format, 0, sizeof(format));
	format.wFormatTag = WAVE_FORMAT_PCM;
    format.nChannels = dma.channels;
    format.wBitsPerSample = dma.samplebits;
    format.nSamplesPerSec = dma.speed;
    format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
    format.cbSize = 0;
    format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; 

	memset (&dsbuf, 0, sizeof(dsbuf));
	dsbuf.dwSize = sizeof(DSBUFFERDESC);

	// Micah: take advantage of 2D hardware.if available.
	dsbuf.dwFlags = DSBCAPS_LOCHARDWARE;
	if (s_alttabmute->integer == 0) {
		// Keep playing when out of focus.
		dsbuf.dwFlags |= DSBCAPS_STICKYFOCUS;
	}
	if (use8) {
		dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2;
	}
	dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
	dsbuf.lpwfxFormat = &format;
	
	memset(&dsbcaps, 0, sizeof(dsbcaps));
	dsbcaps.dwSize = sizeof(dsbcaps);
	
	Com_DPrintf( "...creating secondary buffer: " );
	if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) {
		Com_Printf( "locked hardware.  ok\n" );
	}
	else {
		// Couldn't get hardware, fallback to software.
		dsbuf.dwFlags = DSBCAPS_LOCSOFTWARE;
		if (use8) {
			dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2;
		}
		if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) {
			Com_Printf( "failed\n" );
			SNDDMA_Shutdown ();
			return qfalse;
		}
		Com_DPrintf( "forced to software.  ok\n" );
	}
		
	// Make sure mixer is active
	if ( DS_OK != pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING) ) {
		Com_Printf ("*** Looped sound play failed ***\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}

	// get the returned buffer size
	if ( DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps) ) {
		Com_Printf ("*** GetCaps failed ***\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	
	gSndBufSize = dsbcaps.dwBufferBytes;

	dma.channels = format.nChannels;
	dma.samplebits = format.wBitsPerSample;
	dma.speed = format.nSamplesPerSec;
	dma.samples = gSndBufSize/(dma.samplebits/8);
	dma.submission_chunk = 1;
	dma.buffer = NULL;			// must be locked first

	sample16 = (dma.samplebits/8) - 1;

	SNDDMA_BeginPainting ();
	if (dma.buffer)
		memset(dma.buffer, 0, dma.samples * dma.samplebits/8);
	SNDDMA_Submit ();
	return 1;
}
Exemple #14
0
/*
==================
DS_CreateBuffers
==================
*/
static qboolean DS_CreateBuffers( void *hInst )
{
	DSBUFFERDESC	dsbuf;
	DSBCAPS		dsbcaps;
	WAVEFORMATEX	pformat, format;

	Q_memset( &format, 0, sizeof( format ));

	format.wFormatTag = WAVE_FORMAT_PCM;
	format.nChannels = 2;
	format.wBitsPerSample = 16;
	format.nSamplesPerSec = SOUND_DMA_SPEED;
	format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
	format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; 
	format.cbSize = 0;

	MsgDev( D_NOTE, "DS_CreateBuffers: initialize\n" );

	MsgDev( D_NOTE, "DS_CreateBuffers: setting EXCLUSIVE coop level " );
	if( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, hInst, DSSCL_EXCLUSIVE ))
	{
		MsgDev( D_NOTE, "- failed\n" );
		SNDDMA_FreeSound();
		return false;
	}
	MsgDev( D_NOTE, "- ok\n" );

	// get access to the primary buffer, if possible, so we can set the sound hardware format
	Q_memset( &dsbuf, 0, sizeof( dsbuf ));
	dsbuf.dwSize = sizeof( DSBUFFERDESC );
	dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER;
	dsbuf.dwBufferBytes = 0;
	dsbuf.lpwfxFormat = NULL;

	Q_memset( &dsbcaps, 0, sizeof( dsbcaps ));
	dsbcaps.dwSize = sizeof( dsbcaps );
	primary_format_set = false;

	MsgDev( D_NOTE, "DS_CreateBuffers: creating primary buffer " );
	if( pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSPBuf, NULL ) == DS_OK )
	{
		pformat = format;

		MsgDev( D_NOTE, "- ok\n" );
		if( snd_firsttime )
			MsgDev( D_NOTE, "DS_CreateBuffers: setting primary sound format " );

		if( pDSPBuf->lpVtbl->SetFormat( pDSPBuf, &pformat ) != DS_OK )
		{
			if( snd_firsttime )
				MsgDev( D_NOTE, "- failed\n" );
		}
		else
		{
			if( snd_firsttime )
				MsgDev( D_NOTE, "- ok\n" );
			primary_format_set = true;
		}
	}
	else MsgDev( D_NOTE, "- failed\n" );

	if( !primary_format_set || !s_primary->integer )
	{
		// create the secondary buffer we'll actually work with
		Q_memset( &dsbuf, 0, sizeof( dsbuf ));
		dsbuf.dwSize = sizeof( DSBUFFERDESC );
		dsbuf.dwFlags = (DSBCAPS_CTRLFREQUENCY|DSBCAPS_LOCSOFTWARE);
		dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
		dsbuf.lpwfxFormat = &format;

		Q_memset( &dsbcaps, 0, sizeof( dsbcaps ));
		dsbcaps.dwSize = sizeof( dsbcaps );

		MsgDev( D_NOTE, "DS_CreateBuffers: creating secondary buffer " );
		if( pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSBuf, NULL ) == DS_OK )
		{
			MsgDev( D_NOTE, "- ok\n" );
		}
		else
		{
			// couldn't get hardware, fallback to software.
			dsbuf.dwFlags = (DSBCAPS_LOCSOFTWARE|DSBCAPS_GETCURRENTPOSITION2);
			if( pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSBuf, NULL ) != DS_OK )
			{
				MsgDev( D_NOTE, "- failed\n" );
				SNDDMA_FreeSound ();
				return false;
			}
			MsgDev( D_INFO, "- failed. forced to software\n" );
		}

		if( pDSBuf->lpVtbl->GetCaps( pDSBuf, &dsbcaps ) != DS_OK )
		{
			MsgDev( D_ERROR, "DS_CreateBuffers: GetCaps failed\n");
			SNDDMA_FreeSound ();
			return false;
		}
		MsgDev( D_NOTE, "DS_CreateBuffers: using secondary sound buffer\n" );
	}
	else
	{
		MsgDev( D_NOTE, "DS_CreateBuffers: using primary sound buffer\n" );
		MsgDev( D_NOTE, "DS_CreateBuffers: setting WRITEPRIMARY coop level " );
		if( pDS->lpVtbl->SetCooperativeLevel( pDS, hInst, DSSCL_WRITEPRIMARY ) != DS_OK )
		{
			MsgDev( D_NOTE, "- failed\n" );
			SNDDMA_FreeSound ();
			return false;
		}
		MsgDev( D_NOTE, "- ok\n" );

		if( pDSPBuf->lpVtbl->GetCaps( pDSPBuf, &dsbcaps ) != DS_OK )
		{
			MsgDev( D_ERROR, "DS_CreateBuffers: GetCaps failed\n");
			SNDDMA_FreeSound ();
			return false;
		}
		pDSBuf = pDSPBuf;
	}

	// make sure mixer is active
	if( pDSBuf->lpVtbl->Play( pDSBuf, 0, 0, DSBPLAY_LOOPING ) != DS_OK )
	{
		MsgDev( D_ERROR, "DS_CreateBuffers: looped sound play failed\n" );
		SNDDMA_FreeSound ();
		return false;
	}

	// we don't want anyone to access the buffer directly w/o locking it first
	lpData = NULL;
	dma.samplepos = 0;
	snd_hwnd = (HWND)hInst;
	gSndBufSize = dsbcaps.dwBufferBytes;
	dma.samples = gSndBufSize / 2;
	dma.buffer = (byte *)lpData;

	SNDDMA_BeginPainting();
	if( dma.buffer ) Q_memset( dma.buffer, 0, dma.samples * 2 );
	SNDDMA_Submit();

	return true;
}
int SNDDMA_InitDS ()
{
	HRESULT			hresult;
	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	WAVEFORMATEX	format;
	int				use8;
	HMODULE hdsounddll;
	pDirectSoundEnumerate DSEnumerate;

	if ((hdsounddll = LoadLibrary("dsound.dll")) != NULL &&
		(DSEnumerate = (pDirectSoundEnumerate)GetProcAddress(hdsounddll, "DirectSoundEnumerateA")) != NULL &&
		s_dev->string != NULL && s_dev->string[0] != '\0')
	{
		Com_Printf( "^4Looking for DirectSound Device '%s'\n", s_dev->string);
		
		if (FAILED(DSEnumerate(SNDDMAHD_DSEnumCallback, NULL)))
			Com_Printf("^1Error Enumerating DirectSound Devices\n");
		
		if (g_dsguid == NULL)
			Com_Printf("^1Device '%s' not found. ^2Using default driver.\n", s_dev->string);
	}

	Com_Printf( "Initializing DirectSound\n");

	use8 = 1;
    // Create IDirectSound using the primary sound device
    if( FAILED( hresult = CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void **)&pDS))) {
		use8 = 0;
	    if( FAILED( hresult = CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void **)&pDS))) {
			Com_Printf ("failed\n");
			SNDDMA_Shutdown ();
			return qfalse;
		}
	}

	hresult = pDS->lpVtbl->Initialize( pDS, g_dsguid);

	Com_DPrintf( "ok\n" );

	Com_DPrintf("...setting DSSCL_PRIORITY coop level: " );

	if ( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, g_wv.hWnd, DSSCL_PRIORITY ) )	{
		Com_Printf ("failed\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	Com_DPrintf("ok\n" );


	// create the secondary buffer we'll actually work with
	dma.channels = 2;
	dma.samplebits = 16;

	if (s_khz->integer >= 44) dma.speed = 44100;
	else if (s_khz->integer >= 32) dma.speed = 32000;
	else if (s_khz->integer >= 24) dma.speed = 24000;
	else if (s_khz->integer >= 22) dma.speed = 22050;
	else dma.speed = 11025;

	memset (&format, 0, sizeof(format));
	format.wFormatTag = WAVE_FORMAT_PCM;
    format.nChannels = dma.channels;
    format.wBitsPerSample = dma.samplebits;
    format.nSamplesPerSec = dma.speed;
    format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
    format.cbSize = 0;
    format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; 

	memset (&dsbuf, 0, sizeof(dsbuf));
	dsbuf.dwSize = sizeof(DSBUFFERDESC);

	// Micah: take advantage of 2D hardware.if available.
	dsbuf.dwFlags = DSBCAPS_LOCHARDWARE;
	if (use8) {
		dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2;
	}
	dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
	dsbuf.lpwfxFormat = &format;
	
	memset(&dsbcaps, 0, sizeof(dsbcaps));
	dsbcaps.dwSize = sizeof(dsbcaps);
	
	Com_DPrintf( "...creating secondary buffer: " );
	if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) {
		Com_Printf( "locked hardware.  ok\n" );
	}
	else {
		// Couldn't get hardware, fallback to software.
		dsbuf.dwFlags = DSBCAPS_LOCSOFTWARE;
		if (use8) {
			dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2;
		}
		if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) {
			Com_Printf( "failed\n" );
			SNDDMA_Shutdown ();
			return qfalse;
		}
		Com_DPrintf( "forced to software.  ok\n" );
	}
		
	// Make sure mixer is active
	if ( DS_OK != pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING) ) {
		Com_Printf ("*** Looped sound play failed ***\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}

	// get the returned buffer size
	if ( DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps) ) {
		Com_Printf ("*** GetCaps failed ***\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	
	gSndBufSize = dsbcaps.dwBufferBytes;

	dma.channels = format.nChannels;
	dma.samplebits = format.wBitsPerSample;
	dma.speed = format.nSamplesPerSec;
	dma.samples = gSndBufSize/(dma.samplebits/8);
	dma.submission_chunk = 1;
	dma.buffer = NULL;			// must be locked first

	sample16 = (dma.samplebits/8) - 1;

	SNDDMA_BeginPainting ();
	if (dma.buffer)
		memset(dma.buffer, 0, dma.samples * dma.samplebits/8);
	SNDDMA_Submit ();
	return 1;
}
Exemple #16
0
int SNDDMA_InitDS ()
{
	HRESULT			hresult;
	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	WAVEFORMATEX	format;
	int				use8;

	Com_Printf( "Initializing DirectSound\n");

	use8 = 1;
    // Create IDirectSound using the primary sound device
    if( FAILED( hresult = CoCreateInstance(CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound8, (void **)&pDS))) {
		use8 = 0;
	    if( FAILED( hresult = CoCreateInstance(CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound, (void **)&pDS))) {
			Com_Printf ("failed\n");
			SNDDMA_Shutdown ();
			return qfalse;
		}
	}

	hresult = pDS->Initialize( NULL);

	Com_DPrintf( "ok\n" );

	Com_DPrintf("...setting DSSCL_PRIORITY coop level: " );

	if ( DS_OK != pDS->SetCooperativeLevel( g_wv.hWnd, DSSCL_PRIORITY ) )	{
		Com_Printf ("failed\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	Com_DPrintf("ok\n" );


	// create the secondary buffer we'll actually work with
	dma.channels = 2;
	dma.samplebits = 16;

	if (s_khz->integer == 44)
		dma.speed = 44100;
	else if (s_khz->integer == 22)
		dma.speed = 22050;
	else
		dma.speed = 11025;

	memset (&format, 0, sizeof(format));
	format.wFormatTag = WAVE_FORMAT_PCM;
    format.nChannels = dma.channels;
    format.wBitsPerSample = dma.samplebits;
    format.nSamplesPerSec = dma.speed;
    format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
    format.cbSize = 0;
    format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; 

	memset (&dsbuf, 0, sizeof(dsbuf));
	dsbuf.dwSize = sizeof(DSBUFFERDESC);

	// Micah: take advantage of 2D hardware.if available.
	dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCHARDWARE;
	if (use8) {
		dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2;
	}
//#define idDSBCAPS_GETCURRENTPOSITION2 0x00010000
	dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
	dsbuf.lpwfxFormat = &format;
	
	memset(&dsbcaps, 0, sizeof(dsbcaps));
	dsbcaps.dwSize = sizeof(dsbcaps);
	
	Com_DPrintf( "...creating secondary buffer: " );
	if (DS_OK == pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) {
		Com_Printf( "locked hardware.  ok\n" );
	}
	else {
		// Couldn't get hardware, fallback to software.
		dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE;
		if (use8) {
			dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2;
		}
		if (DS_OK != pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) {
			Com_Printf( "failed\n" );
			SNDDMA_Shutdown ();
			return qfalse;
		}
		Com_DPrintf( "forced to software.  ok\n" );
	}
		
	// Make sure mixer is active
	if ( DS_OK != pDSBuf->Play(0, 0, DSBPLAY_LOOPING) ) {
		Com_Printf ("*** Looped sound play failed ***\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}

	// get the returned buffer size
	if ( DS_OK != pDSBuf->GetCaps (&dsbcaps) ) {
		Com_Printf ("*** GetCaps failed ***\n");
		SNDDMA_Shutdown ();
		return qfalse;
	}
	
	gSndBufSize = dsbcaps.dwBufferBytes;

	dma.channels = format.nChannels;
	dma.samplebits = format.wBitsPerSample;
	dma.speed = format.nSamplesPerSec;
	dma.samples = gSndBufSize/(dma.samplebits/8);
	dma.submission_chunk = 1;
	dma.buffer = NULL;			// must be locked first

	sample16 = (dma.samplebits/8) - 1;

	SNDDMA_BeginPainting ();
	if (dma.buffer)
		memset(dma.buffer, 0, dma.samples * dma.samplebits/8);
	SNDDMA_Submit ();
	return 1;
}
Exemple #17
0
void S_Update_(void)
{
	unsigned     endtime;
	int          samps;
	static float lastTime = 0.0f;
	float        ma, op;
	float        thisTime, sane;
	static int   ot = -1;

	if (!s_soundStarted || s_soundMuted)
	{
		return;
	}

	thisTime = Sys_Milliseconds();

	// Updates s_soundtime
	S_GetSoundtime();

	if (s_soundtime == ot)
	{
		return;
	}
	ot = s_soundtime;

	// clear any sound effects that end before the current time,
	// and start any new sounds
	S_ScanChannelStarts();

	sane = thisTime - lastTime;
	if (sane < 11)
	{
		sane = 11;          // 85hz
	}

	ma = s_mixahead->value * dma.speed;
	op = s_mixPreStep->value + sane * dma.speed * 0.01;

	if (op < ma)
	{
		ma = op;
	}

	// mix ahead of current position
	endtime = s_soundtime + ma;

	// mix to an even submission block size
	endtime = (endtime + dma.submission_chunk - 1)
	          & ~(dma.submission_chunk - 1);

	// never mix more than the complete buffer
	samps = dma.samples >> (dma.channels - 1);
	if (endtime - s_soundtime > samps)
	{
		endtime = s_soundtime + samps;
	}

	// global volume fading

	// endtime or s_paintedtime or s_soundtime...
	if (s_soundtime < s_volTime2)     // still has fading to do
	{
		if (s_soundtime > s_volTime1)     // has started fading
		{
			s_volFadeFrac = ((float)(s_soundtime - s_volTime1) / (float)(s_volTime2 - s_volTime1));
			s_volCurrent  = ((1.0f - s_volFadeFrac) * s_volStart + s_volFadeFrac * s_volTarget);
		}
		else
		{
			s_volCurrent = s_volStart;
		}
	}
	else
	{
		s_volCurrent = s_volTarget;
		if (s_stopSounds)
		{
			// stop playing any sounds if they are all faded out
			S_StopAllSounds();
			s_stopSounds = qfalse;
		}
	}

	SNDDMA_BeginPainting();

	S_PaintChannels(endtime);

	SNDDMA_Submit();

	lastTime = thisTime;
}
Exemple #18
0
void S_DMA_Update( float scale ) {
	int				ma, count;
	static int		lastPos;
	int				thisPos;
	int				lastWrite, lastRead;
	int				bufSize, bufDone;
	int				speed;
	int				buf[2048];

	if (!dmaInit)
		return;

	bufSize = dma.samples >> (dma.channels-1);

	// Check for possible buffer underruns

	thisPos = SNDDMA_GetDMAPos() >> (dma.channels - 1);
	lastWrite = (lastPos <= dmaWrite) ? (dmaWrite - lastPos) : (bufSize - lastPos + dmaWrite);
	lastRead = ( lastPos <= thisPos ) ? (thisPos - lastPos) : (bufSize - lastPos + thisPos);
	if (lastRead > lastWrite) {
		bufDone = 0;
		dmaWrite = thisPos;
//		Com_Printf("OMG Buffer underrun\n");
	} else {
		bufDone = lastWrite - lastRead;
	}
//	Com_Printf( "lastRead %d lastWrite %d done %d\n", lastRead, lastWrite, bufDone );
	lastPos = thisPos;

	ma = s_mixahead->value * dma.speed;

	count = lastRead;
	if (bufDone + count < ma) {
		count = ma - bufDone + 1;
	} else if (bufDone + count > bufSize) {
		count = bufSize - bufDone;
	}

	if (count > sizeof(buf) / (2 * sizeof(int))) {
		count = sizeof(buf) / (2 * sizeof(int));
	}
	// mix to an even submission block size
	count = (count + dma.submission_chunk-1) & ~(dma.submission_chunk-1);

	// never mix more than the complete buffer
	speed = (scale * (MIX_SPEED << MIX_SHIFT)) / dma.speed;

	/* Make sure that the speed will always go forward for very small scales */
	if ( speed == 0 && scale )
		speed = 1;

	/* Mix sound or fill with silence depending on speed */
	if ( speed > 0 ) {
		/* mix the background track or init the buffer with silence */
		S_MixBackground(&dmaBackground, speed, count, buf);
		S_MixChannels(dmaChannels, DMA_SNDCHANNELS, speed, count, buf);
		S_MixLoops(dmaLoops, DMA_LOOPCHANNELS, speed, count, buf);
		S_MixEffects(&dmaEffect, speed, count, buf);
	} else {
		Com_Memset(buf, 0, sizeof( buf[0] ) * count * 2);
	}
	/* Lock dma buffer and copy/clip the final data */
	SNDDMA_BeginPainting ();
	S_MixClipOutput(count, buf, (short *)dma.buffer, dmaWrite, bufSize-1);
	SNDDMA_Submit ();
	dmaWrite += count;
	if (dmaWrite >= bufSize)
		dmaWrite -= bufSize;
}