VGMStream: Updated libvgmstream code base
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
Updated VGMStream to r2023-27-g7b0c835c Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
6e28ac6825
commit
d74af63da0
9 changed files with 102 additions and 105 deletions
|
@ -106,4 +106,5 @@ void vgmstream_apply_config(VGMSTREAM* vgmstream, vgmstream_cfg_t* vcfg) {
|
||||||
|
|
||||||
vgmstream->config_enabled = def->config_set;
|
vgmstream->config_enabled = def->config_set;
|
||||||
setup_vgmstream_play_state(vgmstream);
|
setup_vgmstream_play_state(vgmstream);
|
||||||
|
setup_vgmstream(vgmstream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,10 +166,6 @@ static void setup_state_processing(VGMSTREAM* vgmstream) {
|
||||||
ps->fade_start = ps->pad_begin_duration + ps->body_duration;
|
ps->fade_start = ps->pad_begin_duration + ps->body_duration;
|
||||||
//ps->pad_end_left = ps->pad_end_duration;
|
//ps->pad_end_left = ps->pad_end_duration;
|
||||||
ps->pad_end_start = ps->fade_start + ps->fade_duration;
|
ps->pad_end_start = ps->fade_start + ps->fade_duration;
|
||||||
|
|
||||||
/* other info (updated once mixing is enabled) */
|
|
||||||
ps->input_channels = vgmstream->channels;
|
|
||||||
ps->output_channels = vgmstream->channels;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apply play config to internal state */
|
/* apply play config to internal state */
|
||||||
|
@ -179,7 +175,4 @@ void setup_vgmstream_play_state(VGMSTREAM* vgmstream) {
|
||||||
|
|
||||||
setup_state_modifiers(vgmstream);
|
setup_state_modifiers(vgmstream);
|
||||||
setup_state_processing(vgmstream);
|
setup_state_processing(vgmstream);
|
||||||
|
|
||||||
/* save new config for resets */
|
|
||||||
setup_vgmstream(vgmstream);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,8 +159,6 @@ void vgmstream_mixing_enable(VGMSTREAM* vgmstream, int32_t max_sample_count, int
|
||||||
mixing_setup(vgmstream, max_sample_count);
|
mixing_setup(vgmstream, max_sample_count);
|
||||||
mixing_info(vgmstream, input_channels, output_channels);
|
mixing_info(vgmstream, input_channels, output_channels);
|
||||||
|
|
||||||
/* update internals */
|
|
||||||
mixing_info(vgmstream, &vgmstream->pstate.input_channels, &vgmstream->pstate.output_channels);
|
|
||||||
setup_vgmstream(vgmstream);
|
setup_vgmstream(vgmstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1552,6 +1552,9 @@ static const hcakey_info hcakey_list[] = {
|
||||||
// Suikoden I & II HD Remaster (PC)
|
// Suikoden I & II HD Remaster (PC)
|
||||||
{14510296783270449627u}, // C95EEE0BA85411DB
|
{14510296783270449627u}, // C95EEE0BA85411DB
|
||||||
|
|
||||||
|
// CHUNITHM Chinese Version (AC)
|
||||||
|
{30194896045700459}, // 006B461914D5756B
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,8 +30,10 @@ VGMSTREAM* init_vgmstream_nub(STREAMFILE* sf) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* .nub: standard
|
/* .nub: standard
|
||||||
* .nub2: rare [iDOLM@STER: Gravure For You (PS3), Noby Noby Boy (iOS)] */
|
* .nub2: rare [iDOLM@STER: Gravure For You (PS3), Noby Noby Boy (iOS)]
|
||||||
if (!check_extensions(sf, "nub,nub2"))
|
* .nps: Ace Combat Joint Assault (PSP) BGM only
|
||||||
|
*/
|
||||||
|
if (!check_extensions(sf, "nub,nub2,nps"))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* sometimes LE [Soul Calibur: Broken Destiny (PSP), Tales of Vesperia (PS4) */
|
/* sometimes LE [Soul Calibur: Broken Destiny (PSP), Tales of Vesperia (PS4) */
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "../coding/coding.h"
|
#include "../coding/coding.h"
|
||||||
#include "../util/chunks.h"
|
#include "../util/chunks.h"
|
||||||
|
|
||||||
|
static uint32_t get_name_offset(STREAMFILE* sf_sxd1, uint32_t first_offset, int target_subsong);
|
||||||
|
|
||||||
/* SXDF/SXDS - Sony/SCE's SNDX lib format (cousin of SGXD) [Gravity Rush, Freedom Wars, Soul Sacrifice PSV] */
|
/* SXDF/SXDS - Sony/SCE's SNDX lib format (cousin of SGXD) [Gravity Rush, Freedom Wars, Soul Sacrifice PSV] */
|
||||||
VGMSTREAM* init_vgmstream_sndx(STREAMFILE* sf) {
|
VGMSTREAM* init_vgmstream_sndx(STREAMFILE* sf) {
|
||||||
|
@ -147,19 +148,7 @@ VGMSTREAM* init_vgmstream_sndx(STREAMFILE* sf) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get stream name (NAME is tied to REQD/cues, and SFX cues repeat WAVEs, but should work ok for streams) */
|
name_offset = get_name_offset(sf_sxd1, first_offset, target_subsong);
|
||||||
if (is_dual && find_chunk_le(sf_sxd1, get_id32be("NAME"),first_offset,0, &chunk_offset,NULL)) {
|
|
||||||
/* table: relative offset (32b) + hash? (32b) + cue index (32b) */
|
|
||||||
int i;
|
|
||||||
int num_entries = read_s16le(chunk_offset + 0x04, sf_sxd1); /* can be bigger than streams */
|
|
||||||
for (i = 0; i < num_entries; i++) {
|
|
||||||
uint32_t index = read_u32le(chunk_offset + 0x08 + 0x08 + i * 0x0c,sf_sxd1);
|
|
||||||
if (index+1 == target_subsong) {
|
|
||||||
name_offset = chunk_offset + 0x08 + 0x00 + i*0x0c + read_u32le(chunk_offset + 0x08 + 0x00 + i * 0x0c, sf_sxd1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_external && !is_dual) {
|
if (is_external && !is_dual) {
|
||||||
VGM_LOG("SXD: found single sxd with external data\n");
|
VGM_LOG("SXD: found single sxd with external data\n");
|
||||||
|
@ -228,14 +217,6 @@ VGMSTREAM* init_vgmstream_sndx(STREAMFILE* sf) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .sxd have names but they are a bit complex:
|
|
||||||
* - WAVE chunk has N subsongs
|
|
||||||
* - NAME chunk may define M names but usually doesn't match with subsongs (may be less or more)
|
|
||||||
* - LVRN may define some state and LVAR its possible values (battle_state=bgm_battle_start/win/intro)
|
|
||||||
* - TRNS also has names based on possible transition
|
|
||||||
* - final WAVE seem to depend on NAME (event?) + state=value, similar to Wwise
|
|
||||||
* - presumably TONE/REQD/SEQD chunks have WAVE<>event matching info since they seem to always appear
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
if (!vgmstream_open_stream(vgmstream, sf_data, start_offset))
|
if (!vgmstream_open_stream(vgmstream, sf_data, start_offset))
|
||||||
|
@ -251,3 +232,32 @@ fail:
|
||||||
close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* .sxd have names but they are a bit complex:
|
||||||
|
* - WAVE chunk has N subsongs
|
||||||
|
* - NAME chunk may define M names but may not match with subsongs (less or more, ex. randoms)
|
||||||
|
* - LVRN may define some state and LVAR its possible values (battle_state=bgm_battle_start/win/intro)
|
||||||
|
* - TRNS also has names based on possible transition
|
||||||
|
* - final WAVE seem to depend on NAME (event?) + state=value, similar to Wwise
|
||||||
|
* - presumably TONE/REQD/SEQD chunks have WAVE<>event matching info since they seem to always appear
|
||||||
|
* For now do simple matching.
|
||||||
|
*/
|
||||||
|
static uint32_t get_name_offset(STREAMFILE* sf_sxd1, uint32_t first_offset, int target_subsong) {
|
||||||
|
off_t chunk_offset = 0;
|
||||||
|
|
||||||
|
if (!find_chunk_le(sf_sxd1, get_id32be("NAME"),first_offset,0, &chunk_offset,NULL))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// table: relative offset (32b) + hash? (32b) + cue index (32b)
|
||||||
|
int num_entries = read_s16le(chunk_offset + 0x04, sf_sxd1);
|
||||||
|
|
||||||
|
// TODO: index N to subsong N works ok for streams but not always for SFX
|
||||||
|
for (int i = 0; i < num_entries; i++) {
|
||||||
|
uint32_t index = read_u32le(chunk_offset + 0x08 + 0x08 + i * 0x0c,sf_sxd1);
|
||||||
|
if (index+1 != target_subsong)
|
||||||
|
continue;
|
||||||
|
return chunk_offset + 0x08 + 0x00 + i*0x0c + read_u32le(chunk_offset + 0x08 + 0x00 + i * 0x0c, sf_sxd1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -102,8 +102,7 @@ static void apply_settings(VGMSTREAM* vgmstream, txtp_entry_t* current) {
|
||||||
|
|
||||||
/* add macro to mixing list */
|
/* add macro to mixing list */
|
||||||
if (current->channel_mask) {
|
if (current->channel_mask) {
|
||||||
int ch;
|
for (int ch = 0; ch < vgmstream->channels; ch++) {
|
||||||
for (ch = 0; ch < vgmstream->channels; ch++) {
|
|
||||||
if (!((current->channel_mask >> ch) & 1)) {
|
if (!((current->channel_mask >> ch) & 1)) {
|
||||||
txtp_mix_data_t mix = {0};
|
txtp_mix_data_t mix = {0};
|
||||||
mix.ch_dst = ch + 1;
|
mix.ch_dst = ch + 1;
|
||||||
|
@ -113,72 +112,70 @@ static void apply_settings(VGMSTREAM* vgmstream, txtp_entry_t* current) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy mixing list (should be done last as some mixes depend on config) */
|
/* apply play config (after sample rate/etc mods) */
|
||||||
if (current->mixing_count > 0) {
|
txtp_copy_config(&vgmstream->config, ¤t->config);
|
||||||
int m, position_samples;
|
setup_vgmstream_play_state(vgmstream);
|
||||||
|
// config is enabled in layouts or externally (for compatibility, since we don't know yet if this
|
||||||
|
// VGMSTREAM will part of a layout, or is enabled externally to not mess up plugins's calcs)
|
||||||
|
|
||||||
for (m = 0; m < current->mixing_count; m++) {
|
/* apply mixing (last as some mixes depend on config like loops/etc, shouldn't matter much) */
|
||||||
txtp_mix_data_t *mix = ¤t->mixing[m];
|
for (int m = 0; m < current->mixing_count; m++) {
|
||||||
|
txtp_mix_data_t* mix = ¤t->mixing[m];
|
||||||
|
|
||||||
switch(mix->command) {
|
switch(mix->command) {
|
||||||
/* base mixes */
|
// base mixes
|
||||||
case MIX_SWAP: mixing_push_swap(vgmstream, mix->ch_dst, mix->ch_src); break;
|
case MIX_SWAP: mixing_push_swap(vgmstream, mix->ch_dst, mix->ch_src); break;
|
||||||
case MIX_ADD: mixing_push_add(vgmstream, mix->ch_dst, mix->ch_src, 1.0); break;
|
case MIX_ADD: mixing_push_add(vgmstream, mix->ch_dst, mix->ch_src, 1.0); break;
|
||||||
case MIX_ADD_VOLUME: mixing_push_add(vgmstream, mix->ch_dst, mix->ch_src, mix->vol); break;
|
case MIX_ADD_VOLUME: mixing_push_add(vgmstream, mix->ch_dst, mix->ch_src, mix->vol); break;
|
||||||
case MIX_VOLUME: mixing_push_volume(vgmstream, mix->ch_dst, mix->vol); break;
|
case MIX_VOLUME: mixing_push_volume(vgmstream, mix->ch_dst, mix->vol); break;
|
||||||
case MIX_LIMIT: mixing_push_limit(vgmstream, mix->ch_dst, mix->vol); break;
|
case MIX_LIMIT: mixing_push_limit(vgmstream, mix->ch_dst, mix->vol); break;
|
||||||
case MIX_UPMIX: mixing_push_upmix(vgmstream, mix->ch_dst); break;
|
case MIX_UPMIX: mixing_push_upmix(vgmstream, mix->ch_dst); break;
|
||||||
case MIX_DOWNMIX: mixing_push_downmix(vgmstream, mix->ch_dst); break;
|
case MIX_DOWNMIX: mixing_push_downmix(vgmstream, mix->ch_dst); break;
|
||||||
case MIX_KILLMIX: mixing_push_killmix(vgmstream, mix->ch_dst); break;
|
case MIX_KILLMIX: mixing_push_killmix(vgmstream, mix->ch_dst); break;
|
||||||
case MIX_FADE:
|
case MIX_FADE:
|
||||||
/* Convert from time to samples now that sample rate is final.
|
// Convert from time to samples now that sample rate is final.
|
||||||
* Samples and time values may be mixed though, so it's done for every
|
// Samples and time values may be mixed though, so it's done for every
|
||||||
* value (if one is 0 the other will be too, though) */
|
// value (if one is 0 the other will be too, though)
|
||||||
if (mix->time_pre > 0.0) mix->sample_pre = mix->time_pre * vgmstream->sample_rate;
|
if (mix->time_pre > 0.0) mix->sample_pre = mix->time_pre * vgmstream->sample_rate;
|
||||||
if (mix->time_start > 0.0) mix->sample_start = mix->time_start * vgmstream->sample_rate;
|
if (mix->time_start > 0.0) mix->sample_start = mix->time_start * vgmstream->sample_rate;
|
||||||
if (mix->time_end > 0.0) mix->sample_end = mix->time_end * vgmstream->sample_rate;
|
if (mix->time_end > 0.0) mix->sample_end = mix->time_end * vgmstream->sample_rate;
|
||||||
if (mix->time_post > 0.0) mix->sample_post = mix->time_post * vgmstream->sample_rate;
|
if (mix->time_post > 0.0) mix->sample_post = mix->time_post * vgmstream->sample_rate;
|
||||||
/* convert special meaning too */
|
// convert special meaning too
|
||||||
if (mix->time_pre < 0.0) mix->sample_pre = -1;
|
if (mix->time_pre < 0.0) mix->sample_pre = -1;
|
||||||
if (mix->time_post < 0.0) mix->sample_post = -1;
|
if (mix->time_post < 0.0) mix->sample_post = -1;
|
||||||
|
|
||||||
if (mix->position_type == TXTP_POSITION_LOOPS && vgmstream->loop_flag) {
|
if (mix->position_type == TXTP_POSITION_LOOPS && vgmstream->loop_flag) {
|
||||||
int loop_pre = vgmstream->loop_start_sample;
|
int loop_pre = vgmstream->loop_start_sample;
|
||||||
int loop_samples = (vgmstream->loop_end_sample - vgmstream->loop_start_sample);
|
int loop_samples = (vgmstream->loop_end_sample - vgmstream->loop_start_sample);
|
||||||
|
|
||||||
position_samples = loop_pre + loop_samples * mix->position;
|
int position_samples = loop_pre + loop_samples * mix->position;
|
||||||
|
|
||||||
if (mix->sample_pre >= 0) mix->sample_pre += position_samples;
|
if (mix->sample_pre >= 0) mix->sample_pre += position_samples;
|
||||||
mix->sample_start += position_samples;
|
mix->sample_start += position_samples;
|
||||||
mix->sample_end += position_samples;
|
mix->sample_end += position_samples;
|
||||||
if (mix->sample_post >= 0) mix->sample_post += position_samples;
|
if (mix->sample_post >= 0) mix->sample_post += position_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mixing_push_fade(vgmstream,
|
||||||
|
mix->ch_dst, mix->vol_start, mix->vol_end, mix->shape,
|
||||||
|
mix->sample_pre, mix->sample_start, mix->sample_end, mix->sample_post);
|
||||||
|
break;
|
||||||
|
|
||||||
mixing_push_fade(vgmstream, mix->ch_dst, mix->vol_start, mix->vol_end, mix->shape,
|
// macro mixes
|
||||||
mix->sample_pre, mix->sample_start, mix->sample_end, mix->sample_post);
|
case MACRO_VOLUME: mixing_macro_volume(vgmstream, mix->vol, mix->mask); break;
|
||||||
break;
|
case MACRO_TRACK: mixing_macro_track(vgmstream, mix->mask); break;
|
||||||
|
case MACRO_LAYER: mixing_macro_layer(vgmstream, mix->max, mix->mask, mix->mode); break;
|
||||||
|
case MACRO_CROSSTRACK: mixing_macro_crosstrack(vgmstream, mix->max); break;
|
||||||
|
case MACRO_CROSSLAYER: mixing_macro_crosslayer(vgmstream, mix->max, mix->mode); break;
|
||||||
|
case MACRO_DOWNMIX: mixing_macro_downmix(vgmstream, mix->max); break;
|
||||||
|
|
||||||
/* macro mixes */
|
default:
|
||||||
case MACRO_VOLUME: mixing_macro_volume(vgmstream, mix->vol, mix->mask); break;
|
break;
|
||||||
case MACRO_TRACK: mixing_macro_track(vgmstream, mix->mask); break;
|
|
||||||
case MACRO_LAYER: mixing_macro_layer(vgmstream, mix->max, mix->mask, mix->mode); break;
|
|
||||||
case MACRO_CROSSTRACK: mixing_macro_crosstrack(vgmstream, mix->max); break;
|
|
||||||
case MACRO_CROSSLAYER: mixing_macro_crosslayer(vgmstream, mix->max, mix->mode); break;
|
|
||||||
case MACRO_DOWNMIX: mixing_macro_downmix(vgmstream, mix->max); break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* save final config */
|
||||||
/* default play config (last after sample rate mods/mixing/etc) */
|
setup_vgmstream(vgmstream);
|
||||||
txtp_copy_config(&vgmstream->config, ¤t->config);
|
|
||||||
setup_vgmstream_play_state(vgmstream);
|
|
||||||
/* config is enabled in layouts or externally (for compatibility, since we don't know yet if this
|
|
||||||
* VGMSTREAM will part of a layout, or is enabled externally to not mess up plugins's calcs) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -711,14 +711,14 @@ static int parse_xsb_cues(xsb_header *xsb, STREAMFILE *sf) {
|
||||||
* - https://github.com/MonoGame/MonoGame/blob/master/MonoGame.Framework/Audio/Xact/
|
* - https://github.com/MonoGame/MonoGame/blob/master/MonoGame.Framework/Audio/Xact/
|
||||||
* - https://github.com/espes/MacTerrariaWrapper/tree/master/xactxtract
|
* - https://github.com/espes/MacTerrariaWrapper/tree/master/xactxtract
|
||||||
*/
|
*/
|
||||||
static int parse_xsb(xsb_header *xsb, STREAMFILE *sf, char *xwb_wavebank_name) {
|
static bool parse_xsb(xsb_header *xsb, STREAMFILE *sf, char *xwb_wavebank_name) {
|
||||||
|
|
||||||
/* check header */
|
/* check header */
|
||||||
if ((read_u32be(0x00,sf) != 0x5344424B) && /* "SDBK" (LE) */
|
if (!is_id32be(0x00,sf, "SDBK") && // LE
|
||||||
(read_u32be(0x00,sf) != 0x4B424453)) /* "KBDS" (BE) */
|
!is_id32be(0x00,sf, "KBDS")) // BE
|
||||||
goto fail;
|
return false;
|
||||||
|
|
||||||
xsb->big_endian = (read_u32be(0x00,sf) == 0x4B424453); /* "KBDS" */
|
xsb->big_endian = (is_id32be(0x00,sf, "KBDS"));
|
||||||
read_s32_t read_s32 = xsb->big_endian ? read_s32be : read_s32le;
|
read_s32_t read_s32 = xsb->big_endian ? read_s32be : read_s32le;
|
||||||
read_s16_t read_s16 = xsb->big_endian ? read_s16be : read_s16le;
|
read_s16_t read_s16 = xsb->big_endian ? read_s16be : read_s16le;
|
||||||
|
|
||||||
|
@ -843,20 +843,18 @@ static int parse_xsb(xsb_header *xsb, STREAMFILE *sf, char *xwb_wavebank_name) {
|
||||||
|
|
||||||
if (xsb->version > XSB_XACT1_2_MAX && xsb->cue_names_size <= 0) {
|
if (xsb->version > XSB_XACT1_2_MAX && xsb->cue_names_size <= 0) {
|
||||||
VGM_LOG("XSB: no names found\n");
|
VGM_LOG("XSB: no names found\n");
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* find target wavebank */
|
/* find target wavebank */
|
||||||
if (xsb->wavebanks_count) {
|
if (xsb->wavebanks_count) {
|
||||||
char xsb_wavebank_name[64+1];
|
char xsb_wavebank_name[64+1];
|
||||||
int i;
|
|
||||||
off_t offset;
|
|
||||||
|
|
||||||
xsb->selected_wavebank = -1;
|
xsb->selected_wavebank = -1;
|
||||||
|
|
||||||
offset = xsb->wavebanks_offset;
|
off_t offset = xsb->wavebanks_offset;
|
||||||
for (i = 0; i < xsb->wavebanks_count; i++) {
|
for (int i = 0; i < xsb->wavebanks_count; i++) {
|
||||||
read_string(xsb_wavebank_name,xsb->wavebanks_name_size, offset, sf);
|
read_string(xsb_wavebank_name,xsb->wavebanks_name_size, offset, sf);
|
||||||
//;VGM_LOG("XSB wavebanks: bank %i\n", i); //, wavebank_name
|
//;VGM_LOG("XSB wavebanks: bank %i\n", i); //, wavebank_name
|
||||||
if (strcasecmp(xsb_wavebank_name, xwb_wavebank_name)==0) {
|
if (strcasecmp(xsb_wavebank_name, xwb_wavebank_name)==0) {
|
||||||
|
@ -883,9 +881,7 @@ static int parse_xsb(xsb_header *xsb, STREAMFILE *sf, char *xwb_wavebank_name) {
|
||||||
parse_xsb_cues(xsb, sf);
|
parse_xsb_cues(xsb, sf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return true;
|
||||||
fail:
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static STREAMFILE * open_xsb_filename_pair(STREAMFILE *streamXwb) {
|
static STREAMFILE * open_xsb_filename_pair(STREAMFILE *streamXwb) {
|
||||||
|
|
|
@ -81,9 +81,6 @@ typedef struct {
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int input_channels;
|
|
||||||
int output_channels;
|
|
||||||
|
|
||||||
int32_t pad_begin_duration;
|
int32_t pad_begin_duration;
|
||||||
int32_t pad_begin_left;
|
int32_t pad_begin_left;
|
||||||
int32_t trim_begin_duration;
|
int32_t trim_begin_duration;
|
||||||
|
|
Loading…
Reference in a new issue