Example #1
0
qboolean SNDDMAHD_DSEnumSoundDevices(qboolean blistonly)
{
	HMODULE hdsounddll = NULL;
	pDirectSoundEnumerate DSEnumerate;

	if ((hdsounddll = LoadLibrary("dsound.dll")) != NULL &&
		(DSEnumerate = (pDirectSoundEnumerate)GetProcAddress(hdsounddll, "DirectSoundEnumerateA")) != NULL &&
		s_dev->string != NULL && s_dev->string[0] != '\0')
	{
		if (blistonly) 
		{
			Com_Printf( "^4List of DirectSound devices:\n");
			if (FAILED(DSEnumerate(SNDDMAHD_DSEnumCallbackList, NULL)))
			{
				Com_Printf("^1Error Enumerating DirectSound Devices\n");
				return qfalse;
			}
		}
		else
		{
			Com_Printf( "^4Looking for DirectSound Device '%s'\n", s_dev->string);
		
			if (FAILED(DSEnumerate(SNDDMAHD_DSEnumCallback, NULL)))
			{
				Com_Printf("^1Error Enumerating DirectSound Devices\n");
				return qfalse;
			}
		
			if (g_dsguid == NULL)
				Com_Printf("^1Device '%s' not found. ^2Using default driver.\n", s_dev->string);
		}
	}
	if (hdsounddll != NULL) FreeLibrary(hdsounddll);
	hdsounddll = NULL;
	return qtrue;
}
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;
}