X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fsound.c;h=adfb8147f8cb3f19076a8cd87e32eb9c5997d9a9;hb=a7c06161253796a30a0237a7f5a044f459c8cf35;hp=a01ce29dc1565f8b72592caa42fc009563af6d77;hpb=c71f734c9f306daaca1a262d9f07ddae5bc71073;p=rocksndiamonds.git diff --git a/src/libgame/sound.c b/src/libgame/sound.c index a01ce29d..adfb8147 100644 --- a/src/libgame/sound.c +++ b/src/libgame/sound.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "platform.h" @@ -70,13 +71,28 @@ #define SAME_SOUND_NR(x,y) ((x).nr == (y).nr) #define SAME_SOUND_DATA(x,y) ((x).data_ptr == (y).data_ptr) +#define SOUND_VOLUME_FROM_PERCENT(v,p) ((p) < 0 ? SOUND_MIN_VOLUME : \ + (p) > 100 ? (v) : \ + (p) * (v) / 100) + +#define SOUND_VOLUME_SIMPLE(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_simple) +#define SOUND_VOLUME_LOOPS(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_loops) +#define SOUND_VOLUME_MUSIC(v) SOUND_VOLUME_FROM_PERCENT(v, setup.volume_music) + +#define SETUP_SOUND_VOLUME(v,s) ((s) == SND_CTRL_PLAY_MUSIC ? \ + SOUND_VOLUME_MUSIC(v) : \ + (s) == SND_CTRL_PLAY_LOOP ? \ + SOUND_VOLUME_LOOPS(v) : \ + SOUND_VOLUME_SIMPLE(v)) + + #if defined(AUDIO_UNIX_NATIVE) struct SoundHeader_WAV { unsigned short compression_code; unsigned short num_channels; - unsigned long sample_rate; - unsigned long bytes_per_second; + unsigned int sample_rate; + unsigned int bytes_per_second; unsigned short block_align; unsigned short bits_per_sample; }; @@ -98,7 +114,7 @@ struct SampleInfo int type; int format; void *data_ptr; /* pointer to first sample (8 or 16 bit) */ - long data_len; /* number of samples, NOT number of bytes */ + int data_len; /* number of samples, NOT number of bytes */ int num_channels; /* mono: 1 channel, stereo: 2 channels */ }; typedef struct SampleInfo SoundInfo; @@ -114,13 +130,13 @@ struct SoundControl int state; - unsigned long playing_starttime; - unsigned long playing_pos; + unsigned int playing_starttime; + unsigned int playing_pos; int type; int format; void *data_ptr; /* pointer to first sample (8 or 16 bit) */ - long data_len; /* number of samples, NOT number of bytes */ + int data_len; /* number of samples, NOT number of bytes */ int num_channels; /* mono: 1 channel, stereo: 2 channels */ #if defined(TARGET_ALLEGRO) @@ -468,14 +484,14 @@ static void WriteReloadInfoToPipe(char *set_identifier, int type) SoundControl snd_ctrl; TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current : artwork.mus_current); - unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1; - unsigned long str_size2 = strlen(leveldir_current->sounds_path) + 1; - unsigned long str_size3 = strlen(leveldir_current->music_path) + 1; - unsigned long str_size4 = strlen(ti->basepath) + 1; - unsigned long str_size5 = strlen(ti->fullpath) + 1; + unsigned int str_size1 = strlen(leveldir_current->fullpath) + 1; + unsigned int str_size2 = strlen(leveldir_current->sounds_path) + 1; + unsigned int str_size3 = strlen(leveldir_current->music_path) + 1; + unsigned int str_size4 = strlen(ti->basepath) + 1; + unsigned int str_size5 = strlen(ti->fullpath) + 1; boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ? - setup.override_level_sounds : - setup.override_level_music); + gfx.override_level_sounds : + gfx.override_level_music); if (IS_CHILD_PROCESS()) return; @@ -483,7 +499,7 @@ static void WriteReloadInfoToPipe(char *set_identifier, int type) if (leveldir_current == NULL) /* should never happen */ Error(ERR_EXIT, "leveldir_current == NULL"); - memset(&snd_ctrl, 0, sizeof(SoundControl)); /* to make valgrind happy */ + clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */ snd_ctrl.active = FALSE; snd_ctrl.state = type; @@ -500,15 +516,15 @@ static void WriteReloadInfoToPipe(char *set_identifier, int type) write(audio.mixer_pipe[1], ti, sizeof(TreeInfo)) < 0 || write(audio.mixer_pipe[1], &str_size1, - sizeof(unsigned long)) < 0 || + sizeof(unsigned int)) < 0 || write(audio.mixer_pipe[1], &str_size2, - sizeof(unsigned long)) < 0 || + sizeof(unsigned int)) < 0 || write(audio.mixer_pipe[1], &str_size3, - sizeof(unsigned long)) < 0 || + sizeof(unsigned int)) < 0 || write(audio.mixer_pipe[1], &str_size4, - sizeof(unsigned long)) < 0 || + sizeof(unsigned int)) < 0 || write(audio.mixer_pipe[1], &str_size5, - sizeof(unsigned long)) < 0 || + sizeof(unsigned int)) < 0 || write(audio.mixer_pipe[1], leveldir_current->fullpath, str_size1) < 0 || write(audio.mixer_pipe[1], leveldir_current->sounds_path, @@ -531,11 +547,11 @@ static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl) TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ? &artwork.snd_current : &artwork.mus_current); TreeInfo *ti = *ti_ptr; - unsigned long str_size1, str_size2, str_size3, str_size4, str_size5; + unsigned int str_size1, str_size2, str_size3, str_size4, str_size5; static char *set_identifier = NULL; boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ? - &setup.override_level_sounds : - &setup.override_level_music); + &gfx.override_level_sounds : + &gfx.override_level_music); checked_free(set_identifier); @@ -562,15 +578,15 @@ static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl) read(audio.mixer_pipe[0], ti, sizeof(TreeInfo)) != sizeof(TreeInfo) || read(audio.mixer_pipe[0], &str_size1, - sizeof(unsigned long)) != sizeof(unsigned long) || + sizeof(unsigned int)) != sizeof(unsigned int) || read(audio.mixer_pipe[0], &str_size2, - sizeof(unsigned long)) != sizeof(unsigned long) || + sizeof(unsigned int)) != sizeof(unsigned int) || read(audio.mixer_pipe[0], &str_size3, - sizeof(unsigned long)) != sizeof(unsigned long) || + sizeof(unsigned int)) != sizeof(unsigned int) || read(audio.mixer_pipe[0], &str_size4, - sizeof(unsigned long)) != sizeof(unsigned long) || + sizeof(unsigned int)) != sizeof(unsigned int) || read(audio.mixer_pipe[0], &str_size5, - sizeof(unsigned long)) != sizeof(unsigned long)) + sizeof(unsigned int)) != sizeof(unsigned int)) Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds"); leveldir_current->fullpath = checked_calloc(str_size1); @@ -720,7 +736,7 @@ static void Mixer_PlayMusicChannel() /* Mix_VolumeMusic() must be called _after_ Mix_PlayMusic() -- this looks like a bug in the SDL_mixer library */ Mix_PlayMusic(mixer[audio.music_channel].data_ptr, -1); - Mix_VolumeMusic(SOUND_MAX_VOLUME); + Mix_VolumeMusic(mixer[audio.music_channel].volume); } #endif } @@ -874,7 +890,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) /* don't play sound more than n times simultaneously (with n == 2 for now) */ if (k >= 2) { - unsigned long playing_current = Counter(); + unsigned int playing_current = Counter(); int longest = 0, longest_nr = audio.first_sound_channel; /* look for oldest equal sound */ @@ -913,8 +929,8 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) { if (!mixer[i].active) { - Error(ERR_RETURN, "Mixer_InsertSound: Channel %d inactive", i); - Error(ERR_RETURN, "Mixer_InsertSound: This should never happen!"); + Error(ERR_INFO, "Mixer_InsertSound: Channel %d inactive", i); + Error(ERR_INFO, "Mixer_InsertSound: This should never happen!"); mixer_active_channels--; } @@ -925,7 +941,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) if (mixer_active_channels == audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1)) { - unsigned long playing_current = Counter(); + unsigned int playing_current = Counter(); int longest = 0, longest_nr = audio.first_sound_channel; #if 0 @@ -933,8 +949,8 @@ static void Mixer_InsertSound(SoundControl snd_ctrl) /* print some debugging information about audio channel usage */ for (i = audio.first_sound_channel; i < audio.num_channels; i++) { - Error(ERR_RETURN, "Mixer_InsertSound: %d [%d]: %ld (%ld)", - i, mixer[i].active, mixer[i].data_len, (long)mixer[i].data_ptr); + Error(ERR_INFO, "Mixer_InsertSound: %d [%d]: %d (%d)", + i, mixer[i].active, mixer[i].data_len, (int)mixer[i].data_ptr); } #endif #endif @@ -1120,7 +1136,7 @@ static void CopySampleToMixingBuffer(SoundControl *snd_ctrl, static void Mixer_Main_DSP() { static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE]; - static long premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE]; + static int premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE]; static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE]; boolean stereo; int fragment_size; @@ -1147,12 +1163,12 @@ static void Mixer_Main_DSP() max_sample_size = fragment_size / (num_output_channels * sample_bytes); /* first clear the last premixing buffer */ - memset(premix_last_buffer, 0, - max_sample_size * num_output_channels * sizeof(long)); + clear_mem(premix_last_buffer, + max_sample_size * num_output_channels * sizeof(int)); for (i = 0; i < audio.num_channels; i++) { - void *sample_ptr; + // void *sample_ptr; int sample_len; int sample_pos; int sample_size; @@ -1167,7 +1183,7 @@ static void Mixer_Main_DSP() } /* pointer, lenght and actual playing position of sound sample */ - sample_ptr = mixer[i].data_ptr; + // sample_ptr = mixer[i].data_ptr; sample_len = mixer[i].data_len; sample_pos = mixer[i].playing_pos; sample_size = MIN(max_sample_size, sample_len - sample_pos); @@ -1203,7 +1219,7 @@ static void Mixer_Main_DSP() if (mixer[i].volume != SOUND_MAX_VOLUME) for (j = 0; j < sample_size * num_output_channels; j++) premix_first_buffer[j] = - mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME; + mixer[i].volume * (int)premix_first_buffer[j] / SOUND_MAX_VOLUME; /* adjust left and right channel volume due to stereo sound position */ if (stereo) @@ -1265,7 +1281,8 @@ static void Mixer_Main_DSP() } /* finally play the sound fragment */ - write(audio.device_fd, playing_buffer, fragment_size); + if (write(audio.device_fd, playing_buffer, fragment_size) == -1) + Error(ERR_WARN, "write() failed; %s", strerror(errno)); if (!mixer_active_channels) CloseAudioDevice(&audio.device_fd); @@ -1302,7 +1319,7 @@ static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl) if (mixer[i].volume != SOUND_MAX_VOLUME) for (j = 0; j < sample_size; j++) premix_first_buffer[j] = - mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME; + mixer[i].volume * (int)premix_first_buffer[j] / SOUND_MAX_VOLUME; /* might be needed for u-law /dev/audio */ for (j = 0; j < sample_size; j++) @@ -1559,6 +1576,8 @@ static void *Load_WAV(char *filename) #else /* AUDIO_UNIX_NATIVE */ + clear_mem(&header, sizeof(struct SoundHeader_WAV)); /* to make gcc happy */ + if ((file = fopen(filename, MODE_READ)) == NULL) { Error(ERR_WARN, "cannot open sound file '%s'", filename); @@ -1646,8 +1665,8 @@ static void *Load_WAV(char *filename) printf("WAV file: '%s'\n", filename); printf(" Compression code: %d'\n", header.compression_code); printf(" Number of channels: %d'\n", header.num_channels); - printf(" Sample rate: %ld'\n", header.sample_rate); - printf(" Average bytes per second: %ld'\n", header.bytes_per_second); + printf(" Sample rate: %d'\n", header.sample_rate); + printf(" Average bytes per second: %d'\n", header.bytes_per_second); printf(" Block align: %d'\n", header.block_align); printf(" Significant bits per sample: %d'\n", header.bits_per_sample); #endif @@ -1754,14 +1773,108 @@ static void *Load_MOD(char *filename) static void *Load_WAV_or_MOD(char *filename) { +#if 1 + if (FileIsMusic(filename)) + return Load_MOD(filename); + else if (FileIsSound(filename)) + return Load_WAV(filename); + else + return NULL; +#else if (FileIsSound(filename)) return Load_WAV(filename); else if (FileIsMusic(filename)) return Load_MOD(filename); else return NULL; +#endif +} + +#if 1 + +void LoadCustomMusic_NoConf(void) +{ + static boolean draw_init_text = TRUE; /* only draw at startup */ + static char *last_music_directory = NULL; + char *music_directory = getCustomMusicDirectory(); + Directory *dir; + DirectoryEntry *dir_entry; + int num_music = getMusicListSize(); + + if (!audio.sound_available) + return; + + if (last_music_directory != NULL && + strEqual(last_music_directory, music_directory)) + return; /* old and new music directory are the same */ + + if (last_music_directory != NULL) + free(last_music_directory); + last_music_directory = getStringCopy(music_directory); + + FreeAllMusic_NoConf(); + + if ((dir = openDirectory(music_directory)) == NULL) + { + Error(ERR_WARN, "cannot read music directory '%s'", music_directory); + + audio.music_available = FALSE; + + return; + } + + if (draw_init_text) + DrawInitText("Loading music", 120, FC_GREEN); + + while ((dir_entry = readDirectory(dir)) != NULL) /* loop all entries */ + { + char *basename = dir_entry->basename; + char *filename = NULL; + MusicInfo *mus_info = NULL; + boolean music_already_used = FALSE; + int i; + + /* skip all music files that are configured in music config file */ + for (i = 0; i < num_music; i++) + { + struct FileInfo *music = getMusicListEntry(i); + + if (strEqual(basename, music->filename)) + { + music_already_used = TRUE; + break; + } + } + + if (music_already_used) + continue; + + if (draw_init_text) + DrawInitText(basename, 150, FC_YELLOW); + + filename = getPath2(music_directory, basename); + + if (FileIsMusic(basename)) + mus_info = Load_WAV_or_MOD(filename); + + free(filename); + + if (mus_info) + { + num_music_noconf++; + Music_NoConf = checked_realloc(Music_NoConf, + num_music_noconf * sizeof(MusicInfo *)); + Music_NoConf[num_music_noconf - 1] = mus_info; + } + } + + closeDirectory(dir); + + draw_init_text = FALSE; } +#else + void LoadCustomMusic_NoConf(void) { static boolean draw_init_text = TRUE; /* only draw at startup */ @@ -1787,7 +1900,9 @@ void LoadCustomMusic_NoConf(void) if ((dir = opendir(music_directory)) == NULL) { Error(ERR_WARN, "cannot read music directory '%s'", music_directory); + audio.music_available = FALSE; + return; } @@ -1841,6 +1956,8 @@ void LoadCustomMusic_NoConf(void) draw_init_text = FALSE; } +#endif + int getSoundListSize() { return (sound_info->num_file_list_entries + @@ -2073,21 +2190,33 @@ void PlayMusic(int nr) void PlaySound(int nr) { + if (!setup.sound_simple) + return; + PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_SOUND); } void PlaySoundStereo(int nr, int stereo_position) { + if (!setup.sound_simple) + return; + PlaySoundExt(nr, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_SOUND); } void PlaySoundLoop(int nr) { + if (!setup.sound_loops) + return; + PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_LOOP); } void PlaySoundMusic(int nr) { + if (!setup.sound_music) + return; + PlaySoundExt(nr, SOUND_MAX_VOLUME, SOUND_MIDDLE, SND_CTRL_PLAY_MUSIC); } @@ -2100,6 +2229,8 @@ void PlaySoundExt(int nr, int volume, int stereo_position, int state) audio.sound_deactivated) return; + volume = SETUP_SOUND_VOLUME(volume, state); + if (volume < SOUND_MIN_VOLUME) volume = SOUND_MIN_VOLUME; else if (volume > SOUND_MAX_VOLUME) @@ -2110,7 +2241,7 @@ void PlaySoundExt(int nr, int volume, int stereo_position, int state) else if (stereo_position > SOUND_MAX_RIGHT) stereo_position = SOUND_MAX_RIGHT; - memset(&snd_ctrl, 0, sizeof(SoundControl)); /* to make valgrind happy */ + clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */ snd_ctrl.active = TRUE; snd_ctrl.nr = nr; @@ -2171,7 +2302,7 @@ void StopSoundExt(int nr, int state) if (!audio.sound_available) return; - memset(&snd_ctrl, 0, sizeof(SoundControl)); /* to make valgrind happy */ + clear_mem(&snd_ctrl, sizeof(SoundControl)); /* to make valgrind happy */ snd_ctrl.active = FALSE; snd_ctrl.nr = nr;