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 "config.h"
|
||||||
#include "pcsound.h"
|
#include "pcsound.h"
|
||||||
|
#include "pcsound_internal.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extern pcsound_driver_t pcsound_win32_driver;
|
extern pcsound_driver_t pcsound_win32_driver;
|
||||||
|
|
@ -54,6 +55,13 @@ static pcsound_driver_t *drivers[] =
|
||||||
|
|
||||||
static pcsound_driver_t *pcsound_driver = NULL;
|
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)
|
int PCSound_Init(pcsound_callback_func callback_func)
|
||||||
{
|
{
|
||||||
char *driver_name;
|
char *driver_name;
|
||||||
|
|
|
||||||
|
|
@ -26,22 +26,21 @@
|
||||||
#ifndef PCSOUND_H
|
#ifndef PCSOUND_H
|
||||||
#define 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 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
|
// Initialise the PC speaker subsystem. The given function is called
|
||||||
{
|
// periodically to request more sound data to play.
|
||||||
char *name;
|
|
||||||
pcsound_init_func init_func;
|
|
||||||
pcsound_shutdown_func shutdown_func;
|
|
||||||
};
|
|
||||||
|
|
||||||
int PCSound_Init(pcsound_callback_func callback_func);
|
int PCSound_Init(pcsound_callback_func callback_func);
|
||||||
|
|
||||||
|
// Shut down the PC speaker subsystem.
|
||||||
|
|
||||||
void PCSound_Shutdown(void);
|
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 */
|
#endif /* #ifndef PCSOUND_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,22 +19,29 @@
|
||||||
// 02111-1307, USA.
|
// 02111-1307, USA.
|
||||||
//
|
//
|
||||||
// DESCRIPTION:
|
// DESCRIPTION:
|
||||||
// System interface for PC speaker sound.
|
// PC speaker interface.
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef __I_PCSOUND_H__
|
#ifndef PCSOUND_INTERNAL_H
|
||||||
#define __I_PCSOUND_H__
|
#define PCSOUND_INTERNAL_H
|
||||||
|
|
||||||
int I_PCS_StartSound(int id,
|
#include "pcsound.h"
|
||||||
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);
|
|
||||||
|
|
||||||
#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 "SDL_thread.h"
|
||||||
|
|
||||||
#include "pcsound.h"
|
#include "pcsound.h"
|
||||||
|
#include "pcsound_internal.h"
|
||||||
|
|
||||||
#define CONSOLE_DEVICE "/dev/console"
|
#define CONSOLE_DEVICE "/dev/console"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,17 @@
|
||||||
#include "SDL_mixer.h"
|
#include "SDL_mixer.h"
|
||||||
|
|
||||||
#include "pcsound.h"
|
#include "pcsound.h"
|
||||||
|
#include "pcsound_internal.h"
|
||||||
|
|
||||||
#define SQUARE_WAVE_AMP 0x2000
|
#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;
|
static pcsound_callback_func callback;
|
||||||
|
|
||||||
// Output sound format
|
// 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)
|
static int PCSound_SDL_Init(pcsound_callback_func callback_func)
|
||||||
{
|
{
|
||||||
// Check that SDL_mixer has been opened already
|
// Check if SDL_mixer has been opened already
|
||||||
// If not, fail
|
// 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
|
// Only supports AUDIO_S16SYS
|
||||||
|
|
||||||
if (mixing_format != AUDIO_S16SYS || mixing_channels != 2)
|
if (mixing_format != AUDIO_S16SYS || mixing_channels != 2)
|
||||||
|
|
@ -154,6 +203,8 @@ static int PCSound_SDL_Init(pcsound_callback_func callback_func)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PCSound_SDL only supports native signed 16-bit LSB, "
|
"PCSound_SDL only supports native signed 16-bit LSB, "
|
||||||
"stereo format!\n");
|
"stereo format!\n");
|
||||||
|
|
||||||
|
PCSound_SDL_Shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,10 +217,6 @@ static int PCSound_SDL_Init(pcsound_callback_func callback_func)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PCSound_SDL_Shutdown(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
pcsound_driver_t pcsound_sdl_driver =
|
pcsound_driver_t pcsound_sdl_driver =
|
||||||
{
|
{
|
||||||
"SDL",
|
"SDL",
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#include "pcsound.h"
|
#include "pcsound.h"
|
||||||
|
#include "pcsound_internal.h"
|
||||||
|
|
||||||
static SDL_Thread *sound_thread_handle;
|
static SDL_Thread *sound_thread_handle;
|
||||||
static int sound_thread_running;
|
static int sound_thread_running;
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ r_sky.c r_sky.h \
|
||||||
r_state.h \
|
r_state.h \
|
||||||
r_things.c r_things.h \
|
r_things.c r_things.h \
|
||||||
sounds.c sounds.h \
|
sounds.c sounds.h \
|
||||||
|
s_sound.c s_sound.h \
|
||||||
st_lib.c st_lib.h \
|
st_lib.c st_lib.h \
|
||||||
st_stuff.c st_stuff.h \
|
st_stuff.c st_stuff.h \
|
||||||
tables.c tables.h \
|
tables.c tables.h \
|
||||||
|
|
@ -146,9 +147,9 @@ w_merge.c w_merge.h
|
||||||
|
|
||||||
FEATURE_SOUND_SOURCE_FILES = \
|
FEATURE_SOUND_SOURCE_FILES = \
|
||||||
i_pcsound.c i_pcsound.h \
|
i_pcsound.c i_pcsound.h \
|
||||||
i_sound.c i_sound.h \
|
i_sdlsound.c \
|
||||||
mus2mid.c mus2mid.h \
|
i_sdlmusic.c i_music.h \
|
||||||
s_sound.c s_sound.h
|
mus2mid.c mus2mid.h
|
||||||
|
|
||||||
SOURCE_FILES = $(MAIN_SOURCE_FILES) \
|
SOURCE_FILES = $(MAIN_SOURCE_FILES) \
|
||||||
$(FEATURE_DEHACKED_SOURCE_FILES) \
|
$(FEATURE_DEHACKED_SOURCE_FILES) \
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@
|
||||||
#include "p_saveg.h"
|
#include "p_saveg.h"
|
||||||
|
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "i_sound.h"
|
|
||||||
#include "i_timer.h"
|
#include "i_timer.h"
|
||||||
#include "i_video.h"
|
#include "i_video.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,15 +68,7 @@ static void *DEH_SoundStart(deh_context_t *context, char *line)
|
||||||
"in Vanilla dehacked.", sound_number);
|
"in Vanilla dehacked.", sound_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEATURE_SOUND
|
|
||||||
|
|
||||||
return &S_sfx[sound_number];
|
return &S_sfx[sound_number];
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DEH_SoundParseLine(deh_context_t *context, char *line, void *tag)
|
static void DEH_SoundParseLine(deh_context_t *context, char *line, void *tag)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// DESCRIPTION:
|
// DESCRIPTION:
|
||||||
// System interface, sound.
|
// System interface, music.
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -32,59 +32,7 @@
|
||||||
|
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "sounds.h"
|
#include "sounds.h"
|
||||||
|
#include "s_sound.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 );
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// MUSIC I/O
|
// MUSIC I/O
|
||||||
|
|
@ -125,3 +73,4 @@ boolean I_QrySongPlaying(void *handle);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -28,8 +28,8 @@
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
|
|
||||||
#include "i_pcsound.h"
|
#include "deh_main.h"
|
||||||
#include "i_sound.h"
|
#include "s_sound.h"
|
||||||
#include "sounds.h"
|
#include "sounds.h"
|
||||||
|
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
|
|
@ -62,7 +62,7 @@ static float frequencies[] = {
|
||||||
|
|
||||||
#define NUM_FREQUENCIES (sizeof(frequencies) / sizeof(*frequencies))
|
#define NUM_FREQUENCIES (sizeof(frequencies) / sizeof(*frequencies))
|
||||||
|
|
||||||
void PCSCallbackFunc(int *duration, int *freq)
|
static void PCSCallbackFunc(int *duration, int *freq)
|
||||||
{
|
{
|
||||||
int tone;
|
int tone;
|
||||||
|
|
||||||
|
|
@ -144,12 +144,10 @@ static boolean CachePCSLump(int sound_id)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int I_PCS_StartSound(int id,
|
static int I_PCS_StartSound(int id,
|
||||||
int channel,
|
int channel,
|
||||||
int vol,
|
int vol,
|
||||||
int sep,
|
int sep)
|
||||||
int pitch,
|
|
||||||
int priority)
|
|
||||||
{
|
{
|
||||||
int result;
|
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)
|
if (!pcs_initialised)
|
||||||
{
|
{
|
||||||
|
|
@ -214,7 +212,22 @@ void I_PCS_StopSound(int handle)
|
||||||
SDL_UnlockMutex(sound_lock);
|
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)
|
if (!pcs_initialised)
|
||||||
{
|
{
|
||||||
|
|
@ -229,10 +242,58 @@ int I_PCS_SoundIsPlaying(int handle)
|
||||||
return current_sound_lump != NULL && current_sound_remaining > 0;
|
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);
|
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.h"
|
||||||
#include "SDL_mixer.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 "deh_main.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
#include "m_misc.h"
|
|
||||||
#include "w_wad.h"
|
#include "w_wad.h"
|
||||||
|
#include "z_zone.h"
|
||||||
|
|
||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
|
|
||||||
#define NUM_CHANNELS 16
|
#define NUM_CHANNELS 16
|
||||||
|
|
||||||
#define MAXMIDLENGTH (96 * 1024)
|
|
||||||
|
|
||||||
static boolean nosfxparm;
|
|
||||||
static boolean nomusicparm;
|
|
||||||
|
|
||||||
static boolean sound_initialised = false;
|
static boolean sound_initialised = false;
|
||||||
static boolean music_initialised = false;
|
|
||||||
|
|
||||||
static Mix_Chunk sound_chunks[NUMSFX];
|
static Mix_Chunk sound_chunks[NUMSFX];
|
||||||
static int channels_playing[NUM_CHANNELS];
|
static int channels_playing[NUM_CHANNELS];
|
||||||
|
|
@ -67,19 +49,19 @@ static int mixer_freq;
|
||||||
static Uint16 mixer_format;
|
static Uint16 mixer_format;
|
||||||
static int mixer_channels;
|
static int mixer_channels;
|
||||||
|
|
||||||
int snd_samplerate = MIX_DEFAULT_FREQUENCY;
|
|
||||||
|
|
||||||
// When a sound stops, check if it is still playing. If it is not,
|
// 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
|
// we can mark the sound data as CACHE to be freed back for other
|
||||||
// means.
|
// means.
|
||||||
|
|
||||||
void ReleaseSoundOnChannel(int channel)
|
static void ReleaseSoundOnChannel(int channel)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int id = channels_playing[channel];
|
int id = channels_playing[channel];
|
||||||
|
|
||||||
if (!id)
|
if (!id)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
channels_playing[channel] = sfx_None;
|
channels_playing[channel] = sfx_None;
|
||||||
|
|
||||||
|
|
@ -265,27 +247,31 @@ static Mix_Chunk *GetSFXChunk(int sound_id)
|
||||||
// for a given SFX name.
|
// for a given SFX name.
|
||||||
//
|
//
|
||||||
|
|
||||||
int I_GetSfxLumpNum(sfxinfo_t* sfx)
|
static int I_SDL_GetSfxLumpNum(sfxinfo_t* sfx)
|
||||||
{
|
{
|
||||||
char namebuf[9];
|
char namebuf[9];
|
||||||
char *prefix;
|
|
||||||
|
|
||||||
// Different prefix for PC speaker sound effects.
|
sprintf(namebuf, "ds%s", DEH_String(sfx->name));
|
||||||
|
|
||||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
|
||||||
{
|
|
||||||
prefix = "dp";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prefix = "ds";
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(namebuf, "%s%s", prefix, DEH_String(sfx->name));
|
|
||||||
|
|
||||||
return W_GetNumForName(namebuf);
|
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
|
// Starting a sound means adding it
|
||||||
// to the current list of active sounds
|
// 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.
|
// is set, but currently not used by mixing.
|
||||||
//
|
//
|
||||||
|
|
||||||
int
|
static int I_SDL_StartSound(int id, int channel, int vol, int sep)
|
||||||
I_StartSound
|
|
||||||
( int id,
|
|
||||||
int channel,
|
|
||||||
int vol,
|
|
||||||
int sep,
|
|
||||||
int pitch,
|
|
||||||
int priority )
|
|
||||||
{
|
{
|
||||||
Mix_Chunk *chunk;
|
Mix_Chunk *chunk;
|
||||||
|
|
||||||
if (!sound_initialised)
|
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
|
// Release a sound effect if there is already one playing
|
||||||
|
|
@ -340,22 +316,18 @@ I_StartSound
|
||||||
|
|
||||||
// set separation, etc.
|
// set separation, etc.
|
||||||
|
|
||||||
I_UpdateSoundParams(channel, vol, sep, pitch);
|
I_SDL_UpdateSoundParams(channel, vol, sep);
|
||||||
|
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_StopSound (int handle)
|
static void I_SDL_StopSound (int handle)
|
||||||
{
|
{
|
||||||
if (!sound_initialised)
|
if (!sound_initialised)
|
||||||
return;
|
|
||||||
|
|
||||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
|
||||||
{
|
{
|
||||||
I_PCS_StopSound(handle);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mix_HaltChannel(handle);
|
Mix_HaltChannel(handle);
|
||||||
|
|
||||||
// Sound data is no longer needed; release the
|
// 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)
|
if (handle < 0)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
return Mix_Playing(handle);
|
||||||
{
|
|
||||||
return I_PCS_SoundIsPlaying(handle);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Mix_Playing(handle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Periodically called to update the sound system
|
// Periodically called to update the sound system
|
||||||
//
|
//
|
||||||
|
|
||||||
void I_UpdateSound( void )
|
static void I_SDL_UpdateSound(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!sound_initialised)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check all channels to see if a sound has finished
|
// Check all channels to see if a sound has finished
|
||||||
|
|
||||||
for (i=0; i<NUM_CHANNELS; ++i)
|
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,
|
// Sound has finished playing on this channel,
|
||||||
// but sound data has not been released to cache
|
// but sound data has not been released to cache
|
||||||
|
|
@ -416,65 +369,20 @@ void I_UpdateSound( void )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void I_SDL_ShutdownSound(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;
|
|
||||||
|
|
||||||
if (!sound_initialised)
|
if (!sound_initialised)
|
||||||
return;
|
|
||||||
|
|
||||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
|
||||||
{
|
{
|
||||||
return;
|
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();
|
Mix_CloseAudio();
|
||||||
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
SDL_QuitSubSystem(SDL_INIT_AUDIO);
|
||||||
|
|
||||||
sound_initialised = false;
|
sound_initialised = false;
|
||||||
music_initialised = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean I_SDL_InitSound()
|
||||||
|
|
||||||
void
|
|
||||||
I_InitSound()
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -490,75 +398,16 @@ I_InitSound()
|
||||||
channels_playing[i] = sfx_None;
|
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)
|
if (SDL_Init(SDL_INIT_AUDIO) < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Unable to set up sound.\n");
|
fprintf(stderr, "Unable to set up sound.\n");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Mix_OpenAudio(snd_samplerate, AUDIO_S16SYS, 2, 1024) < 0)
|
if (Mix_OpenAudio(snd_samplerate, AUDIO_S16SYS, 2, 1024) < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error initialising SDL_mixer: %s\n", Mix_GetError());
|
fprintf(stderr, "Error initialising SDL_mixer: %s\n", Mix_GetError());
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mix_QuerySpec(&mixer_freq, &mixer_format, &mixer_channels);
|
Mix_QuerySpec(&mixer_freq, &mixer_format, &mixer_channels);
|
||||||
|
|
@ -567,201 +416,32 @@ I_InitSound()
|
||||||
|
|
||||||
SDL_PauseAudio(0);
|
SDL_PauseAudio(0);
|
||||||
|
|
||||||
// If we are using the PC speaker, we now need to initialise it.
|
sound_initialised = true;
|
||||||
|
|
||||||
if (snd_sfxdevice == SNDDEVICE_PCSPEAKER)
|
return true;
|
||||||
{
|
|
||||||
I_PCS_InitSound();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!nomusicparm)
|
|
||||||
music_initialised = true;
|
|
||||||
|
|
||||||
if (!nosfxparm)
|
|
||||||
sound_initialised = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static snddevice_t sound_sdl_devices[] =
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
int vol;
|
SNDDEVICE_SB,
|
||||||
|
SNDDEVICE_PAS,
|
||||||
|
SNDDEVICE_GUS,
|
||||||
|
SNDDEVICE_WAVEBLASTER,
|
||||||
|
SNDDEVICE_SOUNDCANVAS,
|
||||||
|
SNDDEVICE_AWE32,
|
||||||
|
};
|
||||||
|
|
||||||
if (musicpaused)
|
sound_module_t sound_sdl_module =
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
// Internal state variable.
|
sound_sdl_devices,
|
||||||
currentMusicVolume = volume;
|
sizeof(sound_sdl_devices) / sizeof(*sound_sdl_devices),
|
||||||
|
I_SDL_InitSound,
|
||||||
UpdateMusicVolume();
|
I_SDL_ShutdownSound,
|
||||||
}
|
I_SDL_GetSfxLumpNum,
|
||||||
|
I_SDL_UpdateSound,
|
||||||
void I_PlaySong(void *handle, int looping)
|
I_SDL_UpdateSoundParams,
|
||||||
{
|
I_SDL_StartSound,
|
||||||
Mix_Music *music = (Mix_Music *) handle;
|
I_SDL_StopSound,
|
||||||
int loops;
|
I_SDL_SoundIsPlaying,
|
||||||
|
};
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
235
src/s_sound.c
235
src/s_sound.c
|
|
@ -26,20 +26,24 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "i_music.h"
|
||||||
#include "i_system.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 "sounds.h"
|
||||||
#include "s_sound.h"
|
#include "s_sound.h"
|
||||||
|
|
||||||
#include "deh_main.h"
|
|
||||||
#include "z_zone.h"
|
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "w_wad.h"
|
#include "m_argv.h"
|
||||||
|
|
||||||
#include "doomdef.h"
|
|
||||||
#include "p_local.h"
|
#include "p_local.h"
|
||||||
|
#include "w_wad.h"
|
||||||
#include "doomstat.h"
|
#include "z_zone.h"
|
||||||
|
|
||||||
// when to clip out sounds
|
// when to clip out sounds
|
||||||
// Does not fit the large outdoor areas.
|
// Does not fit the large outdoor areas.
|
||||||
|
|
@ -74,10 +78,6 @@
|
||||||
#define DEFAULT_MUSIC_DEVICE SNDDEVICE_NONE
|
#define DEFAULT_MUSIC_DEVICE SNDDEVICE_NONE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int snd_musicdevice = DEFAULT_MUSIC_DEVICE;
|
|
||||||
int snd_sfxdevice = SNDDEVICE_SB;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
// sound information (if null, channel avail.)
|
// sound information (if null, channel avail.)
|
||||||
|
|
@ -91,6 +91,9 @@ typedef struct
|
||||||
|
|
||||||
} channel_t;
|
} channel_t;
|
||||||
|
|
||||||
|
// Low-level sound module we are using
|
||||||
|
|
||||||
|
static sound_module_t *sound_module;
|
||||||
|
|
||||||
// The set of channels available
|
// The set of channels available
|
||||||
|
|
||||||
|
|
@ -105,6 +108,10 @@ int sfxVolume = 8;
|
||||||
|
|
||||||
int musicVolume = 8;
|
int musicVolume = 8;
|
||||||
|
|
||||||
|
// Sound sample rate to use for digital output (Hz)
|
||||||
|
|
||||||
|
int snd_samplerate = 22050;
|
||||||
|
|
||||||
// Internal volume level, ranging from 0-127
|
// Internal volume level, ranging from 0-127
|
||||||
|
|
||||||
static int snd_SfxVolume;
|
static int snd_SfxVolume;
|
||||||
|
|
@ -121,6 +128,81 @@ static musicinfo_t *mus_playing = NULL;
|
||||||
|
|
||||||
int numChannels = 8;
|
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
|
// Initializes sound stuff, including volume
|
||||||
// Sets channels, SFX and music volume,
|
// Sets channels, SFX and music volume,
|
||||||
|
|
@ -131,7 +213,20 @@ void S_Init(int sfxVolume, int musicVolume)
|
||||||
{
|
{
|
||||||
int i;
|
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_SetSfxVolume(sfxVolume);
|
||||||
S_SetMusicVolume(musicVolume);
|
S_SetMusicVolume(musicVolume);
|
||||||
|
|
@ -159,7 +254,12 @@ void S_Init(int sfxVolume, int musicVolume)
|
||||||
|
|
||||||
void S_Shutdown(void)
|
void S_Shutdown(void)
|
||||||
{
|
{
|
||||||
I_ShutdownSound();
|
if (sound_module != NULL)
|
||||||
|
{
|
||||||
|
sound_module->Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
I_ShutdownMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void S_StopChannel(int cnum)
|
static void S_StopChannel(int cnum)
|
||||||
|
|
@ -172,9 +272,13 @@ static void S_StopChannel(int cnum)
|
||||||
if (c->sfxinfo)
|
if (c->sfxinfo)
|
||||||
{
|
{
|
||||||
// stop the sound playing
|
// 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
|
// check to see if other channels are playing the sound
|
||||||
|
|
@ -228,15 +332,15 @@ void S_Start(void)
|
||||||
{
|
{
|
||||||
// Song - Who? - Where?
|
// Song - Who? - Where?
|
||||||
|
|
||||||
mus_e3m4, // American e4m1
|
mus_e3m4, // American e4m1
|
||||||
mus_e3m2, // Romero e4m2
|
mus_e3m2, // Romero e4m2
|
||||||
mus_e3m3, // Shawn e4m3
|
mus_e3m3, // Shawn e4m3
|
||||||
mus_e1m5, // American e4m4
|
mus_e1m5, // American e4m4
|
||||||
mus_e2m7, // Tim e4m5
|
mus_e2m7, // Tim e4m5
|
||||||
mus_e2m4, // Romero e4m6
|
mus_e2m4, // Romero e4m6
|
||||||
mus_e2m6, // J.Anderson e4m7 CHIRON.WAD
|
mus_e2m6, // J.Anderson e4m7 CHIRON.WAD
|
||||||
mus_e2m5, // Shawn e4m8
|
mus_e2m5, // Shawn e4m8
|
||||||
mus_e1m9 // Tim e4m9
|
mus_e1m9, // Tim e4m9
|
||||||
};
|
};
|
||||||
|
|
||||||
if (gameepisode < 4)
|
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.
|
// from the norm of a sound effect to be played.
|
||||||
// If the sound is not audible, returns a 0.
|
// If the sound is not audible, returns a 0.
|
||||||
// Otherwise, modifies parameters and returns 1.
|
// Otherwise, modifies parameters and returns 1.
|
||||||
//
|
//
|
||||||
|
|
||||||
static int S_AdjustSoundParams(mobj_t *listener, mobj_t *source,
|
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 approx_dist;
|
||||||
fixed_t adx;
|
fixed_t adx;
|
||||||
|
|
@ -406,7 +510,6 @@ void S_StartSound(void *origin_p, int sfx_id)
|
||||||
mobj_t *origin;
|
mobj_t *origin;
|
||||||
int rc;
|
int rc;
|
||||||
int sep;
|
int sep;
|
||||||
int pitch;
|
|
||||||
int priority;
|
int priority;
|
||||||
int cnum;
|
int cnum;
|
||||||
int volume;
|
int volume;
|
||||||
|
|
@ -425,7 +528,6 @@ void S_StartSound(void *origin_p, int sfx_id)
|
||||||
// Initialize sound parameters
|
// Initialize sound parameters
|
||||||
if (sfx->link)
|
if (sfx->link)
|
||||||
{
|
{
|
||||||
pitch = sfx->pitch;
|
|
||||||
priority = sfx->priority;
|
priority = sfx->priority;
|
||||||
volume += sfx->volume;
|
volume += sfx->volume;
|
||||||
|
|
||||||
|
|
@ -441,7 +543,6 @@ void S_StartSound(void *origin_p, int sfx_id)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pitch = NORM_PITCH;
|
|
||||||
priority = NORM_PRIORITY;
|
priority = NORM_PRIORITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -453,8 +554,7 @@ void S_StartSound(void *origin_p, int sfx_id)
|
||||||
rc = S_AdjustSoundParams(players[consoleplayer].mo,
|
rc = S_AdjustSoundParams(players[consoleplayer].mo,
|
||||||
origin,
|
origin,
|
||||||
&volume,
|
&volume,
|
||||||
&sep,
|
&sep);
|
||||||
&pitch);
|
|
||||||
|
|
||||||
if (origin->x == players[consoleplayer].mo->x
|
if (origin->x == players[consoleplayer].mo->x
|
||||||
&& origin->y == players[consoleplayer].mo->y)
|
&& origin->y == players[consoleplayer].mo->y)
|
||||||
|
|
@ -472,36 +572,6 @@ void S_StartSound(void *origin_p, int sfx_id)
|
||||||
sep = NORM_SEP;
|
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
|
// kill old sound
|
||||||
S_StopSound(origin);
|
S_StopSound(origin);
|
||||||
|
|
||||||
|
|
@ -513,32 +583,29 @@ void S_StartSound(void *origin_p, int sfx_id)
|
||||||
return;
|
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
|
// increase the usefulness
|
||||||
if (sfx->usefulness++ < 0)
|
if (sfx->usefulness++ < 0)
|
||||||
{
|
{
|
||||||
sfx->usefulness = 1;
|
sfx->usefulness = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assigns the handle to one of the channels in the
|
if (sound_module != NULL)
|
||||||
// mix/output buffer.
|
{
|
||||||
channels[cnum].handle = I_StartSound(sfx_id,
|
// Get lumpnum if necessary
|
||||||
cnum,
|
|
||||||
volume,
|
if (sfx->lumpnum < 0)
|
||||||
sep,
|
{
|
||||||
pitch,
|
sfx->lumpnum = sound_module->GetSfxLumpNum(sfx);
|
||||||
priority);
|
}
|
||||||
|
|
||||||
|
// 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 cnum;
|
||||||
int volume;
|
int volume;
|
||||||
int sep;
|
int sep;
|
||||||
int pitch;
|
|
||||||
sfxinfo_t* sfx;
|
sfxinfo_t* sfx;
|
||||||
channel_t* c;
|
channel_t* c;
|
||||||
|
|
||||||
|
|
@ -584,16 +650,14 @@ void S_UpdateSounds(mobj_t *listener)
|
||||||
|
|
||||||
if (c->sfxinfo)
|
if (c->sfxinfo)
|
||||||
{
|
{
|
||||||
if (I_SoundIsPlaying(c->handle))
|
if (sound_module != NULL && sound_module->SoundIsPlaying(c->handle))
|
||||||
{
|
{
|
||||||
// initialize parameters
|
// initialize parameters
|
||||||
volume = snd_SfxVolume;
|
volume = snd_SfxVolume;
|
||||||
pitch = NORM_PITCH;
|
|
||||||
sep = NORM_SEP;
|
sep = NORM_SEP;
|
||||||
|
|
||||||
if (sfx->link)
|
if (sfx->link)
|
||||||
{
|
{
|
||||||
pitch = sfx->pitch;
|
|
||||||
volume += sfx->volume;
|
volume += sfx->volume;
|
||||||
if (volume < 1)
|
if (volume < 1)
|
||||||
{
|
{
|
||||||
|
|
@ -613,8 +677,7 @@ void S_UpdateSounds(mobj_t *listener)
|
||||||
audible = S_AdjustSoundParams(listener,
|
audible = S_AdjustSoundParams(listener,
|
||||||
c->origin,
|
c->origin,
|
||||||
&volume,
|
&volume,
|
||||||
&sep,
|
&sep);
|
||||||
&pitch);
|
|
||||||
|
|
||||||
if (!audible)
|
if (!audible)
|
||||||
{
|
{
|
||||||
|
|
@ -622,7 +685,7 @@ void S_UpdateSounds(mobj_t *listener)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
I_UpdateSoundParams(c->handle, volume, sep, pitch);
|
sound_module->UpdateSoundParams(c->handle, volume, sep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@
|
||||||
#ifndef __S_SOUND__
|
#ifndef __S_SOUND__
|
||||||
#define __S_SOUND__
|
#define __S_SOUND__
|
||||||
|
|
||||||
|
#include "p_mobj.h"
|
||||||
|
#include "sounds.h"
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
@ -43,8 +45,50 @@ typedef enum
|
||||||
SNDDEVICE_AWE32 = 9,
|
SNDDEVICE_AWE32 = 9,
|
||||||
} snddevice_t;
|
} 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_sfxdevice;
|
||||||
extern int snd_musicdevice;
|
extern int snd_musicdevice;
|
||||||
|
extern int snd_samplerate;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initializes sound stuff, including volume
|
// Initializes sound stuff, including volume
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue