mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-12 01:30:49 +01:00
cleanup: move layout helpers
This commit is contained in:
parent
e987ef2d47
commit
122de356c1
@ -233,81 +233,3 @@ void reset_layout_layered(layered_layout_data *data) {
|
||||
reset_vgmstream(data->layers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* helper for easier creation of layers */
|
||||
VGMSTREAM* allocate_layered_vgmstream(layered_layout_data* data) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
int i, channels, loop_flag, sample_rate, external_looping;
|
||||
int32_t num_samples, loop_start, loop_end;
|
||||
int delta = 1024;
|
||||
coding_t coding_type = data->layers[0]->coding_type;
|
||||
|
||||
/* get data */
|
||||
channels = data->output_channels;
|
||||
|
||||
num_samples = 0;
|
||||
loop_flag = 1;
|
||||
loop_start = data->layers[0]->loop_start_sample;
|
||||
loop_end = data->layers[0]->loop_end_sample;
|
||||
external_looping = 0;
|
||||
sample_rate = 0;
|
||||
|
||||
for (i = 0; i < data->layer_count; i++) {
|
||||
int32_t layer_samples = vgmstream_get_samples(data->layers[i]);
|
||||
int layer_loop = data->layers[i]->loop_flag;
|
||||
int32_t layer_loop_start = data->layers[i]->loop_start_sample;
|
||||
int32_t layer_loop_end = data->layers[i]->loop_end_sample;
|
||||
int layer_rate = data->layers[i]->sample_rate;
|
||||
|
||||
/* internal has own config (and maybe looping), looping now must be done on layout level
|
||||
* (instead of on each layer, that is faster) */
|
||||
if (data->layers[i]->config_enabled) {
|
||||
loop_flag = 0;
|
||||
layer_loop = 0;
|
||||
external_looping = 1;
|
||||
}
|
||||
|
||||
/* all layers should share loop pointsto consider looping enabled,
|
||||
* but allow some leeway (ex. Dragalia Lost bgm+vocals ~12 samples) */
|
||||
if (!layer_loop
|
||||
|| !(loop_start >= layer_loop_start - delta && loop_start <= layer_loop_start + delta)
|
||||
|| !(loop_end >= layer_loop_end - delta && loop_start <= layer_loop_end + delta)) {
|
||||
loop_flag = 0;
|
||||
loop_start = 0;
|
||||
loop_end = 0;
|
||||
}
|
||||
|
||||
if (num_samples < layer_samples) /* max */
|
||||
num_samples = layer_samples;
|
||||
|
||||
if (sample_rate < layer_rate)
|
||||
sample_rate = layer_rate;
|
||||
|
||||
if (coding_type == coding_SILENCE)
|
||||
coding_type = data->layers[i]->coding_type;
|
||||
}
|
||||
|
||||
data->external_looping = external_looping;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = data->layers[0]->meta_type;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = loop_end;
|
||||
vgmstream->coding_type = coding_type;
|
||||
|
||||
vgmstream->layout_type = layout_layered;
|
||||
vgmstream->layout_data = data;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
if (vgmstream) vgmstream->layout_data = NULL;
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ void free_layout_segmented(segmented_layout_data* data);
|
||||
void reset_layout_segmented(segmented_layout_data* data);
|
||||
void seek_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample);
|
||||
void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample);
|
||||
VGMSTREAM* allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment);
|
||||
|
||||
/* layered layout */
|
||||
/* for files made of "parallel" layers, one per group of channels (using a complete sub-VGMSTREAM) */
|
||||
@ -51,7 +50,6 @@ void free_layout_layered(layered_layout_data* data);
|
||||
void reset_layout_layered(layered_layout_data* data);
|
||||
void seek_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample);
|
||||
void loop_layout_layered(VGMSTREAM* vgmstream, int32_t loop_sample);
|
||||
VGMSTREAM* allocate_layered_vgmstream(layered_layout_data* data);
|
||||
|
||||
/* blocked layouts */
|
||||
void render_vgmstream_blocked(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
|
@ -289,67 +289,3 @@ void reset_layout_segmented(segmented_layout_data* data) {
|
||||
reset_vgmstream(data->segments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* helper for easier creation of segments */
|
||||
VGMSTREAM* allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
int channel_layout;
|
||||
int i, sample_rate;
|
||||
int32_t num_samples, loop_start, loop_end;
|
||||
coding_t coding_type = data->segments[0]->coding_type;
|
||||
|
||||
/* save data */
|
||||
channel_layout = data->segments[0]->channel_layout;
|
||||
num_samples = 0;
|
||||
loop_start = 0;
|
||||
loop_end = 0;
|
||||
sample_rate = 0;
|
||||
for (i = 0; i < data->segment_count; i++) {
|
||||
/* needs get_samples since element may use play settings */
|
||||
int32_t segment_samples = vgmstream_get_samples(data->segments[i]);
|
||||
int segment_rate = data->segments[i]->sample_rate;
|
||||
|
||||
if (loop_flag && i == loop_start_segment)
|
||||
loop_start = num_samples;
|
||||
|
||||
num_samples += segment_samples;
|
||||
|
||||
if (loop_flag && i == loop_end_segment)
|
||||
loop_end = num_samples;
|
||||
|
||||
/* inherit first segment's layout but only if all segments' layout match */
|
||||
if (channel_layout != 0 && channel_layout != data->segments[i]->channel_layout)
|
||||
channel_layout = 0;
|
||||
|
||||
if (sample_rate < segment_rate)
|
||||
sample_rate = segment_rate;
|
||||
|
||||
if (coding_type == coding_SILENCE)
|
||||
coding_type = data->segments[i]->coding_type;
|
||||
}
|
||||
|
||||
/* respect loop_flag even when no loop_end found as it's possible file loops are set outside */
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(data->output_channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = data->segments[0]->meta_type;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = loop_end;
|
||||
vgmstream->coding_type = coding_type;
|
||||
vgmstream->channel_layout = channel_layout;
|
||||
|
||||
vgmstream->layout_type = layout_segmented;
|
||||
vgmstream->layout_data = data;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
if (vgmstream) vgmstream->layout_data = NULL;
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util/layout_utils.h"
|
||||
#include "9tav_streamfile.h"
|
||||
|
||||
/* 9TAV - from Metal Gear Solid 2/3 HD (Vita) */
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util/layout_utils.h"
|
||||
#include "aix_streamfile.h"
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "meta.h"
|
||||
#include "../util/endianness.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util/layout_utils.h"
|
||||
#include "../util/companion_files.h"
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util/endianness.h"
|
||||
#include "../util/layout_utils.h"
|
||||
|
||||
#define EA_BLOCKID_HEADER 0x5343486C /* "SCHl" */
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "../util/endianness.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util/companion_files.h"
|
||||
#include "../util/layout_utils.h"
|
||||
|
||||
#define EA_BLOCKID_HEADER 0x5343486C /* "SCHl" */
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/layout_utils.h"
|
||||
|
||||
|
||||
/* PSF single - Pivotal games single segment (external in some PC/Xbox or inside bigfiles) [The Great Escape, Conflict series] */
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util/layout_utils.h"
|
||||
#include "sab_streamfile.h"
|
||||
|
||||
typedef struct {
|
||||
@ -234,7 +235,6 @@ static VGMSTREAM* build_layered_vgmstream(STREAMFILE* sf, sab_header* sab) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* temp_sf = NULL;
|
||||
layered_layout_data* data = NULL;
|
||||
int i;
|
||||
|
||||
if (sab->sound_count == 1 || !sab->is_stream) {
|
||||
return build_vgmstream(sf, sab);
|
||||
@ -245,7 +245,7 @@ static VGMSTREAM* build_layered_vgmstream(STREAMFILE* sf, sab_header* sab) {
|
||||
if (!data) goto fail;
|
||||
|
||||
/* de-chunk audio layers */
|
||||
for (i = 0; i < sab->sound_count; i++) {
|
||||
for (int i = 0; i < sab->sound_count; i++) {
|
||||
temp_sf = setup_sab_streamfile(sf, sab->stream_offset, sab->sound_count, i, sab->block_size);
|
||||
if (!temp_sf) goto fail;
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "../layout/layout.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/endianness.h"
|
||||
#include "../util/layout_utils.h"
|
||||
|
||||
/* also see init_vgmstream_dsp_sps_n1 and init_vgmstream_opus_sps_n1 */
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "../layout/layout.h"
|
||||
#include "../base/mixing.h"
|
||||
#include "../base/plugins.h"
|
||||
#include "../util/layout_utils.h"
|
||||
|
||||
|
||||
/*******************************************************************************/
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "../vgmstream.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../base/plugins.h"
|
||||
|
||||
|
||||
typedef VGMSTREAM* (*init_vgmstream_t)(STREAMFILE*);
|
||||
@ -147,3 +148,148 @@ bool layered_add_done(VGMSTREAM* vs) {
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* helper for easier creation of layers */
|
||||
VGMSTREAM* allocate_layered_vgmstream(layered_layout_data* data) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
int i, channels, loop_flag, sample_rate, external_looping;
|
||||
int32_t num_samples, loop_start, loop_end;
|
||||
int delta = 1024;
|
||||
coding_t coding_type = data->layers[0]->coding_type;
|
||||
|
||||
/* get data */
|
||||
channels = data->output_channels;
|
||||
|
||||
num_samples = 0;
|
||||
loop_flag = 1;
|
||||
loop_start = data->layers[0]->loop_start_sample;
|
||||
loop_end = data->layers[0]->loop_end_sample;
|
||||
external_looping = 0;
|
||||
sample_rate = 0;
|
||||
|
||||
for (i = 0; i < data->layer_count; i++) {
|
||||
int32_t layer_samples = vgmstream_get_samples(data->layers[i]);
|
||||
int layer_loop = data->layers[i]->loop_flag;
|
||||
int32_t layer_loop_start = data->layers[i]->loop_start_sample;
|
||||
int32_t layer_loop_end = data->layers[i]->loop_end_sample;
|
||||
int layer_rate = data->layers[i]->sample_rate;
|
||||
|
||||
/* internal has own config (and maybe looping), looping now must be done on layout level
|
||||
* (instead of on each layer, that is faster) */
|
||||
if (data->layers[i]->config_enabled) {
|
||||
loop_flag = 0;
|
||||
layer_loop = 0;
|
||||
external_looping = 1;
|
||||
}
|
||||
|
||||
/* all layers should share loop pointsto consider looping enabled,
|
||||
* but allow some leeway (ex. Dragalia Lost bgm+vocals ~12 samples) */
|
||||
if (!layer_loop
|
||||
|| !(loop_start >= layer_loop_start - delta && loop_start <= layer_loop_start + delta)
|
||||
|| !(loop_end >= layer_loop_end - delta && loop_start <= layer_loop_end + delta)) {
|
||||
loop_flag = 0;
|
||||
loop_start = 0;
|
||||
loop_end = 0;
|
||||
}
|
||||
|
||||
if (num_samples < layer_samples) /* max */
|
||||
num_samples = layer_samples;
|
||||
|
||||
if (sample_rate < layer_rate)
|
||||
sample_rate = layer_rate;
|
||||
|
||||
if (coding_type == coding_SILENCE)
|
||||
coding_type = data->layers[i]->coding_type;
|
||||
}
|
||||
|
||||
data->external_looping = external_looping;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = data->layers[0]->meta_type;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = loop_end;
|
||||
vgmstream->coding_type = coding_type;
|
||||
|
||||
vgmstream->layout_type = layout_layered;
|
||||
vgmstream->layout_data = data;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
if (vgmstream) vgmstream->layout_data = NULL;
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* helper for easier creation of segments */
|
||||
VGMSTREAM* allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
int channel_layout;
|
||||
int i, sample_rate;
|
||||
int32_t num_samples, loop_start, loop_end;
|
||||
coding_t coding_type = data->segments[0]->coding_type;
|
||||
|
||||
/* save data */
|
||||
channel_layout = data->segments[0]->channel_layout;
|
||||
num_samples = 0;
|
||||
loop_start = 0;
|
||||
loop_end = 0;
|
||||
sample_rate = 0;
|
||||
for (i = 0; i < data->segment_count; i++) {
|
||||
/* needs get_samples since element may use play settings */
|
||||
int32_t segment_samples = vgmstream_get_samples(data->segments[i]);
|
||||
int segment_rate = data->segments[i]->sample_rate;
|
||||
|
||||
if (loop_flag && i == loop_start_segment)
|
||||
loop_start = num_samples;
|
||||
|
||||
num_samples += segment_samples;
|
||||
|
||||
if (loop_flag && i == loop_end_segment)
|
||||
loop_end = num_samples;
|
||||
|
||||
/* inherit first segment's layout but only if all segments' layout match */
|
||||
if (channel_layout != 0 && channel_layout != data->segments[i]->channel_layout)
|
||||
channel_layout = 0;
|
||||
|
||||
if (sample_rate < segment_rate)
|
||||
sample_rate = segment_rate;
|
||||
|
||||
if (coding_type == coding_SILENCE)
|
||||
coding_type = data->segments[i]->coding_type;
|
||||
}
|
||||
|
||||
/* respect loop_flag even when no loop_end found as it's possible file loops are set outside */
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(data->output_channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = data->segments[0]->meta_type;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = loop_end;
|
||||
vgmstream->coding_type = coding_type;
|
||||
vgmstream->channel_layout = channel_layout;
|
||||
|
||||
vgmstream->layout_type = layout_segmented;
|
||||
vgmstream->layout_data = data;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
if (vgmstream) vgmstream->layout_data = NULL;
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _LAYOUTS_UTIL_H
|
||||
|
||||
#include "../vgmstream.h"
|
||||
#include "../layout/layout.h"
|
||||
|
||||
typedef VGMSTREAM* (*init_vgmstream_t)(STREAMFILE*);
|
||||
|
||||
@ -18,4 +19,7 @@ bool layered_add_codec(VGMSTREAM* vs, int layers, int layer_channels);
|
||||
|
||||
/* call when done adding layers */
|
||||
bool layered_add_done(VGMSTREAM* vs);
|
||||
|
||||
VGMSTREAM* allocate_layered_vgmstream(layered_layout_data* data);
|
||||
VGMSTREAM* allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user