static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName) { DSoundData *pData = NULL; LPGUID guid = NULL; HRESULT hr; if(!DSoundLoad()) return ALC_FALSE; if(!deviceName) deviceName = dsDevice; else if(strcmp(deviceName, dsDevice) != 0) { ALuint i; if(!DeviceList) { hr = pDirectSoundEnumerateA(DSoundEnumDevices, NULL); if(FAILED(hr)) AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr); } for(i = 0; i < NumDevices; i++) { if(strcmp(deviceName, DeviceList[i].name) == 0) { if(i > 0) guid = &DeviceList[i].guid; break; } } if(i == NumDevices) return ALC_FALSE; } //Initialise requested device pData = calloc(1, sizeof(DSoundData)); if(!pData) { alcSetError(device, ALC_OUT_OF_MEMORY); return ALC_FALSE; } //DirectSound Init code hr = pDirectSoundCreate(guid, &pData->lpDS, NULL); if(SUCCEEDED(hr)) hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY); if(FAILED(hr)) { if(pData->lpDS) IDirectSound_Release(pData->lpDS); free(pData); AL_PRINT("Device init failed: 0x%08lx\n", hr); return ALC_FALSE; } device->szDeviceName = strdup(deviceName); device->ExtraData = pData; return ALC_TRUE; }
static gboolean gst_directsound_sink_open (GstAudioSink * asink) { GstDirectSoundSink *dsoundsink; HRESULT hRes; dsoundsink = GST_DIRECTSOUND_SINK (asink); /* create and initialize a DirecSound object */ if (FAILED (hRes = DirectSoundCreate (NULL, &dsoundsink->pDS, NULL))) { GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_READ, ("gst_directsound_sink_open: DirectSoundCreate: %s", DXGetErrorString9 (hRes)), (NULL)); return FALSE; } if (FAILED (hRes = IDirectSound_SetCooperativeLevel (dsoundsink->pDS, GetDesktopWindow (), DSSCL_PRIORITY))) { GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_READ, ("gst_directsound_sink_open: IDirectSound_SetCooperativeLevel: %s", DXGetErrorString9 (hRes)), (NULL)); return FALSE; } return TRUE; }
static void FreeSound (void) { if (pDSBuf) { IDirectSoundBuffer_Stop (pDSBuf); IDirectSound_Release (pDSBuf); } // release primary buffer only if it's not also the mixing buffer we just released if (pDSPBuf && (pDSBuf != pDSPBuf)) { IDirectSound_Release (pDSPBuf); } if (pDS) { IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_NORMAL); IDirectSound_Release (pDS); } pDS = NULL; pDSBuf = NULL; pDSPBuf = NULL; hWaveOut = 0; hData = 0; hWaveHdr = 0; lpData = NULL; lpWaveHdr = NULL; }
void m1sdr_PlayStart(void) { waveLogStart(); IDirectSound_SetCooperativeLevel(lpDS, GetForegroundWindow(), DSSCL_PRIORITY); IDirectSoundBuffer_SetCurrentPosition(lpSecB, 0); IDirectSoundBuffer_Play(lpSecB, 0, 0, DSBPLAY_LOOPING); }
static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName) { DSoundData *pData = NULL; LPGUID guid = NULL; HRESULT hr; if(!deviceName) deviceName = dsDevice; else if(strcmp(deviceName, dsDevice) != 0) { ALuint i; for(i = 0;i < NumDevices;i++) { if(strcmp(deviceName, DeviceList[i].name) == 0) { guid = &DeviceList[i].guid; break; } } if(i == NumDevices) return ALC_FALSE; } DSoundLoad(); if(ds_handle == NULL) return ALC_FALSE; //Initialise requested device pData = calloc(1, sizeof(DSoundData)); if(!pData) { alcSetError(ALC_OUT_OF_MEMORY); DSoundUnload(); return ALC_FALSE; } //DirectSound Init code hr = pDirectSoundCreate(guid, &pData->lpDS, NULL); if(SUCCEEDED(hr)) hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY); if(FAILED(hr)) { if(pData->lpDS) IDirectSound_Release(pData->lpDS); free(pData); DSoundUnload(); return ALC_FALSE; } device->szDeviceName = strdup(deviceName); device->ExtraData = pData; return ALC_TRUE; }
/* FreeSound */ void FreeSound (void) { int i; if (pDSBuf) { IDirectSoundBuffer_Stop (pDSBuf); IDirectSound_Release (pDSBuf); } // only release primary buffer if it's not also the mixing buffer we just released if (pDSPBuf && (pDSBuf != pDSPBuf)) { IDirectSound_Release (pDSPBuf); } if (pDS) { IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_NORMAL); IDirectSound_Release (pDS); } if (hWaveOut) { waveOutReset (hWaveOut); if (lpWaveHdr) { for (i = 0; i < WAV_BUFFERS; i++) waveOutUnprepareHeader (hWaveOut, lpWaveHdr + i, sizeof (WAVEHDR)); } waveOutClose (hWaveOut); if (hWaveHdr) { GlobalUnlock (hWaveHdr); GlobalFree (hWaveHdr); } if (hData) { GlobalUnlock (hData); GlobalFree (hData); } } pDS = NULL; pDSBuf = NULL; pDSPBuf = NULL; hWaveOut = 0; hData = 0; hWaveHdr = 0; lpData = NULL; lpWaveHdr = NULL; dsound_init = false; wav_init = false; }
BOOL SSInit(HWND hWnd, int channels, unsigned flags) { LPDIRECTSOUNDBUFFER lpPrimaryBuffer; LPDIRECTSOUND lpDS; DSBUFFERDESC dsbd; if (SSMixer.lpds) return TRUE; // Perform Direct Sound Initialization if (DirectSoundCreate(NULL, &lpDS, NULL) != DS_OK) return FALSE; SSMixer.lpds = lpDS; if (IDirectSound_SetCooperativeLevel(lpDS, hWnd, DSSCL_NORMAL) != DS_OK) { SSDestroy(); return FALSE; } // Start Mixer memset(&dsbd, 0, sizeof(DSBUFFERDESC)); dsbd.dwSize = sizeof(DSBUFFERDESC); dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; if (IDirectSound_CreateSoundBuffer(SSMixer.lpds, &dsbd, &lpPrimaryBuffer, NULL) == DS_OK) { if (IDirectSoundBuffer_Play(lpPrimaryBuffer, 0, 0, DSBPLAY_LOOPING) != DS_OK) { IDirectSoundBuffer_Release(lpPrimaryBuffer); SSDestroy(); return FALSE; } IDirectSoundBuffer_Release(lpPrimaryBuffer); } else { SSDestroy(); return FALSE; } // Finish initializing SSMixer. SSMixer.ch_cur = 0; SSMixer.ch_list = (SSoundBuffer *)malloc(sizeof(SSoundBuffer)*channels); if (!SSMixer.ch_list) return FALSE; memset(SSMixer.ch_list, 0, sizeof(SSoundBuffer)*channels); SSMixer.ch_num = channels; // Determine Sound technology and volume caps waveOutGetVolume((HWAVEOUT)WAVE_MAPPER, (LPDWORD)&SSMixer.old_master_vol); // waveOutSetVolume((HWAVEOUT)WAVE_MAPPER, 0x40004000); return TRUE; }
int pest_open( HWND win ){ HMODULE lib; DIRECTSOUNDCREATE dsound_create; WAVEFORMATEX format; DSBUFFERDESC desc_primary, desc_secondary; lib = (HMODULE)LoadLibrary("dsound.dll"); if(lib==NULL) return FALSE; dsound_create = (DIRECTSOUNDCREATE)GetProcAddress(lib, "DirectSoundCreate"); if(dsound_create==NULL) return FALSE; FreeLibrary(lib); if( dsound_create( NULL, &dsound, NULL )!= DS_OK ) return FALSE; if( IDirectSound_SetCooperativeLevel( dsound, win, DSSCL_EXCLUSIVE | DSSCL_PRIORITY ) != DS_OK ) return FALSE; memset( &desc_primary, 0, sizeof(DSBUFFERDESC) ); desc_primary.dwSize = sizeof(DSBUFFERDESC); desc_primary.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_STICKYFOCUS; if(IDirectSound_CreateSoundBuffer( dsound, &desc_primary, &primary, NULL )!=DS_OK) return FALSE; memset( &format, 0, sizeof(WAVEFORMATEX) ); format.wFormatTag = WAVE_FORMAT_PCM; format.nChannels = 2; format.nSamplesPerSec = 44100; format.nAvgBytesPerSec = 44100 * 4; format.nBlockAlign = 4; format.wBitsPerSample = 16; if( IDirectSoundBuffer_SetFormat( primary, &format )!= DS_OK) return FALSE; memset( &desc_secondary, 0, sizeof(DSBUFFERDESC) ); desc_secondary.dwSize = sizeof(DSBUFFERDESC); desc_secondary.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; desc_secondary.lpwfxFormat = &format; desc_secondary.dwBufferBytes = 2*2*BUFFER_LEN; if(IDirectSound_CreateSoundBuffer( dsound, &desc_secondary, &secondary, NULL )!=DS_OK) return FALSE; InitializeCriticalSection(&critical); return TRUE; }
int DirectSoundInit() { HRESULT hr; HWND hWnd; LoadDsound(); hr = pDirectSoundCreate(NULL, &lpDirectSound, NULL); if( hr != DS_OK ) return 0; hWnd = GetForegroundWindow(); // establecer el nivel de cooperacion hr = IDirectSound_SetCooperativeLevel(lpDirectSound,hWnd, DSSCL_NORMAL ); if( hr != DS_OK) return 0; return 1; }
/* * DirectSoundを初期化する */ BOOL DSInitialize(HWND hWnd) { HRESULT hRet; uintptr_t t; /* IDirectSoundのインスタンスを取得して初期化する */ hRet = CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void **)&pDS); if(hRet != S_OK || pDS == NULL) return FALSE; /* COMオブジェクトを初期化する */ IDirectSound_Initialize(pDS, NULL); /* 協調レベルを設定する */ hRet = IDirectSound_SetCooperativeLevel(pDS, hWnd, DSSCL_PRIORITY); if(hRet != DS_OK) return FALSE; /* プライマリバッファのフォーマットを設定する */ if(!CreatePrimaryBuffer()) return FALSE; /* セカンダリバッファを作成する */ if(!CreateSecondaryBuffers()) return FALSE; /* イベントスレッドへの終了通知用のイベントを作成する */ hQuitEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(hQuitEvent == NULL) return FALSE; /* DirectSoundの再生位置通知を受け取るスレッドを開始する */ t = _beginthread(EventThread, 0, NULL); if(t == (unsigned long)-1) return FALSE; hEventThread = (HANDLE)t; return TRUE; }
/* Initialise audio devices. */ int digi_init() { HRESULT hr; if (!digi_initialised && g_hWnd){ memset(&waveformat, 0, sizeof(waveformat)); waveformat.wFormatTag=WAVE_FORMAT_PCM; waveformat.wBitsPerSample=8; waveformat.nChannels = 1; waveformat.nSamplesPerSec = 11025; waveformat.nBlockAlign = waveformat.nChannels * (waveformat.wBitsPerSample/8); waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec * waveformat.nBlockAlign; if ((hr = DirectSoundCreate(NULL, &lpds, NULL)) != DS_OK) return -1; if ((hr = IDirectSound_SetCooperativeLevel(lpds, g_hWnd, DSSCL_PRIORITY)) //hWndMain != DS_OK) { IDirectSound_Release(lpds); return -1; } memset(&dsbd, 0, sizeof(dsbd)); dsbd.dwSize = sizeof(dsbd); dsbd.dwFlags = (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME) | DSBCAPS_GETCURRENTPOSITION2; dsbd.dwBufferBytes = 8192; dsbd.dwReserved=0; dsbd.lpwfxFormat = &waveformat; digi_initialised = 1; } if (!digi_atexit_initialised){ atexit(digi_close); digi_atexit_initialised=1; } return 0; }
static int dsound_open (dsound *s) { HRESULT hr; 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; } return 0; }
//open the dsound interface. static BOOL setupSoundPlay(VOID) { HWND hwnd; HRESULT hr; hwnd = frameGetWinHandle(); hr =DirectSoundCreate(NULL, &lpDirectSound, NULL); // create dsound object if (hr != DS_OK) { DBPRINTF(("NETPLAY Failed to create dsound interface.\n")); return (FALSE); } hr =IDirectSound_SetCooperativeLevel(lpDirectSound, hwnd, DSSCL_PRIORITY); // Set coop level if (hr != DS_OK) { DBPRINTF(("NETPLAY Failed to create playback buffer..\n")); return (FALSE); } IDirectSound_Compact(lpDirectSound); // compact things return (TRUE); }
static ALCenum DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName) { DSoundPlaybackData *data = NULL; LPGUID guid = NULL; HRESULT hr; if(!PlaybackDeviceList) { hr = DirectSoundEnumerateA(DSoundEnumPlaybackDevices, NULL); if(FAILED(hr)) ERR("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr); } if(!deviceName && NumPlaybackDevices > 0) { deviceName = PlaybackDeviceList[0].name; guid = &PlaybackDeviceList[0].guid; } else { ALuint i; for(i = 0;i < NumPlaybackDevices;i++) { if(strcmp(deviceName, PlaybackDeviceList[i].name) == 0) { guid = &PlaybackDeviceList[i].guid; break; } } if(i == NumPlaybackDevices) return ALC_INVALID_VALUE; } //Initialise requested device data = calloc(1, sizeof(DSoundPlaybackData)); if(!data) return ALC_OUT_OF_MEMORY; hr = DS_OK; data->NotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if(data->NotifyEvent == NULL) hr = E_FAIL; //DirectSound Init code if(SUCCEEDED(hr)) hr = DirectSoundCreate(guid, &data->DS, NULL); if(SUCCEEDED(hr)) hr = IDirectSound_SetCooperativeLevel(data->DS, GetForegroundWindow(), DSSCL_PRIORITY); if(FAILED(hr)) { if(data->DS) IDirectSound_Release(data->DS); if(data->NotifyEvent) CloseHandle(data->NotifyEvent); free(data); ERR("Device init failed: 0x%08lx\n", hr); return ALC_INVALID_VALUE; } device->DeviceName = strdup(deviceName); device->ExtraData = data; return ALC_NO_ERROR; }
INT16 m1sdr_Init(int sample_rate) { DSBUFFERDESC dsbuf; WAVEFORMATEX format; if (!s32SoundEnable) return(0); nDSoundSamRate = sample_rate; samples = NULL; lpDS = NULL; lpPDSB = NULL; lpSecB = NULL; // Calculate the Seg Length and Loop length // (round to nearest sample) nDSoundSegLen=(nDSoundSamRate*10+(nDSoundFps>>1))/nDSoundFps; cbLoopLen=(nDSoundSegLen*nDSoundSegCount)<<2; // create an IDirectSound COM object if (DS_OK != DirectSoundCreate(NULL, &lpDS, NULL)) { printf("Unable to create DirectSound object!\n"); return(0); } // set cooperative level where we need it if (DS_OK != IDirectSound_SetCooperativeLevel(lpDS, GetForegroundWindow(), DSSCL_PRIORITY)) { printf("Unable to set cooperative level!\n"); return(0); } // now create a primary sound buffer memset(&format, 0, sizeof(format)); format.wFormatTag = WAVE_FORMAT_PCM; format.nChannels = 2; format.wBitsPerSample = 16; format.nSamplesPerSec = nDSoundSamRate; format.nBlockAlign = 4; // stereo 16-bit format.cbSize = 0; format.nAvgBytesPerSec=format.nSamplesPerSec*format.nBlockAlign; memset(&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbuf.dwBufferBytes = 0; dsbuf.lpwfxFormat = NULL; if (DS_OK != IDirectSound_CreateSoundBuffer(lpDS, &dsbuf, &lpPDSB, NULL)) { printf("Unable to create primary buffer!"); return(0); } // and set it's format how we want if (DS_OK != IDirectSoundBuffer_SetFormat(lpPDSB, &format)) { printf("Unable to set primary buffer format!\n"); return(0); } // start the primary buffer playing now so we get // minimal lag when we trigger our secondary buffer IDirectSoundBuffer_Play(lpPDSB, 0, 0, DSBPLAY_LOOPING); // that's done, now let's create our secondary buffer memset(&dsbuf, 0, sizeof(DSBUFFERDESC)); dsbuf.dwSize = sizeof(DSBUFFERDESC); // we'll take default controls for this one dsbuf.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY; dsbuf.dwBufferBytes = cbLoopLen; dsbuf.lpwfxFormat = (LPWAVEFORMATEX)&format; if (DS_OK != IDirectSound_CreateSoundBuffer(lpDS, &dsbuf, &lpSecB, NULL)) { printf("Unable to create secondary buffer\n"); return(0); } // ok, cool, we're ready to go! // blank out the entire sound buffer { LPVOID ptr; DWORD len; IDirectSoundBuffer_Lock(lpSecB, 0, 0, &ptr, &len, NULL, NULL, DSBLOCK_ENTIREBUFFER); ZeroMemory(ptr, len); IDirectSoundBuffer_Unlock(lpSecB, ptr, len, 0, 0); } // allocate and zero our local buffer samples = (INT16 *)malloc(nDSoundSegLen<<2); ZeroMemory(samples, nDSoundSegLen<<2); bDSoundOkay=1; // This module was initted okay return(1); }
static void *dsound_init(const char *device, unsigned rate, unsigned latency) { WAVEFORMATEX wfx = {0}; DSBUFFERDESC bufdesc = {0}; struct dsound_dev dev = {0}; dsound_t *ds = (dsound_t*)calloc(1, sizeof(*ds)); if (!ds) goto error; InitializeCriticalSection(&ds->crit); if (device) dev.device = strtoul(device, NULL, 0); RARCH_LOG("DirectSound devices:\n"); #ifndef _XBOX DirectSoundEnumerate(enumerate_cb, &dev); #endif if (DirectSoundCreate(dev.guid, &ds->ds, NULL) != DS_OK) goto error; #ifndef _XBOX if (IDirectSound_SetCooperativeLevel(ds->ds, GetDesktopWindow(), DSSCL_PRIORITY) != DS_OK) goto error; #endif wfx.wFormatTag = WAVE_FORMAT_PCM; wfx.nChannels = 2; wfx.nSamplesPerSec = rate; wfx.wBitsPerSample = 16; wfx.nBlockAlign = 2 * sizeof(int16_t); wfx.nAvgBytesPerSec = rate * 2 * sizeof(int16_t); ds->buffer_size = (latency * wfx.nAvgBytesPerSec) / 1000; ds->buffer_size /= CHUNK_SIZE; ds->buffer_size *= CHUNK_SIZE; if (ds->buffer_size < 4 * CHUNK_SIZE) ds->buffer_size = 4 * CHUNK_SIZE; RARCH_LOG("[DirectSound]: Setting buffer size of %u bytes\n", ds->buffer_size); RARCH_LOG("[DirectSound]: Latency = %u ms\n", (unsigned)((1000 * ds->buffer_size) / wfx.nAvgBytesPerSec)); bufdesc.dwSize = sizeof(DSBUFFERDESC); bufdesc.dwFlags = 0; #ifndef _XBOX bufdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; #endif bufdesc.dwBufferBytes = ds->buffer_size; bufdesc.lpwfxFormat = &wfx; ds->event = CreateEvent(NULL, false, false, NULL); if (!ds->event) goto error; ds->buffer = fifo_new(4 * 1024); if (!ds->buffer) goto error; if (IDirectSound_CreateSoundBuffer(ds->ds, &bufdesc, &ds->dsb, 0) != DS_OK) goto error; IDirectSoundBuffer_SetVolume(ds->dsb, DSBVOLUME_MAX); IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0); dsound_clear_buffer(ds); if (IDirectSoundBuffer_Play(ds->dsb, 0, 0, DSBPLAY_LOOPING) != DS_OK) goto error; if (!dsound_start_thread(ds)) goto error; return ds; error: RARCH_ERR("[DirectSound] Error occured in init.\n"); dsound_free(ds); return NULL; }
HRESULT DSoundRender_create(IUnknown * pUnkOuter, LPVOID * ppv) { HRESULT hr; PIN_INFO piInput; DSoundRenderImpl * pDSoundRender; TRACE("(%p, %p)\n", pUnkOuter, ppv); *ppv = NULL; if (pUnkOuter) return CLASS_E_NOAGGREGATION; pDSoundRender = CoTaskMemAlloc(sizeof(DSoundRenderImpl)); if (!pDSoundRender) return E_OUTOFMEMORY; ZeroMemory(pDSoundRender, sizeof(DSoundRenderImpl)); BaseFilter_Init(&pDSoundRender->filter, &DSoundRender_Vtbl, &CLSID_DSoundRender, (DWORD_PTR)(__FILE__ ": DSoundRenderImpl.csFilter"), &BaseFuncTable); pDSoundRender->IBasicAudio_vtbl = &IBasicAudio_Vtbl; pDSoundRender->IReferenceClock_vtbl = &IReferenceClock_Vtbl; pDSoundRender->IAMDirectSound_vtbl = &IAMDirectSound_Vtbl; /* construct input pin */ piInput.dir = PINDIR_INPUT; piInput.pFilter = (IBaseFilter *)pDSoundRender; lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0])); hr = BaseInputPin_Construct(&DSoundRender_InputPin_Vtbl, &piInput, &input_BaseFuncTable, &input_BaseInputFuncTable, &pDSoundRender->filter.csFilter, NULL, (IPin **)&pDSoundRender->pInputPin); if (SUCCEEDED(hr)) { hr = DirectSoundCreate8(NULL, &pDSoundRender->dsound, NULL); if (FAILED(hr)) ERR("Cannot create Direct Sound object (%x)\n", hr); else IDirectSound_SetCooperativeLevel(pDSoundRender->dsound, GetDesktopWindow(), DSSCL_PRIORITY); } if (SUCCEEDED(hr)) { ISeekingPassThru *passthru; pDSoundRender->state_change = CreateEventW(NULL, TRUE, TRUE, NULL); pDSoundRender->blocked = CreateEventW(NULL, TRUE, TRUE, NULL); hr = CoCreateInstance(&CLSID_SeekingPassThru, (IUnknown*)pDSoundRender, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&pDSoundRender->seekthru_unk); if (!pDSoundRender->state_change || !pDSoundRender->blocked || FAILED(hr)) { IUnknown_Release((IUnknown *)pDSoundRender); return HRESULT_FROM_WIN32(GetLastError()); } IUnknown_QueryInterface(pDSoundRender->seekthru_unk, &IID_ISeekingPassThru, (void**)&passthru); ISeekingPassThru_Init(passthru, TRUE, (IPin*)pDSoundRender->pInputPin); ISeekingPassThru_Release(passthru); *ppv = pDSoundRender; } else { if (pDSoundRender->pInputPin) IPin_Release((IPin*)pDSoundRender->pInputPin); BaseFilterImpl_Release((IBaseFilter*)pDSoundRender); CoTaskMemFree(pDSoundRender); } return hr; }
static int dx_init(const char *param, int *speed, int *fragsize, int *fragnr, int *channels) { HRESULT result; DEBUG(("DirectSound driver initialization: speed = %d, fragsize = %d, fragnr = %d, channels = %d\n", *speed, *fragsize, *fragnr, *channels)); if (ds == NULL) { result = DirectSoundCreate(NULL, &ds, NULL); if (result != DS_OK) { ui_error("Cannot initialize DirectSound:\n%s", ds_error(result)); return -1; } result = IDirectSound_SetCooperativeLevel(ds, ui_get_main_hwnd(), DSSCL_EXCLUSIVE); if (result != DS_OK) { ui_error("Cannot set cooperative level:\n%s", ds_error(result)); return -1; } } memset(&capabilities, 0, sizeof(DSCAPS)); capabilities.dwSize = sizeof(DSCAPS); IDirectSound_GetCaps(ds, &capabilities); if ((capabilities.dwFlags & DSCAPS_PRIMARY16BIT) || (capabilities.dwFlags & DSCAPS_SECONDARY16BIT)) { is16bit = 1; } else { is16bit = 0; } if (!((capabilities.dwFlags & DSCAPS_PRIMARYSTEREO) || (capabilities.dwFlags & DSCAPS_SECONDARYSTEREO))) { *channels = 1; } num_of_channels = *channels; DEBUG(("16bit flag: %d",is16bit)); DEBUG(("Channels: %d",*channels)); DEBUG(("Capabilities %08x",capabilities.dwFlags)); DEBUG(("Secondary min Hz: %d",capabilities.dwMinSecondarySampleRate)); DEBUG(("Secondary max Hz: %d",capabilities.dwMaxSecondarySampleRate)); memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; pcmwf.wf.nChannels = *channels; pcmwf.wf.nSamplesPerSec = *speed; pcmwf.wBitsPerSample = is16bit ? 16 : 8; /* Hack to fix if mmsystem header is bad ((WORD*)&pcmwf)[7] = 16; */ pcmwf.wf.nBlockAlign = (is16bit ? 2 : 1) * *channels; pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; memset(&desc, 0, sizeof(DSBUFFERDESC)); desc.dwSize = sizeof(DSBUFFERDESC); desc.dwFlags = DSBCAPS_PRIMARYBUFFER; fragment_size = *fragsize; /* frames */ buffer_size = *fragsize * *fragnr * (is16bit ? 2 : 1) * *channels; /* bytes */ stream_buffer_size = fragment_size * *fragnr * *channels; /* nr of samples */ buffer_offset = 0; /* bytes */ result = IDirectSound_CreateSoundBuffer(ds, &desc, &pbuffer, NULL); if (result != DS_OK) { ui_error("Cannot create Primary DirectSound bufer: %s", ds_error(result)); return -1; } memset(&desc, 0, sizeof(DSBUFFERDESC)); desc.dwSize = sizeof(DSBUFFERDESC); desc.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS ; desc.dwBufferBytes = buffer_size; desc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf; result = IDirectSound_CreateSoundBuffer(ds, &desc, &buffer, NULL); if (result != DS_OK) { ui_error("Cannot create DirectSound buffer:\n%s", ds_error(result)); return -1; } memset(&wfex, 0, sizeof(WAVEFORMATEX)); wfex.wFormatTag = WAVE_FORMAT_PCM; wfex.nChannels = *channels; wfex.nSamplesPerSec = *speed; wfex.wBitsPerSample = is16bit ? 16 : 8; wfex.nBlockAlign = (is16bit ? 2 : 1) * *channels; wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; result=IDirectSoundBuffer_SetFormat(pbuffer, &wfex); if (result != DS_OK) { ui_error("Cannot set Output format for primary sound buffer:\n%s", ds_error(result)); return -1; } dx_clear(); /* Let's go... */ result = IDirectSoundBuffer_Play(buffer, 0, 0, DSBPLAY_LOOPING); if (result == DSERR_BUFFERLOST) { ui_error("Restoring DirectSound buffer."); if ((result = IDirectSoundBuffer_Restore(buffer)) != DS_OK) ui_error("Cannot restore buffer:\n%s", ds_error(result)); result = IDirectSoundBuffer_Play(buffer, 0, 0, DSBPLAY_LOOPING); } if (result != DS_OK) { ui_error("Cannot play DirectSound buffer:\n%s", ds_error(result)); return -1; } DEBUG(("DirectSound initialization done succesfully.\n")); return 0; }
static HRESULT test_frequency(LPGUID lpGuid) { HRESULT rc; LPDIRECTSOUND dso=NULL; LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL; DSBUFFERDESC bufdesc; DSCAPS dscaps; WAVEFORMATEX wfx, wfx1; DWORD f, r; int ref; int rates[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 96000 }; /* Create the DirectSound object */ rc=DirectSoundCreate(lpGuid,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc)); if (rc!=DS_OK) return rc; /* Get the device capabilities */ ZeroMemory(&dscaps, sizeof(dscaps)); dscaps.dwSize=sizeof(dscaps); rc=IDirectSound_GetCaps(dso,&dscaps); ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc)); if (rc!=DS_OK) goto EXIT; /* We must call SetCooperativeLevel before creating primary buffer */ /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n", DXGetErrorString8(rc)); if (rc!=DS_OK) goto EXIT; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok(rc==DS_OK && primary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a primary buffer " "%s\n",DXGetErrorString8(rc)); if (rc==DS_OK && primary!=NULL) { rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL); ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n", DXGetErrorString8(rc)); if (rc!=DS_OK) goto EXIT1; for (f=0;f<sizeof(fmts)/sizeof(fmts[0]);f++) { for (r=0;r<sizeof(rates)/sizeof(rates[0]);r++) { init_format(&wfx,WAVE_FORMAT_PCM,11025,fmts[f].bits, fmts[f].channels); secondary=NULL; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRLFREQUENCY; bufdesc.dwBufferBytes=align((wfx.nAvgBytesPerSec*rates[r]/11025)* BUFFER_LEN/1000,wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx; if (winetest_interactive) { trace(" Testing a secondary buffer at %ldx%dx%d " "with a primary buffer at %ldx%dx%d\n", wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels, wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels); } rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a secondary " "buffer %s\n",DXGetErrorString8(rc)); if (rc==DS_OK && secondary!=NULL) { test_buffer(dso,&secondary,0,FALSE,0,FALSE,0, winetest_interactive,1.0,0,NULL,0,0,TRUE,rates[r]); ref=IDirectSoundBuffer_Release(secondary); ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " "should have 0\n",ref); } } } EXIT1: ref=IDirectSoundBuffer_Release(primary); ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " "should have 0\n",ref); } /* Set the CooperativeLevel back to normal */ /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n", DXGetErrorString8(rc)); EXIT: ref=IDirectSound_Release(dso); ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); if (ref!=0) return DSERR_GENERIC; return rc; }
/** \brief initilize direct sound \return 0 if error, 1 if ok */ static int InitDirectSound(struct ao *ao) { struct priv *p = ao->priv; DSCAPS dscaps; // initialize directsound HRESULT (WINAPI *OurDirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); HRESULT (WINAPI *OurDirectSoundEnumerate)(LPDSENUMCALLBACKA, LPVOID); p->device_index = 0; p->device_num = p->cfg_device; p->hdsound_dll = LoadLibrary("DSOUND.DLL"); if (p->hdsound_dll == NULL) { MP_ERR(ao, "cannot load DSOUND.DLL\n"); return 0; } OurDirectSoundCreate = (void *)GetProcAddress(p->hdsound_dll, "DirectSoundCreate"); OurDirectSoundEnumerate = (void *)GetProcAddress(p->hdsound_dll, "DirectSoundEnumerateA"); if (OurDirectSoundCreate == NULL || OurDirectSoundEnumerate == NULL) { MP_ERR(ao, "GetProcAddress FAILED\n"); FreeLibrary(p->hdsound_dll); return 0; } // Enumerate all directsound p->devices MP_VERBOSE(ao, "Output Devices:\n"); OurDirectSoundEnumerate(DirectSoundEnum, ao); // Create the direct sound object if (FAILED(OurDirectSoundCreate((p->device_num) ? &p->device : NULL, &p->hds, NULL))) { MP_ERR(ao, "cannot create a DirectSound device\n"); FreeLibrary(p->hdsound_dll); return 0; } /* Set DirectSound Cooperative level, ie what control we want over Windows * sound device. In our case, DSSCL_EXCLUSIVE means that we can modify the * settings of the primary buffer, but also that only the sound of our * application will be hearable when it will have the focus. * !!! (this is not really working as intended yet because to set the * cooperative level you need the window handle of your application, and * I don't know of any easy way to get it. Especially since we might play * sound without any video, and so what window handle should we use ??? * The hack for now is to use the Desktop window handle - it seems to be * working */ if (IDirectSound_SetCooperativeLevel(p->hds, GetDesktopWindow(), DSSCL_EXCLUSIVE)) { MP_ERR(ao, "cannot set direct sound cooperative level\n"); IDirectSound_Release(p->hds); FreeLibrary(p->hdsound_dll); return 0; } MP_VERBOSE(ao, "DirectSound initialized\n"); memset(&dscaps, 0, sizeof(DSCAPS)); dscaps.dwSize = sizeof(DSCAPS); if (DS_OK == IDirectSound_GetCaps(p->hds, &dscaps)) { if (dscaps.dwFlags & DSCAPS_EMULDRIVER) MP_VERBOSE(ao, "DirectSound is emulated\n"); } else { MP_VERBOSE(ao, "cannot get device capabilities\n"); } return 1; }
int DSSetupSound() { HRESULT dsval; WAVEFORMATEX pcmwf; dsval = DirectSoundCreate(NULL,&lpDS,NULL); if(dsval != DS_OK) { MessageBox(hWMain,"DirectSoundCreate!","Error",MB_OK); return -1; } if(DS_OK != IDirectSound_SetCooperativeLevel(lpDS,hWMain, DSSCL_PRIORITY)) { if(DS_OK != IDirectSound_SetCooperativeLevel(lpDS,hWMain, DSSCL_NORMAL)) { MessageBox(hWMain,"SetCooperativeLevel!","Error",MB_OK); return -1; } } memset(&dsbd,0,sizeof(DSBUFFERDESC)); dsbd.dwSize = sizeof(DSBUFFERDESC); // NT4 hack! sizeof(dsbd); dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbd.dwBufferBytes = 0; dsbd.lpwfxFormat = NULL; dsval = IDirectSound_CreateSoundBuffer(lpDS,&dsbd,&lpDSBPRIMARY,NULL); if(dsval != DS_OK) { MessageBox(hWMain, "CreateSoundBuffer (Primary)", "Error",MB_OK); return -1; } memset(&pcmwf, 0, sizeof(WAVEFORMATEX)); pcmwf.wFormatTag = WAVE_FORMAT_PCM; pcmwf.nChannels = 2; pcmwf.nBlockAlign = 4; pcmwf.nSamplesPerSec = SAMPLE_RATE; pcmwf.nAvgBytesPerSec = pcmwf.nSamplesPerSec * pcmwf.nBlockAlign; pcmwf.wBitsPerSample = 16; dsval = IDirectSoundBuffer_SetFormat(lpDSBPRIMARY,&pcmwf); if(dsval != DS_OK) { MessageBox(hWMain, "SetFormat!", "Error",MB_OK); return -1; } dscaps.dwSize = sizeof(DSCAPS); dsbcaps.dwSize = sizeof(DSBCAPS); IDirectSound_GetCaps(lpDS,&dscaps); IDirectSoundBuffer_GetCaps(lpDSBPRIMARY,&dsbcaps); memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); // NT4 hack! sizeof(DSBUFFERDESC); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_LOCHARDWARE | DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2; dsbdesc.dwBufferBytes = SOUNDSIZE; dsbdesc.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf; dsval = IDirectSound_CreateSoundBuffer(lpDS,&dsbdesc,&lpDSBSECONDARY1,NULL); if(dsval != DS_OK) { dsbdesc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2; dsval = IDirectSound_CreateSoundBuffer(lpDS,&dsbdesc,&lpDSBSECONDARY1,NULL); if(dsval != DS_OK) { MessageBox(hWMain,"CreateSoundBuffer (Secondary1)", "Error",MB_OK); return -1; } } dsval = IDirectSoundBuffer_Play(lpDSBPRIMARY,0,0,DSBPLAY_LOOPING); if(dsval != DS_OK) { MessageBox(hWMain,"Play (Primary)","Error",MB_OK); return -1; } dsval = IDirectSoundBuffer_Play(lpDSBSECONDARY1,0,0,DSBPLAY_LOOPING); if(dsval != DS_OK) { MessageBox(hWMain,"Play (Secondary1)","Error",MB_OK); return -1; } // init some play vars LastWrite = 0x00000000; LastPlay = 0; return 0; }
void I_InitSound(void) { // proff 07/04/98: Added for CYGWIN32 compatibility #ifdef HAVE_LIBDSOUND HRESULT error; int c; int i; #endif // HAVE_LIBDSOUND // proff 07/01/98: Added I_InitMusic if (!nomusicparm) I_InitMusic(); if (nosfxparm) return; // proff 07/04/98: Added for CYGWIN32 compatibility #ifdef HAVE_LIBDSOUND // proff 11/21/98: Added DirectSound device selection i = M_CheckParm ("-dsounddevice"); if ((i) || (snd_dsounddevice)) { printf("I_InitSound: Sound Devices\n"); DirectSoundEnumerate(&DSEnumCallback,NULL); DSoundDevice=snd_dsounddevice; if (i) DSoundDevice=atoi(myargv[i+1]); DSoundDevice= (DSoundDevice < 0) ? 0 : (DSoundDevice >= DSDeviceCount) ? 0 : DSoundDevice; } printf("I_InitSound: "); error = DirectSoundCreate(DSDeviceGUIDs[DSoundDevice], &lpDS, NULL); // proff 11/21/98: End of additions and changes if (error == DSERR_NODRIVER) { lpDS = NULL; printf("no sounddevice found\n"); noDSound = true; return; } noDSound = false; if (error != DS_OK) { noDSound = true; return; } // open the hidden sound window we use to play sounds through OpenSoundWnd(); printf("created DirectSound. Selected Device: %i\n", DSoundDevice); atexit(I_ShutdownSound); error = IDirectSound_SetCooperativeLevel(lpDS, soundWnd , DSSCL_EXCLUSIVE); if (error != DS_OK) { noDSound = true; return; } printf("I_InitSound: "); printf("CooperativeLevel set\n"); printf("I_InitSound: "); // error is returned but it works ... ?? error = CreatePrimaryBuffer(); // if (error != DS_OK) // { // printf("ERROR: Couldnt create primary buffer\n"); // noDSound = true; // return; // } numChannels = default_numChannels; lpSecondaryDSB = malloc(sizeof(LPDIRECTSOUNDBUFFER)*numChannels); if (lpSecondaryDSB) { memset(lpSecondaryDSB, 0, sizeof(LPDIRECTSOUNDBUFFER) * numChannels); printf ("Channels : %i\n", numChannels); } else { noDSound = true; return; } ChannelInfo = malloc(sizeof(channel_info_t)*numChannels); if (ChannelInfo) { // proff 11/09/98: Added for security memset(ChannelInfo, 0, sizeof(channel_info_t) * numChannels); } else { noDSound = true; return; } for (c=0; c<numChannels; c++) { error = CreateSecondaryBuffer(&lpSecondaryDSB[c], 65535); if (error != DS_OK) { noDSound = true; return; } } printf("DirectSound initialised ok!\n"); #endif // HAVE_LIBDSOUND }
static int DS_Init(void) { DSBUFFERDESC soundBufferFormat; WAVEFORMATEX pcmwf; DSBPOSITIONNOTIFY positionNotifications[2]; DWORD updateBufferThreadID; LPVOID p = NULL; if (DirectSoundCreate(NULL,&pSoundCard,NULL)!=DS_OK) { _mm_errno=MMERR_OPENING_AUDIO; return 1; } if (IDirectSound_SetCooperativeLevel (pSoundCard,GetForegroundWindow(),DSSCL_PRIORITY)!=DS_OK) { _mm_errno=MMERR_DS_PRIORITY; return 1; } memset(&soundBufferFormat,0,sizeof(DSBUFFERDESC)); soundBufferFormat.dwSize = sizeof(DSBUFFERDESC); soundBufferFormat.dwFlags = DSBCAPS_PRIMARYBUFFER; soundBufferFormat.dwBufferBytes = 0; soundBufferFormat.lpwfxFormat = NULL; if (IDirectSound_CreateSoundBuffer (pSoundCard,&soundBufferFormat,&pPrimarySoundBuffer,NULL)!=DS_OK) { _mm_errno=MMERR_DS_BUFFER; return 1; } memset(&pcmwf,0,sizeof(WAVEFORMATEX)); pcmwf.wFormatTag =(md_mode&DMODE_FLOAT)? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM; pcmwf.nChannels =(md_mode&DMODE_STEREO)?2:1; pcmwf.nSamplesPerSec =md_mixfreq; pcmwf.wBitsPerSample =(md_mode&DMODE_FLOAT)?32:(md_mode&DMODE_16BITS)?16:8; pcmwf.nBlockAlign =(pcmwf.wBitsPerSample * pcmwf.nChannels) / 8; pcmwf.nAvgBytesPerSec=pcmwf.nSamplesPerSec*pcmwf.nBlockAlign; if (IDirectSoundBuffer_SetFormat(pPrimarySoundBuffer,&pcmwf)!=DS_OK) { _mm_errno=MMERR_DS_FORMAT; return 1; } IDirectSoundBuffer_Play(pPrimarySoundBuffer,0,0,DSBPLAY_LOOPING); memset(&soundBufferFormat,0,sizeof(DSBUFFERDESC)); soundBufferFormat.dwSize =sizeof(DSBUFFERDESC); soundBufferFormat.dwFlags =controlflags|DSBCAPS_GETCURRENTPOSITION2 ; soundBufferFormat.dwBufferBytes =fragsize*UPDATES; soundBufferFormat.lpwfxFormat =&pcmwf; if (IDirectSound_CreateSoundBuffer (pSoundCard,&soundBufferFormat,&pSoundBuffer,NULL)!=DS_OK) { _mm_errno=MMERR_DS_BUFFER; return 1; } #ifdef __cplusplus IDirectSoundBuffer_QueryInterface(pSoundBuffer, IID_IDirectSoundNotify,&p); #else IDirectSoundBuffer_QueryInterface(pSoundBuffer,&IID_IDirectSoundNotify,&p); #endif if (!p) { _mm_errno=MMERR_DS_NOTIFY; return 1; } pSoundBufferNotify = (LPDIRECTSOUNDNOTIFY) p; notifyUpdateHandle=CreateEvent (NULL,FALSE,FALSE,"libmikmod DirectSound Driver positionNotify Event"); if (!notifyUpdateHandle) { _mm_errno=MMERR_DS_EVENT; return 1; } updateBufferHandle=CreateThread (NULL,0,updateBufferProc,NULL,CREATE_SUSPENDED,&updateBufferThreadID); if (!updateBufferHandle) { _mm_errno=MMERR_DS_THREAD; return 1; } memset(positionNotifications,0,2*sizeof(DSBPOSITIONNOTIFY)); positionNotifications[0].dwOffset =0; positionNotifications[0].hEventNotify=notifyUpdateHandle; positionNotifications[1].dwOffset =fragsize; positionNotifications[1].hEventNotify=notifyUpdateHandle; if (IDirectSoundNotify_SetNotificationPositions (pSoundBufferNotify,2,positionNotifications) != DS_OK) { _mm_errno=MMERR_DS_UPDATE; return 1; } #if defined HAVE_SSE2 /* this test only works on Windows XP or later */ if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) { md_mode|=DMODE_SIMDMIXER; } #endif return VC_Init(); }
/************************************************************************** * MCICDA_Play [internal] */ static DWORD MCICDA_Play(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) { WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID); DWORD ret = 0, start, end; HANDLE oldcb; DWORD br; CDROM_PLAY_AUDIO_MSF play; CDROM_SUB_Q_DATA_FORMAT fmt; SUB_Q_CHANNEL_DATA data; CDROM_TOC toc; TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms); if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK; if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID; if (!DeviceIoControl(wmcda->handle, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &br, NULL)) { WARN("error reading TOC !\n"); return MCICDA_GetError(wmcda); } if (dwFlags & MCI_FROM) { start = MCICDA_CalcFrame(wmcda, lpParms->dwFrom); if ( (ret=MCICDA_SkipDataTracks(wmcda, &start)) ) return ret; TRACE("MCI_FROM=%08X -> %u\n", lpParms->dwFrom, start); } else { fmt.Format = IOCTL_CDROM_CURRENT_POSITION; if (!DeviceIoControl(wmcda->handle, IOCTL_CDROM_READ_Q_CHANNEL, &fmt, sizeof(fmt), &data, sizeof(data), &br, NULL)) { return MCICDA_GetError(wmcda); } start = FRAME_OF_ADDR(data.CurrentPosition.AbsoluteAddress); if ( (ret=MCICDA_SkipDataTracks(wmcda, &start)) ) return ret; } if (dwFlags & MCI_TO) { end = MCICDA_CalcFrame(wmcda, lpParms->dwTo); if ( (ret=MCICDA_SkipDataTracks(wmcda, &end)) ) return ret; TRACE("MCI_TO=%08X -> %u\n", lpParms->dwTo, end); } else { end = FRAME_OF_TOC(toc, toc.LastTrack + 1) - 1; } if (end < start) return MCIERR_OUTOFRANGE; TRACE("Playing from %u to %u\n", start, end); oldcb = InterlockedExchangePointer(&wmcda->hCallback, (dwFlags & MCI_NOTIFY) ? HWND_32(LOWORD(lpParms->dwCallback)) : NULL); if (oldcb) mciDriverNotify(oldcb, wmcda->wNotifyDeviceID, MCI_NOTIFY_ABORTED); if (start == end || start == FRAME_OF_TOC(toc,toc.LastTrack+1)-1) { if (dwFlags & MCI_NOTIFY) { oldcb = InterlockedExchangePointer(&wmcda->hCallback, NULL); if (oldcb) mciDriverNotify(oldcb, wDevID, MCI_NOTIFY_SUCCESSFUL); } return MMSYSERR_NOERROR; } if (wmcda->hThread != 0) { SetEvent(wmcda->stopEvent); WaitForSingleObject(wmcda->hThread, INFINITE); CloseHandle(wmcda->hThread); wmcda->hThread = 0; CloseHandle(wmcda->stopEvent); wmcda->stopEvent = 0; IDirectSoundBuffer_Stop(wmcda->dsBuf); IDirectSoundBuffer_Release(wmcda->dsBuf); wmcda->dsBuf = NULL; IDirectSound_Release(wmcda->dsObj); wmcda->dsObj = NULL; } if (pDirectSoundCreate) { WAVEFORMATEX format; DSBUFFERDESC desc; DWORD lockLen; void *cdData; HRESULT hr; hr = pDirectSoundCreate(NULL, &wmcda->dsObj, NULL); if (SUCCEEDED(hr)) { IDirectSound_SetCooperativeLevel(wmcda->dsObj, GetDesktopWindow(), DSSCL_PRIORITY); /* The "raw" frame is relative to the start of the first track */ wmcda->start = start - FRAME_OF_TOC(toc, toc.FirstTrack); wmcda->end = end - FRAME_OF_TOC(toc, toc.FirstTrack); 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.nSamplesPerSec * format.nBlockAlign; format.cbSize = 0; memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); desc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS; desc.dwBufferBytes = (CDDA_FRAG_SIZE - (CDDA_FRAG_SIZE%RAW_SECTOR_SIZE)) * CDDA_FRAG_COUNT; desc.lpwfxFormat = &format; hr = IDirectSound_CreateSoundBuffer(wmcda->dsObj, &desc, &wmcda->dsBuf, NULL); } if (SUCCEEDED(hr)) { hr = IDirectSoundBuffer_Lock(wmcda->dsBuf, 0, 0, &cdData, &lockLen, NULL, NULL, DSBLOCK_ENTIREBUFFER); } if (SUCCEEDED(hr)) { RAW_READ_INFO rdInfo; int readok; rdInfo.DiskOffset.QuadPart = wmcda->start<<11; rdInfo.SectorCount = min(desc.dwBufferBytes/RAW_SECTOR_SIZE, wmcda->end-wmcda->start); rdInfo.TrackMode = CDDA; readok = DeviceIoControl(wmcda->handle, IOCTL_CDROM_RAW_READ, &rdInfo, sizeof(rdInfo), cdData, lockLen, &br, NULL); IDirectSoundBuffer_Unlock(wmcda->dsBuf, cdData, lockLen, NULL, 0); if (readok) { wmcda->start += rdInfo.SectorCount; wmcda->stopEvent = CreateEventA(NULL, TRUE, FALSE, NULL); } if (wmcda->stopEvent != 0) wmcda->hThread = CreateThread(NULL, 0, MCICDA_playLoop, wmcda, 0, &br); if (wmcda->hThread != 0) { hr = IDirectSoundBuffer_Play(wmcda->dsBuf, 0, 0, DSBPLAY_LOOPING); if (SUCCEEDED(hr)) { /* FIXME: implement MCI_WAIT and send notification only in that case */ if (0) { oldcb = InterlockedExchangePointer(&wmcda->hCallback, NULL); if (oldcb) mciDriverNotify(oldcb, wmcda->wNotifyDeviceID, FAILED(hr) ? MCI_NOTIFY_FAILURE : MCI_NOTIFY_SUCCESSFUL); } return ret; } SetEvent(wmcda->stopEvent); WaitForSingleObject(wmcda->hThread, INFINITE); CloseHandle(wmcda->hThread); wmcda->hThread = 0; } } if (wmcda->stopEvent != 0) { CloseHandle(wmcda->stopEvent); wmcda->stopEvent = 0; } if (wmcda->dsBuf) { IDirectSoundBuffer_Release(wmcda->dsBuf); wmcda->dsBuf = NULL; } if (wmcda->dsObj) { IDirectSound_Release(wmcda->dsObj); wmcda->dsObj = NULL; } } play.StartingM = start / CDFRAMES_PERMIN; play.StartingS = (start / CDFRAMES_PERSEC) % 60; play.StartingF = start % CDFRAMES_PERSEC; play.EndingM = end / CDFRAMES_PERMIN; play.EndingS = (end / CDFRAMES_PERSEC) % 60; play.EndingF = end % CDFRAMES_PERSEC; if (!DeviceIoControl(wmcda->handle, IOCTL_CDROM_PLAY_AUDIO_MSF, &play, sizeof(play), NULL, 0, &br, NULL)) { wmcda->hCallback = NULL; ret = MCIERR_HARDWARE; } /* The independent CD player has no means to signal MCI_NOTIFY when it's done. * Native sends a notification with MCI_WAIT only. */ return ret; }
HRESULT DSW_InitOutputBuffer( DSoundWrapper *dsw, unsigned long nFrameRate, int nChannels, int bytesPerBuffer ) { DWORD dwDataLen; DWORD playCursor; HRESULT result; LPDIRECTSOUNDBUFFER pPrimaryBuffer; HWND hWnd; HRESULT hr; WAVEFORMATEX wfFormat; DSBUFFERDESC primaryDesc; DSBUFFERDESC secondaryDesc; unsigned char* pDSBuffData; LARGE_INTEGER counterFrequency; dsw->dsw_OutputSize = bytesPerBuffer; dsw->dsw_OutputRunning = FALSE; dsw->dsw_OutputUnderflows = 0; dsw->dsw_FramesWritten = 0; dsw->dsw_BytesPerFrame = nChannels * sizeof(short); // We were using getForegroundWindow() but sometimes the ForegroundWindow may not be the // applications's window. Also if that window is closed before the Buffer is closed // then DirectSound can crash. (Thanks for Scott Patterson for reporting this.) // So we will use GetDesktopWindow() which was suggested by Miller Puckette. // hWnd = GetForegroundWindow(); hWnd = GetDesktopWindow(); // Set cooperative level to DSSCL_EXCLUSIVE so that we can get 16 bit output, 44.1 KHz. // Exclusize also prevents unexpected sounds from other apps during a performance. if ((hr = IDirectSound_SetCooperativeLevel( dsw->dsw_pDirectSound, hWnd, DSSCL_EXCLUSIVE)) != DS_OK) { return hr; } // ----------------------------------------------------------------------- // Create primary buffer and set format just so we can specify our custom format. // Otherwise we would be stuck with the default which might be 8 bit or 22050 Hz. // Setup the primary buffer description ZeroMemory(&primaryDesc, sizeof(DSBUFFERDESC)); primaryDesc.dwSize = sizeof(DSBUFFERDESC); primaryDesc.dwFlags = DSBCAPS_PRIMARYBUFFER; // all panning, mixing, etc done by synth primaryDesc.dwBufferBytes = 0; primaryDesc.lpwfxFormat = NULL; // Create the buffer if ((result = IDirectSound_CreateSoundBuffer( dsw->dsw_pDirectSound, &primaryDesc, &pPrimaryBuffer, NULL)) != DS_OK) return result; // Define the buffer format wfFormat.wFormatTag = WAVE_FORMAT_PCM; wfFormat.nChannels = nChannels; wfFormat.nSamplesPerSec = nFrameRate; wfFormat.wBitsPerSample = 8 * sizeof(short); wfFormat.nBlockAlign = wfFormat.nChannels * wfFormat.wBitsPerSample / 8; wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign; wfFormat.cbSize = 0; /* No extended format info. */ // Set the primary buffer's format if((result = IDirectSoundBuffer_SetFormat( pPrimaryBuffer, &wfFormat)) != DS_OK) return result; // ---------------------------------------------------------------------- // Setup the secondary buffer description ZeroMemory(&secondaryDesc, sizeof(DSBUFFERDESC)); secondaryDesc.dwSize = sizeof(DSBUFFERDESC); secondaryDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2; secondaryDesc.dwBufferBytes = bytesPerBuffer; secondaryDesc.lpwfxFormat = &wfFormat; // Create the secondary buffer if ((result = IDirectSound_CreateSoundBuffer( dsw->dsw_pDirectSound, &secondaryDesc, &dsw->dsw_OutputBuffer, NULL)) != DS_OK) return result; // Lock the DS buffer if ((result = IDirectSoundBuffer_Lock( dsw->dsw_OutputBuffer, 0, dsw->dsw_OutputSize, (LPVOID*)&pDSBuffData, &dwDataLen, NULL, 0, 0)) != DS_OK) return result; // Zero the DS buffer ZeroMemory(pDSBuffData, dwDataLen); // Unlock the DS buffer if ((result = IDirectSoundBuffer_Unlock( dsw->dsw_OutputBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) return result; if( QueryPerformanceFrequency( &counterFrequency ) ) { int framesInBuffer = bytesPerBuffer / (nChannels * sizeof(short)); dsw->dsw_CounterTicksPerBuffer.QuadPart = (counterFrequency.QuadPart * framesInBuffer) / nFrameRate; AddTraceMessage("dsw_CounterTicksPerBuffer = %d\n", dsw->dsw_CounterTicksPerBuffer.LowPart ); } else { dsw->dsw_CounterTicksPerBuffer.QuadPart = 0; } // Let DSound set the starting write position because if we set it to zero, it looks like the // buffer is full to begin with. This causes a long pause before sound starts when using large buffers. hr = IDirectSoundBuffer_GetCurrentPosition( dsw->dsw_OutputBuffer, &playCursor, &dsw->dsw_WriteOffset ); if( hr != DS_OK ) { return hr; } dsw->dsw_FramesWritten = dsw->dsw_WriteOffset / dsw->dsw_BytesPerFrame; /* printf("DSW_InitOutputBuffer: playCursor = %d, writeCursor = %d\n", playCursor, dsw->dsw_WriteOffset ); */ return DS_OK; }
int ghettoInit(GhettoBufferCallback *callback, void *hwnd) { static const WAVEFORMATEX wfxprimary = { WAVE_FORMAT_PCM, 1, 44100, 44100*2, 2, 16, 0 }; //static const WAVEFORMATEX wfxprimary = { WAVE_FORMAT_PCM, 2, 44100, 44100*2*2, 2*2, 16, 0 }; static const DSBUFFERDESC primdesc = { sizeof(DSBUFFERDESC), DSBCAPS_PRIMARYBUFFER, 0, 0, 0 }; static const DSBUFFERDESC streamdesc = { sizeof(DSBUFFERDESC), DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS, BUFFERLEN, 0, (WAVEFORMATEX*)&wfxprimary }; ZeroMemory(&g_dsound, sizeof(g_dsound)); g_dsound.callback = callback; void *buf1, *buf2; DWORD len1, len2; if (DirectSoundCreate(0, &g_dsound.dssd, 0) != S_OK) printf("dsc\n"); if (IDirectSound_SetCooperativeLevel(g_dsound.dssd, (HWND)hwnd, DSSCL_PRIORITY) != S_OK) printf("setcooperative\n"); if (IDirectSound_CreateSoundBuffer(g_dsound.dssd, &primdesc, &g_dsound.pbuf, 0) != S_OK) printf("createsoundbuffer\n"); if(IDirectSound_CreateSoundBuffer(g_dsound.dssd, &streamdesc, &g_dsound.sbuf, 0) != S_OK) printf("createsoundbuffer2\n"); if (IDirectSoundBuffer_SetFormat(g_dsound.pbuf, &wfxprimary) != S_OK) printf("setformat\n"); if (IDirectSoundBuffer_Lock(g_dsound.sbuf, 0, 0, &buf1, &len1, &buf2, &len2, DSBLOCK_ENTIREBUFFER) != S_OK) // lock secondary buf { printf("lock failed\n"); goto fail; } // clear secondary buffer memset(buf1, 0, len1); memset(buf2, 0, len2); if (IDirectSoundBuffer_Unlock(g_dsound.sbuf, buf1, len1, buf2, len2) != S_OK) goto fail; g_dsound.bufcnt = -BUFFERLEN; g_dsound.ltg = -BUFFERLEN; g_dsound.tickev = CreateEvent(0, FALSE, FALSE, 0); g_dsound.exitev = CreateEvent(0, FALSE, FALSE, 0); InitializeCriticalSection(&g_dsound.crsec); if (IDirectSoundBuffer_Play(g_dsound.sbuf, 0, 0, DSBPLAY_LOOPING) != S_OK) { printf("play failed\n"); goto fail; } IDirectSoundBuffer_SetVolume(g_dsound.sbuf, 5000); // start sound thread g_dsound.thndl = CreateThread(0, 0, bufferLoop, 0, 0, &len1); SetThreadPriority(g_dsound.thndl, THREAD_PRIORITY_ABOVE_NORMAL); return 0; fail: ghettoClose(); return -1; }
/* SNDDMA_InitDirect Direct-Sound support */ sndinitstat SNDDMA_InitDirect (void) { DSBUFFERDESC dsbuf; DSBCAPS dsbcaps; DWORD dwSize, dwWrite; DSCAPS dscaps; WAVEFORMATEX format, pformat; HRESULT hresult; int reps; memset ((void *) &sn, 0, sizeof (sn)); shm = &sn; shm->channels = 2; shm->samplebits = 16; shm->speed = 11025; memset (&format, 0, sizeof (format)); format.wFormatTag = WAVE_FORMAT_PCM; format.nChannels = shm->channels; format.wBitsPerSample = shm->samplebits; format.nSamplesPerSec = shm->speed; format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; format.cbSize = 0; format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; if (!hInstDS) { hInstDS = LoadLibrary ("dsound.dll"); if (hInstDS == NULL) { Con_Printf ("Couldn't load dsound.dll\n"); return SIS_FAILURE; } pDirectSoundCreate = (void *) GetProcAddress (hInstDS, "DirectSoundCreate"); if (!pDirectSoundCreate) { Con_Printf ("Couldn't get DS proc addr\n"); return SIS_FAILURE; } } while ((hresult = iDirectSoundCreate (NULL, &pDS, NULL)) != DS_OK) { if (hresult != DSERR_ALLOCATED) { Con_Printf ("DirectSound create failed\n"); return SIS_FAILURE; } Con_Printf ("DirectSoundCreate failure\n" " hardware already in use\n"); return SIS_NOTAVAIL; } dscaps.dwSize = sizeof (dscaps); if (DS_OK != IDirectSound_GetCaps (pDS, &dscaps)) { Con_Printf ("Couldn't get DS caps\n"); } if (dscaps.dwFlags & DSCAPS_EMULDRIVER) { Con_Printf ("No DirectSound driver installed\n"); FreeSound (); return SIS_FAILURE; } if (DS_OK != IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE)) { Con_Printf ("Set coop level failed\n"); FreeSound (); return SIS_FAILURE; } // 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; dsbuf.dwBufferBytes = 0; dsbuf.lpwfxFormat = NULL; memset (&dsbcaps, 0, sizeof (dsbcaps)); dsbcaps.dwSize = sizeof (dsbcaps); primary_format_set = false; if (!COM_CheckParm ("-snoforceformat")) { if (DS_OK == IDirectSound_CreateSoundBuffer (pDS, &dsbuf, &pDSPBuf, NULL)) { pformat = format; if (DS_OK != IDirectSoundBuffer_SetFormat (pDSPBuf, &pformat)) { } else primary_format_set = true; } } if (!primary_format_set || !COM_CheckParm ("-primarysound")) { // create the secondary buffer we'll actually work with memset (&dsbuf, 0, sizeof (dsbuf)); dsbuf.dwSize = sizeof (DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE; dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE; dsbuf.lpwfxFormat = &format; memset (&dsbcaps, 0, sizeof (dsbcaps)); dsbcaps.dwSize = sizeof (dsbcaps); if (DS_OK != IDirectSound_CreateSoundBuffer (pDS, &dsbuf, &pDSBuf, NULL)) { Con_Printf ("DS:CreateSoundBuffer Failed"); FreeSound (); return SIS_FAILURE; } shm->channels = format.nChannels; shm->samplebits = format.wBitsPerSample; shm->speed = format.nSamplesPerSec; if (DS_OK != IDirectSound_GetCaps (pDSBuf, &dsbcaps)) { Con_Printf ("DS:GetCaps failed\n"); FreeSound (); return SIS_FAILURE; } } else { if (DS_OK != IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_WRITEPRIMARY)) { Con_Printf ("Set coop level failed\n"); FreeSound (); return SIS_FAILURE; } if (DS_OK != IDirectSound_GetCaps (pDSPBuf, &dsbcaps)) { Con_Printf ("DS:GetCaps failed\n"); return SIS_FAILURE; } pDSBuf = pDSPBuf; } // Make sure mixer is active IDirectSoundBuffer_Play (pDSBuf, 0, 0, DSBPLAY_LOOPING); gSndBufSize = dsbcaps.dwBufferBytes; // initialize the buffer reps = 0; while ((hresult = IDirectSoundBuffer_Lock (pDSBuf, 0, gSndBufSize, (LPVOID *) & lpData, &dwSize, NULL,NULL, 0)) != DS_OK) { if (hresult != DSERR_BUFFERLOST) { Con_Printf ("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n"); FreeSound (); return SIS_FAILURE; } if (++reps > 10000) { Con_Printf ("SNDDMA_InitDirect: DS: couldn't restore buffer\n"); FreeSound (); return SIS_FAILURE; } } memset (lpData, 0, dwSize); // lpData[4] = lpData[5] = 0x7f; // force a pop for debugging IDirectSoundBuffer_Unlock (pDSBuf, lpData, dwSize, NULL, 0); /* we don't want anyone to access the buffer directly w/o locking it first. */ lpData = NULL; IDirectSoundBuffer_Stop (pDSBuf); IDirectSoundBuffer_GetCurrentPosition (pDSBuf, &mmstarttime.u.sample, &dwWrite); IDirectSoundBuffer_Play (pDSBuf, 0, 0, DSBPLAY_LOOPING); shm->soundalive = true; shm->splitbuffer = false; shm->samples = gSndBufSize / (shm->samplebits / 8); shm->samplepos = 0; shm->submission_chunk = 1; shm->buffer = (unsigned char *) lpData; sample16 = (shm->samplebits / 8) - 1; dsound_init = true; return SIS_SUCCESS; }
int I2_Init() { DSBUFFERDESC desc; LPDIRECTSOUNDBUFFER bufTemp; if(initOk) return true; // Don't init a second time. if(FAILED(hr = EAXDirectSoundCreate(NULL, &dsound, NULL))) { // EAX can't be initialized. Use normal DS, then. ST_Message("I2_Init: EAX 2 couldn't be initialized (result: %i).\n", hr & 0xffff); if(FAILED(hr = DirectSoundCreate(NULL, &dsound, NULL))) { ST_Message("I2_Init: Couldn't create dsound (result: %i).\n", hr & 0xffff); return false; } } // Set the cooperative level. if(FAILED(hr = IDirectSound_SetCooperativeLevel(dsound, hWndMain, DSSCL_PRIORITY))) { ST_Message("I2_Init: Couldn't set dSound cooperative level (result: %i).\n", hr & 0xffff); return false; } // Get the listener. memset(&desc, 0, sizeof(desc)); desc.dwSize = sizeof(desc); desc.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER; if(SUCCEEDED(IDirectSound_CreateSoundBuffer(dsound, &desc, &bufTemp, NULL))) { // Query the listener interface. IDirectSoundBuffer_QueryInterface(bufTemp, &IID_IDirectSound3DListener, &dsListener); } // Release the primary buffer interface, we won't need it. IDirectSoundBuffer_Release(bufTemp); // Try to get the EAX listener property set. Create a temporary secondary buffer for it. if(SUCCEEDED( createDSBuffer(DSBCAPS_STATIC | DSBCAPS_CTRL3D, DSBSIZE_MIN, 22050, 8, 1, &bufTemp) )) { // Now try to get the property set. if(SUCCEEDED(hr = IDirectSoundBuffer_QueryInterface(bufTemp, &IID_IKsPropertySet, &eaxListener))) { DWORD support = 0, revsize = 0; // Check for support. if(FAILED(hr = IKsPropertySet_QuerySupport(eaxListener, &DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT, &support)) || ((support & NEEDED_SUPPORT) != NEEDED_SUPPORT)) { ST_Message("I2_Init: Property set acquired, but EAX 2 not supported.\n Result:%i, support:%x\n", hr&0xffff, support); IKsPropertySet_Release(eaxListener); eaxListener = NULL; } else { // EAX is supported! ST_Message("I2_Init: EAX 2 available.\n"); } } // Release the temporary buffer interface. IDirectSoundBuffer_Release(bufTemp); } // Get the caps. dsCaps.dwSize = sizeof(dsCaps); IDirectSound_GetCaps(dsound, &dsCaps); ST_Message("I2_Init: Number of hardware 3D buffers: %i\n", dsCaps.dwMaxHw3DAllBuffers); // Configure the DS3D listener. if(dsListener) { IDirectSound3DListener_SetDistanceFactor(dsListener, 1/36.0f, DS3D_DEFERRED); IDirectSound3DListener_SetDopplerFactor(dsListener, 2, DS3D_DEFERRED); } // Success! initOk = true; return true; }
static SoundManager * CreateSoundManager(HWND hWnd ) { typedef HRESULT (WINAPI *DS_CREATE_FUNC)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN); PCMWAVEFORMAT pcmwf; DSBUFFERDESC dsbdesc; HRESULT hres; SoundManager * sm; DS_CREATE_FUNC pDirectSoundCreate; // load the DirectSound DLL hmodDirectSound = LoadLibrary ("DSOUND.DLL"); if (hmodDirectSound == NULL) { // Couldn't load DSOUND.DLL return NULL; } pDirectSoundCreate = (DS_CREATE_FUNC)GetProcAddress (hmodDirectSound, "DirectSoundCreate"); if (pDirectSoundCreate == NULL) { // couldn't find the DirectSoundCreate function FreeLibrary (hmodDirectSound); return NULL; } hres = pDirectSoundCreate(NULL, &lpDirectSound, NULL); if (hres != DS_OK) { // failed somehow FreeLibrary (hmodDirectSound); return NULL; } // sm = malloc(sizeof(*sm)); sm = geRam_Allocate(sizeof(*sm)); if (!sm) { IDirectSound_Release(lpDirectSound); FreeLibrary (hmodDirectSound); return NULL; } sm->smChannelCount = 0; sm->smNextChannelID = 1; sm->smChannels = NULL; memset(&pcmwf, 0, sizeof(PCMWAVEFORMAT)); pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; //pcmwf.wf.nChannels = 1; //pcmwf.wf.nSamplesPerSec = 44050; //pcmwf.wf.nBlockAlign = 2; #if 1 pcmwf.wf.nChannels = 2; pcmwf.wf.nSamplesPerSec = 44100; pcmwf.wf.nBlockAlign = 4; pcmwf.wBitsPerSample = 16; pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign; #else pcmwf.wf.nChannels = 1; pcmwf.wf.nSamplesPerSec = 22050; pcmwf.wf.nBlockAlign = 1; pcmwf.wBitsPerSample = 8; pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * 2; #endif memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); dsbdesc.dwSize = sizeof(DSBUFFERDESC); dsbdesc.dwFlags = DSBCAPS_PRIMARYBUFFER;// | DSBCAPS_CTRLDEFAULT;// | DSBCAPS_CTRL3D; dsbdesc.dwBufferBytes = 0; //dwBufferBytes and lpwfxFormat must be set this way. dsbdesc.lpwfxFormat = NULL; #if 1 if (DS_OK== IDirectSound_SetCooperativeLevel(lpDirectSound, hWnd,DSSCL_NORMAL)) #else if (DS_OK== IDirectSound_SetCooperativeLevel(lpDirectSound, hWnd,DSSCL_EXCLUSIVE)) #endif { if (DS_OK== IDirectSound_CreateSoundBuffer(lpDirectSound, &dsbdesc, &sm->smPrimaryChannel, NULL)) { return sm; } IDirectSound_Release(lpDirectSound); FreeLibrary (hmodDirectSound); } // free( sm ); geRam_Free(sm); return NULL; }
int DirectSoundDrv_PCM_Init(int * mixrate, int * numchannels, int * samplebits, void * initdata) { HRESULT err; DSBUFFERDESC bufdesc; WAVEFORMATEX wfex; if (Initialised) { DirectSoundDrv_PCM_Shutdown(); } err = DirectSoundCreate(0, &lpds, 0); if (FAILED( err )) { ErrorCode = DSErr_DirectSoundCreate; return DSErr_Error; } err = IDirectSound_SetCooperativeLevel(lpds, (HWND) initdata, DSSCL_PRIORITY); if (FAILED( err )) { TeardownDSound(err); ErrorCode = DSErr_SetCooperativeLevel; return DSErr_Error; } memset(&bufdesc, 0, sizeof(DSBUFFERDESC)); bufdesc.dwSize = sizeof(DSBUFFERDESC); bufdesc.dwFlags = DSBCAPS_PRIMARYBUFFER; err = IDirectSound_CreateSoundBuffer(lpds, &bufdesc, &lpdsbprimary, 0); if (FAILED( err )) { TeardownDSound(err); ErrorCode = DSErr_CreateSoundBuffer; return DSErr_Error; } memset(&wfex, 0, sizeof(WAVEFORMATEX)); wfex.wFormatTag = WAVE_FORMAT_PCM; wfex.nChannels = *numchannels; wfex.nSamplesPerSec = *mixrate; wfex.wBitsPerSample = *samplebits; wfex.nBlockAlign = wfex.nChannels * wfex.wBitsPerSample / 8; wfex.nAvgBytesPerSec = wfex.nSamplesPerSec * wfex.nBlockAlign; err = IDirectSoundBuffer_SetFormat(lpdsbprimary, &wfex); if (FAILED( err )) { TeardownDSound(err); ErrorCode = DSErr_SetFormat; return DSErr_Error; } bufdesc.dwFlags = DSBCAPS_LOCSOFTWARE | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2; bufdesc.dwBufferBytes = wfex.nBlockAlign * 2048 * 2; bufdesc.lpwfxFormat = &wfex; err = IDirectSound_CreateSoundBuffer(lpds, &bufdesc, &lpdsbsec, 0); if (FAILED( err )) { TeardownDSound(err); ErrorCode = DSErr_SetFormatSecondary; return DSErr_Error; } err = IDirectSoundBuffer_QueryInterface(lpdsbsec, &IID_IDirectSoundNotify, (LPVOID *) &lpdsnotify); if (FAILED( err )) { TeardownDSound(err); ErrorCode = DSErr_Notify; return DSErr_Error; } notifyPositions[0].dwOffset = 0; notifyPositions[0].hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL); notifyPositions[1].dwOffset = bufdesc.dwBufferBytes / 2; notifyPositions[1].hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL); notifyPositions[2].dwOffset = DSBPN_OFFSETSTOP; notifyPositions[2].hEventNotify = CreateEvent(NULL, FALSE, FALSE, NULL); if (!notifyPositions[0].hEventNotify || !notifyPositions[1].hEventNotify || !notifyPositions[2].hEventNotify) { TeardownDSound(DS_OK); ErrorCode = DSErr_NotifyEvents; return DSErr_Error; } err = IDirectSoundNotify_SetNotificationPositions(lpdsnotify, 3, notifyPositions); if (FAILED( err )) { TeardownDSound(err); ErrorCode = DSErr_SetNotificationPositions; return DSErr_Error; } err = IDirectSoundBuffer_Play(lpdsbprimary, 0, 0, DSBPLAY_LOOPING); if (FAILED( err )) { TeardownDSound(err); ErrorCode = DSErr_Play; return DSErr_Error; } mutex = CreateMutex(0, FALSE, 0); if (!mutex) { TeardownDSound(DS_OK); ErrorCode = DSErr_CreateMutex; return DSErr_Error; } Initialised = 1; fprintf(stderr, "DirectSound Init: yay\n"); return DSErr_Ok; }