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)