Split i_sound.c into i_sdlsound.c, i_sdlmusic.c, with generic "sound
driver" modules, one for PC speaker and one for digital output. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 913
This commit is contained in:
parent
5fc7913741
commit
beab4eb58b
15 changed files with 746 additions and 577 deletions
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#include "pcsound.h"
|
||||
#include "pcsound_internal.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
extern pcsound_driver_t pcsound_win32_driver;
|
||||
|
|
@ -54,6 +55,13 @@ static pcsound_driver_t *drivers[] =
|
|||
|
||||
static pcsound_driver_t *pcsound_driver = NULL;
|
||||
|
||||
int pcsound_sample_rate;
|
||||
|
||||
void PCSound_SetSampleRate(int rate)
|
||||
{
|
||||
pcsound_sample_rate = rate;
|
||||
}
|
||||
|
||||
int PCSound_Init(pcsound_callback_func callback_func)
|
||||
{
|
||||
char *driver_name;
|
||||
|
|
|
|||
|
|
@ -26,22 +26,21 @@
|
|||
#ifndef PCSOUND_H
|
||||
#define PCSOUND_H
|
||||
|
||||
#define PCSOUND_8253_FREQUENCY 1193280
|
||||
|
||||
typedef struct pcsound_driver_s pcsound_driver_t;
|
||||
typedef void (*pcsound_callback_func)(int *duration, int *frequency);
|
||||
typedef int (*pcsound_init_func)(pcsound_callback_func callback);
|
||||
typedef void (*pcsound_shutdown_func)(void);
|
||||
|
||||
struct pcsound_driver_s
|
||||
{
|
||||
char *name;
|
||||
pcsound_init_func init_func;
|
||||
pcsound_shutdown_func shutdown_func;
|
||||
};
|
||||
// Initialise the PC speaker subsystem. The given function is called
|
||||
// periodically to request more sound data to play.
|
||||
|
||||
int PCSound_Init(pcsound_callback_func callback_func);
|
||||
|
||||
// Shut down the PC speaker subsystem.
|
||||
|
||||
void PCSound_Shutdown(void);
|
||||
|
||||
// Set the preferred output sample rate when emulating a PC speaker.
|
||||
// This must be called before PCSound_Init.
|
||||
|
||||
void PCSound_SetSampleRate(int rate);
|
||||
|
||||
#endif /* #ifndef PCSOUND_H */
|
||||
|
||||
|
|
|
|||
|
|
@ -19,22 +19,29 @@
|
|||
// 02111-1307, USA.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// System interface for PC speaker sound.
|
||||
// PC speaker interface.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __I_PCSOUND_H__
|
||||
#define __I_PCSOUND_H__
|
||||
#ifndef PCSOUND_INTERNAL_H
|
||||
#define PCSOUND_INTERNAL_H
|
||||
|
||||
int I_PCS_StartSound(int id,
|
||||
int channel,
|
||||
int vol,
|
||||
int sep,
|
||||
int pitch,
|
||||
int priority);
|
||||
void I_PCS_StopSound(int handle);
|
||||
int I_PCS_SoundIsPlaying(int handle);
|
||||
void I_PCS_InitSound(void);
|
||||
#include "pcsound.h"
|
||||
|
||||
#endif /* #ifndef __I_PCSOUND_H__ */
|
||||
#define PCSOUND_8253_FREQUENCY 1193280
|
||||
|
||||
typedef struct pcsound_driver_s pcsound_driver_t;
|
||||
typedef int (*pcsound_init_func)(pcsound_callback_func callback);
|
||||
typedef void (*pcsound_shutdown_func)(void);
|
||||
|
||||
struct pcsound_driver_s
|
||||
{
|
||||
char *name;
|
||||
pcsound_init_func init_func;
|
||||
pcsound_shutdown_func shutdown_func;
|
||||
};
|
||||
|
||||
extern int pcsound_sample_rate;
|
||||
|
||||
#endif /* #ifndef PCSOUND_INTERNAL_H */
|
||||
|
||||
|
|
@ -40,6 +40,7 @@
|
|||
#include "SDL_thread.h"
|
||||
|
||||
#include "pcsound.h"
|
||||
#include "pcsound_internal.h"
|
||||
|
||||
#define CONSOLE_DEVICE "/dev/console"
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,17 @@
|
|||
#include "SDL_mixer.h"
|
||||
|
||||
#include "pcsound.h"
|
||||
#include "pcsound_internal.h"
|
||||
|
||||
#define SQUARE_WAVE_AMP 0x2000
|
||||
|
||||
// If true, we initialised SDL and have the responsibility to shut it
|
||||
// down
|
||||
|
||||
static int sdl_was_initialised = 0;
|
||||
|
||||
// Callback function to invoke when we want new sound data
|
||||
|
||||
static pcsound_callback_func callback;
|
||||
|
||||
// Output sound format
|
||||
|
|
@ -137,16 +145,57 @@ static void PCSound_Mix_Callback(void *udata, Uint8 *stream, int len)
|
|||
}
|
||||
}
|
||||
|
||||
static int SDLIsInitialised(void)
|
||||
{
|
||||
int freq, channels;
|
||||
Uint16 format;
|
||||
|
||||
return Mix_QuerySpec(&freq, &format, &channels);
|
||||
}
|
||||
|
||||
static void PCSound_SDL_Shutdown(void)
|
||||
{
|
||||
if (sdl_was_initialised)
|
||||
{
|
||||
Mix_CloseAudio();
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
sdl_was_initialised = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int PCSound_SDL_Init(pcsound_callback_func callback_func)
|
||||
{
|
||||
// Check that SDL_mixer has been opened already
|
||||
// If not, fail
|
||||
// Check if SDL_mixer has been opened already
|
||||
// If not, we must initialise it now
|
||||
|
||||
if (!Mix_QuerySpec(&mixing_freq, &mixing_format, &mixing_channels))
|
||||
if (!SDLIsInitialised())
|
||||
{
|
||||
return 0;
|
||||
if (SDL_Init(SDL_INIT_AUDIO) < 0)
|
||||
{
|
||||
fprintf(stderr, "Unable to set up sound.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Mix_OpenAudio(pcsound_sample_rate, AUDIO_S16SYS, 2, 1024) < 0)
|
||||
{
|
||||
fprintf(stderr, "Error initialising SDL_mixer: %s\n", Mix_GetError());
|
||||
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
// When this module shuts down, it has the responsibility to
|
||||
// shut down SDL.
|
||||
|
||||
sdl_was_initialised = 1;
|
||||
}
|
||||
|
||||
// Get the mixer frequency, format and number of channels.
|
||||
|
||||
Mix_QuerySpec(&mixing_freq, &mixing_format, &mixing_channels);
|
||||
|
||||
// Only supports AUDIO_S16SYS
|
||||
|
||||
if (mixing_format != AUDIO_S16SYS || mixing_channels != 2)
|
||||
|
|
@ -154,6 +203,8 @@ static int PCSound_SDL_Init(pcsound_callback_func callback_func)
|
|||
fprintf(stderr,
|
||||
"PCSound_SDL only supports native signed 16-bit LSB, "
|
||||
"stereo format!\n");
|
||||
|
||||
PCSound_SDL_Shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -166,10 +217,6 @@ static int PCSound_SDL_Init(pcsound_callback_func callback_func)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void PCSound_SDL_Shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
pcsound_driver_t pcsound_sdl_driver =
|
||||
{
|
||||
"SDL",
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <windows.h>
|
||||
|
||||
#include "pcsound.h"
|
||||
#include "pcsound_internal.h"
|
||||
|
||||
static SDL_Thread *sound_thread_handle;
|
||||
static int sound_thread_running;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ r_sky.c r_sky.h \
|
|||
r_state.h \
|
||||
r_things.c r_things.h \
|
||||
sounds.c sounds.h \
|
||||
s_sound.c s_sound.h \
|
||||
st_lib.c st_lib.h \
|
||||
st_stuff.c st_stuff.h \
|
||||
tables.c tables.h \
|
||||
|
|
@ -146,9 +147,9 @@ w_merge.c w_merge.h
|
|||
|
||||
FEATURE_SOUND_SOURCE_FILES = \
|
||||
i_pcsound.c i_pcsound.h \
|
||||
i_sound.c i_sound.h \
|
||||
mus2mid.c mus2mid.h \
|
||||
s_sound.c s_sound.h
|
||||
i_sdlsound.c \
|
||||
i_sdlmusic.c i_music.h \
|
||||
mus2mid.c mus2mid.h
|
||||
|
||||
SOURCE_FILES = $(MAIN_SOURCE_FILES) \
|
||||
$(FEATURE_DEHACKED_SOURCE_FILES) \
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@
|
|||
#include "p_saveg.h"
|
||||
|
||||
#include "i_system.h"
|
||||
#include "i_sound.h"
|
||||
#include "i_timer.h"
|
||||
#include "i_video.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -68,15 +68,7 @@ static void *DEH_SoundStart(deh_context_t *context, char *line)
|
|||
"in Vanilla dehacked.", sound_number);
|
||||
}
|
||||
|
||||
#ifdef FEATURE_SOUND
|
||||
|
||||
return &S_sfx[sound_number];
|
||||
|
||||
#else
|
||||
|
||||
return NULL;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
static void DEH_SoundParseLine(deh_context_t *context, char *line, void *tag)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
//
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// System interface, sound.
|
||||
// System interface, music.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -32,59 +32,7 @@
|
|||
|
||||
#include "doomstat.h"
|
||||
#include "sounds.h"
|
||||
|
||||
|
||||
|
||||
// Init at program start...
|
||||
void I_InitSound();
|
||||
|
||||
// ... update sound buffer and audio device at runtime...
|
||||
void I_UpdateSound(void);
|
||||
void I_SubmitSound(void);
|
||||
|
||||
// ... shut down and relase at program termination.
|
||||
void I_ShutdownSound(void);
|
||||
|
||||
|
||||
//
|
||||
// SFX I/O
|
||||
//
|
||||
|
||||
// Initialize channels?
|
||||
void I_SetChannels();
|
||||
|
||||
// Get raw data lump index for sound descriptor.
|
||||
int I_GetSfxLumpNum (sfxinfo_t* sfxinfo );
|
||||
|
||||
|
||||
// Starts a sound in a particular sound channel.
|
||||
int
|
||||
I_StartSound
|
||||
( int id,
|
||||
int channel,
|
||||
int vol,
|
||||
int sep,
|
||||
int pitch,
|
||||
int priority );
|
||||
|
||||
|
||||
// Stops a sound channel.
|
||||
void I_StopSound(int handle);
|
||||
|
||||
// Called by S_*() functions
|
||||
// to see if a channel is still playing.
|
||||
// Returns 0 if no longer playing, 1 if playing.
|
||||
int I_SoundIsPlaying(int handle);
|
||||
|
||||
// Updates the volume, separation,
|
||||
// and pitch of a sound channel.
|
||||
void
|
||||
I_UpdateSoundParams
|
||||
( int handle,
|
||||
int vol,
|
||||
int sep,
|
||||
int pitch );
|
||||
|
||||
#include "s_sound.h"
|
||||
|
||||
//
|
||||
// MUSIC I/O
|
||||
|
|
@ -125,3 +73,4 @@ boolean I_QrySongPlaying(void *handle);
|
|||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -28,8 +28,8 @@
|
|||
#include "doomdef.h"
|
||||
#include "doomtype.h"
|
||||
|
||||
#include "i_pcsound.h"
|
||||
#include "i_sound.h"
|
||||
#include "deh_main.h"
|
||||
#include "s_sound.h"
|
||||
#include "sounds.h"
|
||||
|
||||
#include "w_wad.h"
|
||||
|
|
@ -62,7 +62,7 @@ static float frequencies[] = {
|
|||
|
||||
#define NUM_FREQUENCIES (sizeof(frequencies) / sizeof(*frequencies))
|
||||
|
||||
void PCSCallbackFunc(int *duration, int *freq)
|
||||
static void PCSCallbackFunc(int *duration, int *freq)
|
||||
{
|
||||
int tone;
|
||||
|
||||
|
|
@ -144,12 +144,10 @@ static boolean CachePCSLump(int sound_id)
|
|||
return true;
|
||||
}
|
||||
|
||||
int I_PCS_StartSound(int id,
|
||||
int channel,
|
||||
int vol,
|
||||
int sep,
|
||||
int pitch,
|
||||
int priority)
|
||||
static int I_PCS_StartSound(int id,
|
||||
int channel,
|
||||
int vol,
|
||||
int sep)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
|
@ -192,7 +190,7 @@ int I_PCS_StartSound(int id,
|
|||
}
|
||||
}
|
||||
|
||||
void I_PCS_StopSound(int handle)
|
||||
static void I_PCS_StopSound(int handle)
|
||||
{
|
||||
if (!pcs_initialised)
|
||||
{
|
||||
|
|
@ -214,7 +212,22 @@ void I_PCS_StopSound(int handle)
|
|||
SDL_UnlockMutex(sound_lock);
|
||||
}
|
||||
|
||||
int I_PCS_SoundIsPlaying(int handle)
|
||||
//
|
||||
// Retrieve the raw data lump index
|
||||
// for a given SFX name.
|
||||
//
|
||||
|
||||
static int I_PCS_GetSfxLumpNum(sfxinfo_t* sfx)
|
||||
{
|
||||
char namebuf[9];
|
||||
|
||||
sprintf(namebuf, "dp%s", DEH_String(sfx->name));
|
||||
|
||||
return W_GetNumForName(namebuf);
|
||||
}
|
||||
|
||||
|
||||
static boolean I_PCS_SoundIsPlaying(int handle)
|
||||
{
|
||||
if (!pcs_initialised)
|
||||
{
|
||||
|
|
@ -229,10 +242,58 @@ int I_PCS_SoundIsPlaying(int handle)
|
|||
return current_sound_lump != NULL && current_sound_remaining > 0;
|
||||
}
|
||||
|
||||
void I_PCS_InitSound(void)
|
||||
static boolean I_PCS_InitSound(void)
|
||||
{
|
||||
// Use the sample rate from the configuration file
|
||||
|
||||
PCSound_SetSampleRate(snd_samplerate);
|
||||
|
||||
// Initialise the PC speaker subsystem.
|
||||
|
||||
pcs_initialised = PCSound_Init(PCSCallbackFunc);
|
||||
|
||||
sound_lock = SDL_CreateMutex();
|
||||
if (pcs_initialised)
|
||||
{
|
||||
sound_lock = SDL_CreateMutex();
|
||||
}
|
||||
|
||||
return pcs_initialised;
|
||||
}
|
||||
|
||||
static void I_PCS_ShutdownSound(void)
|
||||
{
|
||||
if (pcs_initialised)
|
||||
{
|
||||
PCSound_Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
static void I_PCS_UpdateSound(void)
|
||||
{
|
||||
// no-op.
|
||||
}
|
||||
|
||||
void I_PCS_UpdateSoundParams(int channel, int vol, int sep)
|
||||
{
|
||||
// no-op.
|
||||
}
|
||||
|
||||
static snddevice_t sound_pcsound_devices[] =
|
||||
{
|
||||
SNDDEVICE_PCSPEAKER,
|
||||
};
|
||||
|
||||
sound_module_t sound_pcsound_module =
|
||||
{
|
||||
sound_pcsound_devices,
|
||||
sizeof(sound_pcsound_devices) / sizeof(*sound_pcsound_devices),
|
||||
I_PCS_InitSound,
|
||||
I_PCS_ShutdownSound,
|
||||
I_PCS_GetSfxLumpNum,
|
||||
I_PCS_UpdateSound,
|
||||
I_PCS_UpdateSoundParams,
|
||||
I_PCS_StartSound,
|
||||
I_PCS_StopSound,
|
||||
I_PCS_SoundIsPlaying,
|
||||
};
|
||||
|
||||
|
|
|
|||
317
src/i_sdlmusic.c
Normal file
317
src/i_sdlmusic.c
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 1993-1996 Id Software, Inc.
|
||||
// Copyright(C) 2005 Simon Howard
|
||||
//
|
||||
// This program 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 2
|
||||
// of 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 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 this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// System interface for music.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "SDL.h"
|
||||
#include "SDL_mixer.h"
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "memio.h"
|
||||
#include "mus2mid.h"
|
||||
|
||||
#include "deh_main.h"
|
||||
#include "m_misc.h"
|
||||
#include "s_sound.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
#define MAXMIDLENGTH (96 * 1024)
|
||||
|
||||
static boolean music_initialised = false;
|
||||
|
||||
// If this is true, this module initialised SDL sound and has the
|
||||
// responsibility to shut it down
|
||||
|
||||
static boolean sdl_was_initialised = false;
|
||||
|
||||
static boolean musicpaused = false;
|
||||
static int current_music_volume;
|
||||
|
||||
void I_ShutdownMusic(void)
|
||||
{
|
||||
if (music_initialised)
|
||||
{
|
||||
Mix_HaltMusic();
|
||||
music_initialised = false;
|
||||
|
||||
if (sdl_was_initialised)
|
||||
{
|
||||
Mix_CloseAudio();
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
sdl_was_initialised = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static boolean SDLIsInitialised(void)
|
||||
{
|
||||
int freq, channels;
|
||||
Uint16 format;
|
||||
|
||||
return Mix_QuerySpec(&freq, &format, &channels) != 0;
|
||||
}
|
||||
|
||||
void I_InitMusic()
|
||||
{
|
||||
// When trying to run with music enabled on OSX, display
|
||||
// a warning message.
|
||||
|
||||
#ifdef __MACOSX__
|
||||
printf("\n"
|
||||
" *** WARNING ***\n"
|
||||
" Music playback on OSX may cause crashes and\n"
|
||||
" is disabled by default.\n"
|
||||
"\n");
|
||||
#endif
|
||||
|
||||
// If SDL_mixer is not initialised, we have to initialise it
|
||||
// and have the responsibility to shut it down later on.
|
||||
|
||||
if (!SDLIsInitialised())
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_AUDIO) < 0)
|
||||
{
|
||||
fprintf(stderr, "Unable to set up sound.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Mix_OpenAudio(snd_samplerate, AUDIO_S16SYS, 2, 1024) < 0)
|
||||
{
|
||||
fprintf(stderr, "Error initialising SDL_mixer: %s\n", Mix_GetError());
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
sdl_was_initialised = true;
|
||||
}
|
||||
|
||||
music_initialised = true;
|
||||
}
|
||||
|
||||
//
|
||||
// SDL_mixer's native MIDI music playing does not pause properly.
|
||||
// As a workaround, set the volume to 0 when paused.
|
||||
//
|
||||
|
||||
static void UpdateMusicVolume(void)
|
||||
{
|
||||
int vol;
|
||||
|
||||
if (musicpaused)
|
||||
{
|
||||
vol = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vol = (current_music_volume * MIX_MAX_VOLUME) / 127;
|
||||
}
|
||||
|
||||
Mix_VolumeMusic(vol);
|
||||
}
|
||||
|
||||
// MUSIC API - dummy. Some code from DOS version.
|
||||
void I_SetMusicVolume(int volume)
|
||||
{
|
||||
// Internal state variable.
|
||||
current_music_volume = volume;
|
||||
|
||||
UpdateMusicVolume();
|
||||
}
|
||||
|
||||
void I_PlaySong(void *handle, int looping)
|
||||
{
|
||||
Mix_Music *music = (Mix_Music *) handle;
|
||||
int loops;
|
||||
|
||||
if (!music_initialised)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (handle == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (looping)
|
||||
{
|
||||
loops = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
loops = 1;
|
||||
}
|
||||
|
||||
Mix_PlayMusic(music, loops);
|
||||
}
|
||||
|
||||
void I_PauseSong (void *handle)
|
||||
{
|
||||
if (!music_initialised)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
musicpaused = true;
|
||||
|
||||
UpdateMusicVolume();
|
||||
}
|
||||
|
||||
void I_ResumeSong (void *handle)
|
||||
{
|
||||
if (!music_initialised)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
musicpaused = false;
|
||||
|
||||
UpdateMusicVolume();
|
||||
}
|
||||
|
||||
void I_StopSong(void *handle)
|
||||
{
|
||||
if (!music_initialised)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Mix_HaltMusic();
|
||||
}
|
||||
|
||||
void I_UnRegisterSong(void *handle)
|
||||
{
|
||||
Mix_Music *music = (Mix_Music *) handle;
|
||||
|
||||
if (!music_initialised)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (handle == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Mix_FreeMusic(music);
|
||||
}
|
||||
|
||||
// Determine whether memory block is a .mid file
|
||||
|
||||
static boolean IsMid(byte *mem, int len)
|
||||
{
|
||||
return len > 4 && !memcmp(mem, "MThd", 4);
|
||||
}
|
||||
|
||||
static boolean ConvertMus(byte *musdata, int len, char *filename)
|
||||
{
|
||||
MEMFILE *instream;
|
||||
MEMFILE *outstream;
|
||||
void *outbuf;
|
||||
size_t outbuf_len;
|
||||
int result;
|
||||
|
||||
instream = mem_fopen_read(musdata, len);
|
||||
outstream = mem_fopen_write();
|
||||
|
||||
result = mus2mid(instream, outstream);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
mem_get_buf(outstream, &outbuf, &outbuf_len);
|
||||
|
||||
M_WriteFile(filename, outbuf, outbuf_len);
|
||||
}
|
||||
|
||||
mem_fclose(instream);
|
||||
mem_fclose(outstream);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void *I_RegisterSong(void *data, int len)
|
||||
{
|
||||
char *filename;
|
||||
Mix_Music *music;
|
||||
|
||||
if (!music_initialised)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// MUS files begin with "MUS"
|
||||
// Reject anything which doesnt have this signature
|
||||
|
||||
filename = M_TempFile("doom.mid");
|
||||
|
||||
if (IsMid(data, len) && len < MAXMIDLENGTH)
|
||||
{
|
||||
M_WriteFile(filename, data, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assume a MUS file and try to convert
|
||||
|
||||
ConvertMus(data, len, filename);
|
||||
}
|
||||
|
||||
// Load the MIDI
|
||||
|
||||
music = Mix_LoadMUS(filename);
|
||||
|
||||
if (music == NULL)
|
||||
{
|
||||
// Failed to load
|
||||
|
||||
fprintf(stderr, "Error loading midi: %s\n", Mix_GetError());
|
||||
}
|
||||
|
||||
// remove file now
|
||||
|
||||
remove(filename);
|
||||
|
||||
Z_Free(filename);
|
||||
|
||||
return music;
|
||||
}
|
||||
|
||||
// Is the song playing?
|
||||
boolean I_QrySongPlaying(void *handle)
|
||||
{
|
||||
if (!music_initialised)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Mix_PlayingMusic();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -30,35 +30,17 @@
|
|||
#include "SDL.h"
|
||||
#include "SDL_mixer.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "memio.h"
|
||||
#include "mus2mid.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
#include "i_system.h"
|
||||
#include "i_pcsound.h"
|
||||
#include "i_sound.h"
|
||||
#include "i_swap.h"
|
||||
#include "deh_main.h"
|
||||
#include "s_sound.h"
|
||||
#include "m_argv.h"
|
||||
#include "m_misc.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
#include "doomdef.h"
|
||||
|
||||
#define NUM_CHANNELS 16
|
||||
|
||||
#define MAXMIDLENGTH (96 * 1024)
|
||||
|
||||
static boolean nosfxparm;
|
||||
static boolean nomusicparm;
|
||||
|
||||
static boolean sound_initialised = false;
|
||||
static boolean music_initialised = false;
|
||||
|
||||
static Mix_Chunk sound_chunks[NUMSFX];
|
||||
static int channels_playing[NUM_CHANNELS];
|
||||
|
|
@ -67,19 +49,19 @@ static int mixer_freq;
|
|||
static Uint16 mixer_format;
|
||||
static int mixer_channels;
|
||||
|
||||
int snd_samplerate = MIX_DEFAULT_FREQUENCY;
|
||||
|
||||
// When a sound stops, check if it is still playing. If it is not,
|
||||
// we can mark the sound data as CACHE to be freed back for other
|
||||
// means.
|
||||
|
||||
void ReleaseSoundOnChannel(int channel)
|
||||
static void ReleaseSoundOnChannel(int channel)
|
||||
{
|
||||
int i;
|
||||
int id = channels_playing[channel];
|
||||
|
||||
if (!id)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
channels_playing[channel] = sfx_None;
|
||||
|
||||
|
|
@ -265,27 +247,31 @@ static Mix_Chunk *GetSFXChunk(int sound_id)
|
|||
// for a given SFX name.
|
||||
//
|
||||
|
||||
int I_GetSfxLumpNum(sfxinfo_t* sfx)
|
||||
static int I_SDL_GetSfxLumpNum(sfxinfo_t* sfx)
|
||||
{
|
||||
char namebuf[9];
|
||||
char *prefix;
|
||||
|
||||
// Different prefix for PC speaker sound effects.
|
||||
|
||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
||||
{
|
||||
prefix = "dp";
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = "ds";
|
||||
}
|
||||
|
||||
sprintf(namebuf, "%s%s", prefix, DEH_String(sfx->name));
|
||||
sprintf(namebuf, "ds%s", DEH_String(sfx->name));
|
||||
|
||||
return W_GetNumForName(namebuf);
|
||||
}
|
||||
|
||||
static void I_SDL_UpdateSoundParams(int handle, int vol, int sep)
|
||||
{
|
||||
int left, right;
|
||||
|
||||
if (!sound_initialised)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
left = ((254 - sep) * vol) / 127;
|
||||
right = ((sep) * vol) / 127;
|
||||
|
||||
Mix_SetPanning(handle, left, right);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Starting a sound means adding it
|
||||
// to the current list of active sounds
|
||||
|
|
@ -299,23 +285,13 @@ int I_GetSfxLumpNum(sfxinfo_t* sfx)
|
|||
// is set, but currently not used by mixing.
|
||||
//
|
||||
|
||||
int
|
||||
I_StartSound
|
||||
( int id,
|
||||
int channel,
|
||||
int vol,
|
||||
int sep,
|
||||
int pitch,
|
||||
int priority )
|
||||
static int I_SDL_StartSound(int id, int channel, int vol, int sep)
|
||||
{
|
||||
Mix_Chunk *chunk;
|
||||
|
||||
if (!sound_initialised)
|
||||
return 0;
|
||||
|
||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
||||
{
|
||||
return I_PCS_StartSound(id, channel, vol, sep, pitch, priority);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Release a sound effect if there is already one playing
|
||||
|
|
@ -340,22 +316,18 @@ I_StartSound
|
|||
|
||||
// set separation, etc.
|
||||
|
||||
I_UpdateSoundParams(channel, vol, sep, pitch);
|
||||
I_SDL_UpdateSoundParams(channel, vol, sep);
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
void I_StopSound (int handle)
|
||||
static void I_SDL_StopSound (int handle)
|
||||
{
|
||||
if (!sound_initialised)
|
||||
return;
|
||||
|
||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
||||
{
|
||||
I_PCS_StopSound(handle);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Mix_HaltChannel(handle);
|
||||
|
||||
// Sound data is no longer needed; release the
|
||||
|
|
@ -365,48 +337,29 @@ void I_StopSound (int handle)
|
|||
}
|
||||
|
||||
|
||||
int I_SoundIsPlaying(int handle)
|
||||
static boolean I_SDL_SoundIsPlaying(int handle)
|
||||
{
|
||||
if (!sound_initialised)
|
||||
return false;
|
||||
|
||||
if (handle < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
||||
{
|
||||
return I_PCS_SoundIsPlaying(handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Mix_Playing(handle);
|
||||
}
|
||||
return Mix_Playing(handle);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Periodically called to update the sound system
|
||||
//
|
||||
|
||||
void I_UpdateSound( void )
|
||||
static void I_SDL_UpdateSound(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!sound_initialised)
|
||||
return;
|
||||
|
||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check all channels to see if a sound has finished
|
||||
|
||||
for (i=0; i<NUM_CHANNELS; ++i)
|
||||
{
|
||||
if (channels_playing[i] && !I_SoundIsPlaying(i))
|
||||
if (channels_playing[i] && !I_SDL_SoundIsPlaying(i))
|
||||
{
|
||||
// Sound has finished playing on this channel,
|
||||
// but sound data has not been released to cache
|
||||
|
|
@ -416,65 +369,20 @@ void I_UpdateSound( void )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// This would be used to write out the mixbuffer
|
||||
// during each game loop update.
|
||||
// Updates sound buffer and audio device at runtime.
|
||||
// It is called during Timer interrupt with SNDINTR.
|
||||
// Mixing now done synchronous, and
|
||||
// only output be done asynchronous?
|
||||
//
|
||||
void
|
||||
I_SubmitSound(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
I_UpdateSoundParams
|
||||
( int handle,
|
||||
int vol,
|
||||
int sep,
|
||||
int pitch)
|
||||
{
|
||||
int left, right;
|
||||
|
||||
static void I_SDL_ShutdownSound(void)
|
||||
{
|
||||
if (!sound_initialised)
|
||||
return;
|
||||
|
||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
left = ((254 - sep) * vol) / 127;
|
||||
right = ((sep) * vol) / 127;
|
||||
|
||||
Mix_SetPanning(handle, left, right);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void I_ShutdownSound(void)
|
||||
{
|
||||
if (!sound_initialised && !music_initialised)
|
||||
return;
|
||||
|
||||
Mix_HaltMusic();
|
||||
Mix_CloseAudio();
|
||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||
|
||||
sound_initialised = false;
|
||||
music_initialised = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
I_InitSound()
|
||||
static boolean I_SDL_InitSound()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -490,75 +398,16 @@ I_InitSound()
|
|||
channels_playing[i] = sfx_None;
|
||||
}
|
||||
|
||||
//!
|
||||
// Disable music playback.
|
||||
//
|
||||
|
||||
nomusicparm = M_CheckParm("-nomusic") > 0;
|
||||
|
||||
if (snd_musicdevice < SNDDEVICE_ADLIB)
|
||||
{
|
||||
nomusicparm = true;
|
||||
}
|
||||
|
||||
//!
|
||||
// Disable sound effects.
|
||||
//
|
||||
|
||||
nosfxparm = M_CheckParm("-nosfx") > 0;
|
||||
|
||||
// If the SFX device is 0 (none), then disable sound effects,
|
||||
// just like if we specified -nosfx. However, we still continue
|
||||
// with initialising digital sound output even if we are using
|
||||
// the PC speaker, because we might be using the SDL PC speaker
|
||||
// emulation.
|
||||
|
||||
if (snd_sfxdevice == SNDDEVICE_NONE)
|
||||
{
|
||||
nosfxparm = true;
|
||||
}
|
||||
|
||||
//!
|
||||
// Disable sound effects and music.
|
||||
//
|
||||
|
||||
if (M_CheckParm("-nosound") > 0)
|
||||
{
|
||||
nosfxparm = true;
|
||||
nomusicparm = true;
|
||||
}
|
||||
|
||||
// When trying to run with music enabled on OSX, display
|
||||
// a warning message.
|
||||
|
||||
#ifdef __MACOSX__
|
||||
if (!nomusicparm)
|
||||
{
|
||||
printf("\n"
|
||||
" *** WARNING ***\n"
|
||||
" Music playback on OSX may cause crashes and\n"
|
||||
" is disabled by default.\n"
|
||||
"\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// If music or sound is going to play, we need to at least
|
||||
// initialise SDL
|
||||
// No sound in screensaver mode.
|
||||
|
||||
if (screensaver_mode || (nomusicparm && nosfxparm))
|
||||
return;
|
||||
|
||||
if (SDL_Init(SDL_INIT_AUDIO) < 0)
|
||||
{
|
||||
fprintf(stderr, "Unable to set up sound.\n");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Mix_OpenAudio(snd_samplerate, AUDIO_S16SYS, 2, 1024) < 0)
|
||||
{
|
||||
fprintf(stderr, "Error initialising SDL_mixer: %s\n", Mix_GetError());
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
Mix_QuerySpec(&mixer_freq, &mixer_format, &mixer_channels);
|
||||
|
|
@ -567,201 +416,32 @@ I_InitSound()
|
|||
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
// If we are using the PC speaker, we now need to initialise it.
|
||||
sound_initialised = true;
|
||||
|
||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
||||
{
|
||||
I_PCS_InitSound();
|
||||
}
|
||||
|
||||
if (!nomusicparm)
|
||||
music_initialised = true;
|
||||
|
||||
if (!nosfxparm)
|
||||
sound_initialised = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// MUSIC API.
|
||||
//
|
||||
|
||||
static boolean musicpaused = false;
|
||||
static int currentMusicVolume;
|
||||
|
||||
//
|
||||
// SDL_mixer's native MIDI music playing does not pause properly.
|
||||
// As a workaround, set the volume to 0 when paused.
|
||||
//
|
||||
|
||||
static void UpdateMusicVolume(void)
|
||||
static snddevice_t sound_sdl_devices[] =
|
||||
{
|
||||
int vol;
|
||||
SNDDEVICE_SB,
|
||||
SNDDEVICE_PAS,
|
||||
SNDDEVICE_GUS,
|
||||
SNDDEVICE_WAVEBLASTER,
|
||||
SNDDEVICE_SOUNDCANVAS,
|
||||
SNDDEVICE_AWE32,
|
||||
};
|
||||
|
||||
if (musicpaused)
|
||||
vol = 0;
|
||||
else
|
||||
vol = (currentMusicVolume * MIX_MAX_VOLUME) / 127;
|
||||
|
||||
Mix_VolumeMusic(vol);
|
||||
}
|
||||
|
||||
// MUSIC API - dummy. Some code from DOS version.
|
||||
void I_SetMusicVolume(int volume)
|
||||
sound_module_t sound_sdl_module =
|
||||
{
|
||||
// Internal state variable.
|
||||
currentMusicVolume = volume;
|
||||
|
||||
UpdateMusicVolume();
|
||||
}
|
||||
|
||||
void I_PlaySong(void *handle, int looping)
|
||||
{
|
||||
Mix_Music *music = (Mix_Music *) handle;
|
||||
int loops;
|
||||
|
||||
if (!music_initialised)
|
||||
return;
|
||||
|
||||
if (handle == NULL)
|
||||
return;
|
||||
|
||||
if (looping)
|
||||
loops = -1;
|
||||
else
|
||||
loops = 1;
|
||||
|
||||
Mix_PlayMusic(music, loops);
|
||||
}
|
||||
|
||||
void I_PauseSong (void *handle)
|
||||
{
|
||||
if (!music_initialised)
|
||||
return;
|
||||
|
||||
musicpaused = true;
|
||||
|
||||
UpdateMusicVolume();
|
||||
}
|
||||
|
||||
void I_ResumeSong (void *handle)
|
||||
{
|
||||
if (!music_initialised)
|
||||
return;
|
||||
|
||||
musicpaused = false;
|
||||
|
||||
UpdateMusicVolume();
|
||||
}
|
||||
|
||||
void I_StopSong(void *handle)
|
||||
{
|
||||
if (!music_initialised)
|
||||
return;
|
||||
|
||||
Mix_HaltMusic();
|
||||
}
|
||||
|
||||
void I_UnRegisterSong(void *handle)
|
||||
{
|
||||
Mix_Music *music = (Mix_Music *) handle;
|
||||
|
||||
if (!music_initialised)
|
||||
return;
|
||||
|
||||
if (handle == NULL)
|
||||
return;
|
||||
|
||||
Mix_FreeMusic(music);
|
||||
}
|
||||
|
||||
// Determine whether memory block is a .mid file
|
||||
|
||||
static boolean IsMid(byte *mem, int len)
|
||||
{
|
||||
return len > 4 && !memcmp(mem, "MThd", 4);
|
||||
}
|
||||
|
||||
static boolean ConvertMus(byte *musdata, int len, char *filename)
|
||||
{
|
||||
MEMFILE *instream;
|
||||
MEMFILE *outstream;
|
||||
void *outbuf;
|
||||
size_t outbuf_len;
|
||||
int result;
|
||||
|
||||
instream = mem_fopen_read(musdata, len);
|
||||
outstream = mem_fopen_write();
|
||||
|
||||
result = mus2mid(instream, outstream);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
mem_get_buf(outstream, &outbuf, &outbuf_len);
|
||||
|
||||
M_WriteFile(filename, outbuf, outbuf_len);
|
||||
}
|
||||
|
||||
mem_fclose(instream);
|
||||
mem_fclose(outstream);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void *I_RegisterSong(void *data, int len)
|
||||
{
|
||||
char *filename;
|
||||
Mix_Music *music;
|
||||
|
||||
if (!music_initialised)
|
||||
return NULL;
|
||||
|
||||
// MUS files begin with "MUS"
|
||||
// Reject anything which doesnt have this signature
|
||||
|
||||
filename = M_TempFile("doom.mid");
|
||||
|
||||
if (IsMid(data, len) && len < MAXMIDLENGTH)
|
||||
{
|
||||
M_WriteFile(filename, data, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assume a MUS file and try to convert
|
||||
|
||||
ConvertMus(data, len, filename);
|
||||
}
|
||||
|
||||
// Load the MIDI
|
||||
|
||||
music = Mix_LoadMUS(filename);
|
||||
|
||||
if (music == NULL)
|
||||
{
|
||||
// Failed to load
|
||||
|
||||
fprintf(stderr, "Error loading midi: %s\n", Mix_GetError());
|
||||
}
|
||||
|
||||
// remove file now
|
||||
|
||||
remove(filename);
|
||||
|
||||
Z_Free(filename);
|
||||
|
||||
return music;
|
||||
}
|
||||
|
||||
// Is the song playing?
|
||||
boolean I_QrySongPlaying(void *handle)
|
||||
{
|
||||
if (!music_initialised)
|
||||
return false;
|
||||
|
||||
return Mix_PlayingMusic();
|
||||
}
|
||||
|
||||
|
||||
sound_sdl_devices,
|
||||
sizeof(sound_sdl_devices) / sizeof(*sound_sdl_devices),
|
||||
I_SDL_InitSound,
|
||||
I_SDL_ShutdownSound,
|
||||
I_SDL_GetSfxLumpNum,
|
||||
I_SDL_UpdateSound,
|
||||
I_SDL_UpdateSoundParams,
|
||||
I_SDL_StartSound,
|
||||
I_SDL_StopSound,
|
||||
I_SDL_SoundIsPlaying,
|
||||
};
|
||||
|
||||
235
src/s_sound.c
235
src/s_sound.c
|
|
@ -26,20 +26,24 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "i_music.h"
|
||||
#include "i_system.h"
|
||||
#include "i_sound.h"
|
||||
|
||||
#include "doomfeatures.h"
|
||||
#include "deh_main.h"
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "doomdef.h"
|
||||
|
||||
#include "sounds.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
#include "deh_main.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_random.h"
|
||||
#include "w_wad.h"
|
||||
#include "m_argv.h"
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "w_wad.h"
|
||||
#include "z_zone.h"
|
||||
|
||||
// when to clip out sounds
|
||||
// Does not fit the large outdoor areas.
|
||||
|
|
@ -74,10 +78,6 @@
|
|||
#define DEFAULT_MUSIC_DEVICE SNDDEVICE_NONE
|
||||
#endif
|
||||
|
||||
int snd_musicdevice = DEFAULT_MUSIC_DEVICE;
|
||||
int snd_sfxdevice = SNDDEVICE_SB;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// sound information (if null, channel avail.)
|
||||
|
|
@ -91,6 +91,9 @@ typedef struct
|
|||
|
||||
} channel_t;
|
||||
|
||||
// Low-level sound module we are using
|
||||
|
||||
static sound_module_t *sound_module;
|
||||
|
||||
// The set of channels available
|
||||
|
||||
|
|
@ -105,6 +108,10 @@ int sfxVolume = 8;
|
|||
|
||||
int musicVolume = 8;
|
||||
|
||||
// Sound sample rate to use for digital output (Hz)
|
||||
|
||||
int snd_samplerate = 22050;
|
||||
|
||||
// Internal volume level, ranging from 0-127
|
||||
|
||||
static int snd_SfxVolume;
|
||||
|
|
@ -121,6 +128,81 @@ static musicinfo_t *mus_playing = NULL;
|
|||
|
||||
int numChannels = 8;
|
||||
|
||||
int snd_musicdevice = DEFAULT_MUSIC_DEVICE;
|
||||
int snd_sfxdevice = SNDDEVICE_SB;
|
||||
|
||||
// Sound effect modules
|
||||
|
||||
extern sound_module_t sound_sdl_module;
|
||||
extern sound_module_t sound_pcsound_module;
|
||||
|
||||
// Compiled-in sound modules:
|
||||
|
||||
static sound_module_t *sound_modules[] =
|
||||
{
|
||||
#ifdef FEATURE_SOUND
|
||||
&sound_sdl_module,
|
||||
&sound_pcsound_module,
|
||||
#endif
|
||||
};
|
||||
|
||||
// Check if a sound device is in the given list of devices
|
||||
|
||||
static boolean SndDeviceInList(snddevice_t device, snddevice_t *list,
|
||||
int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<len; ++i)
|
||||
{
|
||||
if (device == list[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find and initialise a sound_module_t appropriate for the setting
|
||||
// in snd_sfxdevice.
|
||||
|
||||
static void InitSfxModule(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
sound_module = NULL;
|
||||
|
||||
for (i=0; i<sizeof(sound_modules) / sizeof(*sound_modules); ++i)
|
||||
{
|
||||
// Is the sfx device in the list of devices supported by
|
||||
// this module?
|
||||
|
||||
if (SndDeviceInList(snd_sfxdevice,
|
||||
sound_modules[i]->sound_devices,
|
||||
sound_modules[i]->num_sound_devices))
|
||||
{
|
||||
// Initialise the module
|
||||
|
||||
if (sound_modules[i]->Init())
|
||||
{
|
||||
sound_module = sound_modules[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialise music according to snd_musicdevice.
|
||||
|
||||
static void InitMusicModule(void)
|
||||
{
|
||||
if (snd_musicdevice >= SNDDEVICE_ADLIB)
|
||||
{
|
||||
I_InitMusic();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Initializes sound stuff, including volume
|
||||
// Sets channels, SFX and music volume,
|
||||
|
|
@ -131,7 +213,20 @@ void S_Init(int sfxVolume, int musicVolume)
|
|||
{
|
||||
int i;
|
||||
|
||||
I_InitSound();
|
||||
// Initialise the sound and music subsystems.
|
||||
|
||||
if (M_CheckParm("-nosound") <= 0 && !screensaver_mode)
|
||||
{
|
||||
if (M_CheckParm("-nosfx") <= 0)
|
||||
{
|
||||
InitSfxModule();
|
||||
}
|
||||
|
||||
if (M_CheckParm("-nomusic") <= 0)
|
||||
{
|
||||
InitMusicModule();
|
||||
}
|
||||
}
|
||||
|
||||
S_SetSfxVolume(sfxVolume);
|
||||
S_SetMusicVolume(musicVolume);
|
||||
|
|
@ -159,7 +254,12 @@ void S_Init(int sfxVolume, int musicVolume)
|
|||
|
||||
void S_Shutdown(void)
|
||||
{
|
||||
I_ShutdownSound();
|
||||
if (sound_module != NULL)
|
||||
{
|
||||
sound_module->Shutdown();
|
||||
}
|
||||
|
||||
I_ShutdownMusic();
|
||||
}
|
||||
|
||||
static void S_StopChannel(int cnum)
|
||||
|
|
@ -172,9 +272,13 @@ static void S_StopChannel(int cnum)
|
|||
if (c->sfxinfo)
|
||||
{
|
||||
// stop the sound playing
|
||||
if (I_SoundIsPlaying(c->handle))
|
||||
|
||||
if (sound_module != NULL)
|
||||
{
|
||||
I_StopSound(c->handle);
|
||||
if (sound_module->SoundIsPlaying(c->handle))
|
||||
{
|
||||
sound_module->StopSound(c->handle);
|
||||
}
|
||||
}
|
||||
|
||||
// check to see if other channels are playing the sound
|
||||
|
|
@ -228,15 +332,15 @@ void S_Start(void)
|
|||
{
|
||||
// Song - Who? - Where?
|
||||
|
||||
mus_e3m4, // American e4m1
|
||||
mus_e3m2, // Romero e4m2
|
||||
mus_e3m4, // American e4m1
|
||||
mus_e3m2, // Romero e4m2
|
||||
mus_e3m3, // Shawn e4m3
|
||||
mus_e1m5, // American e4m4
|
||||
mus_e2m7, // Tim e4m5
|
||||
mus_e2m4, // Romero e4m6
|
||||
mus_e2m6, // J.Anderson e4m7 CHIRON.WAD
|
||||
mus_e1m5, // American e4m4
|
||||
mus_e2m7, // Tim e4m5
|
||||
mus_e2m4, // Romero e4m6
|
||||
mus_e2m6, // J.Anderson e4m7 CHIRON.WAD
|
||||
mus_e2m5, // Shawn e4m8
|
||||
mus_e1m9 // Tim e4m9
|
||||
mus_e1m9, // Tim e4m9
|
||||
};
|
||||
|
||||
if (gameepisode < 4)
|
||||
|
|
@ -326,14 +430,14 @@ static int S_GetChannel(mobj_t *origin, sfxinfo_t *sfxinfo)
|
|||
}
|
||||
|
||||
//
|
||||
// Changes volume, stereo-separation, and pitch variables
|
||||
// Changes volume and stereo-separation variables
|
||||
// from the norm of a sound effect to be played.
|
||||
// If the sound is not audible, returns a 0.
|
||||
// Otherwise, modifies parameters and returns 1.
|
||||
//
|
||||
|
||||
static int S_AdjustSoundParams(mobj_t *listener, mobj_t *source,
|
||||
int *vol, int *sep, int *pitch)
|
||||
int *vol, int *sep)
|
||||
{
|
||||
fixed_t approx_dist;
|
||||
fixed_t adx;
|
||||
|
|
@ -406,7 +510,6 @@ void S_StartSound(void *origin_p, int sfx_id)
|
|||
mobj_t *origin;
|
||||
int rc;
|
||||
int sep;
|
||||
int pitch;
|
||||
int priority;
|
||||
int cnum;
|
||||
int volume;
|
||||
|
|
@ -425,7 +528,6 @@ void S_StartSound(void *origin_p, int sfx_id)
|
|||
// Initialize sound parameters
|
||||
if (sfx->link)
|
||||
{
|
||||
pitch = sfx->pitch;
|
||||
priority = sfx->priority;
|
||||
volume += sfx->volume;
|
||||
|
||||
|
|
@ -441,7 +543,6 @@ void S_StartSound(void *origin_p, int sfx_id)
|
|||
}
|
||||
else
|
||||
{
|
||||
pitch = NORM_PITCH;
|
||||
priority = NORM_PRIORITY;
|
||||
}
|
||||
|
||||
|
|
@ -453,8 +554,7 @@ void S_StartSound(void *origin_p, int sfx_id)
|
|||
rc = S_AdjustSoundParams(players[consoleplayer].mo,
|
||||
origin,
|
||||
&volume,
|
||||
&sep,
|
||||
&pitch);
|
||||
&sep);
|
||||
|
||||
if (origin->x == players[consoleplayer].mo->x
|
||||
&& origin->y == players[consoleplayer].mo->y)
|
||||
|
|
@ -472,36 +572,6 @@ void S_StartSound(void *origin_p, int sfx_id)
|
|||
sep = NORM_SEP;
|
||||
}
|
||||
|
||||
// hacks to vary the sfx pitches
|
||||
if (sfx_id >= sfx_sawup
|
||||
&& sfx_id <= sfx_sawhit)
|
||||
{
|
||||
pitch += 8 - (M_Random()&15);
|
||||
|
||||
if (pitch < 0)
|
||||
{
|
||||
pitch = 0;
|
||||
}
|
||||
else if (pitch > 255)
|
||||
{
|
||||
pitch = 255;
|
||||
}
|
||||
}
|
||||
else if (sfx_id != sfx_itemup
|
||||
&& sfx_id != sfx_tink)
|
||||
{
|
||||
pitch += 16 - (M_Random()&31);
|
||||
|
||||
if (pitch < 0)
|
||||
{
|
||||
pitch = 0;
|
||||
}
|
||||
else if (pitch > 255)
|
||||
{
|
||||
pitch = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// kill old sound
|
||||
S_StopSound(origin);
|
||||
|
||||
|
|
@ -513,32 +583,29 @@ void S_StartSound(void *origin_p, int sfx_id)
|
|||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// This is supposed to handle the loading/caching.
|
||||
// For some odd reason, the caching is done nearly
|
||||
// each time the sound is needed?
|
||||
//
|
||||
|
||||
// get lumpnum if necessary
|
||||
if (sfx->lumpnum < 0)
|
||||
{
|
||||
sfx->lumpnum = I_GetSfxLumpNum(sfx);
|
||||
}
|
||||
|
||||
// increase the usefulness
|
||||
if (sfx->usefulness++ < 0)
|
||||
{
|
||||
sfx->usefulness = 1;
|
||||
}
|
||||
|
||||
// Assigns the handle to one of the channels in the
|
||||
// mix/output buffer.
|
||||
channels[cnum].handle = I_StartSound(sfx_id,
|
||||
cnum,
|
||||
volume,
|
||||
sep,
|
||||
pitch,
|
||||
priority);
|
||||
if (sound_module != NULL)
|
||||
{
|
||||
// Get lumpnum if necessary
|
||||
|
||||
if (sfx->lumpnum < 0)
|
||||
{
|
||||
sfx->lumpnum = sound_module->GetSfxLumpNum(sfx);
|
||||
}
|
||||
|
||||
// Assigns the handle to one of the channels in the
|
||||
// mix/output buffer.
|
||||
|
||||
channels[cnum].handle = sound_module->StartSound(sfx_id,
|
||||
cnum,
|
||||
volume,
|
||||
sep);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -573,7 +640,6 @@ void S_UpdateSounds(mobj_t *listener)
|
|||
int cnum;
|
||||
int volume;
|
||||
int sep;
|
||||
int pitch;
|
||||
sfxinfo_t* sfx;
|
||||
channel_t* c;
|
||||
|
||||
|
|
@ -584,16 +650,14 @@ void S_UpdateSounds(mobj_t *listener)
|
|||
|
||||
if (c->sfxinfo)
|
||||
{
|
||||
if (I_SoundIsPlaying(c->handle))
|
||||
if (sound_module != NULL && sound_module->SoundIsPlaying(c->handle))
|
||||
{
|
||||
// initialize parameters
|
||||
volume = snd_SfxVolume;
|
||||
pitch = NORM_PITCH;
|
||||
sep = NORM_SEP;
|
||||
|
||||
if (sfx->link)
|
||||
{
|
||||
pitch = sfx->pitch;
|
||||
volume += sfx->volume;
|
||||
if (volume < 1)
|
||||
{
|
||||
|
|
@ -613,8 +677,7 @@ void S_UpdateSounds(mobj_t *listener)
|
|||
audible = S_AdjustSoundParams(listener,
|
||||
c->origin,
|
||||
&volume,
|
||||
&sep,
|
||||
&pitch);
|
||||
&sep);
|
||||
|
||||
if (!audible)
|
||||
{
|
||||
|
|
@ -622,7 +685,7 @@ void S_UpdateSounds(mobj_t *listener)
|
|||
}
|
||||
else
|
||||
{
|
||||
I_UpdateSoundParams(c->handle, volume, sep, pitch);
|
||||
sound_module->UpdateSoundParams(c->handle, volume, sep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@
|
|||
#ifndef __S_SOUND__
|
||||
#define __S_SOUND__
|
||||
|
||||
#include "p_mobj.h"
|
||||
#include "sounds.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
@ -43,8 +45,50 @@ typedef enum
|
|||
SNDDEVICE_AWE32 = 9,
|
||||
} snddevice_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
snddevice_t *sound_devices;
|
||||
int num_sound_devices;
|
||||
|
||||
// Initialise sound module
|
||||
// Returns true if successfully initialised
|
||||
|
||||
boolean (*Init)(void);
|
||||
|
||||
// Shutdown sound module
|
||||
|
||||
void (*Shutdown)(void);
|
||||
|
||||
// Returns the lump index of the given sound.
|
||||
|
||||
int (*GetSfxLumpNum)(sfxinfo_t *sfxinfo);
|
||||
|
||||
// Called periodically to update the subsystem.
|
||||
|
||||
void (*Update)(void);
|
||||
|
||||
// Update the sound settings on the given channel.
|
||||
|
||||
void (*UpdateSoundParams)(int channel, int vol, int sep);
|
||||
|
||||
// Start a sound on a given channel. Returns the channel id
|
||||
// or -1 on failure.
|
||||
|
||||
int (*StartSound)(int id, int channel, int vol, int sep);
|
||||
|
||||
// Stop the sound playing on the given channel.
|
||||
|
||||
void (*StopSound)(int channel);
|
||||
|
||||
// Query if a sound is playing on the given channel
|
||||
|
||||
boolean (*SoundIsPlaying)(int channel);
|
||||
|
||||
} sound_module_t;
|
||||
|
||||
extern int snd_sfxdevice;
|
||||
extern int snd_musicdevice;
|
||||
extern int snd_samplerate;
|
||||
|
||||
//
|
||||
// Initializes sound stuff, including volume
|
||||
|
|
|
|||
Loading…
Reference in a new issue