static int InitDSound(HWND hWnd) { HRESULT hr; pDirectSoundCreate8 SoundCreate; dsoundDLL = LoadLibrary("dsound.dll"); if (dsoundDLL == NULL) { WriteLog("not find dsound.dll"); } SoundCreate = (pDirectSoundCreate8)GetProcAddress(dsoundDLL, "DirectSoundCreate8"); hr = SoundCreate(NULL, &lpDS, NULL); if (FAILED(hr)) { goto end; } hr = lpDS->SetCooperativeLevel(hWnd, DSSCL_PRIORITY); if (FAILED(hr)) { goto end; } DSBUFFERDESC desc; ZeroMemory(&desc,sizeof(DSBUFFERDESC)); desc.dwSize = sizeof(DSBUFFERDESC); desc.dwFlags = DSBCAPS_PRIMARYBUFFER; hr = lpDS->CreateSoundBuffer(&desc, &lpDSP, NULL); if (FAILED(hr)) { goto end; } WriteLog("init sound\n"); return 1; end: return 0; }
bool Dsoundinit( HWND hwnd ) { // SBArrの初期化 initSBArr(); // DirectSound8 の作成 if (FAILED(DirectSoundCreate8(NULL,&lpDS,NULL))) { MessageBox(NULL,"DirectSound オブジェクトの作成に失敗しました。","DirectSoundエラー",MB_OK | MB_ICONSTOP); return false; } // DirectSound の協調レベルを設定 if (FAILED(lpDS->SetCooperativeLevel(hwnd,DSSCL_PRIORITY))) { MessageBox(NULL,"DirectSound の協調レベルの設定に失敗しました。","DirectSoundエラー",MB_OK | MB_ICONSTOP); // 閉じる SendMessage(hwnd,WM_CLOSE,0,0); return false; } // プライマリ サウンドバッファ作成 DSBUFFERDESC desc; ZeroMemory(&desc,sizeof(DSBUFFERDESC)); desc.dwSize = sizeof(DSBUFFERDESC); desc.dwFlags = DSBCAPS_PRIMARYBUFFER; if (FAILED(lpDS->CreateSoundBuffer(&desc,&lpDSP,NULL))) { MessageBox(NULL,"プライマリサウンドバッファの作成に失敗しました。","DirectSoundエラー",MB_OK | MB_ICONSTOP); // 閉じる SendMessage(hwnd,WM_CLOSE,0,0); return false; } //ここまでは一回行えばOKの処理 //SEの数だけセカンダリバッファにデータ読み込み //読み込みファイル名をリストから読み込む initSBFileList(); int nCount; for(nCount = 0;nCount <= SE_MAX - 1;nCount++){ // WAVE ファイルの読み込み // MessageBox(NULL,SBArr[nCount].cSeFileName,"",MB_OK); SBArr[nCount].SB_lpDSB = LoadWave(SBArr[nCount].cSeFileName); //効果音 if (SBArr[nCount].SB_lpDSB == NULL) { MessageBox(NULL,"ファイルの読み込みに失敗しました。","DirectSoundエラー",MB_OK | MB_ICONSTOP); // 閉じる SendMessage(hwnd,WM_CLOSE,0,0); return false; } } return true; }
/* ================= SNDDMA_Activate When we change windows we need to do this ================= */ void SNDDMA_Activate( void ) { if ( !pDS ) { return; } if ( DS_OK != pDS->SetCooperativeLevel( g_wv.hWnd, DSSCL_PRIORITY ) ) { Com_Printf ("sound SetCooperativeLevel failed\n"); SNDDMA_Shutdown (); } }
BOOL InitSound() { DSBUFFERDESC dsbdesc; if (!hWnd) { return true; } if (!lpds) { //Create DirectSound interface if (DirectSoundCreate8(NULL, &lpds, NULL)) { Error("DirectSoundCreate8(NULL, &lpds, NULL)"); return true; } //Set cooperative level if (lpds->SetCooperativeLevel(hWnd, DSSCL_NORMAL)) { Error("lpds->SetCooperativeLevel(hWnd, DSSCL_NORMAL)"); CloseSound(); return true; } } //Get primary buffer and set it to run silently if (!lpdsbPrimary) { ZeroMemory(&dsbdesc, sizeof(dsbdesc)); dsbdesc.dwSize = sizeof(dsbdesc); dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; if (lpds->CreateSoundBuffer(&dsbdesc, &lpdsbPrimary, NULL)) { Error("lpds->CreateSoundBuffer(&dsbdesc, &lpdsbPrimary, NULL)"); CloseSound(); return true; } if (lpdsbPrimary->Play(0, 0, DSBPLAY_LOOPING)) { Error("lpdsbPrimary->Play(0, 0, DSBPLAY_LOOPING)"); CloseSound(); return true; } } Settings.SoundEnabled = true; return false; }
/******************************************************************* * initDirectSound * Initializes DirectSound *******************************************************************/ bool D3DUtil::initDirectSound(HWND hwnd) { HRESULT hr; hr = DirectSoundCreate8( NULL, &g_pDS, NULL ); if FAILED (hr) return false; // Set DirectSound cooperative level hr = g_pDS->SetCooperativeLevel( hwnd, DSSCL_PRIORITY ); if FAILED ( hr ) return false; return true; }
/** * \brief Initialize audio service. * * Documentation: http://msdn.microsoft.com/en-us/library/windows/desktop/ee416960(v=vs.85).aspx */ bool Main::initAudio() { LPDIRECTSOUND8 pds; HRESULT result = DirectSoundCreate8(NULL, &pds, NULL); if (result != DS_OK) { Platform::error << "DirectSoundCreate8() failed."; return false; } result = pds->SetCooperativeLevel(applicationWindowHandle, DSSCL_NORMAL); if (result != DS_OK) { return false; } return true; }
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; }
/* ================== SNDDMA_Shutdown ================== */ void SNDDMA_Shutdown( void ) { Com_DPrintf( "Shutting down sound system\n" ); if ( pDS ) { Com_DPrintf( "Destroying DS buffers\n" ); if ( pDS ) { Com_DPrintf( "...setting NORMAL coop level\n" ); pDS->SetCooperativeLevel( g_wv.hWnd, DSSCL_PRIORITY ); } if ( pDSBuf ) { Com_DPrintf( "...stopping and releasing sound buffer\n" ); pDSBuf->Stop(); pDSBuf->Release(); } // only release primary buffer if it's not also the mixing buffer we just released if ( pDSPBuf && ( pDSBuf != pDSPBuf ) ) { Com_DPrintf( "...releasing primary buffer\n" ); pDSPBuf->Release(); } pDSBuf = NULL; pDSPBuf = NULL; dma.buffer = NULL; Com_DPrintf( "...releasing DS object\n" ); pDS->Release(); } if ( hInstDS ) { Com_DPrintf( "...freeing DSOUND.DLL\n" ); FreeLibrary( hInstDS ); hInstDS = NULL; } pDS = NULL; pDSBuf = NULL; pDSPBuf = NULL; dsound_init = false; memset ((void *)&dma, 0, sizeof (dma)); CoUninitialize( ); }
BOOL ApplicationCreateWritePrimaryBuffer( LPDIRECTSOUND8 lpDirectSound, LPDIRECTSOUNDBUFFER8 *lplpDsb, LPDWORD lpdwBufferSize, HWND hwnd ){ DSBUFFERDESC dsbdesc; DSBCAPS dsbcaps; HRESULT hr; WAVEFORMATEX wf; memset(&wf, 0, sizeof(WAVEFORMATEX)); wf.wFormatTag = WAVE_FORMAT_PCM; wf.nChannels = 2; wf.nSamplesPerSec = 22050; wf.nBlockAlign = 4; wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign; wf.wBitsPerSample = 16; memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; //缓存大小由声音硬件返回 dsbdesc.dwBufferBytes = 0; dsbdesc.lpwfxFormat = NULL;//对于主缓存来说必须是NULL //得到写数据协作权限 hr = lpDirectSound->SetCooperativeLevel(hwnd, DSSCL_WRITEPRIMARY); if (SUCCEEDED(hr)){ hr = lpDirectSound->CreateSoundBuffer(&dsbdesc, lplpDsb, NULL); if (SUCCEEDED(hr)){ hr = (*lplpDsb)->SetFormat(&wf); if (SUCCEEDED(hr)){ dsbcaps.dwSize = sizeof(DSBCAPS); (*lplpDsb)->GetCaps(&dsbcaps); *lpdwBufferSize = dsbcaps.dwBufferBytes; return TRUE; } } } //失败 *lplpDsb = NULL; *lpdwBufferSize = 0; return FALSE; }
CString COggDlg::init(HWND hwnd,int sm) { DirectSoundCreate8(NULL,&m_ds,NULL); if(m_ds==NULL) return _T("DirectSoundを生成できません。\nDirectX7が正常にインストールされているか確認してください。"); if(m_ds->SetCooperativeLevel(hwnd,DSSCL_PRIORITY)!=DS_OK){ return _T("DirectSoundの強調レベルを設定できません。\nDirectX7が正常にインストールされているか確認してください。"); } hw=0; // ZeroMemory(&d,sizeof(d));d.dwSize=sizeof(d);HRESULT r =m_ds->GetCaps(&d); // if(r!=DS_OK){ // return "DirectSoundの情報を獲得出来ません。\nDirectX7が正常にインストールされているか確認してください。"; // } // if(d.dwFlags & (DSCAPS_SECONDARYSTEREO|DSCAPS_PRIMARYSTEREO |DSCAPS_PRIMARY16BIT) && d.dwFreeHwMemBytes!=0){ // hw=DSBCAPS_LOCHARDWARE; // }::timeSetEvent m_p=NULL; DSBUFFERDESC dss; ZeroMemory(&dss,sizeof(dss)); dss.dwSize=sizeof(dss); // dss.dwFlags=DSBCAPS_CTRL3D | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_CTRLFREQUENCY|DSBCAPS_PRIMARYBUFFER|hw; dss.dwFlags=DSBCAPS_PRIMARYBUFFER; dss.lpwfxFormat=NULL; dss.dwBufferBytes=0; if(m_ds->CreateSoundBuffer(&dss,&m_p,NULL)!=DS_OK){ return _T("DirectSoundのプライマリバッファを生成できません。\nDirectX7が正常にインストールされているか確認してください。"); } if(m_p!=NULL){ // //PCMWAVEFORMAT p; WAVEFORMATEX p; ZeroMemory(&p,sizeof(p)); p.wFormatTag=WAVE_FORMAT_PCM; p.nChannels= wavch; p.nSamplesPerSec= wavbit; p.wBitsPerSample = wavsam; p.nBlockAlign = p.nChannels * p.wBitsPerSample / 8; p.nAvgBytesPerSec = p.nSamplesPerSec * p.nBlockAlign; p.cbSize = 0; m_p->SetFormat(&p); } //m_p->QueryInterface(IID_IDirectSound3DListener, (LPVOID*)&m_listener); //m_listener->SetPosition(0.0f, 0.0f, 0.0f, DS3D_IMMEDIATE); return _T(""); }
/* ** DS_DestroyBuffers */ static void DS_DestroyBuffers( void ) { Com_Printf( "Destroying DirectSound 8 buffers\n" ); if ( pDS ) { Com_Printf( "...setting NORMAL coop level\n" ); #ifdef QDSNDCOMPILERHACK pDS->lpVtbl->SetCooperativeLevel( pDS, cl_hwnd, DSSCL_NORMAL ); #else pDS->SetCooperativeLevel(cl_hwnd, DSSCL_NORMAL); #endif } if ( pDSBuf ) { Com_Printf( "...stopping and releasing secondary buffer\n" ); #ifdef QDSNDCOMPILERHACK pDSBuf->lpVtbl->Stop(pDSBuf); pDSBuf->lpVtbl->Release(pDSBuf); #else pDSBuf->Stop(); pDSBuf->Release(); #endif } // only release primary buffer if it's not also the mixing buffer we just released if ( pDSPBuf && ( pDSBuf != pDSPBuf ) ) { Com_Printf( "...releasing primary buffer\n" ); #ifdef QDSNDCOMPILERHACK pDSPBuf->lpVtbl->Stop(pDSPBuf); pDSPBuf->lpVtbl->Release(pDSPBuf); #else pDSPBuf->Stop(); pDSPBuf->Release(); #endif } pDSBuf = NULL; pDSPBuf = NULL; dma.buffer = NULL; }
void InitDSound() { int seconds = 1; DirectSoundCreate8(NULL, &ds8, NULL); ds8->SetCooperativeLevel(window.getWindowHwnd(), DSSCL_NORMAL); waveFormat.wFormatTag = WAVE_FORMAT_PCM; waveFormat.nChannels = 1; waveFormat.nSamplesPerSec = 44100; waveFormat.wBitsPerSample = 16; waveFormat.nBlockAlign = (waveFormat.wBitsPerSample/8)*waveFormat.nChannels; waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; waveFormat.cbSize = 0; memset(&bufdesc, 0, sizeof(DSBUFFERDESC)); bufdesc.dwSize = sizeof(DSBUFFERDESC); bufdesc.dwFlags = DSBCAPS_STATIC | DSBCAPS_GLOBALFOCUS; bufdesc.dwBufferBytes = waveFormat.nAvgBytesPerSec * seconds; bufdesc.guid3DAlgorithm = GUID_NULL; bufdesc.lpwfxFormat = &waveFormat; }
void DXAudioOutput::run() { HRESULT hr; DSBUFFERDESC dsbdesc; WAVEFORMATEXTENSIBLE wfx; WAVEFORMATEXTENSIBLE wfxSet; int ns = 0; unsigned int chanmasks[32]; LPDIRECTSOUND8 pDS = NULL; LPDIRECTSOUNDBUFFER pDSBPrimary = NULL; LPDIRECTSOUNDBUFFER pDSBOutput = NULL; LPDIRECTSOUNDNOTIFY8 pDSNotify = NULL; DWORD dwBufferSize; DWORD dwLastWritePos; DWORD dwLastPlayPos; DWORD dwTotalPlayPos; int iLastwriteblock; LPVOID aptr1, aptr2; DWORD nbytes1, nbytes2; int playblock; int nowriteblock; DWORD dwPlayPosition, dwWritePosition; unsigned int iByteSize; bool bOk; DWORD dwSpeakerConfig; bool failed = false; bOk = false; DWORD dwMask = 0; bool bHead = false; ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; if (! g.s.qbaDXOutput.isEmpty()) { LPGUID lpguid = reinterpret_cast<LPGUID>(g.s.qbaDXOutput.data()); if (FAILED(hr = DirectSoundCreate8(lpguid, &pDS, NULL))) { failed = true; } } if (! pDS && FAILED(hr = DirectSoundCreate8(&DSDEVID_DefaultVoicePlayback, &pDS, NULL))) { qWarning("DXAudioOutput: DirectSoundCreate failed: hr=0x%08lx", hr); goto cleanup; } else if (FAILED(hr = pDS->SetCooperativeLevel(g.mw->winId(), DSSCL_PRIORITY))) { qWarning("DXAudioOutput: SetCooperativeLevel failed: hr=0x%08lx", hr); goto cleanup; } else if (FAILED(hr = pDS->CreateSoundBuffer(&dsbdesc, &pDSBPrimary, NULL))) { qWarning("DXAudioOutput: CreateSoundBuffer (Primary) failed: hr=0x%08lx", hr); goto cleanup; } pDS->GetSpeakerConfig(&dwSpeakerConfig); switch (DSSPEAKER_CONFIG(dwSpeakerConfig)) { case DSSPEAKER_HEADPHONE: dwMask = KSAUDIO_SPEAKER_STEREO; bHead = true; break; case DSSPEAKER_MONO: dwMask = KSAUDIO_SPEAKER_MONO; break; case DSSPEAKER_QUAD: dwMask = KSAUDIO_SPEAKER_QUAD; break; case DSSPEAKER_STEREO: dwMask = KSAUDIO_SPEAKER_STEREO; break; case DSSPEAKER_SURROUND: dwMask = KSAUDIO_SPEAKER_SURROUND; break; case DSSPEAKER_5POINT1: dwMask = KSAUDIO_SPEAKER_5POINT1; break; case DSSPEAKER_7POINT1: dwMask = KSAUDIO_SPEAKER_7POINT1; break; case DSSPEAKER_7POINT1_SURROUND: dwMask = KSAUDIO_SPEAKER_7POINT1_SURROUND; break; case DSSPEAKER_5POINT1_SURROUND: dwMask = KSAUDIO_SPEAKER_5POINT1_SURROUND; break; default: dwMask = 0; break; } if (! g.s.doPositionalAudio()) dwMask = KSAUDIO_SPEAKER_MONO; for (int i=0;i<32;i++) { if (dwMask & (1 << i)) { chanmasks[ns++] = 1 << i; } } iMixerFreq = SAMPLE_RATE; iChannels = ns; eSampleFormat = SampleShort; iByteSize = iFrameSize * sizeof(short) * ns; ZeroMemory(&wfxSet, sizeof(wfxSet)); wfxSet.Format.wFormatTag = WAVE_FORMAT_PCM; ZeroMemory(&wfx, sizeof(wfx)); wfx.Format.wFormatTag = WAVE_FORMAT_PCM; wfx.Format.nChannels = qMax(ns, 1); wfx.Format.nSamplesPerSec = SAMPLE_RATE; wfx.Format.nBlockAlign = sizeof(short) * wfx.Format.nChannels; wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign; wfx.Format.wBitsPerSample = 16; if (FAILED(hr = pDSBPrimary->SetFormat(reinterpret_cast<WAVEFORMATEX *>(&wfx)))) { qWarning("DXAudioOutput: SetFormat failed: hr=0x%08lx", hr); goto cleanup; } if (FAILED(hr = pDSBPrimary->GetFormat(reinterpret_cast<WAVEFORMATEX *>(&wfxSet), sizeof(wfxSet), NULL))) { qWarning("DXAudioOutput: GetFormat failed: hr=0x%08lx", hr); goto cleanup; } qWarning("DXAudioOutput: Primary buffer of %ld Hz, %d channels, %d bits",wfxSet.Format.nSamplesPerSec,wfxSet.Format.nChannels,wfxSet.Format.wBitsPerSample); ZeroMemory(&wfx, sizeof(wfx)); wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfx.Format.nChannels = ns; wfx.Format.nSamplesPerSec = SAMPLE_RATE; wfx.Format.nBlockAlign = sizeof(short) * wfx.Format.nChannels; wfx.Format.nAvgBytesPerSec = wfx.Format.nSamplesPerSec * wfx.Format.nBlockAlign; wfx.Format.wBitsPerSample = 16; wfx.Format.cbSize = 32; wfx.Samples.wValidBitsPerSample = wfx.Format.wBitsPerSample; wfx.dwChannelMask = dwMask; wfx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; ZeroMemory(&dsbdesc, sizeof(DSBUFFERDESC)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2; dsbdesc.dwFlags |= DSBCAPS_CTRLPOSITIONNOTIFY; dsbdesc.dwBufferBytes = wfx.Format.nChannels * iFrameSize * sizeof(short) * NBLOCKS; dsbdesc.lpwfxFormat = reinterpret_cast<WAVEFORMATEX *>(&wfx); if (FAILED(hr = pDS->CreateSoundBuffer(&dsbdesc, &pDSBOutput, NULL))) { qWarning("DXAudioOutputUser: CreateSoundBuffer (Secondary) failed: hr=0x%08lx", hr); goto cleanup; } if (FAILED(hr = pDSBOutput->QueryInterface(IID_IDirectSoundNotify, reinterpret_cast<void **>(&pDSNotify)))) { qWarning("DXAudioOutputUser: QueryInterface (Notify) failed: hr=0x%08lx", hr); goto cleanup; } qWarning("DXAudioOutputUser: New %dHz output buffer of %ld bytes", SAMPLE_RATE, dsbdesc.dwBufferBytes); if (failed) g.mw->msgBox(tr("Opening chosen DirectSound Output failed. Default device will be used.")); initializeMixer(chanmasks, bHead); if (FAILED(hr = pDSBOutput->Lock(0, 0, &aptr1, &nbytes1, &aptr2, &nbytes2, DSBLOCK_ENTIREBUFFER))) { qWarning("DXAudioOutputUser: Initial Lock failed: hr=0x%08lx", hr); goto cleanup; } dwBufferSize = nbytes1 + nbytes2; if (aptr1) ZeroMemory(aptr1, nbytes1); if (aptr2) ZeroMemory(aptr2, nbytes2); if (FAILED(hr = pDSBOutput->Unlock(aptr1, nbytes1, aptr2, nbytes2))) { qWarning("DXAudioOutputUser: Initial Unlock failed: hr=0x%08lx", hr); goto cleanup; } if (FAILED(hr = pDSBOutput->Play(0, 0, DSBPLAY_LOOPING))) { qWarning("DXAudioOutputUser: Play failed: hr=0x%08lx", hr); goto cleanup; } dwLastWritePos = 0; dwLastPlayPos = 0; dwTotalPlayPos = 0; iLastwriteblock = (NBLOCKS - 1 + g.s.iOutputDelay) % NBLOCKS; bOk = true; while (bRunning && ! FAILED(hr)) { if (FAILED(hr = pDSBOutput->GetCurrentPosition(&dwPlayPosition, &dwWritePosition))) { qWarning("DXAudioOutputUser: GetCurrentPosition failed: hr=0x%08lx", hr); break; } playblock = dwWritePosition / iByteSize; nowriteblock = (playblock + g.s.iOutputDelay + 1) % NBLOCKS; for (int block=(iLastwriteblock + 1) % NBLOCKS;(!FAILED(hr)) && (block!=nowriteblock);block=(block + 1) % NBLOCKS) { iLastwriteblock = block; if (FAILED(hr = pDSBOutput->Lock(block * iByteSize, iByteSize, &aptr1, &nbytes1, &aptr2, &nbytes2, 0))) { qWarning("DXAudioOutput: Lock block %u (%d bytes) failed: hr=0x%08lx",block, iByteSize, hr); break; } if (aptr2 || nbytes2) { qWarning("DXAudioOutput: Split buffer"); break; } if (!aptr1 || ! nbytes1) { qWarning("DXAudioOutput: Zerolock"); break; } if (! mix(reinterpret_cast<short *>(aptr1), iFrameSize)) ZeroMemory(aptr1, iByteSize); if (FAILED(hr = pDSBOutput->Unlock(aptr1, nbytes1, aptr2, nbytes2))) { qWarning("DXAudioOutput: Unlock %p(%lu) %p(%lu) failed: hr=0x%08lx",aptr1,nbytes1,aptr2,nbytes2,hr); break; } if (FAILED(hr = pDSBOutput->GetCurrentPosition(&dwPlayPosition, &dwWritePosition))) { qWarning("DXAudioOutputUser: GetCurrentPosition failed: hr=0x%08lx", hr); break; } playblock = dwWritePosition / iByteSize; nowriteblock = (playblock + g.s.iOutputDelay + 1) % NBLOCKS; } if (! FAILED(hr)) msleep(19); } if (FAILED(hr)) { g.mw->msgBox(tr("Lost DirectSound output device.")); } cleanup: if (! bOk) { g.mw->msgBox(tr("Opening chosen DirectSound Output failed. No audio will be heard.")); return; } if (pDSNotify) pDSNotify->Release(); if (pDSBOutput) { pDSBOutput->Stop(); pDSBOutput->Release(); } if (pDSBPrimary) pDSBPrimary->Release(); if (pDS) pDS->Release(); }
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; }
/* ** DS_CreateBuffers */ static int DS_CreateBuffers( void ) { 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 = 0; format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; Com_Printf( "Creating DirectSound 8 buffers\n" ); Com_Printf("...setting PRIORITY coop level: " ); #ifdef QDSNDCOMPILERHACK if ( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, cl_hwnd, DSSCL_PRIORITY ) ) #else if ( DS_OK != pDS->SetCooperativeLevel( cl_hwnd, DSSCL_PRIORITY ) ) #endif { Com_Printf ("failed\n"); FreeSound (); return 0; } Com_Printf("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; // | DSBCAPS_CTRL3D; dsbuf.dwBufferBytes = 0; dsbuf.lpwfxFormat = NULL; memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); primary_format_set = 0; if (!pDSPBuf) { Com_Printf( "...creating primary buffer: " ); #ifdef QDSNDCOMPILERHACK if (DS_OK == pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSPBuf, NULL)) #else if (DS_OK == pDS->CreateSoundBuffer(&dsbuf, &pDSPBuf, NULL)) #endif { pformat = format; Com_Printf( "ok\n" ); #ifdef QDSNDCOMPILERHACK if (DS_OK != pDSPBuf->lpVtbl->SetFormat (pDSPBuf, &pformat)) #else if (DS_OK != pDSPBuf->SetFormat (&pformat)) #endif { if (snd_firsttime) Com_Printf ("...setting primary sound format: failed\n"); } else { if (snd_firsttime) Com_Printf ("...setting primary sound format: ok\n"); primary_format_set = 1; } } else Com_Printf( "failed\n" ); } if ( !primary_format_set || !s_primary->value) { // create the secondary buffer we'll actually work with memset (&dsbuf, 0, sizeof(DSBUFFERDESC)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCHARDWARE; //| DSBCAPS_MUTE3DATMAXDISTANCE; // | DSBCAPS_CTRL3D; //dsbuf.dwFlags |= DSBCAPS_CTRLVOLUME; // Allow volume control //dsbuf.dwBufferBytes = format.nAvgBytesPerSec * SECONDARY_BUFFER_LEN_SECONDS; dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE * s_buffersize->value; dsbuf.lpwfxFormat = &format; //dsbuf.guid3DAlgorithm = DS3DALG_DEFAULT; //dsbuf.guid3DAlgorithm = DS3DALG_HRTF_FULL; // Use high quality 3D processing memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); Com_Printf( "...creating secondary buffer: " ); //pDSPBuf->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*) pDSBuf); //myDirectSoundIID = &IID_IDirectSoundBuffer8; //pDSPBuf->lpVtbl->QueryInterface(pDSPBuf, myDirectSoundIID, &pDSBuf); if (!pDSBuf) { //MessageBox (NULL, "Got Here!\n\n", "Quake II", MB_OK | MB_SETFOREGROUND | MB_ICONEXCLAMATION); #ifdef QDSNDCOMPILERHACK if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) #else if (DS_OK != pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) #endif //if (DS_OK != pDSPBuf->lpVtbl->QueryInterface(pDSPBuf, myDirectSoundIID, &pDSBuf)) { Com_Printf( "failed\n" ); Com_Printf( "Attempting to locate buffer in software...\n"); dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCSOFTWARE; //pDSBuf->lpVtbl->Release(pDSBuf); pDSBuf = NULL; #ifdef QDSNDCOMPILERHACK if (DS_OK != pDS->lpVtbl->CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL)) #else if (DS_OK != pDS->CreateSoundBuffer(&dsbuf, &pDSBuf, NULL)) #endif //if (DS_OK != pDSPBuf->lpVtbl->QueryInterface(pDSPBuf, myDirectSoundIID, &pDSBuf)) { // NeVo - try switching to primary s_primary->value = 1; Com_Printf( "failed\n" ); Com_Printf( "Attempting fallback to primary buffer...\n"); //pDSBuf->lpVtbl->Release(pDSBuf); pDSBuf = NULL; return DS_CreateBuffers(); //FreeSound (); //return 0; } Com_Printf( "ok\n" ); Com_Printf( "Sound Buffer in Software\n" ); } else { Com_Printf( "ok\n" ); Com_Printf( "Sound Buffer in Hardware\n" ); } } dma.channels = format.nChannels; dma.samplebits = format.wBitsPerSample; dma.speed = format.nSamplesPerSec; #ifdef QDSNDCOMPILERHACK if (DS_OK != pDSBuf->lpVtbl->GetCaps (pDSBuf, &dsbcaps)) #else if (DS_OK != pDSBuf->GetCaps (&dsbcaps)) #endif { Com_Printf ("*** GetCaps failed ***\n"); FreeSound (); return 0; } Com_Printf ("...using secondary sound buffer\n"); } else { Com_Printf( "...using primary buffer\n" ); Com_Printf( "...setting WRITEPRIMARY coop level: " ); #ifdef QDSNDCOMPILERHACK if (DS_OK != pDS->lpVtbl->SetCooperativeLevel (pDS, cl_hwnd, DSSCL_WRITEPRIMARY)) #else if (DS_OK != pDS->SetCooperativeLevel (cl_hwnd, DSSCL_WRITEPRIMARY)) #endif { Com_Printf( "failed\n" ); FreeSound (); return 0; } Com_Printf( "ok\n" ); #ifdef QDSNDCOMPILERHACK if (DS_OK != pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps)) #else if (DS_OK != pDSPBuf->GetCaps (&dsbcaps)) #endif { Com_Printf ("*** GetCaps failed ***\n"); return 0; } pDSBuf = pDSPBuf; } // Make sure mixer is active //if ( !s_primary->value) #ifdef QDSNDCOMPILERHACK pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); #else pDSBuf->Play (0, 0, DSBPLAY_LOOPING); #endif //else // pDSPBuf->lpVtbl->Play(pDSPBuf, 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; /* we don't want anyone to access the buffer directly w/o locking it first. */ lpData = NULL; //if ( !s_primary->value) //{ #ifdef QDSNDCOMPILERHACK pDSBuf->lpVtbl->Stop(pDSBuf); pDSBuf->lpVtbl->GetCurrentPosition(pDSBuf, &mmstarttime.u.sample, &dwWrite); pDSBuf->lpVtbl->Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); #else pDSBuf->Stop(); pDSBuf->GetCurrentPosition(&mmstarttime.u.sample, &dwWrite); pDSBuf->Play(0, 0, DSBPLAY_LOOPING); #endif //} //else //{ // pDSPBuf->lpVtbl->Stop(pDSPBuf); // pDSPBuf->lpVtbl->GetCurrentPosition(pDSPBuf, &mmstarttime.u.sample, &dwWrite); // pDSPBuf->lpVtbl->Play(pDSPBuf, 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 1; }
int main() { using namespace flamenco; LPDIRECTSOUND8 directSound; // Создаем интерфейс DirectSound. check_directx(DirectSoundCreate8(&GUID_NULL, &directSound, NULL)); check_directx(directSound->SetCooperativeLevel(GetForegroundWindow(), DSSCL_PRIORITY)); // Получаем первичный буфер. LPDIRECTSOUNDBUFFER primaryBuffer = NULL; DSBUFFERDESC descr; ZeroMemory(&descr, sizeof(DSBUFFERDESC)); descr.dwSize = sizeof(DSBUFFERDESC); descr.dwFlags = DSBCAPS_PRIMARYBUFFER; descr.lpwfxFormat = NULL; check_directx(directSound->CreateSoundBuffer(&descr, &primaryBuffer, NULL)); // Изменяем формат первичного буфера. WAVEFORMATEX wfx; ZeroMemory(&wfx, sizeof(WAVEFORMATEX)); wfx.cbSize = sizeof(WAVEFORMATEX); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 2; wfx.nSamplesPerSec = FREQUENCY; wfx.wBitsPerSample = 16; wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels; wfx.nAvgBytesPerSec = (u32)wfx.nSamplesPerSec * wfx.nBlockAlign; check_directx(primaryBuffer->SetFormat(&wfx)); primaryBuffer->Release(); // Формат буфера микшера. const u32 MIXER_BUFFER_SIZE_IN_BYTES = MIXER_BUFFER_SIZE_IN_SAMPLES * sizeof(s16); // Размер звукового буфера должен быть больше 100 ms, иначе GetCurrentPosition() // будет выдавать неправильные данные. const u32 SOUND_BUFFER_SIZE_IN_BYTES = 10 * MIXER_BUFFER_SIZE_IN_BYTES; DSBUFFERDESC desc; ZeroMemory(&desc, sizeof(DSBUFFERDESC)); desc.dwSize = sizeof(DSBUFFERDESC); desc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; desc.dwBufferBytes = SOUND_BUFFER_SIZE_IN_BYTES; desc.guid3DAlgorithm = DS3DALG_DEFAULT; desc.lpwfxFormat = &wfx; // Создаем буфер. LPDIRECTSOUNDBUFFER soundBuffer = NULL; check_directx(directSound->CreateSoundBuffer(&desc, &soundBuffer, NULL)); //reference<stream<ogg_decoder> > sound = stream<ogg_decoder>::create(std::auto_ptr<source>(new file_source("input.ogg"))); // Инициализация flamenco. mixer & mixer = mixer::singleton(); reference<sound_stream_base> sound = stream<wavpack_decoder>::create(std::auto_ptr<source>(new file_source("input.wv"))); //assert(!src.get()); mixer.attach(sound); /* reference<pin> sine = sine::create(400); reference<ogg> wave = ogg::create("input.ogg"); reference<pin> noise = noise::create(); reference<volume_pan> vp = volume_pan::create(sound, 1.0f, 0.0f); //mixer.attach(sine); mixer.attach(vp); //mixer.attach(noise); */ // Заполнение звукового буфера. s16 * bufferPtr; u32 bufferSize; check_directx(soundBuffer->Lock(0, 0, reinterpret_cast<void **>(&bufferPtr), &bufferSize, NULL, NULL, DSBLOCK_ENTIREBUFFER)); // Заполняем обе половинки буфера. mixer.mix(bufferPtr); mixer.mix(bufferPtr + MIXER_BUFFER_SIZE_IN_SAMPLES); check_directx(soundBuffer->Unlock(bufferPtr, bufferSize, NULL, 0)); // Проигрываем звук и дописываем данные по ходу. soundBuffer->Play(0, 0, DSBPLAY_LOOPING); u32 writeOffset = MIXER_BUFFER_SIZE_IN_BYTES * 2; while (true) { u32 cursorPos; soundBuffer->GetCurrentPosition(&cursorPos, NULL); // Определяем, нужно ли дописать очередную порцию данных. u32 offset = (SOUND_BUFFER_SIZE_IN_BYTES + writeOffset - cursorPos) % SOUND_BUFFER_SIZE_IN_BYTES; if (offset > MIXER_BUFFER_SIZE_IN_BYTES) { check_directx(soundBuffer->Lock(writeOffset, MIXER_BUFFER_SIZE_IN_BYTES, reinterpret_cast<void **>(&bufferPtr), &bufferSize, NULL, NULL, 0)); mixer.mix(bufferPtr); check_directx(soundBuffer->Unlock(bufferPtr, bufferSize, NULL, 0)); writeOffset = (writeOffset + MIXER_BUFFER_SIZE_IN_BYTES) % SOUND_BUFFER_SIZE_IN_BYTES; } // Не нужно опрашивать GetCurrentPosition() слишком часто. Sleep(LATENCY_MSEC >> 1); if (_kbhit()) { switch (_getch()) { case '+': //vp->pan.set(vp->pan() + 0.1f); continue; case '-': //vp->pan.set(vp->pan() - 0.1f); continue; case 'l': sound->looping.set(!sound->looping()); continue; } // Если нажата любая другая клавиша - выходим. break; } } // Освобождение ресурсов. soundBuffer->Release(); directSound->Release(); }
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 SNDDXInit(int buffersize) { DSBUFFERDESC dsbdesc; WAVEFORMATEX wfx; HRESULT ret; char tempstr[512]; if (FAILED(ret = DirectSoundCreate8(NULL, &lpDS8, NULL))) { sprintf(tempstr, "DirectSound8Create error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION); return -1; } if (FAILED(ret = lpDS8->SetCooperativeLevel(MainWindow->getHWnd(), DSSCL_PRIORITY))) { sprintf(tempstr, "IDirectSound8_SetCooperativeLevel error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION); return -1; } memset(&dsbdesc, 0, sizeof(dsbdesc)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbdesc.dwBufferBytes = 0; dsbdesc.lpwfxFormat = NULL; if (FAILED(ret = lpDS8->CreateSoundBuffer(&dsbdesc, &lpDSB, NULL))) { sprintf(tempstr, "Error when creating primary sound buffer: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION); return -1; } soundbufsize = buffersize * 2; // caller already multiplies buffersize by 2 soundoffset = 0; memset(&wfx, 0, sizeof(wfx)); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 2; wfx.nSamplesPerSec = DESMUME_SAMPLE_RATE; wfx.wBitsPerSample = 16; wfx.nBlockAlign = (wfx.wBitsPerSample / 8) * wfx.nChannels; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; if (FAILED(ret = lpDSB->SetFormat(&wfx))) { sprintf(tempstr, "IDirectSoundBuffer8_SetFormat error: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION); return -1; } memset(&dsbdesc, 0, sizeof(dsbdesc)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_STICKYFOCUS | DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCHARDWARE; dsbdesc.dwBufferBytes = soundbufsize; dsbdesc.lpwfxFormat = &wfx; if (FAILED(ret = lpDS8->CreateSoundBuffer(&dsbdesc, &lpDSB2, NULL))) { if (ret == DSERR_CONTROLUNAVAIL || ret == DSERR_INVALIDCALL || ret == E_FAIL || ret == E_NOTIMPL) { // Try using a software buffer instead dsbdesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_STICKYFOCUS | DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCSOFTWARE; if (FAILED(ret = lpDS8->CreateSoundBuffer(&dsbdesc, &lpDSB2, NULL))) { sprintf(tempstr, "Error when creating secondary sound buffer: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION); return -1; } } else { sprintf(tempstr, "Error when creating secondary sound buffer: %s - %s", DXGetErrorString8(ret), DXGetErrorDescription8(ret)); MessageBox (NULL, tempstr, "Error", MB_OK | MB_ICONINFORMATION); return -1; } } lpDSB2->Play(0, 0, DSBPLAY_LOOPING); if ((stereodata16 = new s16[soundbufsize / sizeof(s16)]) == NULL) return -1; memset(stereodata16, 0, soundbufsize); soundvolume = DSBVOLUME_MAX; issoundmuted = 0; doterminate = false; terminated = false; CreateThread(0,0,SNDDXThread,0,0,0); return 0; }
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; }