📄 dsoundout.c
字号:
return DSOUND_Ok;}/* * DSOUND_Shutdown * Shuts down DirectSound and it's associates. */int32_t DSOUND_Shutdown(void){ int32_t i; if (DSOUND_Installed) initprintf("Uninitializing DirectSound...\n"); DSOUND_Installed = FALSE; DSOUND_StopPlayback(); if (lpDSNotify) { IDirectSoundNotify_Release(lpDSNotify); lpDSNotify = NULL; } if (hPosNotify) { for (i=0; i<_DSOUND_NumBuffers; i++) { if (hPosNotify[i]) CloseHandle(hPosNotify[i]); } free(hPosNotify); hPosNotify = NULL; } if (lpDSBSecondary) {// initprintf(" - Releasing secondary buffer\n"); IDirectSoundBuffer_Stop(lpDSBSecondary); IDirectSoundBuffer_Release(lpDSBSecondary); lpDSBSecondary = NULL; } if (lpDSBPrimary) {// initprintf(" - Releasing primary buffer\n"); IDirectSoundBuffer_Release(lpDSBPrimary); lpDSBPrimary = NULL; } if (lpDS) {// initprintf(" - Releasing DirectSound object\n"); IDirectSound_Release(lpDS); lpDS = NULL; } if (hDSoundDLL) {// initprintf(" - Unloading DSOUND.DLL\n"); FreeLibrary(hDSoundDLL); hDSoundDLL = NULL; } DSOUND_SetErrorCode(DSOUND_Ok); return DSOUND_Ok;}/* * DSOUND_SetMixMode * Bit of filler for the future. */int32_t DSOUND_SetMixMode(int32_t mode){ return mode;}//#define DEBUGAUDIO#ifdef DEBUGAUDIO#include <sys/stat.h>#endifstatic DWORD WINAPI isr(LPVOID parm){ HANDLE *handles; HRESULT hr; int32_t rv;#ifdef DEBUGAUDIO int32_t h;#endif int32_t p; LPVOID lockptr; DWORD lockbytes; LPVOID lockptr2; DWORD lockbytes2; UNREFERENCED_PARAMETER(parm); handles = (HANDLE *)malloc(sizeof(HANDLE)*(1+_DSOUND_NumBuffers)); if (!handles) return 1; handles[0] = isrfinish; for (p=0; p<_DSOUND_NumBuffers; p++) handles[p+1] = hPosNotify[p];#ifdef DEBUGAUDIO h = creat("audio.raw",S_IREAD|S_IWRITE);#endif while (1) {#ifdef USE_OPENAL AL_Update();#endif rv = WaitForMultipleObjects(1+_DSOUND_NumBuffers, handles, FALSE, INFINITE); if (!(rv >= WAIT_OBJECT_0 && rv <= WAIT_OBJECT_0+1+_DSOUND_NumBuffers)) return -1; if (rv == WAIT_OBJECT_0) { // we've been asked to finish up break; } // otherwise we just service the interrupt if (_DSOUND_CallBack) { DisableInterrupts(); p = _DSOUND_CallBack(rv-WAIT_OBJECT_0-1);#ifdef DEBUGAUDIO write(h, _DSOUND_MixBuffer + p*_DSOUND_BufferLength, _DSOUND_BufferLength);#endif hr = IDirectSoundBuffer_Lock(lpDSBSecondary, p*_DSOUND_BufferLength, _DSOUND_BufferLength, &lockptr, &lockbytes, &lockptr2, &lockbytes2, 0); if (hr == DSERR_BUFFERLOST) { hr = IDirectSoundBuffer_Restore(lpDSBSecondary); } if (hr == DS_OK) { /* #define copybuf(S,D,c) \ ({ void *__S=(S), *__D=(D); int32_t __c=(c); \ __asm__ __volatile__ ("rep; movsl" \ : "+S" (__S), "+D" (__D), "+c" (__c) : : "memory", "cc"); \ 0; }) */ //copybuf(_DSOUND_MixBuffer + p * _DSOUND_BufferLength, lockptr, _DSOUND_BufferLength >> 2); memcpy(lockptr, _DSOUND_MixBuffer + p * _DSOUND_BufferLength, _DSOUND_BufferLength); IDirectSoundBuffer_Unlock(lpDSBSecondary, lockptr, lockbytes, lockptr2, lockbytes2); } RestoreInterrupts(0); } }#ifdef DEBUGAUDIO close(h);#endif return 0;}/* * DSOUND_BeginBufferedPlayback * Spins off a thread that behaves somewhat like the SoundBlaster DMA ISR did. */int32_t DSOUND_BeginBufferedPlayback(char *BufferStart, int32_t(*CallBackFunc)(int32_t), int32_t buffersize, int32_t numdivisions){ DWORD threadid; HRESULT hr; DSBPOSITIONNOTIFY *posns; int32_t i; _DSOUND_CallBack = CallBackFunc; _DSOUND_MixBuffer = BufferStart; if (!lpDSBSecondary) return DSOUND_Error; if (isrthread) { DSOUND_StopPlayback(); } isrfinish = CreateEvent(NULL, TRUE, FALSE, NULL); if (!isrfinish) { DSOUND_SetErrorCode(DSOUND_FailedCreateFinishEvent); return DSOUND_Error; } isrthread = CreateThread(NULL, 0, isr, NULL, CREATE_SUSPENDED, &threadid); if (!isrthread) { DSOUND_SetErrorCode(DSOUND_FailedCreateThread); return DSOUND_Error; } hPosNotify = (HANDLE *)malloc(sizeof(HANDLE)*numdivisions); if (!hPosNotify) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedSetNotify); return DSOUND_Error; } memset(hPosNotify, 0, sizeof(HANDLE)*numdivisions); for (i=0; i<numdivisions; i++) { hPosNotify[i] = CreateEvent(NULL, FALSE, FALSE, NULL); if (!hPosNotify[i]) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedSetNotify); return DSOUND_Error; } } posns = (LPDSBPOSITIONNOTIFY)malloc(sizeof(DSBPOSITIONNOTIFY)*numdivisions); if (!posns) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedSetNotify); return DSOUND_Error; } _DSOUND_BufferLength = buffersize/numdivisions; _DSOUND_NumBuffers = numdivisions; for (i=0; i<numdivisions; i++) { posns[i].dwOffset = i*_DSOUND_BufferLength; posns[i].hEventNotify = hPosNotify[i]; } hr = IDirectSoundNotify_SetNotificationPositions(lpDSNotify, numdivisions, posns); if (hr != DS_OK) { free(posns); DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedSetNotify); return DSOUND_Error; } free(posns); SetThreadPriority(isrthread, THREAD_PRIORITY_ABOVE_NORMAL); ResumeThread(isrthread); hr = IDirectSoundBuffer_Play(lpDSBSecondary, 0, 0, DSBPLAY_LOOPING); if (hr != DS_OK) { DSOUND_SetErrorCode(DSOUND_FailedPlaySecondary); return DSOUND_Error; } return DSOUND_Ok;}/* * DSOUND_StopPlayback * Halts the playback thread. */int32_t DSOUND_StopPlayback(void){// DWORD exitcode; int32_t i; if (isrthread) { SetEvent(isrfinish);// initprintf("DirectSound: Waiting for sound thread to exit\n");// if (WaitForSingleObject(isrthread, 300) == WAIT_OBJECT_0)// initprintf("DirectSound: Sound thread has exited\n");// else// initprintf("DirectSound: Sound thread failed to exit!\n"); if (WaitForSingleObject(isrthread, 300) != WAIT_OBJECT_0) initprintf("DirectSound: Sound thread failed to exit!\n"); /* while (1) { if (!GetExitCodeThread(isrthread, &exitcode)) { DSOUND_SetErrorCode(DSOUND_FailedGetExitCode); return DSOUND_Warning; } if (exitcode != STILL_ACTIVE) break; }*/ CloseHandle(isrthread); isrthread = NULL; } if (isrfinish) { CloseHandle(isrfinish); isrfinish = NULL; } if (lpDSBSecondary) { IDirectSoundBuffer_Stop(lpDSBSecondary); } if (hPosNotify) { for (i=0; i<_DSOUND_NumBuffers; i++) { if (hPosNotify[i]) CloseHandle(hPosNotify[i]); } free(hPosNotify); hPosNotify = NULL; } return DSOUND_Ok;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -