static uint32_t DriverGetMemory(void) { DSCAPS caps; sysMemZero(&caps, sizeof(DSCAPS)); caps.dwSize = sizeof(DSCAPS); g_lpDSDevice->GetCaps(&caps); return caps.dwMaxContigFreeHwMemBytes; }
//----------------------------------------------------------------------------- // Получение параметров устройства воспроизведения // на входе : direct - указатель интерфейс Direct Sound // caps - указатель на структуру описывающую параметры // устройства воспроизведения // на выходе : успешность получения информации //----------------------------------------------------------------------------- int ds_GetCaps(LPDIRECTSOUND direct, LPDSCAPS caps) { // проверка наличия объекта if (direct) { caps->dwSize = sizeof(DSCAPS); // получение свойств объекта if (direct->GetCaps(caps) == DS_OK) return true; } return false; }
bool AudioOutputDSoundPrivate::init() { if (!loadDll()) return false; typedef HRESULT (WINAPI *DirectSoundCreateFunc)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); //typedef HRESULT (WINAPI *DirectSoundEnumerateFunc)(LPDSENUMCALLBACKA, LPVOID); DirectSoundCreateFunc dsound_create = (DirectSoundCreateFunc)GetProcAddress(dll, "DirectSoundCreate"); //DirectSoundEnumerateFunc dsound_enumerate = (DirectSoundEnumerateFunc)GetProcAddress(dll, "DirectSoundEnumerateA"); if (!dsound_create) { qWarning("Failed to resolve 'DirectSoundCreate'"); unloadDll(); return false; } if (FAILED(dsound_create(NULL/*dev guid*/, &dsound, NULL))){ unloadDll(); return false; } /* DSSCL_EXCLUSIVE: can modify the settings of the primary buffer, only the sound of this app will be hearable when it will have the focus. */ if (FAILED(dsound->SetCooperativeLevel(GetDesktopWindow(), DSSCL_EXCLUSIVE))) { qWarning("Cannot set direct sound cooperative level"); SafeRelease(&dsound); return false; } qDebug("DirectSound initialized."); DSCAPS dscaps; memset(&dscaps, 0, sizeof(DSCAPS)); dscaps.dwSize = sizeof(DSCAPS); if (FAILED(dsound->GetCaps(&dscaps))) { qWarning("Cannot get device capabilities."); SafeRelease(&dsound); return false; } if (dscaps.dwFlags & DSCAPS_EMULDRIVER) qDebug("DirectSound is emulated"); write_offset = 0; return true; }
void nuiAudioDevice_DirectSound::Init() { DSCCAPS icaps; icaps.dwSize = sizeof(DSCCAPS); if (mpDirectSoundCapture) mpDirectSoundCapture->GetCaps(&icaps); else { icaps.dwChannels = 0; icaps.dwFormats = 0; icaps.dwFlags = 0; } DSCAPS ocaps; ocaps.dwSize = sizeof(DSCAPS); mpDirectSound->GetCaps(&ocaps); // Input channels: if (icaps.dwChannels == 1) { nglString str(mInName); str.Add(_T(" (Input)")); mInputChannels.push_back(str); } else if (icaps.dwChannels > 1) { { nglString str(mInName); str.Add(_T(" (Left input)")); mInputChannels.push_back(str); } { nglString str(mInName); str.Add(_T(" (Right input)")); mInputChannels.push_back(str); } } // Output channels: { nglString str(mOutName); str.Add(_T(" (Left output)")); mOutputChannels.push_back(str); } { nglString str(mOutName); str.Add(_T(" (Right output)")); mOutputChannels.push_back(str); } mSampleRates.clear(); mBufferSizes.clear(); if ( ( ( icaps.dwFormats & WAVE_FORMAT_1M16 ) || ( icaps.dwFormats & WAVE_FORMAT_1S16 ) ) && ocaps.dwMinSecondarySampleRate <= 11025 && ocaps.dwMaxSecondarySampleRate >= 11025 ) mSampleRates.push_back(11025); if ( ( ( icaps.dwFormats & WAVE_FORMAT_2M16 ) || ( icaps.dwFormats & WAVE_FORMAT_2S16 ) ) && ocaps.dwMinSecondarySampleRate <= 22050 && ocaps.dwMaxSecondarySampleRate >= 22050 ) mSampleRates.push_back(22050); if ( ( ( icaps.dwFormats & WAVE_FORMAT_4M16 ) || ( icaps.dwFormats & WAVE_FORMAT_4S16 ) ) && ocaps.dwMinSecondarySampleRate <= 44100 && ocaps.dwMaxSecondarySampleRate >= 44100 ) mSampleRates.push_back(44100); if ( ( ( icaps.dwFormats & WAVE_FORMAT_48M16 ) || ( icaps.dwFormats & WAVE_FORMAT_48S16 ) ) && ocaps.dwMinSecondarySampleRate <= 48000 && ocaps.dwMaxSecondarySampleRate >= 48000 ) mSampleRates.push_back(48000); if ( ( ( icaps.dwFormats & WAVE_FORMAT_96M16 ) || ( icaps.dwFormats & WAVE_FORMAT_96S16 ) ) && ocaps.dwMinSecondarySampleRate <= 96000 && ocaps.dwMaxSecondarySampleRate >= 96000 ) mSampleRates.push_back(96000); if (mSampleRates.empty()) { mInputChannels.clear(); if (ocaps.dwMinSecondarySampleRate <= 11025 && ocaps.dwMaxSecondarySampleRate >= 11025 ) mSampleRates.push_back(11025); if (ocaps.dwMinSecondarySampleRate <= 22050 && ocaps.dwMaxSecondarySampleRate >= 22050 ) mSampleRates.push_back(22050); if (ocaps.dwMinSecondarySampleRate <= 44100 && ocaps.dwMaxSecondarySampleRate >= 44100 ) mSampleRates.push_back(44100); if (ocaps.dwMinSecondarySampleRate <= 48000 && ocaps.dwMaxSecondarySampleRate >= 48000 ) mSampleRates.push_back(48000); if (ocaps.dwMinSecondarySampleRate <= 96000 && ocaps.dwMaxSecondarySampleRate >= 96000 ) mSampleRates.push_back(96000); } mIsPresent = true; uint i = 0; int sizes[] = { 64, 128, 256, 384, 512, 768, 1024, 2048, 4096, 8192, 16384, 32768 ,0 }; while (sizes[i]) mBufferSizes.push_back(sizes[i++]); }
HRESULT sound_direct_sound::dsound_init() { assert(!m_dsound); HRESULT result; // create the DirectSound object result = DirectSoundCreate(nullptr, &m_dsound, nullptr); if (result != DS_OK) { osd_printf_error("Error creating DirectSound: %08x\n", (unsigned)result); goto error; } // get the capabilities DSCAPS dsound_caps; dsound_caps.dwSize = sizeof(dsound_caps); result = m_dsound->GetCaps(&dsound_caps); if (result != DS_OK) { osd_printf_error("Error getting DirectSound capabilities: %08x\n", (unsigned)result); goto error; } // set the cooperative level { #ifdef SDLMAME_WIN32 SDL_SysWMinfo wminfo; SDL_VERSION(&wminfo.version); SDL_GetWindowWMInfo(osd_common_t::s_window_list.front()->platform_window<SDL_Window*>(), &wminfo); HWND const window = wminfo.info.win.window; #else // SDLMAME_WIN32 HWND const window = osd_common_t::s_window_list.front()->platform_window<HWND>(); #endif // SDLMAME_WIN32 result = m_dsound->SetCooperativeLevel(window, DSSCL_PRIORITY); } if (result != DS_OK) { osd_printf_error("Error setting DirectSound cooperative level: %08x\n", (unsigned)result); goto error; } { // make a format description for what we want WAVEFORMATEX stream_format; stream_format.wBitsPerSample = 16; stream_format.wFormatTag = WAVE_FORMAT_PCM; stream_format.nChannels = 2; stream_format.nSamplesPerSec = sample_rate(); stream_format.nBlockAlign = stream_format.wBitsPerSample * stream_format.nChannels / 8; stream_format.nAvgBytesPerSec = stream_format.nSamplesPerSec * stream_format.nBlockAlign; // compute the buffer size based on the output sample rate DWORD stream_buffer_size = stream_format.nSamplesPerSec * stream_format.nBlockAlign * m_audio_latency / 10; stream_buffer_size = std::max(DWORD(1024), (stream_buffer_size / 1024) * 1024); LOG(("stream_buffer_size = %u\n", (unsigned)stream_buffer_size)); // create the buffers m_bytes_per_sample = stream_format.nBlockAlign; m_stream_buffer_in = 0; result = create_buffers(stream_buffer_size, stream_format); if (result != DS_OK) goto error; } // start playing result = m_stream_buffer.play_looping(); if (result != DS_OK) { osd_printf_error("Error playing: %08x\n", (UINT32)result); goto error; } return DS_OK; // error handling error: destroy_buffers(); dsound_kill(); return result; }
/* =============== idAudioHardwareWIN32::SetPrimaryBufferFormat Set primary buffer to a specified format For example, to set the primary buffer format to 22kHz stereo, 16-bit then: dwPrimaryChannels = 2 dwPrimaryFreq = 22050, dwPrimaryBitRate = 16 =============== */ void idAudioHardwareWIN32::SetPrimaryBufferFormat(dword dwPrimaryFreq, dword dwPrimaryBitRate, dword dwSpeakers) { HRESULT hr; if (m_pDS == NULL) { return; } ulong cfgSpeakers; m_pDS->GetSpeakerConfig(&cfgSpeakers); DSCAPS dscaps; dscaps.dwSize = sizeof(DSCAPS); m_pDS->GetCaps(&dscaps); if (dscaps.dwFlags & DSCAPS_EMULDRIVER) { return; } // Get the primary buffer DSBUFFERDESC dsbd; ZeroMemory(&dsbd, sizeof(DSBUFFERDESC)); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbd.dwBufferBytes = 0; dsbd.lpwfxFormat = NULL; // Obtain write-primary cooperative level. if (FAILED(hr = m_pDS->SetCooperativeLevel(win32.hWnd, DSSCL_PRIORITY))) { DXTRACE_ERR(TEXT("SetPrimaryBufferFormat"), hr); return; } if (FAILED(hr = m_pDS->CreateSoundBuffer(&dsbd, &pDSBPrimary, NULL))) { return; } if (dwSpeakers == 6 && (cfgSpeakers == DSSPEAKER_5POINT1 || cfgSpeakers == DSSPEAKER_SURROUND)) { WAVEFORMATEXTENSIBLE waveFormatPCMEx; ZeroMemory(&waveFormatPCMEx, sizeof(WAVEFORMATEXTENSIBLE)); waveFormatPCMEx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; waveFormatPCMEx.Format.nChannels = 6; waveFormatPCMEx.Format.nSamplesPerSec = dwPrimaryFreq; waveFormatPCMEx.Format.wBitsPerSample = (WORD) dwPrimaryBitRate; waveFormatPCMEx.Format.nBlockAlign = waveFormatPCMEx.Format.wBitsPerSample / 8 * waveFormatPCMEx.Format.nChannels; waveFormatPCMEx.Format.nAvgBytesPerSec = waveFormatPCMEx.Format.nSamplesPerSec * waveFormatPCMEx.Format.nBlockAlign; waveFormatPCMEx.dwChannelMask = KSAUDIO_SPEAKER_5POINT1; // SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | // SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | // SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT waveFormatPCMEx.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; // Specify PCM waveFormatPCMEx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE); waveFormatPCMEx.Samples.wValidBitsPerSample = 16; if (FAILED(hr = pDSBPrimary->SetFormat((WAVEFORMATEX *)&waveFormatPCMEx))) { DXTRACE_ERR(TEXT("SetPrimaryBufferFormat"), hr); return; } numSpeakers = 6; // force it to think 5.1 blockAlign = waveFormatPCMEx.Format.nBlockAlign; } else { if (dwSpeakers == 6) { common->Printf("sound: hardware reported unable to use multisound, defaulted to stereo\n"); } WAVEFORMATEX wfx; ZeroMemory(&wfx, sizeof(WAVEFORMATEX)); wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 2; wfx.nSamplesPerSec = dwPrimaryFreq; wfx.wBitsPerSample = (WORD) dwPrimaryBitRate; wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels; wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; wfx.cbSize = sizeof(WAVEFORMATEX); if (FAILED(hr = pDSBPrimary->SetFormat(&wfx))) { return; } numSpeakers = 2; // force it to think stereo blockAlign = wfx.nBlockAlign; } byte *speakerData; bufferSize = MIXBUFFER_SAMPLES * sizeof(word) * numSpeakers * ROOM_SLICES_IN_BUFFER; speakerData = (byte *)Mem_Alloc(bufferSize); memset(speakerData, 0, bufferSize); InitializeSpeakers(speakerData, bufferSize, dwPrimaryFreq, dwPrimaryBitRate, numSpeakers); }
HRESULT STDMETHODCALLTYPE DirectSound::GetCaps(LPDSCAPS pDSCaps) { return m_ds->GetCaps(pDSCaps); }
//=========================================================================== // DS_Init //=========================================================================== int DS_Init(void) { HWND hWnd; DSBUFFERDESC desc; LPDIRECTSOUNDBUFFER bufTemp; if(initOk) return true; // Are we in verbose mode? if((verbose = ArgExists("-verbose"))) Con_Message("DS_Init(Compat): Initializing sound driver...\n"); // Get Doomsday's window handle. hWnd = (HWND) DD_GetInteger(DD_WINDOW_HANDLE); hr = DS_OK; if(ArgExists("-noeax") || FAILED(hr = EAXDirectSoundCreate(NULL, &dsound, NULL))) { // EAX can't be initialized. Use normal DS, then. if(FAILED(hr)) Error("DS_Init", "EAX 2 couldn't be initialized."); if(FAILED(hr = DirectSoundCreate(NULL, &dsound, NULL))) { Error("DS_Init", "Failed to create dsound interface."); return false; } } // Set the cooperative level. if(FAILED(hr = dsound->SetCooperativeLevel(hWnd, DSSCL_PRIORITY))) { Error("DS_Init", "Couldn't set dSound coop level."); return false; } // Get the primary buffer and the listener. primary = NULL; memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); desc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER; dsListener = NULL; if(SUCCEEDED(dsound->CreateSoundBuffer(&desc, &primary, NULL))) { // Query the listener interface. primary->QueryInterface(IID_IDirectSound3DListener, (void**) &dsListener); } else { // Failure; get a 2D primary buffer, then. desc.dwFlags = DSBCAPS_PRIMARYBUFFER; dsound->CreateSoundBuffer(&desc, &primary, NULL); } // Start playing the primary buffer. if(primary) { if(FAILED(hr = primary->Play(0, 0, DSBPLAY_LOOPING))) Error("DS_Init", "Can't play primary buffer."); } // Try to get the EAX listener property set. // Create a temporary secondary buffer for it. eaxListener = NULL; if(SUCCEEDED(CreateDSBuffer(DSBCAPS_STATIC | DSBCAPS_CTRL3D, DSBSIZE_MIN, 22050, 8, 1, &bufTemp))) { // Now try to get the property set. if(SUCCEEDED(hr = bufTemp->QueryInterface(IID_IKsPropertySet, (void**) &eaxListener))) { DWORD support = 0, revsize = 0; // Check for support. if(FAILED(hr = eaxListener->QuerySupport( DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT, &support)) || ((support & NEEDED_SUPPORT) != NEEDED_SUPPORT)) { Error("DS_Init", "Sufficient EAX2 support not present."); eaxListener->Release(); eaxListener = NULL; } else { // EAX is supported! if(verbose) Con_Message("DS_Init(Compat): EAX2 is available.\n"); } } // Release the temporary buffer interface. bufTemp->Release(); } // Get the caps. dsCaps.dwSize = sizeof(dsCaps); dsound->GetCaps(&dsCaps); if(verbose) Con_Message("DS_Init(Compat): Number of hardware 3D " "buffers: %i\n", dsCaps.dwMaxHw3DAllBuffers); // Configure the DS3D listener. if(dsListener) { dsListener->SetDistanceFactor(1/36.0f, DS3D_DEFERRED); dsListener->SetDopplerFactor(2, DS3D_DEFERRED); } // Success! initOk = true; return true; }