static int dsound_open (dsound *s) { int err; HRESULT hr; WAVEFORMATEX wfx; DSBUFFERDESC dsbd; HWND hwnd; hwnd = GetForegroundWindow (); hr = IDirectSound_SetCooperativeLevel ( s->dsound, hwnd, DSSCL_PRIORITY ); if (FAILED (hr)) { dsound_logerr (hr, "Could not set cooperative level for window %p\n", hwnd); return -1; } if (!conf.set_primary) { return 0; } err = waveformat_from_audio_settings (&wfx, &conf.settings); if (err) { return -1; } memset (&dsbd, 0, sizeof (dsbd)); dsbd.dwSize = sizeof (dsbd); dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbd.dwBufferBytes = 0; dsbd.lpwfxFormat = NULL; hr = IDirectSound_CreateSoundBuffer ( s->dsound, &dsbd, &s->dsound_primary_buffer, NULL ); if (FAILED (hr)) { dsound_logerr (hr, "Could not create primary playback buffer\n"); return -1; } hr = IDirectSoundBuffer_SetFormat (s->dsound_primary_buffer, &wfx); if (FAILED (hr)) { dsound_logerr (hr, "Could not set primary playback buffer format\n"); } hr = IDirectSoundBuffer_GetFormat ( s->dsound_primary_buffer, &wfx, sizeof (wfx), NULL ); if (FAILED (hr)) { dsound_logerr (hr, "Could not get primary playback buffer format\n"); goto fail0; } #ifdef DEBUG_DSOUND dolog ("Primary\n"); print_wave_format (&wfx); #endif err = waveformat_to_audio_settings (&wfx, &s->settings); if (err) { goto fail0; } return 0; fail0: dsound_close (s); return -1; }
// open dsound. int dsound_open(const char *name) { HRESULT hr; // close dsound device dsound_close(); if (name && name[0]) { struct enum_callback { HRESULT hr; const char *name; static BOOL CALLBACK func(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext) { enum_callback *context = (enum_callback *)lpContext; if (_stricmp(context->name, lpcstrDescription) == 0) { context->hr = DirectSoundCreate(lpGuid, &dsound, NULL); return false; } return true; } } callback; callback.name = name; callback.hr = E_FAIL; DirectSoundEnumerate(&enum_callback::func, &callback); // create dsound object if (FAILED(hr = callback.hr)) goto error; } else { // create dsound object if (FAILED(DirectSoundCreate(NULL, &dsound, NULL))) goto error; } // wave format used for primary buffer WAVEFORMATEX format; memset(&format, 0, sizeof(format)); format.wFormatTag = WAVE_FORMAT_PCM; format.nChannels = 2; format.nSamplesPerSec = 44100; format.wBitsPerSample = 16; format.nBlockAlign = (format.nChannels * format.wBitsPerSample) / 8; format.nAvgBytesPerSec = format.nBlockAlign * format.nSamplesPerSec; format.cbSize = sizeof(format); #define USE_PRIMIARY_WRITE 0 #if USE_PRIMIARY_WRITE // set cooperative level if (FAILED(hr = dsound->SetCooperativeLevel(gui_get_window(), DSSCL_WRITEPRIMARY))) goto error; // initialize parameters DSBUFFERDESC desc; memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); desc.dwFlags = DSBCAPS_PRIMARYBUFFER; // create primary buffer if (FAILED(dsound->CreateSoundBuffer(&desc, &primary_buffer, NULL))) goto error; // set primary buffer format if (FAILED(primary_buffer->SetFormat(&format))) goto error; #else // set cooperative level if (FAILED(hr = dsound->SetCooperativeLevel(gui_get_window(), DSSCL_PRIORITY))) goto error; // initialize parameters DSBUFFERDESC desc; memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; desc.dwBufferBytes = 4096 * format.nBlockAlign; desc.lpwfxFormat = &format; // create primary buffer if (FAILED(hr = dsound->CreateSoundBuffer(&desc, &primary_buffer, NULL))) goto error; #endif // create input thread dsound_thread = CreateThread(NULL, 0, &dsound_play_thread, NULL, NULL, NULL); // change thread priority to highest SetThreadPriority(dsound_thread, THREAD_PRIORITY_TIME_CRITICAL); return S_OK; error: dsound_close(); return hr; }