mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-31 04:13:47 +01:00
Preserve channel layout when downmixing some cases
This commit is contained in:
parent
1c666f27d5
commit
80d8ce2414
@ -7,6 +7,7 @@ typedef VGMSTREAM* (*init_vgmstream_t)(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_silence(int channels, int sample_rate, int32_t num_samples);
|
||||
VGMSTREAM* init_vgmstream_silence_container(int total_subsongs);
|
||||
VGMSTREAM* init_vgmstream_silence_base(VGMSTREAM* vgmstream);
|
||||
|
||||
|
||||
VGMSTREAM* init_vgmstream_adx(STREAMFILE* sf);
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "meta.h"
|
||||
|
||||
/* silent stream - mainly for engines that need them or dummy subsongs */
|
||||
VGMSTREAM* init_vgmstream_silence(int channels, int sample_rate, int32_t num_samples) {
|
||||
static VGMSTREAM* init_vgmstream_silence_internal(int channels, int sample_rate, int32_t num_samples, uint32_t channel_layout) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
|
||||
if (channels <= 0)
|
||||
@ -18,6 +18,7 @@ VGMSTREAM* init_vgmstream_silence(int channels, int sample_rate, int32_t num_sam
|
||||
vgmstream->meta_type = meta_SILENCE;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->channel_layout = channel_layout;
|
||||
|
||||
vgmstream->coding_type = coding_SILENCE;
|
||||
vgmstream->layout_type = layout_none;
|
||||
@ -28,11 +29,15 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VGMSTREAM* init_vgmstream_silence(int channels, int sample_rate, int32_t num_samples) {
|
||||
return init_vgmstream_silence_internal(channels, sample_rate, num_samples, 0);
|
||||
}
|
||||
|
||||
/* silent stream - for containers that have dummy streams but it's a hassle to detect/filter out */
|
||||
VGMSTREAM* init_vgmstream_silence_container(int total_subsongs) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
|
||||
vgmstream = init_vgmstream_silence(0, 0, 0);
|
||||
vgmstream = init_vgmstream_silence_internal(0, 0, 0, 0);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
@ -43,3 +48,14 @@ fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VGMSTREAM* init_vgmstream_silence_base(VGMSTREAM* v) {
|
||||
if (!v)
|
||||
return init_vgmstream_silence_internal(0, 0, 0, 0);
|
||||
|
||||
return init_vgmstream_silence_internal(
|
||||
v->channels,
|
||||
v->sample_rate,
|
||||
0, //v->num_samples ?
|
||||
v->channel_layout);
|
||||
}
|
@ -218,15 +218,12 @@ static void clean_txtp(txtp_header* txtp, int fail) {
|
||||
|
||||
static int parse_silents(txtp_header* txtp) {
|
||||
int i;
|
||||
int channels = 0;
|
||||
int sample_rate = 0;
|
||||
int32_t num_samples = 0;
|
||||
VGMSTREAM* v_base = NULL;
|
||||
|
||||
/* silents use same channels as close files */
|
||||
for (i = 0; i < txtp->vgmstream_count; i++) {
|
||||
if (!txtp->entry[i].silent) {
|
||||
channels = txtp->vgmstream[i]->channels;
|
||||
sample_rate = txtp->vgmstream[i]->sample_rate;
|
||||
v_base = txtp->vgmstream[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -236,7 +233,7 @@ static int parse_silents(txtp_header* txtp) {
|
||||
if (!txtp->entry[i].silent)
|
||||
continue;
|
||||
|
||||
txtp->vgmstream[i] = init_vgmstream_silence(channels, sample_rate, num_samples);
|
||||
txtp->vgmstream[i] = init_vgmstream_silence_base(v_base);
|
||||
if (!txtp->vgmstream[i]) goto fail;
|
||||
|
||||
apply_settings(txtp->vgmstream[i], &txtp->entry[i]);
|
||||
|
58
src/mixing.c
58
src/mixing.c
@ -1283,7 +1283,57 @@ void mixing_macro_downmix(VGMSTREAM* vgmstream, int max /*, mapping_t output_map
|
||||
|
||||
/* ******************************************************************* */
|
||||
|
||||
void mixing_setup(VGMSTREAM * vgmstream, int32_t max_sample_count) {
|
||||
static int fix_layered_channel_layout(VGMSTREAM* vgmstream) {
|
||||
int i;
|
||||
mixing_data* data = vgmstream->mixing_data;
|
||||
layered_layout_data* layout_data;
|
||||
uint32_t prev_cl;
|
||||
|
||||
if (vgmstream->channel_layout || vgmstream->layout_type != layout_layered)
|
||||
return 0;
|
||||
|
||||
layout_data = vgmstream->layout_data;
|
||||
|
||||
/* mainly layer-v (in cases of layers-within-layers should cascade) */
|
||||
if (data->output_channels != layout_data->layers[0]->channels)
|
||||
return 0;
|
||||
|
||||
/* check all layers share layout (implicitly works as a channel check, if not 0) */
|
||||
prev_cl = layout_data->layers[0]->channel_layout;
|
||||
if (prev_cl == 0)
|
||||
return 0;
|
||||
|
||||
for (i = 1; i < layout_data->layer_count; i++) {
|
||||
uint32_t layer_cl = layout_data->layers[i]->channel_layout;
|
||||
if (prev_cl != layer_cl)
|
||||
return 0;
|
||||
|
||||
prev_cl = layer_cl;
|
||||
}
|
||||
|
||||
vgmstream->channel_layout = prev_cl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* channel layout + down/upmixing = ?, salvage what we can */
|
||||
static void fix_channel_layout(VGMSTREAM* vgmstream) {
|
||||
mixing_data* data = vgmstream->mixing_data;
|
||||
|
||||
if (fix_layered_channel_layout(vgmstream))
|
||||
goto done;
|
||||
|
||||
/* segments should share channel layout automatically */
|
||||
|
||||
/* a bit wonky but eh... */
|
||||
if (vgmstream->channel_layout && vgmstream->channels != data->output_channels) {
|
||||
vgmstream->channel_layout = 0;
|
||||
}
|
||||
|
||||
done:
|
||||
((VGMSTREAM*)vgmstream->start_vgmstream)->channel_layout = vgmstream->channel_layout;
|
||||
}
|
||||
|
||||
void mixing_setup(VGMSTREAM* vgmstream, int32_t max_sample_count) {
|
||||
mixing_data *data = vgmstream->mixing_data;
|
||||
float *mixbuf_re = NULL;
|
||||
|
||||
@ -1300,11 +1350,7 @@ void mixing_setup(VGMSTREAM * vgmstream, int32_t max_sample_count) {
|
||||
data->mixbuf = mixbuf_re;
|
||||
data->mixing_on = 1;
|
||||
|
||||
/* a bit wonky but eh... */
|
||||
if (vgmstream->channel_layout && vgmstream->channels != data->output_channels) {
|
||||
vgmstream->channel_layout = 0;
|
||||
((VGMSTREAM*)vgmstream->start_vgmstream)->channel_layout = 0;
|
||||
}
|
||||
fix_channel_layout(vgmstream);
|
||||
|
||||
/* since data exists on its own memory and pointer is already set
|
||||
* there is no need to propagate to start_vgmstream */
|
||||
|
Loading…
x
Reference in New Issue
Block a user