int _tmain(int argc, _TCHAR* argv[])
{
	LPDIRECTSOUND8 lpsd;
	//DirectSound基于COM,but you do not have to initilize COM, if you don't use effective DMOs
	//HRESULT hr = DirectSoundCreate8(NULL, &lpsd, NULL);
	//if (FAILED(hr)){
	//	cout << "DirectSound Create failed" << endl;
	//	return 0;
	//}
    hr = CoInitializeEx(NULL, 0);
	if (FAILED(hRes)){
		cout << "CoInitializeEx failed" << endl;
		return 0;
	}
	hr = CoCreateInstanceEx(&CLSID_DirectSound8, 
		NULL,
		CLSTX_INPROC_SERVER,
		IID_IDirectSound8,
		(LPVOID*)&lpsd);
	if (FAILED(hr)){
		cout << "CoCreateInstanceEx failed" << endl;
		return 0;
	}
	hr = lpsd->Initialize(NULL);
	if (FAILED(hr)){
		cout << "DirectSound Device Initialize failed" << endl;
		return 0;
	}
	//不设置这个,没有声音
	hr = lpsd->SetCooperativeLevel(NULL, DSSCL_PRIORITY);
	if (FAILED(hr)){
		cout << "SetCooperativeLevel Failed" << endl;
		return 0;
	}
	DSCAPS dscaps;
	dscaps.dwSize = sizeof(DSCAPS);
	hr = lpsd->GetCaps(&dscaps);//得到设备的相关参数,这一步一般不需要做
	if (FAILED(hr)){
		cout << "GetCaps failed" << endl;
		return 0;
	}
	//创建二级缓存,这个控制声音从源到目的地, source sound can come from synthesizer,another buffer,a wav file,resource
	//CreateBaseBuffer(lpsd, );

	CoUninitialize();
	return 0;
}
bool DirectSound::init(long sampleRate)
{
	HRESULT hr;
	DWORD freq;
	DSBUFFERDESC dsbdesc;
	int i;

	hr = CoCreateInstance( CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, IID_IDirectSound8, (LPVOID *)&pDirectSound );
	if( hr != S_OK ) {
		systemMessage( IDS_CANNOT_CREATE_DIRECTSOUND, NULL, hr );
		return false;
	}

	pDirectSound->Initialize( &DSDEVID_DefaultPlayback );
	if( hr != DS_OK ) {
		systemMessage( IDS_CANNOT_CREATE_DIRECTSOUND, NULL, hr );
		return false;
	}

	if( FAILED( hr = pDirectSound->SetCooperativeLevel( theApp.m_pMainWnd->GetSafeHwnd(), DSSCL_EXCLUSIVE ) ) ) {
		systemMessage( IDS_CANNOT_SETCOOPERATIVELEVEL, _T("Cannot SetCooperativeLevel %08x"), hr );
		return false;
	}


	// Create primary sound buffer
	ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
	dsbdesc.dwSize = sizeof(DSBUFFERDESC);
	dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;
	if( dsoundDisableHardwareAcceleration ) {
		dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE;
	}

	if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbPrimary, NULL ) ) ) {
		systemMessage(IDS_CANNOT_CREATESOUNDBUFFER, _T("Cannot CreateSoundBuffer %08x"), hr);
		return false;
	}

	freq = sampleRate;
	// calculate the number of samples per frame first
	// then multiply it with the size of a sample frame (16 bit * stereo)
	soundBufferLen = ( freq / 60 ) * 4;
	soundBufferTotalLen = soundBufferLen * 10;
	soundNextPosition = 0;

	ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
	wfx.wFormatTag = WAVE_FORMAT_PCM;
	wfx.nChannels = 2;
	wfx.nSamplesPerSec = freq;
	wfx.wBitsPerSample = 16;
	wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
	wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;

	if( FAILED( hr = dsbPrimary->SetFormat( &wfx ) ) ) {
		systemMessage( IDS_CANNOT_SETFORMAT_PRIMARY, _T("CreateSoundBuffer(primary) failed %08x"), hr );
		return false;
	}


	// Create secondary sound buffer
	ZeroMemory( &dsbdesc, sizeof(DSBUFFERDESC) );
	dsbdesc.dwSize = sizeof(DSBUFFERDESC);
	dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS;
	if( dsoundDisableHardwareAcceleration ) {
		dsbdesc.dwFlags |= DSBCAPS_LOCSOFTWARE;
	}
	dsbdesc.dwBufferBytes = soundBufferTotalLen;
	dsbdesc.lpwfxFormat = &wfx;

	if( FAILED( hr = pDirectSound->CreateSoundBuffer( &dsbdesc, &dsbSecondary, NULL ) ) ) {
		systemMessage( IDS_CANNOT_CREATESOUNDBUFFER, _T("CreateSoundBuffer(secondary) failed %08x"), hr );
		return false;
	}

	if( FAILED( hr = dsbSecondary->SetCurrentPosition( 0 ) ) ) {
		systemMessage( 0, _T("dsbSecondary->SetCurrentPosition failed %08x"), hr );
		return false;
	}


	if( SUCCEEDED( hr = dsbSecondary->QueryInterface( IID_IDirectSoundNotify8, (LPVOID*)&dsbNotify ) ) ) {
		dsbEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
		DSBPOSITIONNOTIFY notify[10];
		for( i = 0; i < 10; i++ ) {
			notify[i].dwOffset = i * soundBufferLen;
			notify[i].hEventNotify = dsbEvent;
		}

		if( FAILED( dsbNotify->SetNotificationPositions( 10, notify ) ) ) {
			dsbNotify->Release();
			dsbNotify = NULL;
			CloseHandle(dsbEvent);
			dsbEvent = NULL;
		}
	}


	// Play primary buffer
	if( FAILED( hr = dsbPrimary->Play( 0, 0, DSBPLAY_LOOPING ) ) ) {
		systemMessage( IDS_CANNOT_PLAY_PRIMARY, _T("Cannot Play primary %08x"), hr );
		return false;
	}

	return true;
}
Exemple #3
0
bool DS_addDeviceRef(signed int deviceID)
{
    HWND ownerWindow;
    HRESULT res = DS_OK;
    LPDIRECTSOUND8 devPlay;
    LPDIRECTSOUNDCAPTURE8 devCapture;
    LPGUID lpGuid = NULL;

    if (g_audioDeviceCache[deviceID].dev == NULL)
    {
        /* Create DirectSound */
        //TRACE1("Creating DirectSound object for device %d\n", deviceID);
        lpGuid = &(g_audioDeviceCache[deviceID].guid);
        if (isEqualGUID(lpGuid, NULL))
        {
            lpGuid = NULL;
        }
        if (g_audioDeviceCache[deviceID].isSource)
        {
#if 0
            //CoInitialize(NULL);
            res = DirectSoundCreate8(lpGuid, &devPlay, NULL);		//生成DirectSound接口对象
#else
            res = CoInitializeEx(NULL, 0);
            res = CoCreateInstance(CLSID_DirectSound8,
                NULL,
                CLSCTX_INPROC_SERVER,
                IID_IDirectSound8,
                (LPVOID*)&devPlay);
            devPlay->Initialize(NULL);
#endif

            g_audioDeviceCache[deviceID].dev = (void*) devPlay;
        }
        else
        {
            res = DirectSoundCaptureCreate8(lpGuid, &devCapture, NULL);
            g_audioDeviceCache[deviceID].dev = (void*) devCapture;
        }
        g_audioDeviceCache[deviceID].refCount = 0;
        if (FAILED(res))
        {
            ERROR1("DS_addDeviceRef: ERROR: Failed to create DirectSound: %s", TranslateDSError(res));
            g_audioDeviceCache[deviceID].dev = NULL;
            return false;
        }
        if (g_audioDeviceCache[deviceID].isSource)
        {
            ownerWindow = GetForegroundWindow();
            if (ownerWindow == NULL)
            {
                ownerWindow = GetDesktopWindow();
            }
            //TRACE0("DS_addDeviceRef: Setting cooperative level\n");
            res = devPlay->SetCooperativeLevel(ownerWindow, DSSCL_PRIORITY);	//设置应用程序对声音设备的合作级别
            if (FAILED(res))
            {
                ERROR1("DS_addDeviceRef: ERROR: Failed to set cooperative level: %s", TranslateDSError(res));
                return false;
            }
        }
    }
    g_audioDeviceCache[deviceID].refCount++;
    return true;
}
int SNDDMA_InitDS ()
{
	HRESULT			hresult;
	DSBUFFERDESC	dsbuf;
	DSBCAPS			dsbcaps;
	WAVEFORMATEX	format;

	Com_Printf( "Initializing DirectSound\n");

    // Create IDirectSound using the primary sound device
    if( FAILED( hresult = DirectSoundCreate8(NULL, &pDS, NULL) ) ) {
		Com_Printf ("failed\n");
		SNDDMA_Shutdown ();
		return false;
	}

	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 false;
	}
	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;

	dma.speed = 22050;
	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;
	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->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) {
		Com_Printf( "locked hardware.  ok\n" );
	}
	else {
		// Couldn't get hardware, fallback to software.
		dsbuf.dwFlags = DSBCAPS_LOCSOFTWARE;
		dsbuf.dwFlags |= DSBCAPS_GETCURRENTPOSITION2;
		if (DS_OK != pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) {
			Com_Printf( "failed\n" );
			SNDDMA_Shutdown ();
			return false;
		}
		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 false;
	}

	// get the returned buffer size
	if ( DS_OK != pDSBuf->GetCaps (&dsbcaps) ) {
		Com_Printf ("*** GetCaps failed ***\n");
		SNDDMA_Shutdown ();
		return false;
	}
	
	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;
}