X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Flibgame%2Fsound.c;h=048829f579247e404b95d3e8f9ae7c1236d7acd6;hp=cb7dc63d92f96da122b9b2f22c22725ee912b324;hb=2f1f47c267eb7b16d95eb25cfb53eb5effedea9a;hpb=e4467a70cdf808b36d10965bdf6316f0cbc35214 diff --git a/src/libgame/sound.c b/src/libgame/sound.c index cb7dc63d..048829f5 100644 --- a/src/libgame/sound.c +++ b/src/libgame/sound.c @@ -17,6 +17,21 @@ #include #include #include +#include + +#include "platform.h" + +#if defined(PLATFORM_LINUX) +#include +#include +#elif defined(PLATFORM_FREEBSD) +#include +#elif defined(PLATFORM_NETBSD) +#include +#include +#elif defined(PLATFORM_HPUX) +#include +#endif #include "system.h" #include "sound.h" @@ -24,8 +39,101 @@ #include "setup.h" -#define IS_PARENT_PROCESS(pid) ((pid) > 0) -#define IS_CHILD_PROCESS(pid) ((pid) == 0) +/* expiration time (in milliseconds) for sound loops */ +#define SOUND_LOOP_EXPIRATION_TIME 200 + +#if defined(TARGET_SDL) +/* one second fading interval == 1000 ticks (milliseconds) */ +#define SOUND_FADING_INTERVAL 1000 +#define SOUND_MAX_VOLUME SDL_MIX_MAXVOLUME +#endif + +#if defined(AUDIO_STREAMING_DSP) +#define SOUND_FADING_VOLUME_STEP (PSND_MAX_VOLUME / 40) +#define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2) +#endif + +#if !defined(PLATFORM_HPUX) +#define SND_BLOCKSIZE 4096 +#else +#define SND_BLOCKSIZE 32768 +#endif + +#define SND_TYPE_NONE 0 +#define SND_TYPE_WAV 1 + +#define MUS_TYPE_NONE 0 +#define MUS_TYPE_WAV 1 +#define MUS_TYPE_MOD 2 + +#define DEVICENAME_DSP "/dev/dsp" +#define DEVICENAME_AUDIO "/dev/audio" +#define DEVICENAME_AUDIOCTL "/dev/audioCtl" + + +#if 0 +struct SoundHeader_SUN +{ + unsigned long magic; + unsigned long hdr_size; + unsigned long data_size; + unsigned long encoding; + unsigned long sample_rate; + unsigned long channels; +}; + +struct SoundHeader_8SVX +{ + char magic_FORM[4]; + unsigned long chunk_size; + char magic_8SVX[4]; +}; +#endif + +struct AudioFormatInfo +{ + boolean stereo; /* availability of stereo sound */ + int format; /* size and endianess of sample data */ + int sample_rate; /* sample frequency */ + int fragment_size; /* audio device fragment size in bytes */ +}; + +struct SampleInfo +{ + char *source_filename; + int num_references; + + int type; + int format; + long data_len; + void *data_ptr; +}; +typedef struct SampleInfo SoundInfo; +typedef struct SampleInfo MusicInfo; + +struct SoundControl +{ + boolean active; + + int nr; + int volume; + int stereo_position; + + int state; + + unsigned long playing_starttime; + unsigned long playing_pos; + + int type; + int format; + long data_len; + void *data_ptr; + +#if defined(PLATFORM_MSDOS) + int voice; +#endif +}; +typedef struct SoundControl SoundControl; struct ListNode { @@ -483,6 +591,45 @@ void Mixer_InitChannels() mixer_active_channels = 0; } +static void Mixer_ResetChannelExpiration(int channel) +{ + mixer[channel].playing_starttime = Counter(); + +#if defined(TARGET_SDL) + if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel])) + Mix_ExpireChannel(channel, SOUND_LOOP_EXPIRATION_TIME); +#endif +} + +static boolean Mixer_ChannelExpired(int channel) +{ + if (!mixer[channel].active) + return TRUE; + + if (IS_LOOP(mixer[channel]) && !IS_MUSIC(mixer[channel]) && + DelayReached(&mixer[channel].playing_starttime, + SOUND_LOOP_EXPIRATION_TIME)) + return TRUE; + +#if defined(TARGET_SDL) + + if (!Mix_Playing(channel)) + return TRUE; + +#elif defined(TARGET_ALLEGRO) + + mixer[channel].playing_pos = voice_get_position(mixer[channel].voice); + mixer[channel].volume = voice_get_volume(mixer[channel].voice); + + /* sound sample has completed playing or was completely faded out */ + if (mixer[channel].playing_pos == -1 || mixer[channel].volume == 0) + return TRUE; + +#endif /* TARGET_ALLEGRO */ + + return FALSE; +} + static void Mixer_PlayChannel(int channel) { /* start with inactive channel in case something goes wrong */ @@ -491,9 +638,6 @@ static void Mixer_PlayChannel(int channel) if (mixer[channel].type != MUS_TYPE_WAV) return; - mixer[channel].playing_pos = 0; - mixer[channel].playing_starttime = Counter(); - #if defined(TARGET_SDL) Mix_Volume(channel, SOUND_MAX_VOLUME); Mix_PlayChannel(channel, mixer[channel].data_ptr, @@ -511,6 +655,9 @@ static void Mixer_PlayChannel(int channel) voice_start(mixer[channel].voice); #endif + Mixer_ResetChannelExpiration(channel); + + mixer[channel].playing_pos = 0; mixer[channel].active = TRUE; mixer_active_channels++; } @@ -532,12 +679,6 @@ static void Mixer_PlayMusicChannel() static void Mixer_StopChannel(int channel) { -#if 0 -#if defined(TARGET_SDL) - printf("----------> %d [%d]\n", Mix_Playing(channel), Mix_Playing(0)); -#endif -#endif - if (!mixer[channel].active) return; @@ -642,15 +783,31 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) /* check if sound is already being played (and how often) */ for (k=0, i=audio.first_sound_channel; i= 1 && IS_LOOP(snd_ctrl)) +#if 0 + printf("SOUND %d [CURRENTLY PLAYING %d TIMES]\n", snd_ctrl.nr, k); +#endif + + /* reset expiration delay for already playing loop sounds */ + if (k > 0 && IS_LOOP(snd_ctrl)) { for(i=audio.first_sound_channel; i= longest) { @@ -700,12 +853,8 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) for (i=audio.first_sound_channel; i longest) { @@ -717,7 +866,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) Mixer_StopChannel(longest_nr); } - /* add new sound to mixer */ + /* add the new sound to the mixer */ for(i=0; i