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