📄 dsoundout.c
字号:
/* * DirectSound output code for MultiVoc * by Jonathon Fowler (jonof@edgenetwk.com) *///-------------------------------------------------------------------------/*Duke Nukem Copyright (C) 1996, 2003 3D Realms EntertainmentThis file is part of Duke Nukem 3D version 1.5 - Atomic EditionDuke Nukem 3D is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*///-------------------------------------------------------------------------#include "dsound.h"#include "dsoundout.h"#define WIN32_LEAN_AND_MEAN#include <windows.h>#include <mmsystem.h>#include <stdio.h>#include <string.h>#ifdef USE_OPENAL#include "openal.h"#endif#include "compat.h"#include "winlayer.h"#if defined(__WATCOMC__) || defined(_MSC_VER)#include <malloc.h>#endif#ifndef RENDERTYPEWIN#error The DirectSound output module for AudioLib only works with the Windows interface.#endifstatic CRITICAL_SECTION mutex;static int32_t _DSOUND_CriticalSectionAlloced = FALSE;static HANDLE isrthread = NULL;static HANDLE isrfinish = NULL;static HMODULE hDSoundDLL = NULL;static LPDIRECTSOUND lpDS = NULL;static LPDIRECTSOUNDBUFFER lpDSBPrimary = NULL;static LPDIRECTSOUNDBUFFER lpDSBSecondary = NULL;static LPDIRECTSOUNDNOTIFY lpDSNotify = NULL;static HANDLE *hPosNotify = NULL;static int32_t(*_DSOUND_CallBack)(int32_t) = NULL;static int32_t _DSOUND_BufferLength = 0;static int32_t _DSOUND_NumBuffers = 0;static char *_DSOUND_MixBuffer = NULL;static int32_t DSOUND_Installed = FALSE;int32_t DSOUND_ErrorCode = DSOUND_Ok;#define DSOUND_SetErrorCode( status ) \ DSOUND_ErrorCode = ( status );/* * DisableInterrupts * Enter the critical section. */int32_t DisableInterrupts(void){ if (!_DSOUND_CriticalSectionAlloced) return -1; EnterCriticalSection(&mutex); return 0;}/* * RestoreInterrupts * Leave the critical section. */int32_t RestoreInterrupts(int32_t a){ if (!_DSOUND_CriticalSectionAlloced) return -1; LeaveCriticalSection(&mutex); return 0; a=a;}/* * DSOUND_ErrorString * Returns a description of an error code. */char *DSOUND_ErrorString(int32_t errorcode){ switch (errorcode) { case DSOUND_Warning: case DSOUND_Error: return DSOUND_ErrorString(DSOUND_ErrorCode); case DSOUND_Ok: return "DirectSound ok."; case DSOUND_NoDLL: return "Failed loading DSOUND.DLL."; case DSOUND_NoDirectSoundCreate: return "Failed getting DirectSoundCreate entry point."; case DSOUND_FailedDSC: return "DirectSoundCreate failed."; case DSOUND_FailedSetCoopLevel: return "Failed setting cooperative level."; case DSOUND_FailedCreatePrimary: return "Failed creating primary buffer."; case DSOUND_FailedSetFormat: return "Failed setting primary buffer format."; case DSOUND_FailedCreateSecondary: return "Failed creating secondary buffer."; case DSOUND_FailedCreateNotifyEvent: return "Failed creating notification event object."; case DSOUND_FailedQueryNotify: return "Failed querying notification interface."; case DSOUND_FailedSetNotify: return "Failed setting notification positions."; case DSOUND_FailedCreateFinishEvent: return "Failed creating finish event object."; case DSOUND_FailedCreateThread: return "Failed creating playback thread."; case DSOUND_FailedPlaySecondary: return "Failed playing secondary buffer."; case DSOUND_FailedGetExitCode: return "GetExitCodeThread failed."; default: return "Unknown DirectSound error code."; }}/* * DSOUND_Init * Initializes the DirectSound objects. */int32_t DSOUND_Init(int32_t soundcard, int32_t mixrate, int32_t numchannels, int32_t samplebits, int32_t buffersize){ HRESULT(WINAPI *aDirectSoundCreate)(LPGUID,LPDIRECTSOUND*,LPUNKNOWN); HRESULT hr; DSBUFFERDESC dsbuf; WAVEFORMATEX wfex; DSBPOSITIONNOTIFY posn; UNREFERENCED_PARAMETER(soundcard); if (DSOUND_Installed) { DSOUND_Shutdown(); } initprintf("Initializing DirectSound...\n"); if (!_DSOUND_CriticalSectionAlloced) { // initialize the critical section object we'll use to // simulate (dis|en)abling interrupts InitializeCriticalSection(&mutex); _DSOUND_CriticalSectionAlloced = TRUE; }// initprintf(" - Loading DSOUND.DLL\n"); hDSoundDLL = LoadLibrary("DSOUND.DLL"); if (!hDSoundDLL) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_NoDLL); return DSOUND_Error; } aDirectSoundCreate = (void *)GetProcAddress(hDSoundDLL, "DirectSoundCreate"); if (!aDirectSoundCreate) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_NoDirectSoundCreate); return DSOUND_Error; }// initprintf(" - Creating DirectSound object\n"); hr = aDirectSoundCreate(NULL, &lpDS, NULL); if (hr != DS_OK) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedDSC); return DSOUND_Error; } hr = IDirectSound_SetCooperativeLevel(lpDS, (HWND)win_gethwnd(), DSSCL_EXCLUSIVE); if (hr != DS_OK) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedSetCoopLevel); return DSOUND_Error; }// initprintf(" - Creating primary buffer\n"); ZeroMemory(&dsbuf, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER; hr = IDirectSound_CreateSoundBuffer(lpDS, &dsbuf, &lpDSBPrimary, NULL); if (hr != DS_OK) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedCreatePrimary); return DSOUND_Error; }/* initprintf(" - Setting primary buffer format\n" " Channels: %d\n" " Sample rate: %dHz\n" " Sample size: %d bits\n", numchannels, mixrate, samplebits); */ initprintf(" - Primary buffer format: %d ch, %dHz, %d bits\n", numchannels, mixrate, samplebits); ZeroMemory(&wfex, sizeof(wfex)); wfex.wFormatTag = WAVE_FORMAT_PCM; wfex.nChannels = numchannels; wfex.nSamplesPerSec = mixrate; wfex.wBitsPerSample = samplebits; wfex.nBlockAlign = (wfex.wBitsPerSample / 8) * wfex.nChannels; wfex.nAvgBytesPerSec = wfex.nBlockAlign * wfex.nSamplesPerSec; hr = IDirectSoundBuffer_SetFormat(lpDSBPrimary, &wfex); if (hr != DS_OK) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedSetFormat); return DSOUND_Error; } initprintf(" - Creating secondary buffer\n"); ZeroMemory(&dsbuf, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE; dsbuf.dwBufferBytes = buffersize; dsbuf.lpwfxFormat = &wfex; hr = IDirectSound_CreateSoundBuffer(lpDS, &dsbuf, &lpDSBSecondary, NULL); if (hr != DS_OK) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedCreateSecondary); return DSOUND_Error; } hr = IDirectSoundBuffer_QueryInterface(lpDSBSecondary, &IID_IDirectSoundNotify, (LPVOID *)&lpDSNotify); if (hr != DS_OK) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedQueryNotify); return DSOUND_Error; } hPosNotify = (HANDLE *)malloc(sizeof(HANDLE)); if (!hPosNotify) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedSetNotify); return DSOUND_Error; } hPosNotify[0] = CreateEvent(NULL, FALSE, FALSE, NULL); if (!hPosNotify) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedCreateNotifyEvent); return DSOUND_Error; } _DSOUND_BufferLength = 0; _DSOUND_NumBuffers = 1; posn.dwOffset = 0; posn.hEventNotify = hPosNotify[0]; hr = IDirectSoundNotify_SetNotificationPositions(lpDSNotify, 1, &posn); if (hr != DS_OK) { DSOUND_Shutdown(); DSOUND_SetErrorCode(DSOUND_FailedSetNotify); return DSOUND_Error; } DSOUND_Installed = TRUE; DSOUND_SetErrorCode(DSOUND_Ok);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -