37 #define SND_F_USED                      (1<<0)          // Sounds[] element is used 
   65                 m_defaultVolume(defaultVolume),
 
   66                 m_dynamicVolume(dynamicVolume)
 
   92 #define MIN_SOUND_VOLUME                                0.05f 
   94 static int snd_next_sig = 1;
 
  139                 nprintf(( 
"Sound", 
"SOUND => Audio is already initialized!\n" ));
 
  148                 nprintf(( 
"Sound", 
"SOUND ==> Fatal error initializing audio device, turn sound off.\n" ));
 
  154                 mprintf((
"Could not initialize the OGG vorbis converter.\n"));
 
  168         nprintf(( 
"Sound", 
"SOUND => Audio init unsuccessful, continuing without sound.\n" ));
 
  185         for (idx = 0; idx < Sounds.size(); idx++) {
 
  190                 sprintf(txt, 
"%s (%ds)\n", Sounds[idx].
filename, Sounds[idx].info.duration); 
 
  202 DCF(show_sounds, 
"Toggles display of sound debug info")
 
  215         int message_sounds = 0;
 
  216         int interface_sounds = 0;
 
  224         for (
size_t idx = 0; 
idx < Sounds.size(); 
idx++) {
 
  264         gr_printf_no_resize(sx, sy, 
"Total sounds : %d\n", game_sounds + interface_sounds + message_sounds);
 
  287         int                             rc, FileSize, FileOffset;
 
  299         for (n = 0; n < Sounds.size(); n++) {
 
  314         if ( n == Sounds.size() ) {
 
  319                 Sounds.push_back( new_sound );
 
  331         char *
p = strrchr(filename, 
'.');
 
  345         nprintf((
"Sound", 
"SOUND => Loading '%s'\n", filename));
 
  349                 nprintf((
"Sound", 
"SOUND ==> Could not read sound file!\n"));
 
  382         if (si->
data != NULL) {
 
  392                 nprintf((
"Sound", 
"SOUND ==> Failed to load '%s'\n", filename));
 
  399         snd->
sig = snd_next_sig++;
 
  400         if (snd_next_sig < 0 ) snd_next_sig = 1;
 
  420         if ( (n < 0) || ((
size_t)n >= Sounds.size()) ) {
 
  426         if (Sounds[n].sid != -1) {
 
  431         if ( (
size_t)n == Sounds.size()-1 ) {
 
  449         while ( !Sounds.empty() ) {
 
  477 int snd_play_raw( 
int soundnum, 
float pan, 
float vol_scale, 
int priority )
 
  482         if ( (soundnum < 0) || ((
size_t)soundnum >= Sounds.size() ) ) {
 
  487         gs.
id_sig = Sounds[soundnum].sig;
 
  493         rval = 
snd_play(&gs, pan, vol_scale, priority, 
true);
 
  534         if ( gs->id == -1 ) {
 
  537         } 
else if ( gs->id_sig != Sounds[gs->id].sig ) {
 
  544         volume = gs->default_volume * vol_scale;
 
  553         snd = &Sounds[gs->id];
 
  562                 handle = 
ds_play( snd->
sid, gs->id_sig, 
ds_priority(priority), &gs->enhanced_sound_data, volume, pan, 0, is_voice_msg);
 
  594 int snd_play_3d(
game_snd *
gs, 
vec3d *source_pos, 
vec3d *listen_pos, 
float radius, 
vec3d *source_vel, 
int looping, 
float vol_scale, 
int priority, 
vec3d *sound_fvec, 
float range_factor, 
int force, 
bool is_ambient )
 
  597         vec3d   vector_to_sound;
 
  599         float           volume, distance, max_volume;
 
  600         float           min_range, max_range;
 
  616         }
else if ( gs->id_sig != Sounds[gs->id].sig ) {
 
  623         snd = &Sounds[gs->id];
 
  634         min_range = (gs->min + radius) * range_factor;
 
  635         max_range = (gs->max + radius) * range_factor;
 
  645         if ( (distance > max_range) && !force){
 
  649         max_volume = gs->default_volume * vol_scale;
 
  651         if ( distance <= min_range ) {
 
  655                 volume = max_volume - max_volume*(distance/max_range);
 
  658         if ( volume > 1.0
f ){
 
  663                 if ( volume < 0.3 ) {
 
  678                 if (distance <= 0.0
f) {
 
  684                 handle = 
ds_play(snd->
sid, gs->id_sig, 
ds_priority(priority), &gs->enhanced_sound_data, volume / gs->default_volume, pan, looping);
 
  686                 handle = 
ds3d_play(snd->
sid, gs->id_sig, source_pos, source_vel, min_range, max_range, looping, (max_volume*
Master_sound_volume*
aav_effect_volume), volume, &gs->enhanced_sound_data, 
ds_priority(priority));
 
  714                 Assertion( gs != NULL, 
"*gs was NULL in snd_update_3d_pos(); get a coder!\n" );
 
  716                 if ( gs->
id == -1 ) {
 
  723                 snd = &Sounds[gs->
id];
 
  729                         nprintf(( 
"Sound", 
"WARNING: Trying to set position for a non-playing sound.\n" ));
 
  733                 float min_range = (
float) (
fl2i( (gs->
min) * range_factor));
 
  734                 float max_range = (
float) (
fl2i( (gs->
max) * range_factor + 0.5f));
 
  761         vec3d   vector_to_sound;
 
  762         float           distance, max_volume;
 
  771         Assertion( gs != NULL, 
"*gs was NULL in snd_get_3d_vol_and_pan(); get a coder!\n" );
 
  773         if ( gs->
id == -1 ) {
 
  780         snd = &Sounds[gs->
id];
 
  784         float min_range = (
float) (
fl2i( (gs->
min) * range_factor));
 
  785         float max_range = (
float) (
fl2i( (gs->
max) * range_factor + 0.5f));
 
  791         if ( distance <= min_range ) {
 
  795                 *vol = max_volume - (distance - min_range) * max_volume / (max_range - min_range);
 
  839         if ( gs->
id == -1 ) {
 
  842         else if ( gs->
id_sig != Sounds[gs->
id].sig ) {
 
  849         snd = &Sounds[gs->
id];
 
  862                 if(handle != -1 && scriptingUpdateVolume) {
 
  880         if ( sig < 0 ) 
return;
 
  887         while (iter != currentlyLoopingSoundInfos.end())
 
  889                 if(iter->m_dsHandle == sig) {
 
  890                         iter = currentlyLoopingSoundInfos.erase(iter);
 
  910         currentlyLoopingSoundInfos.clear();
 
  932         if ( channel == -1 ) {
 
  933                 nprintf(( 
"Sound", 
"WARNING: Trying to set volume for a non-playing sound.\n" ));
 
  937         bool isLoopingSound = 
false;
 
  940         for (iter = currentlyLoopingSoundInfos.begin(); iter != currentlyLoopingSoundInfos.end(); ++iter) {
 
  941                 if(iter->m_dsHandle == sig) {
 
  942                         iter->m_dynamicVolume = volume;
 
  944                         isLoopingSound = 
true;
 
  950         if(!isLoopingSound) {
 
  975         if ( channel == -1 ) {
 
  976                 nprintf(( 
"Sound", 
"WARNING: Trying to set pan for a non-playing sound.\n" ));
 
 1003         if ( channel == -1 ) {
 
 1004                 nprintf(( 
"Sound", 
"WARNING: Trying to get pitch for a non-playing sound.\n" ));
 
 1026         if ( sig < 0 ) 
return;
 
 1029         if ( channel == -1 ) {
 
 1030                 nprintf(( 
"Sound", 
"WARNING: Trying to set pitch for a non-playing sound.\n" ));
 
 1058         if ( channel == -1 )
 
 1062         if ( is_playing == 
TRUE ) {
 
 1087         Assertion( !Sounds.empty(), 
"Sounds vector is empty. Why are we trying to look up an index?\n" );
 
 1089         if ( Sounds.empty() )
 
 1092         Assertion(Sounds[snd_id].duration > 0, 
"Sound duration for sound %s is bogus (%d)\n", Sounds[snd_id].
filename, Sounds[snd_id].duration);
 
 1094         if (Sounds[snd_id].duration > 0)
 
 1095                 return Sounds[snd_id].duration;
 
 1103         Assertion(snd_id >= 0 && snd_id < (
int) Sounds.size(), 
"Invalid sound id %d!", snd_id);
 
 1105         return Sounds[snd_id].filename;
 
 1122         float current_time,desired_time;
 
 1124         DWORD current_offset,desired_offset;
 
 1133         snd = &Sounds[gs->
id].info;
 
 1137         current_time = (
float)current_offset/bps;                                                                               
 
 1140         if(current_time - seconds < 0.0
f)
 
 1143         desired_time = current_time - seconds;                                                                                  
 
 1144         desired_offset = (
DWORD)(desired_time * bps);                                                           
 
 1152         float current_time,desired_time;
 
 1154         DWORD current_offset,desired_offset;
 
 1163         snd = &Sounds[gs->
id].info;
 
 1167         current_time = (
float)current_offset/bps;                                                                               
 
 1170         if(current_time + seconds > (
float)snd->
duration)
 
 1173         desired_time = current_time + seconds;                                                                                  
 
 1174         desired_offset = (
DWORD)(desired_time * bps);                                                           
 
 1190         snd = &Sounds[gs->
id].info;
 
 1194                 Assert((val >= 0.0) && (val <= 1.0));
 
 1217         for ( i = 0; i < 16; i++ ) {
 
 1234         Assert( (handle >= 0) && ((
size_t)handle < Sounds.size()) );
 
 1246         Assert( (handle >= 0) && ((
size_t)handle < Sounds.size()) );
 
 1258         Assert( (handle >= 0) && ((
size_t)handle < Sounds.size()) );
 
 1260         if (bits_per_sample)
 
 1261                 *bits_per_sample = Sounds[handle].info.bits;
 
 1264                 *frequency = Sounds[handle].info.sample_rate;
 
 1281         for (i = 0; i < Sounds.size(); i++) {
 
 1293         int channel, is_playing, time_remaining = 0;
 
 1302         if ( channel == -1 )
 
 1306         if ( !is_playing ) {
 
 1310         int current_offset, max_offset, sdx;
 
 1311         int bits_per_sample = 0, frequency = 0;
 
 1322         if ( (bits_per_sample <= 0) || (frequency <= 0) )
 
 1328         if ( bits_per_sample == 4 ) {
 
 1329                 bits_per_sample = 16;
 
 1332         Assert( bits_per_sample >= 8 );
 
 1337         if ( current_offset < max_offset ) {
 
 1338                 int bytes_remaining = max_offset - current_offset;
 
 1339                 int samples_remaining = bytes_remaining / (bits_per_sample/8);
 
 1340                 time_remaining = 
fl2i(1000.0
f * samples_remaining/frequency + 0.5
f);
 
 1344         return time_remaining;
 
 1350 static int Sound_env_id;
 
 1351 static float Sound_env_volume;
 
 1352 static float Sound_env_damping;
 
 1353 static float Sound_env_decay;
 
 1360                 Sound_env_id = se->
id;
 
 1361                 Sound_env_volume = se->
volume;
 
 1362                 Sound_env_damping = se->
damping;
 
 1363                 Sound_env_decay = se->
decay;
 
 1418         for (iter = currentlyLoopingSoundInfos.begin(); iter != currentlyLoopingSoundInfos.end(); ++iter) {
 
 1431         uint total_bytes = 0;
 
 1432         int bytes_per_measure = 0;
 
 1441         if (num_measures <= 0.0
f)
 
 1446                 nprintf((
"Sound", 
"Could not read sould file '%s' for SPM check!\n", filename));
 
 1455                 total_bytes /= si.
bits;
 
 1459         bytes_per_measure = 
fl2i(total_bytes / num_measures);
 
 1462         return (bytes_per_measure / 2);
 
 1467         Assert( type >= 0 && type < 3 );
 
 1469         if ( type >= 0 && type < 3 ) {
 
 1526         CLAMP(*volume_now, 0.0
f, 1.0
f);
 
 1541         for (
int i = 0; 
i < 3; 
i++) {
 
 1542                 aav_data[
i].
delta = 0.0f;
 
int ds_priority(int priority)
SCP_vector< sound > Sounds
void audiostream_set_volume_all(float volume, int type)
void snd_update_listener(vec3d *pos, vec3d *vel, matrix *orient)
int Cmdline_freespace_no_music
#define WAVE_FORMAT_ADPCM
char filename[MAX_FILENAME_LEN]
unsigned int ds_get_play_position(int channel_id)
LOCAL state_stack gs[GS_STACK_SIZE]
const char * audio_ext_list[]
int ds_play(int sid, int snd_id, int priority, const EnhancedSoundData *enhanced_sound_data, float volume, float pan, int looping, bool is_voice_msg)
int sound_env_set(sound_env *se)
SCP_vector< game_snd > Snds
int snd_load(game_snd *gs, int allow_hardware_load)
float m_defaultVolume
The default volume of this sound (from game_snd) 
void ds_set_pan(int channel_id, float pan)
int min
distance at which sound will stop getting louder 
void ds_set_pitch(int channel_id, int pitch)
void ds_stop_channel_all()
int ds_load_buffer(int *sid, int *final_size, void *header, sound_info *si, int flags)
Load a secondary buffer with sound data. 
int sound_env_supported()
int snd_is_playing(int sig)
int ds_eax_get_all(EAX_REVERBPROPERTIES *er, int id)
#define Assertion(expr, msg,...)                                                                        
int cf_find_file_location_ext(const char *filename, const int ext_num, const char **ext_list, int pathtype, int max_out=0, char *pack_filename=NULL, int *size=NULL, int *offset=NULL, bool localize=false)
void gr_set_color_fast(color *dst)
void adjust_volume_on_frame(float *volume_now, aav *data)
void snd_update_3d_pos(int soundnum, game_snd *gs, vec3d *new_pos, float radius, float range_factor)
#define cfopen_special(...)
char filename[MAX_FILENAME_LEN]
SCP_list< LoopingSoundInfo > currentlyLoopingSoundInfos
#define CLAMP(x, min, max)
void snd_get_format(int handle, int *bits_per_sample, int *frequency)
#define SND_PRIORITY_DOUBLE_INSTANCE
int ds3d_update_buffer(int channel_id, float min, float max, vec3d *pos, vec3d *vel)
void snd_rewind(int snd_handle, game_snd *gs, float seconds)
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
int ds_get_channel(int sig)
struct matrix::@228::@230 vec
int snd_get_pitch(int sig)
float Master_sound_volume
int ds3d_update_listener(vec3d *pos, vec3d *vel, matrix *orient)
int snd_get_data(int handle, char *data)
void snd_stop_any_sound()
int id
index into Sounds[], where sound data is stored 
int snd_play_3d(game_snd *gs, vec3d *source_pos, vec3d *listen_pos, float radius, vec3d *source_vel, int looping, float vol_scale, int priority, vec3d *sound_fvec, float range_factor, int force, bool is_ambient)
int cfwrite_string(const char *buf, CFILE *file)
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
int snd_play(game_snd *gs, float pan, float vol_scale, int priority, bool is_voice_msg)
void snd_set_pitch(int sig, int pitch)
EnhancedSoundData enhanced_sound_data
LoopingSoundInfo(int dsHandle, float defaultVolume, float dynamicVolume)
DCF(show_sounds,"Toggles display of sound debug info")
bool dc_optional_string_either(const char *str1, const char *str2)
Searches for an optional string and it's alias. 
#define MONITOR(function_name)
int snd_size(int handle, int *size)
int ds_get_size(int sid, int *size)
int ds_get_data(int sid, char *data)
int snd_get_duration(int snd_id)
#define MONITOR_INC(function_name, inc)
int ds_get_pitch(int channel_id)
#define SND_PRIORITY_MUST_PLAY
int ds_get_channel_size(int channel_id)
int snd_get_3d_vol_and_pan(game_snd *gs, vec3d *pos, float *vol, float *pan, float radius, float range_factor)
int max
distance at which sound is inaudible 
int sound_env_get(sound_env *se, int preset)
typedef void(APIENTRY *PFNGLARRAYELEMENTEXTPROC)(GLint i)
unsigned int SND_ENV_DEFAULT
int ds_get_number_channels()
const char * snd_get_filename(int snd_id)
GLuint const GLchar * name
float vm_vec_normalized_dir_quick(vec3d *dest, const vec3d *end, const vec3d *start)
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
int Cmdline_freespace_no_sound
const unsigned int SND_ENHANCED_MAX_LIMIT
int snd_time_remaining(int handle)
#define GAME_SND_USE_DS3D
float m_dynamicVolume
The dynamic volume before scripted volume adjustment is applied (is updated via snd_set_volume) ...
int snd_play_looping(game_snd *gs, float pan, int start_loop, int stop_loop, float vol_scale, int scriptingUpdateVolume)
void snd_ffwd(int snd_handle, game_snd *gs, float seconds)
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
void snd_set_volume(int sig, float volume)
float Master_event_music_volume
void snd_set_pos(int snd_handle, game_snd *gs, float val, int as_pct)
GLenum GLsizei GLenum GLenum const GLvoid * data
int ds_eax_set_all(unsigned long id, float vol, float damping, float decay)
int snd_get_index(int sig)
#define SND_PRIORITY_SINGLE_INSTANCE
int ds_parse_sound_info(char *real_filename, sound_info *s_info)
int snd_get_samples_per_measure(char *filename, float num_measures)
#define SND_PRIORITY_TRIPLE_INSTANCE
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
int ds_get_sound_id(int channel_id)
void ds_stop_channel(int channel_id)
int ds3d_play(int sid, int snd_id, vec3d *pos, vec3d *vel, float min, float max, int looping, float max_volume, float estimated_vol, const EnhancedSoundData *enhanced_sound_data, int priority, bool is_ambient)
int ds_parse_sound(CFILE *fp, ubyte **dest, uint *dest_size, WAVEFORMATEX **header, bool ogg, OggVorbis_File *ovf)
Parse a wave file. 
void dc_printf(const char *format,...)
Prints the given char string to the debug console. 
int id_sig
signature of Sounds[] element 
void snd_spew_debug_info()
void _cdecl gr_printf_no_resize(int x, int y, const char *format,...)
void ds_unload_buffer(int sid)
int cfclose(CFILE *cfile)
void snd_adjust_audio_volume(int type, float percent, int time)
void ds_set_volume(int channel_id, float vol)
Set the volume for a channel. The volume is expected to be in linear scale. 
float default_volume
range: 0.0 -> 1.0 
int ds_is_channel_playing(int channel_id)
void ds_set_position(int channel_id, unsigned int offset)
float Master_voice_volume
void snd_set_pan(int sig, float pan)
int snd_play_raw(int soundnum, float pan, float vol_scale, int priority)