示例#1
0
/*
==================
SNDDMA_InitDirect

Direct-Sound support
==================
*/
sndinitstat SNDDMA_InitDirect (void)
{
	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	DWORD			dwSize, dwWrite;
	DSCAPS			dscaps;
	WAVEFORMATEX	format, pformat; 
	HRESULT			hresult;
	int				reps;

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

	shm = &sn;

	shm->channels = 2;
	shm->samplebits = 16;
	//@Strelkin
	shm->speed = 44100;// 11025;

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

	if (!hInstDS)
	{
		hInstDS = LoadLibrary("dsound.dll");
		
		if (hInstDS == NULL)
		{
			Con_SafePrintf ("Couldn't load dsound.dll\n");
			return SIS_FAILURE;
		}

		pDirectSoundCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCreate");

		if (!pDirectSoundCreate)
		{
			Con_SafePrintf ("Couldn't get DS proc addr\n");
			return SIS_FAILURE;
		}
	}

	while ((hresult = iDirectSoundCreate(NULL, &pDS, NULL)) != DS_OK)
	{
		if (hresult != DSERR_ALLOCATED)
		{
			Con_SafePrintf ("DirectSound create failed\n");
			return SIS_FAILURE;
		}

		if (MessageBox (NULL,
						"The sound hardware is in use by another app.\n\n"
					    "Select Retry to try to start sound again or Cancel to run Quake with no sound.",
						"Sound not available",
						MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY)
		{
			Con_SafePrintf ("DirectSoundCreate failure\n"
							"  hardware already in use\n");
			return SIS_NOTAVAIL;
		}
	}

	dscaps.dwSize = sizeof(dscaps);

	if (DS_OK != pDS->lpVtbl->GetCaps (pDS, &dscaps))
	{
		Con_SafePrintf ("Couldn't get DS caps\n");
	}

	if (dscaps.dwFlags & DSCAPS_EMULDRIVER)
	{
		Con_SafePrintf ("No DirectSound driver installed\n");
		FreeSound ();
		return SIS_FAILURE;
	}

	if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE))
	{
		Con_SafePrintf ("Set coop level failed\n");
		FreeSound ();
		return SIS_FAILURE;
	}

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

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

	if (!COM_CheckParm ("-snoforceformat"))
	{
		if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSPBuf, NULL))
		{
			pformat = format;

			if (DS_OK != pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat))
			{
				if (snd_firsttime)
					Con_SafePrintf ("Set primary sound buffer format: no\n");
			}
			else
			{
				if (snd_firsttime)
					Con_SafePrintf ("Set primary sound buffer format: yes\n");

				primary_format_set = true;
			}
		}
	}

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

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

		if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL))
		{
			Con_SafePrintf ("DS:CreateSoundBuffer Failed");
			FreeSound ();
			return SIS_FAILURE;
		}

		shm->channels = format.nChannels;
		shm->samplebits = format.wBitsPerSample;
		shm->speed = format.nSamplesPerSec;

		if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps))
		{
			Con_SafePrintf ("DS:GetCaps failed\n");
			FreeSound ();
			return SIS_FAILURE;
		}

		if (snd_firsttime)
			Con_SafePrintf ("Using secondary sound buffer\n");
	}
	else
	{
		if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_WRITEPRIMARY))
		{
			Con_SafePrintf ("Set coop level failed\n");
			FreeSound ();
			return SIS_FAILURE;
		}

		if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps))
		{
			Con_Printf ("DS:GetCaps failed\n");
			return SIS_FAILURE;
		}

		pDSBuf = pDSPBuf;
		Con_SafePrintf ("Using primary sound buffer\n");
	}

	// Make sure mixer is active
	pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);

	if (snd_firsttime)
		Con_SafePrintf("   %d channel(s)\n"
		               "   %d bits/sample\n"
					   "   %d bytes/sec\n",
					   shm->channels, shm->samplebits, shm->speed);
	
	gSndBufSize = dsbcaps.dwBufferBytes;

// initialize the buffer
	reps = 0;

	while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &lpData, &dwSize, NULL, NULL, 0)) != DS_OK)
	{
		if (hresult != DSERR_BUFFERLOST)
		{
			Con_SafePrintf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n");
			FreeSound ();
			return SIS_FAILURE;
		}

		if (++reps > 10000)
		{
			Con_SafePrintf ("SNDDMA_InitDirect: DS: couldn't restore buffer\n");
			FreeSound ();
			return SIS_FAILURE;
		}

	}

	memset(lpData, 0, dwSize);
//		lpData[4] = lpData[5] = 0x7f;	// force a pop for debugging

	pDSBuf->lpVtbl->Unlock(pDSBuf, lpData, dwSize, NULL, 0);

	/* we don't want anyone to access the buffer directly w/o locking it first. */
	lpData = NULL; 

	pDSBuf->lpVtbl->Stop(pDSBuf);
	pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmstarttime.u.sample, &dwWrite);
	pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);

	shm->soundalive = true;
	shm->splitbuffer = false;
	shm->samples = gSndBufSize/(shm->samplebits/8);
	shm->samplepos = 0;
	shm->submission_chunk = 1;
	shm->buffer = (unsigned char *) lpData;
	sample16 = (shm->samplebits/8) - 1;

	dsound_init = true;

	return SIS_SUCCESS;
}
示例#2
0
//Crappy windows multimedia base
static qbool SNDDMA_InitWav (void)
{
	WAVEFORMATEX format;
	int i;
	HRESULT hr;
	UINT_PTR devicenum;
	int temp;

	snd_sent = 0;
	snd_completed = 0;

	memset((void *)shm, 0, sizeof(*shm));
	shm->format.channels = 2;
	shm->format.width = 2;
	shm->format.speed = (s_khz.value == 44) ? 44100 : (s_khz.value == 22) ? 22050 : 11025;

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

	devicenum = WAVE_MAPPER;
	if ((temp = COM_CheckParm("-snddev")) && temp + 1 < COM_Argc())
		devicenum = Q_atoi(COM_Argv(temp + 1));

	hr = waveOutOpen((LPHWAVEOUT) &hWaveOut, devicenum, &format, 0, 0L, CALLBACK_NULL);
	if (hr != MMSYSERR_NOERROR && devicenum != WAVE_MAPPER) {
		Com_Printf ("Couldn't open preferred sound device. Falling back to primary sound device.\n");
		hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, &format, 0, 0L, CALLBACK_NULL);
	}

	/* Open a waveform device for output using window callback. */
	if (hr != MMSYSERR_NOERROR) {
		if (hr == MMSYSERR_ALLOCATED)
			Com_Printf ("waveOutOpen failed, hardware already in use\n");
		else
			Com_Printf ("waveOutOpen failed\n");

		return false;
	}

	/*
	 * Allocate and lock memory for the waveform data. The memory 
	 * for waveform data must be globally allocated with 
	 * GMEM_MOVEABLE and GMEM_SHARE flags.
	 */
	gSndBufSize = WAV_BUFFERS*WAV_BUFFER_SIZE;
	hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, gSndBufSize);
	if (!hData) {
		Com_Printf ("Sound: Out of memory.\n");
		FreeSound ();
		return false;
	}
	lpData = GlobalLock(hData);
	if (!lpData) {
		Com_Printf ("Sound: Failed to lock.\n");
		FreeSound ();
		return false;
	}
	memset (lpData, 0, gSndBufSize);

	/*
	 * Allocate and lock memory for the header. This memory must 
	 * also be globally allocated with GMEM_MOVEABLE and 
	 * GMEM_SHARE flags. 
	 */
	hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
	                       (DWORD) sizeof(WAVEHDR) * WAV_BUFFERS);

	if (hWaveHdr == NULL) {
		Com_Printf ("Sound: Failed to Alloc header.\n");
		FreeSound ();
		return false;
	}

	lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr);

	if (lpWaveHdr == NULL) {
		Com_Printf ("Sound: Failed to lock header.\n");
		FreeSound ();
		return false;
	}

	memset (lpWaveHdr, 0, sizeof(WAVEHDR) * WAV_BUFFERS);

	/* After allocation, set up and prepare headers. */
	for (i = 0; i < WAV_BUFFERS; i++) {
		lpWaveHdr[i].dwBufferLength = WAV_BUFFER_SIZE;
		lpWaveHdr[i].lpData = lpData + i*WAV_BUFFER_SIZE;

		if (waveOutPrepareHeader(hWaveOut, lpWaveHdr+i, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) {
			Com_Printf ("Sound: failed to prepare wave headers\n");
			FreeSound ();
			return false;
		}
	}

	shm->samples = gSndBufSize / shm->format.width;
	shm->sampleframes = shm->samples / shm->format.channels;
	shm->samplepos = 0;
	shm->buffer = (unsigned char *) lpData;

	wav_init = true;

	return true;
}
示例#3
0
//Reset the sound device for exiting
void SNDDMA_Shutdown(void)
{
	FreeSound ();
}
示例#4
0
//=========================================================
// Think - at interval, the entire active sound list is checked
// for sounds that have ExpireTimes less than or equal
// to the current world time, and these sounds are deallocated.
//=========================================================
void CSoundEnt::Think ( void )
{
	int iSound;
	int iPreviousSound;

	SetNextThink( gpGlobals->curtime + 0.1 );// how often to check the sound list.

	iPreviousSound = SOUNDLIST_EMPTY;
	iSound = m_iActiveSound; 

	while ( iSound != SOUNDLIST_EMPTY )
	{
		if ( (m_SoundPool[ iSound ].m_flExpireTime <= gpGlobals->curtime && (!m_SoundPool[ iSound ].m_bNoExpirationTime)) || !m_SoundPool[iSound].ValidateOwner() )
		{
			int iNext = m_SoundPool[ iSound ].m_iNext;

			if( displaysoundlist.GetInt() == 1 )
			{
				Msg("  Removed Sound: %d (Time:%f)\n", m_SoundPool[ iSound ].SoundType(), gpGlobals->curtime );
			}
			if( displaysoundlist.GetInt() == 2 && m_SoundPool[ iSound ].IsSoundType( SOUND_DANGER ) )
			{
				Msg("  Removed Danger Sound: %d (time:%f)\n", m_SoundPool[ iSound ].SoundType(), gpGlobals->curtime );
			}

			// move this sound back into the free list
			FreeSound( iSound, iPreviousSound );

			iSound = iNext;
		}
		else
		{
			if( displaysoundlist.GetBool() )
			{
				Vector forward, right, up;
				GetVectors( &forward, &right, &up );
				byte r, g, b;

				// Default to yellow.
				r = 255;
				g = 255;
				b = 0;

				CSound *pSound = &m_SoundPool[ iSound ];

				if( pSound->IsSoundType( SOUND_DANGER ) )
				{
					r = 255;
					g = 0;
					b = 0;
				}

				if( displaysoundlist.GetInt() == 1 || (displaysoundlist.GetInt() == 2 && pSound->IsSoundType( SOUND_DANGER ) ) )
				{
					NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() + forward * pSound->Volume(), r,g,b, false, 0.1 );
					NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() - forward * pSound->Volume(), r,g,b, false, 0.1 );

					NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() + right * pSound->Volume(), r,g,b, false, 0.1 );
					NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() - right * pSound->Volume(), r,g,b, false, 0.1 );

					NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() + up * pSound->Volume(), r,g,b, false, 0.1 );
					NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() - up * pSound->Volume(), r,g,b, false, 0.1 );

					if( pSound->m_flOcclusionScale != 1.0 )
					{
						// Draw the occluded radius, too.
						r = 0; g = 150; b = 255;
						NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() + forward * pSound->OccludedVolume(), r,g,b, false, 0.1 );
						NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() - forward * pSound->OccludedVolume(), r,g,b, false, 0.1 );

						NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() + right * pSound->OccludedVolume(), r,g,b, false, 0.1 );
						NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() - right * pSound->OccludedVolume(), r,g,b, false, 0.1 );

						NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() + up * pSound->OccludedVolume(), r,g,b, false, 0.1 );
						NDebugOverlay::Line( pSound->GetSoundOrigin(), pSound->GetSoundOrigin() - up * pSound->OccludedVolume(), r,g,b, false, 0.1 );
					}
				}

				DevMsg( 2, "Soundlist: %d / %d  (%d)\n", ISoundsInList( SOUNDLISTTYPE_ACTIVE ),ISoundsInList( SOUNDLISTTYPE_FREE ), ISoundsInList( SOUNDLISTTYPE_ACTIVE ) - m_cLastActiveSounds );
				m_cLastActiveSounds = ISoundsInList ( SOUNDLISTTYPE_ACTIVE );
			}

			iPreviousSound = iSound;
			iSound = m_SoundPool[ iSound ].m_iNext;
		}
	}

}
示例#5
0
static sndinitstat SNDDMA_InitDirect (void)
{
	DSBUFFERDESC dsbuf;
	DSBCAPS dsbcaps;
	DWORD dwSize, dwWrite;
	DSCAPS dscaps;
	WAVEFORMATEX format, pformat;
	HRESULT hresult;
	int reps, temp, devicenum;

	memset((void *)shm, 0, sizeof(*shm));

	shm->format.channels = 2;
	shm->format.width = 2;
	shm->format.speed = SND_Rate((int)s_khz.value);

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

	dsdevice = NULL;
	if ((temp = COM_CheckParm("-snddev")) && temp + 1 < COM_Argc()) {
		devicenum = Q_atoi(COM_Argv(temp + 1));
		currentenum = 0;
		if ((hresult = DirectSoundEnumerate(DS_EnumDevices, &devicenum)) != DS_OK) {
			Com_Printf_State (PRINT_INFO, "Couldn't open preferred sound device. Falling back to primary sound device.\n");
			dsdevice = NULL;
		}
	}

	hresult = DirectSoundCreate(dsdevice, &pDS, NULL);
	if (hresult != DS_OK && dsdevice) {
		Com_Printf_State (PRINT_INFO, "Couldn't open preferred sound device. Falling back to primary sound device.\n");
		dsdevice = NULL;
		hresult = DirectSoundCreate(dsdevice, &pDS, NULL);
	}

	if (hresult != DS_OK) {
		if (hresult == DSERR_ALLOCATED) {
			Com_Printf_State (PRINT_FAIL, "DirectSoundCreate failed, hardware already in use\n");
			return SIS_NOTAVAIL;
		}

		Com_Printf_State (PRINT_FAIL, "DirectSound create failed\n");
		return SIS_FAILURE;
	}

	dscaps.dwSize = sizeof(dscaps);

	if (DS_OK != pDS->lpVtbl->GetCaps (pDS, &dscaps))
		Com_Printf_State (PRINT_FAIL, "Couldn't get DS caps\n");

	if (dscaps.dwFlags & DSCAPS_EMULDRIVER) {
		Com_Printf_State (PRINT_FAIL, "No DirectSound driver installed\n");
		FreeSound ();
		return SIS_FAILURE;
	}

	if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE)) {
		Com_Printf_State (PRINT_FAIL, "Set coop level failed\n");
		FreeSound ();
		return SIS_FAILURE;
	}

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

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

	if (!COM_CheckParm ("-snoforceformat")) {
		if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSPBuf, NULL)) {
			pformat = format;

			if (DS_OK != pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat)) {
//				if (snd_firsttime)
//					Com_Printf ("Set primary sound buffer format: no\n");
			} else {
//				if (snd_firsttime)
//					Com_Printf ("Set primary sound buffer format: yes\n");
				primary_format_set = true;
			}
		}
	}

	if (!primary_format_set || !COM_CheckParm ("-primarysound")) {
		// create the secondary buffer we'll actually work with
		memset (&dsbuf, 0, sizeof(dsbuf));
		dsbuf.dwSize = sizeof(DSBUFFERDESC);
		dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE | (sys_inactivesound.value ? DSBCAPS_GLOBALFOCUS : 0);
		dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
		dsbuf.lpwfxFormat = &format;

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

		if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) {
			Com_Printf_State (PRINT_FAIL, "DS:CreateSoundBuffer Failed");
			FreeSound ();
			return SIS_FAILURE;
		}

		shm->format.channels = format.nChannels;
		shm->format.width = format.wBitsPerSample / 8;
		shm->format.speed = format.nSamplesPerSec;

		if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps)) {
			Com_Printf_State (PRINT_FAIL, "DS:GetCaps failed\n");
			FreeSound ();
			return SIS_FAILURE;
		}

//		if (snd_firsttime)
//			Com_Printf ("Using secondary sound buffer\n");
	} else {
		if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_WRITEPRIMARY)) {
			Com_Printf_State (PRINT_FAIL, "Set coop level failed\n");
			FreeSound ();
			return SIS_FAILURE;
		}

		if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps)) {
			Com_Printf_State (PRINT_FAIL, "DS:GetCaps failed\n");
			return SIS_FAILURE;
		}

		pDSBuf = pDSPBuf;
//		Com_Printf ("Using primary sound buffer\n");
	}

	// Make sure mixer is active
	pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);

/*	if (snd_firsttime)
		Com_Printf ("   %d channel(s)\n"
			"   %d bits/sample\n"
			"   %d bytes/sec\n",
		shm->format.channels, shm->format.width * , shm->format.speed);*/

	gSndBufSize = dsbcaps.dwBufferBytes;

	// initialize the buffer
	reps = 0;

	while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &lpData, &dwSize, NULL, NULL, 0)) != DS_OK) {
		if (hresult != DSERR_BUFFERLOST) {
			Com_Printf_State (PRINT_FAIL, "SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n");
			FreeSound ();
			return SIS_FAILURE;
		}

		if (++reps > 10000) {
			Com_Printf_State (PRINT_FAIL, "SNDDMA_InitDirect: DS: couldn't restore buffer\n");
			FreeSound ();
			return SIS_FAILURE;
		}

	}

	memset(lpData, 0, dwSize);
//		lpData[4] = lpData[5] = 0x7f;	// force a pop for debugging

	pDSBuf->lpVtbl->Unlock(pDSBuf, lpData, dwSize, NULL, 0);

	/* we don't want anyone to access the buffer directly w/o locking it first. */
	lpData = NULL;

	pDSBuf->lpVtbl->Stop(pDSBuf);
	pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmstarttime.u.sample, &dwWrite);
	pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);

	shm->samples = gSndBufSize/shm->format.width;
	shm->sampleframes = shm->samples / shm->format.channels;
	shm->samplepos = 0;
	shm->buffer = (unsigned char *) lpData;
	sample16 = shm->format.width - 1;

	dsound_init = true;

	return SIS_SUCCESS;
}
示例#6
0
/*
==================
SNDDMA_InitDirect

Direct-Sound support
==================
*/
sndinitstat SNDDMA_InitDirect (void)
{
	DSCAPS			dscaps;
	HRESULT			hresult;

	dma.channels = 2;
	dma.samplebits = 16;

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

	if (!cl_quietstartup->intvalue || developer->intvalue)
		Com_Printf( "Initializing DirectSound\n", LOG_CLIENT|LOG_NOTICE);

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

		hInstDS = LoadLibrary("dsound.dll");
		
		if (hInstDS == NULL)
		{
			Com_Printf ("failed (%d)\n", LOG_CLIENT, GetLastError());
			return SIS_FAILURE;
		}

		Com_DPrintf ("ok\n");

		//if (s_dx8->value)
		//	pDirectSoundCreate8 = (int (__stdcall *)(struct _GUID *,struct IDirectSound8 ** ,struct IUnknown *))GetProcAddress(hInstDS,"DirectSoundCreate8");
		//else
		pDirectSoundCreate = (HRESULT (__stdcall *)(GUID *, LPDIRECTSOUND *, IUnknown *))GetProcAddress(hInstDS,"DirectSoundCreate");

		if (!pDirectSoundCreate)
		{
			Com_Printf ("*** couldn't get DS procaddr (do you have DirectX installed properly?) ***\n", LOG_CLIENT|LOG_ERROR);
			return SIS_FAILURE;
		}
	}*/

	Com_DPrintf( "...creating DS object: " );
	while ( ( hresult = DirectSoundCreate ( NULL, &pDS, NULL ) ) != DS_OK )
	{
		if (hresult != DSERR_ALLOCATED)
		{
			Com_Printf( "failed (%d)\n", LOG_CLIENT, hresult );
			return SIS_FAILURE;
		}

		if (MessageBox (NULL,
						"The sound hardware is in use by another app.\n\n"
					    "Select Retry to try to start sound again or Cancel to run Quake with no sound.",
						"Sound not available",
						MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY)
		{
			Com_Printf ("failed to setup directsound, hardware already in use\n", LOG_CLIENT );
			return SIS_NOTAVAIL;
		}
	}
	Com_DPrintf( "ok\n" );

	dscaps.dwSize = sizeof(dscaps);

	if ( DS_OK != pDS->lpVtbl->GetCaps( pDS, &dscaps ) )
	{
		Com_Printf ("*** couldn't get DS caps ***\n", LOG_CLIENT|LOG_ERROR);
	}

	if ( dscaps.dwFlags & DSCAPS_EMULDRIVER )
	{
		Com_DPrintf ("...no DSound driver found\n" );
		FreeSound();
		return SIS_FAILURE;
	}

	if ( !DS_CreateBuffers() )
		return SIS_FAILURE;

	dsound_init = true;

	Com_DPrintf("...completed successfully\n" );

	return SIS_SUCCESS;
}
示例#7
0
/*
==================
SNDDM_InitWav

Crappy windows multimedia base
==================
*/
qboolean SNDDMA_InitWav (void)
{
	WAVEFORMATEX  format; 
	int				i;
	HRESULT			hr;

	Com_Printf( "Initializing wave sound\n", LOG_CLIENT|LOG_NOTICE);
	
	snd_sent = 0;
	snd_completed = 0;

	dma.channels = 2;
	dma.samplebits = 16;

	if (s_khz->intvalue == 44)
		dma.speed = 44100;
	else if (s_khz->intvalue == 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; 
	
	/* Open a waveform device for output using window callback. */ 
	Com_DPrintf ("...opening waveform device: ");
	while ((hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, 
					&format, 
					0, 0L, CALLBACK_NULL)) != MMSYSERR_NOERROR)
	{
		if (!SUCCEEDED (hr))
		{
			Com_Printf ("failed\n", LOG_CLIENT);
			return false;
		}

		if (MessageBox (NULL,
						"The sound hardware is in use by another app.\n\n"
					    "Select Retry to try to start sound again or Cancel to run Quake 2 with no sound.",
						"Sound not available",
						MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY)
		{
			Com_Printf ("hw in use\n", LOG_CLIENT);
			return false;
		}
	} 
	Com_DPrintf( "ok\n" );

	/* 
	 * Allocate and lock memory for the waveform data. The memory 
	 * for waveform data must be globally allocated with 
	 * GMEM_MOVEABLE and GMEM_SHARE flags. 

	*/ 
	Com_DPrintf ("...allocating waveform buffer: ");
	gSndBufSize = WAV_BUFFERS*WAV_BUFFER_SIZE;
	hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, gSndBufSize); 
	if (!hData) 
	{ 
		Com_Printf( " failed\n", LOG_CLIENT);
		FreeSound ();
		return false; 
	}
	Com_DPrintf( "ok\n" );

	Com_DPrintf ("...locking waveform buffer: ");
	lpData = GlobalLock(hData);
	if (!lpData)
	{ 
		Com_Printf( " failed\n", LOG_CLIENT);
		FreeSound ();
		return false; 
	} 
	memset (lpData, 0, gSndBufSize);
	Com_DPrintf( "ok\n" );

	/* 
	 * Allocate and lock memory for the header. This memory must 
	 * also be globally allocated with GMEM_MOVEABLE and 
	 * GMEM_SHARE flags. 
	 */ 
	Com_DPrintf ("...allocating waveform header: ");
	hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, 
		(DWORD) sizeof(WAVEHDR) * WAV_BUFFERS); 

	if (hWaveHdr == NULL)
	{ 
		Com_Printf( "failed\n", LOG_CLIENT);
		FreeSound ();
		return false; 
	} 
	Com_DPrintf( "ok\n" );

	Com_DPrintf ("...locking waveform header: ");
	lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr); 

	if (lpWaveHdr == NULL)
	{ 
		Com_Printf( "failed\n", LOG_CLIENT);
		FreeSound ();
		return false; 
	}
	memset (lpWaveHdr, 0, sizeof(WAVEHDR) * WAV_BUFFERS);
	Com_DPrintf( "ok\n" );

	/* After allocation, set up and prepare headers. */ 
	Com_DPrintf ("...preparing headers: ");
	for (i=0 ; i<WAV_BUFFERS ; i++)
	{
		lpWaveHdr[i].dwBufferLength = WAV_BUFFER_SIZE; 
		lpWaveHdr[i].lpData = lpData + i*WAV_BUFFER_SIZE;

		if (waveOutPrepareHeader(hWaveOut, lpWaveHdr+i, sizeof(WAVEHDR)) !=
				MMSYSERR_NOERROR)
		{
			Com_Printf ("failed\n", LOG_CLIENT);
			FreeSound ();
			return false;
		}
	}
	Com_DPrintf ("ok\n");

	dma.samples = gSndBufSize/(dma.samplebits/8);
	dma.samplepos = 0;
	dma.submission_chunk = 512;
	dma.buffer = (unsigned char *) lpData;
	sample16 = (dma.samplebits/8) - 1;

	wav_init = true;

	return true;
}
示例#8
0
文件: win_snd.c 项目: MGXRace/racesow
/*
** DS_CreateBuffers
*/
static bool DS_CreateBuffers( void )
{
	DSBUFFERDESC dsbuf;
	DSBCAPS	dsbcaps;
	WAVEFORMATEX format;
	DWORD dwWrite;

	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;

	if( developer->integer )
		Com_Printf( "Creating DS buffer\n" );

	if( developer->integer )
		Com_Printf( "...setting PRIORITY coop level: " );
	if( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, cl_hwnd, DSSCL_PRIORITY ) )
	{
		if( developer->integer )
			Com_Printf( "failed\n" );
		FreeSound( false );
		return false;
	}
	if( developer->integer )
		Com_Printf( "ok\n" );

	// create the secondary buffer we'll actually work with
	memset( &dsbuf, 0, sizeof( dsbuf ) );
	dsbuf.dwSize = sizeof( DSBUFFERDESC );
	dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCHARDWARE;
	dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
	dsbuf.lpwfxFormat = &format;

	if( s_globalfocus->integer ) {
		dsbuf.dwFlags |= DSBCAPS_GLOBALFOCUS;
	}

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

	if( developer->integer )
		Com_Printf( "...creating secondary buffer: " );
	if( DS_OK != pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSBuf, NULL ) )
	{
		dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE;
		if( s_globalfocus->integer ) {
			dsbuf.dwFlags |= DSBCAPS_GLOBALFOCUS;
		}

		if( DS_OK != pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSBuf, NULL ) )
		{
			if( developer->integer )
				Com_Printf( "failed\n" );
			FreeSound( false );
			return false;
		}

		if( developer->integer )
			Com_Printf( "ok\n...forced to software\n" );
	}
	else
	{
		if( developer->integer )
			Com_Printf( "ok\n...locked hardware\n" );
	}

	dma.channels = format.nChannels;
	dma.samplebits = format.wBitsPerSample;
	dma.speed = format.nSamplesPerSec;
	dma.msec_per_sample = 1000.0 / dma.speed;

	if( DS_OK != pDSBuf->lpVtbl->GetCaps( pDSBuf, &dsbcaps ) )
	{
		if( developer->integer )
			Com_Printf( "*** GetCaps failed ***\n" );
		FreeSound( false );
		return false;
	}

	// Make sure mixer is active
	if( DS_OK != pDSBuf->lpVtbl->Play( pDSBuf, 0, 0, DSBPLAY_LOOPING ) )
	{
		if( developer->integer )
			Com_Printf( "*** Play failed ***\n" );
		FreeSound( false );
		return false;
	}

	if( developer->integer )
		Com_Printf( "   %d channel(s)\n"
		"   %d bits/sample\n"
		"   %d bytes/sec\n",
		dma.channels, dma.samplebits, dma.speed );

	gSndBufSize = dsbcaps.dwBufferBytes;

	/* we don't want anyone to access the buffer directly w/o locking it first. */
	lpData = NULL;

	pDSBuf->lpVtbl->Stop( pDSBuf );
	pDSBuf->lpVtbl->GetCurrentPosition( pDSBuf, &mmstarttime.u.sample, &dwWrite );
	pDSBuf->lpVtbl->Play( pDSBuf, 0, 0, DSBPLAY_LOOPING );

	dma.samples = gSndBufSize/( dma.samplebits/8 );
	dma.samplepos = 0;
	dma.submission_chunk = 1;
	dma.buffer = (unsigned char *) lpData;
	sample16 = ( dma.samplebits/8 ) - 1;

	return true;
}
示例#9
0
/*
** DS_CreateBuffers
*/
static qboolean DS_CreateBuffers( void )
{
	int ret;

	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	WAVEFORMATEX	pformat, format;
	DWORD			dwWrite;

	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 = sizeof(WAVEFORMATEX);
    format.nAvgBytesPerSec = format.nSamplesPerSec*format.nBlockAlign; 

	Com_DPrintf( "Creating DS buffers\n");

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

	ret = pDS->lpVtbl->SetCooperativeLevel(pDS, cl_hwnd, DSSCL_EXCLUSIVE);
	if (ret != DS_OK)
	{
		Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret));
		FreeSound ();
		return false;
	}
	Com_DPrintf("ok\n" );

// get access to the primary buffer, if possible, so we can set the
// sound hardware format
	memset (&dsbuf, 0, sizeof(dsbuf));

	dsbuf.dwSize = sizeof(DSBUFFERDESC);
	dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER;
	dsbuf.dwBufferBytes = 0;
	dsbuf.lpwfxFormat = NULL;

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

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

		Com_DPrintf( "ok\n" );

		ret = pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat);
		if (DS_OK != ret)
		{
			if (snd_firsttime)
			{
				Com_DPrintf ("...setting primary sound format: ");
				Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret));
			}
		}
		else
		{
			if (snd_firsttime)
				Com_DPrintf ("...setting primary sound format: ok\n");

			primary_format_set = true;
		}
	}
	else
	{
		Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret));
	}

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

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

		Com_DPrintf( "...creating secondary buffer: " );
		ret = pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL);
		if (DS_OK != ret)
		{
			Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret));
			FreeSound ();
			return false;
		}
		Com_DPrintf( "ok\n" );

		dma.channels = format.nChannels;
		dma.samplebits = format.wBitsPerSample;
		dma.speed = format.nSamplesPerSec;

		if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps))
		{
			Com_Printf ("*** GetCaps failed ***\n", LOG_CLIENT|LOG_ERROR);
			FreeSound ();
			return false;
		}

		Com_DPrintf ("...using secondary sound buffer\n");
	}
	else
	{
		Com_DPrintf( "...using primary buffer\n" );

		Com_DPrintf( "...setting WRITEPRIMARY coop level: " );
		pDS->lpVtbl->SetCooperativeLevel (pDS, cl_hwnd, DSSCL_WRITEPRIMARY);
		if (DS_OK != ret)
		{
			Com_Printf ("failed (%s)\n", LOG_CLIENT, DSoundError(ret));
			FreeSound ();
			return false;
		}
		Com_DPrintf( "ok\n" );

		if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps))
		{
			Com_Printf ("*** GetCaps failed ***\n", LOG_CLIENT|LOG_ERROR);
			return false;
		}

		pDSBuf = pDSPBuf;
	}

	// Make sure mixer is active
	pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);

	if (snd_firsttime)
		if (!cl_quietstartup->intvalue || developer->intvalue)
			Com_Printf("   %d channel(s)\n"
		               "   %d bits/sample\n"
					   "   %d bytes/sec\n", LOG_CLIENT|LOG_NOTICE,
					   dma.channels, dma.samplebits, dma.speed);
	
	gSndBufSize = dsbcaps.dwBufferBytes;

	/* we don't want anyone to access the buffer directly w/o locking it first. */
	lpData = NULL; 

	pDSBuf->lpVtbl->Stop(pDSBuf);
	pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmstarttime.u.sample, &dwWrite);
	pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);

	dma.samples = gSndBufSize/(dma.samplebits/8);
	dma.samplepos = 0;
	dma.submission_chunk = 1;
	dma.buffer = (unsigned char *) lpData;
	sample16 = (dma.samplebits/8) - 1;

	return true;
}
示例#10
0
文件: win_snd.c 项目: MGXRace/racesow
/*
* SNDDMA_Shutdown
* 
* Reset the sound device for exiting
*/
void SNDDMA_Shutdown( bool verbose )
{
	FreeSound( verbose );
}
示例#11
0
文件: win_snd.c 项目: MGXRace/racesow
/*
* SNDDMA_Submit
* 
* Send sound to device if buffer isn't really the dma buffer
* Also unlocks the dsound buffer
*/
void SNDDMA_Submit( void )
{
	LPWAVEHDR h;
	int wResult;

	if( !dma.buffer )
		return;

	// unlock the dsound buffer
	if( pDSBuf )
		pDSBuf->lpVtbl->Unlock( pDSBuf, dma.buffer, locksize, NULL, 0 );

	if( !wav_init )
		return;

	//
	// find which sound blocks have completed
	//
	while( 1 )
	{
		if( snd_completed == snd_sent )
		{
			//Com_Printf( "Sound overrun\n" );
			break;
		}

		if( !( lpWaveHdr[snd_completed & WAV_MASK].dwFlags & WHDR_DONE ) )
		{
			break;
		}

		snd_completed++; // this buffer has been played
	}

	//
	// submit a few new sound blocks
	//
	while( ( ( snd_sent - snd_completed ) >> sample16 ) < 8 )
	{
		h = lpWaveHdr + ( snd_sent&WAV_MASK );
		if( paintedtime/256 <= snd_sent )
			break;
		snd_sent++;
		/*
		* Now the data block can be sent to the output device. The
		* waveOutWrite function returns immediately and waveform
		* data is sent to the output device in the background.
		*/
		if( s_active )
		{
			wResult = waveOutWrite( hWaveOut, h, sizeof( WAVEHDR ) );

			if( wResult != MMSYSERR_NOERROR )
			{
				Com_Printf( "Failed to write block to device\n" );
				FreeSound( true );
				return;
			}
		}
	}
}
示例#12
0
文件: win_snd.c 项目: MGXRace/racesow
/*
* SNDDMA_InitDirect
* 
* Direct-Sound support
*/
sndinitstat SNDDMA_InitDirect( bool verbose )
{
	DSCAPS dscaps;
	HRESULT	hresult;

	dma.channels = 2;
	dma.samplebits = 16;

	if( s_khz->integer == 48 )
		dma.speed = 48000;
	else if( s_khz->integer == 44 )
		dma.speed = 44100;
	else if( s_khz->integer == 22 )
		dma.speed = 22050;
	else
		dma.speed = 11025;
	dma.msec_per_sample = 1000.0 / dma.speed;

	if( verbose )
		Com_Printf( "Initializing DirectSound\n" );

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

		hInstDS = LoadLibrary( "dsound.dll" );

		if( hInstDS == NULL )
		{
			if( verbose )
				Com_Printf( "failed\n" );
			return SIS_FAILURE;
		}

		if( verbose )
			Com_Printf( "ok\n" );
		pDirectSoundCreate = (void *)GetProcAddress( hInstDS, "DirectSoundCreate" );

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

	if( verbose )
		Com_Printf( "...creating DS object: " );
	while( ( hresult = pDirectSoundCreate( NULL, &pDS, NULL ) ) != DS_OK )
	{
		if( hresult != DSERR_ALLOCATED )
		{
			if( verbose )
				Com_Printf( "failed\n" );
			return SIS_FAILURE;
		}

		if( MessageBox( NULL,
			"The sound hardware is in use by another app.\n\n"
			"Select Retry to try to start sound again or Cancel to run with no sound.",
			"Sound not available",
			MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION ) != IDRETRY )
		{
			if( verbose )
				Com_Printf( "failed, hardware already in use\n" );
			return SIS_NOTAVAIL;
		}
	}
	if( verbose )
		Com_Printf( "ok\n" );

	dscaps.dwSize = sizeof( dscaps );

	if( DS_OK != pDS->lpVtbl->GetCaps( pDS, &dscaps ) )
	{
		if( verbose )
			Com_Printf( "*** couldn't get DS caps ***\n" );
	}

	if( dscaps.dwFlags & DSCAPS_EMULDRIVER )
	{
		if( verbose )
			Com_Printf( "...no DSound driver found\n" );
		FreeSound( verbose );
		return SIS_FAILURE;
	}

	if( !DS_CreateBuffers() )
		return SIS_FAILURE;

	dsound_init = true;

	if( verbose )
		Com_Printf( "...completed successfully\n" );

	return SIS_SUCCESS;
}
示例#13
0
文件: snd_win.c 项目: luaman/zq
/*
==================
SNDDM_InitWav

Crappy windows multimedia base
==================
*/
static qbool SNDDMA_InitWav (void)
{
	WAVEFORMATEX  format;
	int				i;
	HRESULT			hr;

	snd_sent = 0;
	snd_completed = 0;

	dma.channels = 2;
	dma.samplebits = 16;
	if (s_khz.value == 44)
		dma.speed = 44100;
	else if (s_khz.value == 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;

	/* Open a waveform device for output using window callback. */
	if ((hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER,
					&format,
					0, 0L, CALLBACK_NULL)) != MMSYSERR_NOERROR)
	{
		if (hr == MMSYSERR_ALLOCATED)
			Com_Printf ("waveOutOpen failed, hardware already in use\n");
		else
			Com_Printf ("waveOutOpen failed\n");

		return false;
	}

	/*
	 * Allocate and lock memory for the waveform data. The memory
	 * for waveform data must be globally allocated with
	 * GMEM_MOVEABLE and GMEM_SHARE flags.

	*/
	gSndBufSize = WAV_BUFFERS*WAV_BUFFER_SIZE;
	hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, gSndBufSize);
	if (!hData)
	{
		Com_Printf ("Sound: Out of memory.\n");
		FreeSound ();
		return false;
	}
	lpData = GlobalLock(hData);
	if (!lpData)
	{
		Com_Printf ("Sound: Failed to lock.\n");
		FreeSound ();
		return false;
	}
	memset (lpData, 0, gSndBufSize);

	/*
	 * Allocate and lock memory for the header. This memory must
	 * also be globally allocated with GMEM_MOVEABLE and
	 * GMEM_SHARE flags.
	 */
	hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
		(DWORD) sizeof(WAVEHDR) * WAV_BUFFERS);

	if (hWaveHdr == NULL)
	{
		Com_Printf ("Sound: Failed to Alloc header.\n");
		FreeSound ();
		return false;
	}

	lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr);

	if (lpWaveHdr == NULL)
	{
		Com_Printf ("Sound: Failed to lock header.\n");
		FreeSound ();
		return false;
	}

	memset (lpWaveHdr, 0, sizeof(WAVEHDR) * WAV_BUFFERS);

	/* After allocation, set up and prepare headers. */
	for (i=0 ; i<WAV_BUFFERS ; i++)
	{
		lpWaveHdr[i].dwBufferLength = WAV_BUFFER_SIZE;
		lpWaveHdr[i].lpData = lpData + i*WAV_BUFFER_SIZE;

		if (waveOutPrepareHeader(hWaveOut, lpWaveHdr+i, sizeof(WAVEHDR)) !=
				MMSYSERR_NOERROR)
		{
			Com_Printf ("Sound: failed to prepare wave headers\n");
			FreeSound ();
			return false;
		}
	}

	dma.samples = gSndBufSize/(dma.samplebits/8);
	dma.samplepos = 0;
	dma.submission_chunk = 1;
	dma.buffer = (unsigned char *) lpData;
	sample16 = (dma.samplebits/8) - 1;

	wav_init = true;

	return true;
}
示例#14
0
文件: snd_win.c 项目: luaman/zq
/*
==================
SNDDMA_InitDirect

Direct-Sound support
==================
*/
static sndinitstat SNDDMA_InitDirect (void)
{
	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	DWORD			dwSize, dwWrite;
	DSCAPS			dscaps;
	WAVEFORMATEX	format, pformat;
	HRESULT			hresult;
	int				reps;

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

	dma.channels = 2;
	dma.samplebits = 16;
	if (s_khz.value == 44)
		dma.speed = 44100;
	else if (s_khz.value == 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;

	if (!hInstDS)
	{
		hInstDS = LoadLibrary("dsound.dll");

		if (hInstDS == NULL)
		{
			Com_Printf ("Couldn't load dsound.dll\n");
			return SIS_FAILURE;
		}

		pDirectSoundCreate = (HRESULT (WINAPI *)(GUID FAR *, LPDIRECTSOUND FAR *, IUnknown FAR *))GetProcAddress(hInstDS,"DirectSoundCreate");

		if (!pDirectSoundCreate)
		{
			Com_Printf ("Couldn't get DS proc addr\n");
			return SIS_FAILURE;
		}
	}

	if ((hresult = iDirectSoundCreate(NULL, &pDS, NULL)) != DS_OK)
	{
		if (hresult == DSERR_ALLOCATED)
		{
			Com_Printf ("DirectSoundCreate failed, hardware already in use\n");
			return SIS_NOTAVAIL;
		}

		Com_Printf ("DirectSound create failed\n");
		return SIS_FAILURE;
	}

	dscaps.dwSize = sizeof(dscaps);

	if (DS_OK != pDS->lpVtbl->GetCaps (pDS, &dscaps))
	{
		Com_Printf ("Couldn't get DS caps\n");
	}

	if (dscaps.dwFlags & DSCAPS_EMULDRIVER)
	{
		Com_Printf ("No DirectSound driver installed\n");
		FreeSound ();
		return SIS_FAILURE;
	}

	if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE))
	{
		Com_Printf ("Set coop level failed\n");
		FreeSound ();
		return SIS_FAILURE;
	}

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

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

	if (!COM_CheckParm ("-snoforceformat"))
	{
		if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSPBuf, NULL))
		{
			pformat = format;

			if (DS_OK != pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat))
			{
//				if (snd_firsttime)
//					Com_Printf ("Set primary sound buffer format: no\n");
			}
			else
//			{
//				if (snd_firsttime)
//					Com_Printf ("Set primary sound buffer format: yes\n");

				primary_format_set = true;
//			}
		}
	}

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

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

		if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL))
		{
			Com_Printf ("DS:CreateSoundBuffer Failed");
			FreeSound ();
			return SIS_FAILURE;
		}

		dma.channels = format.nChannels;
		dma.samplebits = format.wBitsPerSample;
		dma.speed = format.nSamplesPerSec;

		if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps))
		{
			Com_Printf ("DS:GetCaps failed\n");
			FreeSound ();
			return SIS_FAILURE;
		}

//		if (snd_firsttime)
//			Com_Printf ("Using secondary sound buffer\n");
	}
	else
	{
		if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, mainwindow, DSSCL_WRITEPRIMARY))
		{
			Com_Printf ("Set coop level failed\n");
			FreeSound ();
			return SIS_FAILURE;
		}

		if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps))
		{
			Com_Printf ("DS:GetCaps failed\n");
			return SIS_FAILURE;
		}

		pDSBuf = pDSPBuf;
//		Com_Printf ("Using primary sound buffer\n");
	}

	// Make sure mixer is active
	pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);

/*	if (snd_firsttime)
		Com_Printf ("   %d channel(s)\n"
		               "   %d bits/sample\n"
					   "   %d bytes/sec\n",
					   dma.channels, dma.samplebits, dma.speed);*/

	gSndBufSize = dsbcaps.dwBufferBytes;

// initialize the buffer
	reps = 0;

#ifdef MINGW32
#define Lock(a,b,c,d,e,f,g,h) Lock(a,b,c,(void *)d,e,(void *)f,g,h)
#endif

	while ((hresult = pDSBuf->lpVtbl->Lock(pDSBuf, 0, gSndBufSize, &lpData, &dwSize, NULL, NULL, 0)) != DS_OK)
	{
		if (hresult != DSERR_BUFFERLOST)
		{
			Com_Printf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n");
			FreeSound ();
			return SIS_FAILURE;
		}

		if (++reps > 10000)
		{
			Com_Printf ("SNDDMA_InitDirect: DS: couldn't restore buffer\n");
			FreeSound ();
			return SIS_FAILURE;
		}

	}

	memset(lpData, 0, dwSize);
//		lpData[4] = lpData[5] = 0x7f;	// force a pop for debugging

	pDSBuf->lpVtbl->Unlock(pDSBuf, lpData, dwSize, NULL, 0);

	/* we don't want anyone to access the buffer directly w/o locking it first. */
	lpData = NULL;

	pDSBuf->lpVtbl->Stop(pDSBuf);
	pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmstarttime.u.sample, &dwWrite);
	pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING);

	dma.samples = gSndBufSize/(dma.samplebits/8);
	dma.samplepos = 0;
	dma.submission_chunk = 1;
	dma.buffer = (unsigned char *) lpData;
	sample16 = (dma.samplebits/8) - 1;

	dsound_init = true;

	return SIS_SUCCESS;
}