bool DSoundAudioBackend::CreateBuffer() { PCMWAVEFORMAT pcmwf; DSBUFFERDESC dsbdesc; memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); bufferSize_ = BUFSIZE; pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; pcmwf.wf.nChannels = 2; pcmwf.wf.nSamplesPerSec = sampleRate_; pcmwf.wf.nBlockAlign = 4; pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; pcmwf.wBitsPerSample = 16; dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; // //DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; dsbdesc.dwBufferBytes = bufferSize_; //FIX32(pcmwf.wf.nAvgBytesPerSec); //change to set buffer size dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&pcmwf; if (SUCCEEDED(ds_->CreateSoundBuffer(&dsbdesc, &dsBuffer_, NULL))) { dsBuffer_->SetCurrentPosition(0); return true; } else { dsBuffer_ = NULL; return false; } }
bool VDAudioOutputDirectSoundW32::InitPlayback() { tWAVEFORMATEX *wf = &*mInitFormat; mMillisecsPerByte = 1000.0 * (double)wf->nBlockAlign / (double)wf->nAvgBytesPerSec; // create looping secondary buffer DSBUFFERDESC dsd={sizeof(DSBUFFERDESC)}; dsd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; dsd.dwBufferBytes = mDSBufferSize; dsd.lpwfxFormat = (WAVEFORMATEX *)wf; dsd.guid3DAlgorithm = DS3DALG_DEFAULT; IDirectSoundBuffer *pDSB; HRESULT hr = mpDS8->CreateSoundBuffer(&dsd, &pDSB, NULL); if (FAILED(hr)) { VDDEBUG("VDAudioOutputDirectSound: Failed to create secondary buffer! hr=%08x\n", hr); return false; } // query to IDirectSoundBuffer8 hr = pDSB->QueryInterface(IID_IDirectSoundBuffer8, (void **)&mpDSBuffer); pDSB->Release(); if (FAILED(hr)) { VDDEBUG("VDAudioOutputDirectSound: Failed to obtain IDirectSoundBuffer8 interface! hr=%08x\n", hr); return false; } // all done! mDSWriteCursor = 0; return true; }
s32 Init() { numBuffers = Config_DSoundOut.NumBuffers; // // Initialize DSound // GUID cGuid; try { if( Config_DSoundOut.Device.empty() ) throw std::runtime_error( "screw it" ); // Convert from unicode to ANSI: char guid[256]; sprintf_s( guid, "%S", Config_DSoundOut.Device.c_str() ); if( (FAILED(GUIDFromString( guid, &cGuid ))) || FAILED( DirectSoundCreate8(&cGuid,&dsound,NULL) ) ) throw std::runtime_error( "try again?" ); } catch( std::runtime_error& ) { // if the GUID failed, just open up the default dsound driver: if( FAILED(DirectSoundCreate8(NULL,&dsound,NULL) ) ) throw std::runtime_error( "DirectSound failed to initialize!" ); } if( FAILED(dsound->SetCooperativeLevel(GetDesktopWindow(),DSSCL_PRIORITY)) ) throw std::runtime_error( "DirectSound Error: Cooperative level could not be set." ); // Determine the user's speaker configuration, and select an expansion option as needed. // FAIL : Directsound doesn't appear to support audio expansion >_< DWORD speakerConfig = 2; //dsound->GetSpeakerConfig( &speakerConfig ); IDirectSoundBuffer* buffer_; DSBUFFERDESC desc; // Set up WAV format structure. memset(&wfx, 0, sizeof(WAVEFORMATEX)); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nSamplesPerSec = SampleRate; wfx.nChannels = (WORD)speakerConfig; wfx.wBitsPerSample = 16; wfx.nBlockAlign = 2*(WORD)speakerConfig; wfx.nAvgBytesPerSec = SampleRate * wfx.nBlockAlign; wfx.cbSize = 0; uint BufferSizeBytes = BufferSize * wfx.nBlockAlign; // Set up DSBUFFERDESC structure. memset(&desc, 0, sizeof(DSBUFFERDESC)); desc.dwSize = sizeof(DSBUFFERDESC); desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY;// _CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; desc.dwBufferBytes = BufferSizeBytes * numBuffers; desc.lpwfxFormat = &wfx; desc.dwFlags |= DSBCAPS_LOCSOFTWARE; desc.dwFlags |= DSBCAPS_GLOBALFOCUS; if( FAILED(dsound->CreateSoundBuffer(&desc,&buffer_,0) ) ) throw std::runtime_error( "DirectSound Error: Interface could not be queried." ); if( FAILED(buffer_->QueryInterface(IID_IDirectSoundBuffer8,(void**)&buffer)) ) throw std::runtime_error( "DirectSound Error: Interface could not be queried." ); buffer_->Release(); verifyc( buffer->QueryInterface(IID_IDirectSoundNotify8,(void**)&buffer_notify) ); DSBPOSITIONNOTIFY not[MAX_BUFFER_COUNT]; for(u32 i=0;i<numBuffers;i++) { // [Air] note: wfx.nBlockAlign modifier was *10 -- seems excessive to me but maybe // it was needed for some quirky driver? Theoretically we want the notification as soon // as possible after the buffer has finished playing. buffer_events[i] = CreateEvent(NULL,FALSE,FALSE,NULL); not[i].dwOffset = (wfx.nBlockAlign + BufferSizeBytes*(i+1)) % desc.dwBufferBytes; not[i].hEventNotify = buffer_events[i]; } buffer_notify->SetNotificationPositions(numBuffers,not); LPVOID p1=0,p2=0; DWORD s1=0,s2=0; verifyc(buffer->Lock(0,desc.dwBufferBytes,&p1,&s1,&p2,&s2,0)); assert(p2==0); memset(p1,0,s1); verifyc(buffer->Unlock(p1,s1,p2,s2)); //Play the buffer ! verifyc(buffer->Play(0,0,DSBPLAY_LOOPING)); // Start Thread myLastWrite = 0; dsound_running = true; thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)RThread<StereoOut16>,this,0,&tid); SetThreadPriority(thread,THREAD_PRIORITY_ABOVE_NORMAL); return 0; }
s32 Init() { CoInitializeEx( NULL, COINIT_MULTITHREADED ); // // Initialize DSound // GUID cGuid; try { if( m_Device.empty() ) throw std::runtime_error( "screw it" ); // Convert from unicode to ANSI: char guid[256]; sprintf_s( guid, "%S", m_Device.c_str() ); if( (FAILED(GUIDFromString( guid, &cGuid ))) || FAILED( DirectSoundCreate8(&cGuid,&dsound,NULL) ) ) throw std::runtime_error( "try again?" ); } catch( std::runtime_error& ) { // if the GUID failed, just open up the default dsound driver: if( FAILED(DirectSoundCreate8(NULL,&dsound,NULL) ) ) throw std::runtime_error( "DirectSound failed to initialize!" ); } if( FAILED(dsound->SetCooperativeLevel(GetDesktopWindow(),DSSCL_PRIORITY)) ) throw std::runtime_error( "DirectSound Error: Cooperative level could not be set." ); // Determine the user's speaker configuration, and select an expansion option as needed. // FAIL : Directsound doesn't appear to support audio expansion >_< DWORD speakerConfig = 2; //dsound->GetSpeakerConfig( &speakerConfig ); IDirectSoundBuffer* buffer_; DSBUFFERDESC desc; // Set up WAV format structure. memset(&wfx, 0, sizeof(WAVEFORMATEX)); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nSamplesPerSec = SampleRate; wfx.nChannels = (WORD)speakerConfig; wfx.wBitsPerSample = 16; wfx.nBlockAlign = 2*(WORD)speakerConfig; wfx.nAvgBytesPerSec = SampleRate * wfx.nBlockAlign; wfx.cbSize = 0; uint BufferSizeBytes = BufferSize * wfx.nBlockAlign; // Set up DSBUFFERDESC structure. memset(&desc, 0, sizeof(DSBUFFERDESC)); desc.dwSize = sizeof(DSBUFFERDESC); desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY; desc.dwBufferBytes = BufferSizeBytes * m_NumBuffers; desc.lpwfxFormat = &wfx; // Try a hardware buffer first, and then fall back on a software buffer if // that one fails. desc.dwFlags |= m_UseHardware ? DSBCAPS_LOCHARDWARE : DSBCAPS_LOCSOFTWARE; desc.dwFlags |= m_DisableGlobalFocus ? DSBCAPS_STICKYFOCUS : DSBCAPS_GLOBALFOCUS; if( FAILED(dsound->CreateSoundBuffer(&desc, &buffer_, 0) ) ) { if( m_UseHardware ) { desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE; desc.dwFlags |= m_DisableGlobalFocus ? DSBCAPS_STICKYFOCUS : DSBCAPS_GLOBALFOCUS; if( FAILED(dsound->CreateSoundBuffer(&desc, &buffer_, 0) ) ) throw std::runtime_error( "DirectSound Error: Buffer could not be created." ); } throw std::runtime_error( "DirectSound Error: Buffer could not be created." ); } if( FAILED(buffer_->QueryInterface(IID_IDirectSoundBuffer8,(void**)&buffer)) || buffer == NULL ) throw std::runtime_error( "DirectSound Error: Interface could not be queried." ); buffer_->Release(); verifyc( buffer->QueryInterface(IID_IDirectSoundNotify8,(void**)&buffer_notify) ); DSBPOSITIONNOTIFY not[MAX_BUFFER_COUNT]; for(uint i=0;i<m_NumBuffers;i++) { buffer_events[i] = CreateEvent(NULL,FALSE,FALSE,NULL); not[i].dwOffset = (wfx.nBlockAlign + BufferSizeBytes*(i+1)) % desc.dwBufferBytes; not[i].hEventNotify = buffer_events[i]; } buffer_notify->SetNotificationPositions(m_NumBuffers,not); LPVOID p1=0,p2=0; DWORD s1=0,s2=0; verifyc(buffer->Lock(0,desc.dwBufferBytes,&p1,&s1,&p2,&s2,0)); assert(p2==0); memset(p1,0,s1); verifyc(buffer->Unlock(p1,s1,p2,s2)); //Play the buffer ! verifyc(buffer->Play(0,0,DSBPLAY_LOOPING)); // Start Thread myLastWrite = 0; dsound_running = true; thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)RThread<StereoOut16>,this,0,&tid); SetThreadPriority(thread,THREAD_PRIORITY_ABOVE_NORMAL); return 0; }
HRESULT DemoApp::Initialize() { HRESULT hr; //register window class WNDCLASSEX wcex = { sizeof(WNDCLASSEX) }; wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = DemoApp::WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = sizeof(LONG_PTR); wcex.hInstance = HINST_THISCOMPONENT; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = NULL; wcex.lpszMenuName = NULL; wcex.lpszClassName = L"App"; RegisterClassEx(&wcex); hr = CreateDeviceIndependentResources(); if (SUCCEEDED(hr)) { // Create the application window. m_hwnd = CreateWindow( L"App", L"달걀 채색 공장(201001622 이진용)", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1200, 600, NULL, NULL, HINST_THISCOMPONENT, this ); hr = m_hwnd ? S_OK : E_FAIL; if (SUCCEEDED(hr)) { float length = 0; hr = m_wheelPath->ComputeLength( NULL, //no transform &length ); if (SUCCEEDED(hr) ) { m_Animation.SetStart(0); //start at beginning of path m_Animation.SetEnd(length); //length at end of path m_Animation.SetDuration(5.f ); //seconds ZeroMemory(&m_DwmTimingInfo, sizeof(m_DwmTimingInfo)); m_DwmTimingInfo.cbSize = sizeof(m_DwmTimingInfo); // Get the composition refresh rate. If the DWM isn't running, // get the refresh rate from GDI -- probably going to be 60Hz if (FAILED(DwmGetCompositionTimingInfo(NULL, &m_DwmTimingInfo))) { HDC hdc = GetDC(m_hwnd); m_DwmTimingInfo.rateCompose.uiDenominator = 1; m_DwmTimingInfo.rateCompose.uiNumerator = GetDeviceCaps(hdc, VREFRESH); ReleaseDC(m_hwnd, hdc); } ShowWindow(m_hwnd, SW_SHOWNORMAL); UpdateWindow(m_hwnd); } } if (SUCCEEDED(hr)) { float pLength = 0; hr = m_flyPath->ComputeLength( NULL, //no transform &pLength ); if (SUCCEEDED(hr) ) { m_linearAnimation.SetStart(0); //start at beginning of path m_linearAnimation.SetEnd(pLength); //length at end of path m_linearAnimation.SetDuration(10.f); //seconds ZeroMemory(&m_DwmTimingInfo, sizeof(m_DwmTimingInfo)); m_DwmTimingInfo.cbSize = sizeof(m_DwmTimingInfo); // Get the composition refresh rate. If the DWM isn't running, // get the refresh rate from GDI -- probably going to be 60Hz if (FAILED(DwmGetCompositionTimingInfo(NULL, &m_DwmTimingInfo))) { HDC hdc = GetDC(m_hwnd); m_DwmTimingInfo.rateCompose.uiDenominator = 1; m_DwmTimingInfo.rateCompose.uiNumerator = GetDeviceCaps(hdc, VREFRESH); ReleaseDC(m_hwnd, hdc); } ShowWindow(m_hwnd, SW_SHOWNORMAL); UpdateWindow(m_hwnd); } } } //장치 객체 생성 IDirectSound8* directSound; DirectSoundCreate8(NULL,&directSound, NULL); //협력레벨 지정 directSound->SetCooperativeLevel(m_hwnd,DSSCL_PRIORITY); //주버퍼 포맷 지정 DSBUFFERDESC dsbd; ZeroMemory(&dsbd,sizeof(DSBUFFERDESC) ); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME; dsbd.dwBufferBytes = 0; dsbd.lpwfxFormat = NULL; //IDirectSoundBuffer* pDSBPrimary = NULL; directSound->CreateSoundBuffer(&dsbd, &pDSBPrimary, NULL); WAVEFORMATEX wfx; ZeroMemory(&wfx, sizeof(WAVEFORMATEX) ); wfx.wFormatTag = (WORD)WAVE_FORMAT_PCM; wfx.nChannels =(WORD)2; wfx.nSamplesPerSec = (DWORD)22050; wfx.wBitsPerSample = (WORD)16; wfx.nBlockAlign = (WORD)(wfx.wBitsPerSample / 8 * wfx.nChannels ); wfx.nAvgBytesPerSec = (DWORD)(wfx.nSamplesPerSec * wfx.nBlockAlign ); pDSBPrimary->SetFormat(&wfx); pDSBPrimary->Release(); //2차 버퍼 생성 BGM CWaveFile* pWaveFile = NULL; pWaveFile = new CWaveFile(); pWaveFile->Open( L".\\pokemonCenter.wav", NULL, WAVEFILE_READ ); //DSBUFFERDESC dsbd; ZeroMemory(&dsbd, sizeof(DSBUFFERDESC) ); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = DSBCAPS_CTRLVOLUME; dsbd.guid3DAlgorithm = GUID_NULL; dsbd.lpwfxFormat = pWaveFile->m_pwfx; dsbd.dwBufferBytes = pWaveFile->GetSize(); directSound->CreateSoundBuffer(&dsbd, &pDSBuffer, NULL); //이차버퍼에 데이터 채우기 sound = new CSound(&pDSBuffer, dsbd.dwBufferBytes, 1 , pWaveFile, 0 ); // pDSBuffer 위에 전역변수임 pDSBPrimary->SetVolume(scaledVolume); sound->Play(0,DSBPLAY_LOOPING); soundManager = new CSoundManager; if( ! soundManager->init(m_hwnd) ) return FALSE; int id; if (! soundManager->add(L".\\boss.wav", &id)) //id=0부터 시작함. return FALSE; if (! soundManager->add(L".\\storm.wav",&id)); return hr; }
cstring DirectSound::Buffer::Create(IDirectSound8& device,const bool priority) { Release(); Object::Pod<DSBUFFERDESC> desc; desc.dwSize = sizeof(desc); desc.dwFlags = DSBCAPS_PRIMARYBUFFER; desc.lpwfxFormat = NULL; if (priority) { ComInterface<IDirectSoundBuffer> primary; if (FAILED(device.CreateSoundBuffer( &desc, &primary, NULL )) || FAILED(primary->SetFormat( &waveFormat ))) { static bool logged = false; if (logged == false) { logged = true; Io::Log() << "DirectSound: warning, couldn't set the sample format for the primary sound buffer!\r\n"; } } } NST_ASSERT( settings.size % waveFormat.nBlockAlign == 0 ); desc.Clear(); desc.dwSize = sizeof(desc); desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2; if (settings.globalFocus) desc.dwFlags |= DSBCAPS_GLOBALFOCUS; if (settings.pool == POOL_SYSTEM) desc.dwFlags |= DSBCAPS_LOCSOFTWARE; desc.dwBufferBytes = settings.size; desc.lpwfxFormat = &waveFormat; ComInterface<IDirectSoundBuffer> oldCom; if (FAILED(device.CreateSoundBuffer( &desc, &oldCom, NULL ))) { if (!(desc.dwFlags & DSBCAPS_LOCSOFTWARE)) { desc.dwFlags |= DSBCAPS_LOCSOFTWARE; static bool logged = false; if (logged == false) { logged = true; Io::Log() << "DirectSound: warning, couldn't create the sound buffer! Retrying with software buffers..\r\n"; } if (FAILED(device.CreateSoundBuffer( &desc, &oldCom, NULL ))) return "IDirectSound8::CreateSoundBuffer()"; } } if (FAILED(oldCom->QueryInterface( IID_IDirectSoundBuffer8, reinterpret_cast<void**>(&com) ))) return "IDirectSoundBuffer::QueryInterface()"; return NULL; }