From ad2a82ebb2b165cb82d38e5169f1718d3596fe08 Mon Sep 17 00:00:00 2001 From: Felix Rueegg Date: Wed, 13 Nov 2013 18:20:39 +0100 Subject: [PATCH] Added OpenAL support for doomclassic --- doomclassic/doom/i_sound_openal.cpp | 950 ++++++++++++++++++++++++++ neo/sound/OpenAL/AL_SoundHardware.cpp | 15 +- 2 files changed, 957 insertions(+), 8 deletions(-) create mode 100644 doomclassic/doom/i_sound_openal.cpp diff --git a/doomclassic/doom/i_sound_openal.cpp b/doomclassic/doom/i_sound_openal.cpp new file mode 100644 index 00000000..ac217af6 --- /dev/null +++ b/doomclassic/doom/i_sound_openal.cpp @@ -0,0 +1,950 @@ +/* +=========================================================================== + +Doom 3 BFG Edition GPL Source Code +Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2013 Felix Rueegg + +This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). + +Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY 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 License +along with Doom 3 BFG Edition Source Code. If not, see . + +In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. + +If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. + +=========================================================================== +*/ + +#include "Precompiled.h" +#include "globaldata.h" + +// +// DESCRIPTION: +// System interface for sound. +// +//----------------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +// Timer stuff. Experimental. +#include +#include +#include "z_zone.h" +#include "i_system.h" +#include "i_sound.h" +#include "m_argv.h" +#include "m_misc.h" +#include "w_wad.h" +#include "d_main.h" +#include "doomdef.h" +#include "../timidity/timidity.h" +#include "../timidity/controls.h" + +#include "sound/snd_local.h" + +#pragma warning ( disable : 4244 ) + +#define SFX_RATE 11050 +#define SFX_SAMPLETYPE AL_FORMAT_MONO8 + +#define MIDI_CHANNELS 2 +#define MIDI_RATE 22050 +#define MIDI_SAMPLETYPE AL_FORMAT_STEREO8 +#define MIDI_FORMAT AUDIO_U8 +#define MIDI_FORMAT_BYTES 1 + +#define OPENAL_SCALE 0.008f + + +ALuint alMusicSourceVoice; +ALuint alMusicBuffer; + +MidiSong* doomMusic; +byte* musicBuffer; +int totalBufferSize; + +bool waitingForMusic; +bool musicReady; + +typedef struct { + float x; + float y; + float z; +} vec3_t; + +typedef struct { + vec3_t OrientTop; + vec3_t OrientFront; + vec3_t Position; +} doomListener_t; + +typedef struct tagActiveSound_t { + ALuint alSourceVoice; + int id; + int valid; + int start; + int player; + bool localSound; + mobj_t *originator; +} activeSound_t; + +// cheap little struct to hold a sound +typedef struct { + int vol; + int player; + int pitch; + int priority; + mobj_t *originator; + mobj_t *listener; +} soundEvent_t; + +// array of all the possible sounds +// in split screen we only process the loudest sound of each type per frame +soundEvent_t soundEvents[128]; +extern int PLAYERCOUNT; + +// Real volumes +const float GLOBAL_VOLUME_MULTIPLIER = 0.5f; + +float x_SoundVolume = GLOBAL_VOLUME_MULTIPLIER; +float x_MusicVolume = GLOBAL_VOLUME_MULTIPLIER; + +// The actual lengths of all sound effects. +static int lengths[NUMSFX]; +ALuint alBuffers[NUMSFX]; +activeSound_t activeSounds[NUM_SOUNDBUFFERS] = {0}; + +int S_initialized = 0; +bool Music_initialized = false; +static bool soundHardwareInitialized = false; +static int numOutputChannels = 0; + +doomListener_t doom_Listener; + +void I_InitSoundChannel( int channel, int numOutputChannels_ ); + +/* +====================== +getsfx +====================== +*/ +// This function loads the sound data from the WAD lump, +// for single sound. +// +void* getsfx ( char* sfxname, int* len ) +{ + unsigned char* sfx; + unsigned char* sfxmem; + int size; + char name[20]; + int sfxlump; + //float scale = 1.0f; + + // Get the sound data from the WAD + sprintf( name, "ds%s", sfxname ); + + // Scale down the plasma gun, it clips + //if ( strcmp( sfxname, "plasma" ) == 0 ) { + // scale = 0.75f; + //} + //if ( strcmp( sfxname, "itemup" ) == 0 ) { + // scale = 1.333f; + //} + + // If sound requested is not found in current WAD, use pistol as default + if ( W_CheckNumForName( name ) == -1 ) + sfxlump = W_GetNumForName( "dspistol" ); + else + sfxlump = W_GetNumForName( name ); + + // Sound lump headers are 8 bytes. + const int SOUND_LUMP_HEADER_SIZE_IN_BYTES = 8; + + size = W_LumpLength( sfxlump ) - SOUND_LUMP_HEADER_SIZE_IN_BYTES; + + sfx = (unsigned char*)W_CacheLumpNum( sfxlump, PU_CACHE_SHARED ); + const unsigned char * sfxSampleStart = sfx + SOUND_LUMP_HEADER_SIZE_IN_BYTES; + + // Allocate from zone memory. + //sfxmem = (float*)DoomLib::Z_Malloc( size*(sizeof(float)), PU_SOUND_SHARED, 0 ); + sfxmem = (unsigned char*)malloc( size * sizeof(unsigned char) ); + + // Now copy, and convert to Xbox360 native float samples, do initial volume ramp, and scale + for ( int i = 0; i < size; i++ ) { + sfxmem[i] = sfxSampleStart[i];// * scale; + } + + // Remove the cached lump. + Z_Free( sfx ); + + // Set length. + *len = size; + + // Return allocated padded data. + return (void *) (sfxmem); +} + +/* +====================== +I_SetChannels +====================== +*/ +void I_SetChannels() +{ + // Original Doom set up lookup tables here +} + +/* +====================== +I_SetSfxVolume +====================== +*/ +void I_SetSfxVolume( int volume ) +{ + x_SoundVolume = ((float)volume / 15.f) * GLOBAL_VOLUME_MULTIPLIER; +} + +/* +====================== +I_GetSfxLumpNum +====================== +*/ +// +// Retrieve the raw data lump index +// for a given SFX name. +// +int I_GetSfxLumpNum( sfxinfo_t* sfx ) +{ + char namebuf[9]; + sprintf( namebuf, "ds%s", sfx->name ); + return W_GetNumForName( namebuf ); +} + +/* +====================== +I_StartSound2 +====================== +*/ +// Starting a sound means adding it +// to the current list of active sounds +// in the internal channels. +// As the SFX info struct contains +// e.g. a pointer to the raw data, +// it is ignored. +// As our sound handling does not handle +// priority, it is ignored. +// Pitching (that is, increased speed of playback) is set +// +int I_StartSound2 ( int id, int player, mobj_t *origin, mobj_t *listener_origin, int pitch, int priority ) +{ + if ( !soundHardwareInitialized || id == 0 ) { + return id; + } + + int i; + activeSound_t* sound = 0; + int oldest = 0, oldestnum = -1; + + // these id's should not overlap + if ( id == sfx_sawup || id == sfx_sawidl || id == sfx_sawful || id == sfx_sawhit || id == sfx_stnmov ) { + // Loop all channels, check. + for ( i = 0; i < NUM_SOUNDBUFFERS; i++ ) + { + sound = &activeSounds[i]; + + if ( sound->valid && ( sound->id == id && sound->player == player ) ) { + I_StopSound( sound->id, player ); + break; + } + } + } + + // find a valid channel, or one that has finished playing + for ( i = 0; i < NUM_SOUNDBUFFERS; i++ ) { + sound = &activeSounds[i]; + + if ( !sound->valid ) + break; + + if ( !oldest || oldest > sound->start ) { + oldestnum = i; + oldest = sound->start; + } + + ALint sourceState; + alGetSourcei( sound->alSourceVoice, AL_SOURCE_STATE, &sourceState ); + if ( sourceState == AL_STOPPED ) { + break; + } + } + + // none found, so use the oldest one + if ( i == NUM_SOUNDBUFFERS ) { + i = oldestnum; + sound = &activeSounds[i]; + } + + alSourceStop( sound->alSourceVoice ); + + // Attach the source voice to the correct buffer + if ( sound->id != id ) { + alSourcei( sound->alSourceVoice, AL_BUFFER, 0 ); + alSourcei( sound->alSourceVoice, AL_BUFFER, alBuffers[id] ); + } + + // Set the source voice volume + alSourcef( sound->alSourceVoice, AL_GAIN, x_SoundVolume ); + + // Set the source voice pitch + alSourcef( sound->alSourceVoice, AL_PITCH, 1 + ((float)pitch-128.f)/95.f ); + + // Set the source voice position + ALfloat x = 0.f; + ALfloat y = 0.f; + ALfloat z = 0.f; + if ( origin ) { + if ( origin == listener_origin ) { + sound->localSound = true; + } else { + sound->localSound = false; + x = OPENAL_SCALE * (ALfloat)(origin->x >> FRACBITS); + z = OPENAL_SCALE * (ALfloat)(origin->y >> FRACBITS); + } + } else { + sound->localSound = true; + } + if ( sound->localSound ) { + x = doom_Listener.Position.x; + z = doom_Listener.Position.z; + } + alSource3f( sound->alSourceVoice, AL_POSITION, x, y, z ); + + alSourcePlay( sound->alSourceVoice ); + + // Set id, and start time + sound->id = id; + sound->start = ::g->gametic; + sound->valid = 1; + sound->player = player; + sound->originator = origin; + + return id; +} + +/* +====================== +I_ProcessSoundEvents +====================== +*/ +void I_ProcessSoundEvents( void ) +{ + for( int i = 0; i < 128; i++ ) { + if( soundEvents[i].pitch ) { + I_StartSound2( i, soundEvents[i].player, soundEvents[i].originator, soundEvents[i].listener, + soundEvents[i].pitch, soundEvents[i].priority ); + } + } + memset( soundEvents, 0, sizeof( soundEvents ) ); +} + +/* +====================== +I_StartSound +====================== +*/ +int I_StartSound ( int id, mobj_t *origin, mobj_t *listener_origin, int vol, int pitch, int priority ) +{ + // only allow player 0s sounds in intermission and finale screens + if( ::g->gamestate != GS_LEVEL && DoomLib::GetPlayer() != 0 ) { + return 0; + } + + // if we're only one player or we're trying to play the chainsaw sound, do it normal + // otherwise only allow one sound of each type per frame + if( PLAYERCOUNT == 1 || id == sfx_sawup || id == sfx_sawidl || id == sfx_sawful || id == sfx_sawhit ) { + return I_StartSound2( id, ::g->consoleplayer, origin, listener_origin, pitch, priority ); + } else { + if( soundEvents[ id ].vol < vol ) { + soundEvents[ id ].player = DoomLib::GetPlayer(); + soundEvents[ id ].pitch = pitch; + soundEvents[ id ].priority = priority; + soundEvents[ id ].vol = vol; + soundEvents[ id ].originator = origin; + soundEvents[ id ].listener = listener_origin; + } + return id; + } +} + +/* +====================== +I_StopSound +====================== +*/ +void I_StopSound ( int handle, int player ) +{ + // You need the handle returned by StartSound. + // Would be looping all channels, + // tracking down the handle, + // and setting the channel to zero. + int i; + activeSound_t* sound = 0; + + for ( i = 0; i < NUM_SOUNDBUFFERS; ++i ) { + sound = &activeSounds[i]; + if ( !sound->valid || sound->id != handle || (player >= 0 && sound->player != player) ) + continue; + break; + } + + if ( i == NUM_SOUNDBUFFERS ) + return; + + // Stop the sound + alSourceStop( sound->alSourceVoice ); + + sound->valid = 0; + sound->player = -1; +} + +/* +====================== +I_SoundIsPlaying +====================== +*/ +int I_SoundIsPlaying( int handle ) +{ + if ( !soundHardwareInitialized ) { + return 0; + } + + int i; + activeSound_t* sound; + + for ( i = 0; i < NUM_SOUNDBUFFERS; ++i ) { + sound = &activeSounds[i]; + if ( !sound->valid || sound->id != handle ) + continue; + + ALint sourceState; + alGetSourcei( sound->alSourceVoice, AL_SOURCE_STATE, &sourceState ); + if ( sourceState == AL_PLAYING ) { + return 1; + } + } + + return 0; +} + +/* +====================== +I_UpdateSound +====================== +*/ +// Update listener position and go through all the +// channels and update sound positions. +void I_UpdateSound( void ) +{ + if ( !soundHardwareInitialized ) { + return; + } + + // Update listener orientation and position + mobj_t *playerObj = ::g->players[0].mo; + if ( playerObj ) { + angle_t pAngle = playerObj->angle; + fixed_t fx, fz; + + pAngle >>= ANGLETOFINESHIFT; + + fx = finecosine[pAngle]; + fz = finesine[pAngle]; + + doom_Listener.OrientFront.x = (float)(fx) / 65535.f; + doom_Listener.OrientFront.y = 0.f; + doom_Listener.OrientFront.z = (float)(fz) / 65535.f; + + doom_Listener.Position.x = OPENAL_SCALE * (float)(playerObj->x >> FRACBITS); + doom_Listener.Position.y = 0.f; + doom_Listener.Position.z = OPENAL_SCALE * (float)(playerObj->y >> FRACBITS); + } else { + doom_Listener.OrientFront.x = 0.f; + doom_Listener.OrientFront.y = 0.f; + doom_Listener.OrientFront.z = 1.f; + + doom_Listener.Position.x = 0.f; + doom_Listener.Position.y = 0.f; + doom_Listener.Position.z = 0.f; + } + + ALfloat listenerOrientation[] = { doom_Listener.OrientTop.x, doom_Listener.OrientTop.y, + doom_Listener.OrientTop.z, doom_Listener.OrientFront.x, doom_Listener.OrientFront.y, + doom_Listener.OrientFront.z }; + alListenerfv( AL_ORIENTATION, listenerOrientation ); + alListener3f( AL_POSITION, doom_Listener.Position.x, doom_Listener.Position.y, doom_Listener.Position.z ); + + // Update playing source voice positions + int i; + activeSound_t* sound; + for ( i=0; i < NUM_SOUNDBUFFERS; i++ ) { + sound = &activeSounds[i]; + + if ( !sound->valid ) { + continue; + } + + ALint sourceState; + alGetSourcei( sound->alSourceVoice, AL_SOURCE_STATE, &sourceState ); + if ( sourceState == AL_PLAYING ) { + if ( sound->localSound ) { + alSource3f( sound->alSourceVoice, AL_POSITION, doom_Listener.Position.x, + doom_Listener.Position.y, doom_Listener.Position.z ); + } else { + ALfloat x = OPENAL_SCALE * (ALfloat)(sound->originator->x >> FRACBITS); + ALfloat y = 0.f; + ALfloat z = OPENAL_SCALE * (ALfloat)(sound->originator->y >> FRACBITS); + + alSource3f( sound->alSourceVoice, AL_POSITION, x, y, z ); + } + } + } +} + +/* +====================== +I_UpdateSoundParams +====================== +*/ +void I_UpdateSoundParams( int handle, int vol, int sep, int pitch ) +{ +} + +/* +====================== +I_ShutdownSound +====================== +*/ +void I_ShutdownSound( void ) +{ + int done = 0; + int i; + + if ( S_initialized ) { + // Stop all sounds + for ( i = 0; i < NUM_SOUNDBUFFERS; i++ ) { + activeSound_t * sound = &activeSounds[i]; + + if ( !sound ) { + continue; + } + + I_StopSound( sound->id, 0 ); + } + + // Free allocated sound memory + for ( i = 1; i < NUMSFX; i++ ) { + if ( S_sfx[i].data && !(S_sfx[i].link) ) { + free( S_sfx[i].data ); + } + } + } + + I_StopSong( 0 ); + + S_initialized = 0; +} + +/* +====================== +I_InitSoundHardware + +Called from the tech4x initialization code. Sets up Doom classic's +sound channels. +====================== +*/ +void I_InitSoundHardware( int numOutputChannels_, int channelMask ) +{ + ::numOutputChannels = numOutputChannels_; + + // Initialize source voices + for ( int i = 0; i < NUM_SOUNDBUFFERS; i++ ) { + I_InitSoundChannel( i, numOutputChannels ); + } + + // Create OpenAL buffers for all sounds + for ( int i = 1; i < NUMSFX; i++ ) { + alGenBuffers( (ALuint)1, &alBuffers[i] ); + } + + I_InitMusic(); + + soundHardwareInitialized = true; +} + +/* +====================== +I_ShutdownSoundHardware + +Called from the tech4x shutdown code. Tears down Doom classic's +sound channels. +====================== +*/ +void I_ShutdownSoundHardware() +{ + soundHardwareInitialized = false; + + I_ShutdownMusic(); + + // Delete all source voices + for ( int i = 0; i < NUM_SOUNDBUFFERS; ++i ) { + activeSound_t * sound = &activeSounds[i]; + + if ( !sound ) { + continue; + } + + if ( sound->alSourceVoice ) { + alSourceStop( sound->alSourceVoice ); + alSourcei( sound->alSourceVoice, AL_BUFFER, 0 ); + alDeleteSources( 1, &sound->alSourceVoice ); + } + } + + // Delete OpenAL buffers for all sounds + for ( int i = 0; i < NUMSFX; i++ ) { + alDeleteBuffers( 1, &alBuffers[i] ); + } +} + +/* +====================== +I_InitSoundChannel +====================== +*/ +void I_InitSoundChannel( int channel, int numOutputChannels_ ) +{ + activeSound_t *soundchannel = &activeSounds[ channel ]; + + alGenSources( (ALuint)1, &soundchannel->alSourceVoice ); + + alSource3f( soundchannel->alSourceVoice, AL_VELOCITY, 0.f, 0.f, 0.f ); + alSourcef( soundchannel->alSourceVoice, AL_LOOPING, AL_FALSE ); +} + +/* +====================== +I_InitSound +====================== +*/ +void I_InitSound() +{ + if ( S_initialized == 0 ) { + // Set up listener parameters + doom_Listener.OrientFront.x = 0.f; + doom_Listener.OrientFront.y = 0.f; + doom_Listener.OrientFront.z = 1.f; + + doom_Listener.OrientTop.x = 0.f; + doom_Listener.OrientTop.y = 1.f; + doom_Listener.OrientTop.z = 0.f; + + doom_Listener.Position.x = 0.f; + doom_Listener.Position.y = 0.f; + doom_Listener.Position.z = 0.f; + + for ( int i = 1; i < NUMSFX; i++ ) { + // Alias? Example is the chaingun sound linked to pistol. + if ( !S_sfx[i].link ) { + // Load data from WAD file. + S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] ); + } else { + // Previously loaded already? + S_sfx[i].data = S_sfx[i].link->data; + lengths[i] = lengths[ (S_sfx[i].link-S_sfx) / sizeof(sfxinfo_t) ]; + } + if ( S_sfx[i].data ) { + alBufferData( alBuffers[i], SFX_SAMPLETYPE, (byte*)S_sfx[i].data, lengths[i], SFX_RATE ); + } + } + + S_initialized = 1; + } +} + +/* +====================== +I_SubmitSound +====================== +*/ +void I_SubmitSound( void ) +{ + // Only do this for player 0, it will still handle positioning + // for other players, but it can't be outside the game + // frame like the soundEvents are. + if ( DoomLib::GetPlayer() == 0 ) { + // Do 3D positioning of sounds + I_UpdateSound(); + + // Change music if required + I_UpdateMusic(); + } +} + + +// ========================================================= +// ========================================================= +// Background Music +// ========================================================= +// ========================================================= + +/* +====================== +I_SetMusicVolume +====================== +*/ +void I_SetMusicVolume( int volume ) +{ + x_MusicVolume = (float)volume / 15.f; +} + +/* +====================== +I_InitMusic +====================== +*/ +void I_InitMusic( void ) +{ + if ( !Music_initialized ) { + // Initialize Timidity + Timidity_Init( MIDI_RATE, MIDI_FORMAT, MIDI_CHANNELS, MIDI_RATE, "classicmusic/gravis.cfg" ); + + musicBuffer = NULL; + totalBufferSize = 0; + waitingForMusic = false; + musicReady = false; + + alGenSources( (ALuint)1, &alMusicSourceVoice ); + + alSourcef( alMusicSourceVoice, AL_PITCH, 1.f ); + alSourcef( alMusicSourceVoice, AL_LOOPING, AL_TRUE ); + + alGenBuffers( (ALuint)1, &alMusicBuffer ); + + Music_initialized = true; + } +} + +/* +====================== +I_ShutdownMusic +====================== +*/ +void I_ShutdownMusic( void ) +{ + if ( Music_initialized ) { + if ( alMusicSourceVoice ) { + I_StopSong( 0 ); + alSourcei( alMusicSourceVoice, AL_BUFFER, 0 ); + alDeleteSources( 1, &alMusicSourceVoice ); + } + + if ( alMusicBuffer ) { + alDeleteBuffers( 1, &alMusicBuffer ); + } + + if ( musicBuffer ) { + free( musicBuffer ); + musicBuffer = NULL; + } + + Timidity_Shutdown(); + } + + totalBufferSize = 0; + waitingForMusic = false; + musicReady = false; + + Music_initialized = false; +} + +int Mus2Midi(unsigned char* bytes, unsigned char* out, int* len); + +namespace { + const int MaxMidiConversionSize = 1024 * 1024; + unsigned char midiConversionBuffer[MaxMidiConversionSize]; +} + +/* +====================== +I_LoadSong +====================== +*/ +void I_LoadSong( const char * songname ) +{ + idStr lumpName = "d_"; + lumpName += static_cast< const char * >( songname ); + + unsigned char * musFile = static_cast< unsigned char * >( W_CacheLumpName( lumpName.c_str(), PU_STATIC_SHARED ) ); + + int length = 0; + Mus2Midi( musFile, midiConversionBuffer, &length ); + + doomMusic = Timidity_LoadSongMem( midiConversionBuffer, length ); + + if ( doomMusic ) { + musicBuffer = (byte *)malloc( MIDI_CHANNELS * MIDI_FORMAT_BYTES * doomMusic->samples ); + totalBufferSize = doomMusic->samples * MIDI_CHANNELS * MIDI_FORMAT_BYTES; + Timidity_Start( doomMusic ); + + int rc = RC_NO_RETURN_VALUE; + int num_bytes = 0; + int offset = 0; + + do { + rc = Timidity_PlaySome( musicBuffer + offset, MIDI_RATE, &num_bytes ); + offset += num_bytes; + } while ( rc != RC_TUNE_END ); + + Timidity_Stop(); + Timidity_FreeSong( doomMusic ); + } + + musicReady = true; +} + +/* +====================== +I_PlaySong +====================== +*/ +void I_PlaySong( const char *songname, int looping ) +{ + if ( !Music_initialized ) { + return; + } + + I_StopSong( 0 ); + + // Clear old state + if ( musicBuffer ) { + free( musicBuffer ); + musicBuffer = 0; + } + + musicReady = false; + I_LoadSong( songname ); + waitingForMusic = true; + + if ( DoomLib::GetPlayer() >= 0 ) { + ::g->mus_looping = looping; + } +} + +/* +====================== +I_UpdateMusic +====================== +*/ +void I_UpdateMusic( void ) +{ + if ( !Music_initialized ) { + return; + } + + if ( alMusicSourceVoice ) { + // Set the volume + alSourcef( alMusicSourceVoice, AL_GAIN, x_MusicVolume * GLOBAL_VOLUME_MULTIPLIER ); + } + + if ( waitingForMusic ) { + if ( musicReady && alMusicSourceVoice ) { + if ( musicBuffer ) { + alSourcei( alMusicSourceVoice, AL_BUFFER, 0 ); + alBufferData( alMusicBuffer, MIDI_SAMPLETYPE, musicBuffer, totalBufferSize, MIDI_RATE ); + alSourcei( alMusicSourceVoice, AL_BUFFER, alMusicBuffer ); + alSourcePlay( alMusicSourceVoice ); + } + + waitingForMusic = false; + } + } +} + +/* +====================== +I_PauseSong +====================== +*/ +void I_PauseSong ( int handle ) +{ + if ( !Music_initialized || !alMusicSourceVoice ) { + return; + } + + alSourcePause( alMusicSourceVoice ); +} + +/* +====================== +I_ResumeSong +====================== +*/ +void I_ResumeSong ( int handle ) +{ + if ( !Music_initialized || !alMusicSourceVoice ) { + return; + } + + alSourcePlay( alMusicSourceVoice ); +} + +/* +====================== +I_StopSong +====================== +*/ +void I_StopSong( int handle ) +{ + if ( !Music_initialized || !alMusicSourceVoice ) { + return; + } + + alSourceStop( alMusicSourceVoice ); +} + +/* +====================== +I_UnRegisterSong +====================== +*/ +void I_UnRegisterSong( int handle ) +{ + // does nothing +} + +/* +====================== +I_RegisterSong +====================== +*/ +int I_RegisterSong( void* data, int length ) +{ + // does nothing + return 0; +} diff --git a/neo/sound/OpenAL/AL_SoundHardware.cpp b/neo/sound/OpenAL/AL_SoundHardware.cpp index 83fd15a4..4b60e270 100644 --- a/neo/sound/OpenAL/AL_SoundHardware.cpp +++ b/neo/sound/OpenAL/AL_SoundHardware.cpp @@ -30,7 +30,7 @@ If you have questions concerning this license or the applicable additional terms #pragma hdrstop #include "precompiled.h" #include "../snd_local.h" -//#include "../../../doomclassic/doom/i_sound.h" +#include "../../../doomclassic/doom/i_sound.h" idCVar s_showLevelMeter( "s_showLevelMeter", "0", CVAR_BOOL | CVAR_ARCHIVE, "Show VU meter" ); idCVar s_meterTopTime( "s_meterTopTime", "1000", CVAR_INTEGER | CVAR_ARCHIVE, "How long (in milliseconds) peaks are displayed on the VU meter" ); @@ -199,7 +199,7 @@ void idSoundHardware_OpenAL::Init() // --------------------- // Initialize the Doom classic sound system. // --------------------- - //I_InitSoundHardware( outputChannels, channelMask ); + I_InitSoundHardware( voices.Max(), 0 ); // --------------------- // Create VU Meter Effect @@ -278,6 +278,11 @@ void idSoundHardware_OpenAL::Shutdown() freeVoices.Clear(); zombieVoices.Clear(); + // --------------------- + // Shutdown the Doom classic sound system. + // --------------------- + I_ShutdownSoundHardware(); + alcMakeContextCurrent( NULL ); alcDestroyContext( openalContext ); @@ -286,12 +291,6 @@ void idSoundHardware_OpenAL::Shutdown() alcCloseDevice( openalDevice ); openalDevice = NULL; - - // --------------------- - // Shutdown the Doom classic sound system. - // --------------------- - //I_ShutdownSoundHardware(); - /* if( vuMeterRMS != NULL ) {