diff --git a/include/audio.h b/include/audio.h index 282b4b9..b6a7e32 100644 --- a/include/audio.h +++ b/include/audio.h @@ -19,6 +19,8 @@ #include +#define AUDIO_NO_METADATA -1 + struct archive_data; void audio_init(void); @@ -88,7 +90,7 @@ int bgm_prepare_from_file(int id, char *filename); int wav_get_group_num_from_data_num(int no); // Takes ownership of dfile. -int wav_prepare_from_archive_data(int id, struct archive_data *dfile); -int bgm_prepare_from_archive_data(int id, struct archive_data *dfile); +int wav_prepare_from_archive_data(int id, int metadata_no, struct archive_data *dfile); +int bgm_prepare_from_archive_data(int id, int metadata_no, struct archive_data *dfile); #endif /* SYSTEM4_AUDIO_H */ diff --git a/include/mixer.h b/include/mixer.h index e9149a1..7bf9a1d 100644 --- a/include/mixer.h +++ b/include/mixer.h @@ -59,8 +59,9 @@ struct channel; enum asset_type; struct channel *channel_open(enum asset_type type, int no); -// Takes ownership of dfile. -struct channel *channel_open_archive_data(struct archive_data *dfile); +// Takes ownership of dfile. Metadata is not applied if metadata_no is negative. +struct channel *channel_open_archive_data(struct archive_data *dfile, + enum asset_type type, int metadata_no); struct channel *channel_open_file(const char *path); void channel_close(struct channel *ch); int channel_play(struct channel *ch); diff --git a/src/3d/s3de.c b/src/3d/s3de.c index 18465ab..842fa2d 100644 --- a/src/3d/s3de.c +++ b/src/3d/s3de.c @@ -1464,7 +1464,7 @@ struct s3de_effect *s3de_effect_create(struct s3de *s, struct archive *aar) struct archive_data *dfile = RE_get_aar_entry(aar, s->path, basename, ".wav"); if (dfile) { int ch = wav_get_unused_channel(); - if (wav_prepare_from_archive_data(ch, dfile)) { + if (wav_prepare_from_archive_data(ch, AUDIO_NO_METADATA, dfile)) { eff->wav_channel = ch; } else { WARNING("wav_prepare_from_archive_data failed for %s\\%s.wav", s->path, basename); diff --git a/src/audio.c b/src/audio.c index 9f7dd2f..8d584d3 100644 --- a/src/audio.c +++ b/src/audio.c @@ -103,7 +103,7 @@ bool audio_play_archive_data(struct archive_data *dfile) for (int i = 0; i < NR_ANONYMOUS_CHANNELS; i++) { if (anonymous_channels[i] == -1) { int ch = wav_get_unused_channel(); - if (!wav_prepare_from_archive_data(ch, dfile)) + if (!wav_prepare_from_archive_data(ch, AUDIO_NO_METADATA, dfile)) return false; if (!wav_play(ch)) { wav_unprepare(ch); @@ -404,23 +404,29 @@ static int audio_prepare_from_file(struct id_pool *pool, int id, char *filename) int wav_prepare_from_file(int id, char *filename) { return audio_prepare_from_file(&wav, id, filename); } int bgm_prepare_from_file(int id, char *filename) { return audio_prepare_from_file(&bgm, id, filename); } -static int audio_prepare_from_archive_data(struct id_pool *pool, int id, struct archive_data *dfile) +static int audio_prepare_from_archive_data(struct id_pool *pool, int id, + enum asset_type type, int metadata_no, + struct archive_data *dfile) { if (id < 0) return 0; - struct channel *ch = channel_open_archive_data(dfile); + struct channel *ch = channel_open_archive_data(dfile, type, metadata_no); struct channel *old = id_pool_set(pool, id, ch); if (old) channel_close(old); return !!ch; } -int wav_prepare_from_archive_data(int id, struct archive_data *dfile) { - return audio_prepare_from_archive_data(&wav, id, dfile); +int wav_prepare_from_archive_data(int id, int metadata_no, struct archive_data *dfile) +{ + return audio_prepare_from_archive_data( + &wav, id, ASSET_SOUND, metadata_no, dfile); } -int bgm_prepare_from_archive_data(int id, struct archive_data *dfile) { - return audio_prepare_from_archive_data(&bgm, id, dfile); +int bgm_prepare_from_archive_data(int id, int metadata_no, struct archive_data *dfile) +{ + return audio_prepare_from_archive_data( + &bgm, id, ASSET_BGM, metadata_no, dfile); } int wav_get_group_num_from_data_num(int no) diff --git a/src/audio_mixer.c b/src/audio_mixer.c index 4d90a09..e3abbc4 100644 --- a/src/audio_mixer.c +++ b/src/audio_mixer.c @@ -505,33 +505,12 @@ struct channel *channel_open(enum asset_type type, int no) return NULL; } - struct channel *ch = channel_open_archive_data(dfile); + struct channel *ch = channel_open_archive_data(dfile, type, no); if (!ch) { WARNING("Failed to open %s %d", type == ASSET_SOUND ? "WAV" : "BGM", no); return NULL; } - if (type == ASSET_SOUND) { - struct wai *wai = wai_get(no); - ch->volume = 100; - ch->loop_start = 0; - ch->loop_end = ch->info.frames; - ch->loop_count = 1; - ch->mixer_no = wai ? wai->channel : 1; - } else { - struct bgi *bgi = bgi_get(no); - if (bgi) { - ch->volume = clamp(0, 100, bgi->volume); - ch->loop_start = clamp(0, ch->info.frames, bgi->loop_start); - ch->loop_end = clamp(0, ch->info.frames, bgi->loop_end); - ch->loop_count = max(0, bgi->loop_count); - ch->mixer_no = clamp(0, nr_mixers, bgi->channel); - } else { - ch->loop_count = 0; - } - } - ch->no = no; - return ch; } @@ -565,7 +544,8 @@ static bool init_channel(struct channel *ch) return true; } -struct channel *channel_open_archive_data(struct archive_data *dfile) +struct channel *channel_open_archive_data(struct archive_data *dfile, + enum asset_type type, int metadata_no) { struct channel *ch = xcalloc(1, sizeof(struct channel)); ch->dfile = dfile; @@ -580,6 +560,24 @@ struct channel *channel_open_archive_data(struct archive_data *dfile) free(ch); return NULL; } + if (metadata_no >= 0) { + if (type == ASSET_SOUND) { + struct wai *wai = wai_get(metadata_no); + ch->mixer_no = wai ? wai->channel : 1; + } else if (type == ASSET_BGM) { + struct bgi *bgi = bgi_get(metadata_no); + if (bgi) { + ch->volume = clamp(0, 100, bgi->volume); + ch->loop_start = clamp(0, ch->info.frames, bgi->loop_start); + ch->loop_end = clamp(0, ch->info.frames, bgi->loop_end); + ch->loop_count = max(0, bgi->loop_count); + ch->mixer_no = clamp(0, nr_mixers, bgi->channel); + } else { + ch->loop_count = 0; + } + } + ch->no = metadata_no; + } return ch; } diff --git a/src/hll/ChrLoader.c b/src/hll/ChrLoader.c index 0067477..f309d4b 100644 --- a/src/hll/ChrLoader.c +++ b/src/hll/ChrLoader.c @@ -288,7 +288,7 @@ static bool ChrLoader_LoadWavFile(int sound_channel, int id) { int blob = chr_loader_get_blob_handle(id, 4); struct archive_data *dfile = chr_loader_get_blob_as_archive_data(blob); - if (!dfile || !wav_prepare_from_archive_data(sound_channel, dfile)) { + if (!dfile || !wav_prepare_from_archive_data(sound_channel, AUDIO_NO_METADATA, dfile)) { WARNING("ChrLoader.LoadWavFile %d failed", id); return false; } diff --git a/src/hll/KiwiSoundEngine.c b/src/hll/KiwiSoundEngine.c index 0b61f8d..4c4969f 100644 --- a/src/hll/KiwiSoundEngine.c +++ b/src/hll/KiwiSoundEngine.c @@ -73,7 +73,7 @@ static int rance9_bgm_prepare(int ch, int num) struct archive_data *dfile = asset_get_by_name(ASSET_BGM, name, NULL); if (!dfile) return 0; - return bgm_prepare_from_archive_data(ch, dfile); + return bgm_prepare_from_archive_data(ch, num, dfile); } static bool rance9_wav_exists(int num) @@ -90,7 +90,7 @@ static int rance9_wav_prepare(int ch, int num) struct archive_data *dfile = asset_get_by_name(ASSET_SOUND, name, NULL); if (!dfile) return 0; - return wav_prepare_from_archive_data(ch, dfile); + return wav_prepare_from_archive_data(ch, num, dfile); } static void KiwiSoundEngine_PreLink(void); diff --git a/src/hll/vmSound.c b/src/hll/vmSound.c index ad93815..28faec1 100644 --- a/src/hll/vmSound.c +++ b/src/hll/vmSound.c @@ -39,7 +39,7 @@ static int vmSound_LoadMemory(int channel, int memory) struct archive_data *dfile = chr_loader_get_blob_as_archive_data(memory); if (!dfile) return 0; - return wav_prepare_from_archive_data(channel, dfile); + return wav_prepare_from_archive_data(channel, AUDIO_NO_METADATA, dfile); } static void vmSound_Unload(int channel, int length)