mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-31 04:13:47 +01:00
Merge pull request #876 from bnnm/misc
- Fix some .MSB+MSH - Move .wma to common extensions list - Tweak segmented bitrate
This commit is contained in:
commit
bc91258ebf
@ -554,6 +554,7 @@ void replace_filename(char* dst, size_t dstsize, const char* outfilename, const
|
|||||||
/* ************************************************************ */
|
/* ************************************************************ */
|
||||||
|
|
||||||
static int convert_file(cli_config* cfg);
|
static int convert_file(cli_config* cfg);
|
||||||
|
static int write_file(VGMSTREAM* vgmstream, cli_config* cfg);
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
cli_config cfg = {0};
|
cli_config cfg = {0};
|
||||||
@ -596,13 +597,8 @@ fail:
|
|||||||
|
|
||||||
static int convert_file(cli_config* cfg) {
|
static int convert_file(cli_config* cfg) {
|
||||||
VGMSTREAM* vgmstream = NULL;
|
VGMSTREAM* vgmstream = NULL;
|
||||||
FILE* outfile = NULL;
|
|
||||||
char outfilename_temp[PATH_LIMIT];
|
char outfilename_temp[PATH_LIMIT];
|
||||||
|
|
||||||
sample_t* buf = NULL;
|
|
||||||
int channels, input_channels;
|
|
||||||
int32_t len_samples;
|
int32_t len_samples;
|
||||||
int i, j;
|
|
||||||
|
|
||||||
|
|
||||||
/* for plugin testing */
|
/* for plugin testing */
|
||||||
@ -641,19 +637,27 @@ static int convert_file(cli_config* cfg) {
|
|||||||
/* modify the VGMSTREAM if needed (before printing file info) */
|
/* modify the VGMSTREAM if needed (before printing file info) */
|
||||||
apply_config(vgmstream, cfg);
|
apply_config(vgmstream, cfg);
|
||||||
|
|
||||||
channels = vgmstream->channels;
|
|
||||||
input_channels = vgmstream->channels;
|
|
||||||
|
|
||||||
/* enable after config but before outbuf */
|
/* enable after config but before outbuf */
|
||||||
if (cfg->downmix_channels)
|
if (cfg->downmix_channels) {
|
||||||
vgmstream_mixing_autodownmix(vgmstream, cfg->downmix_channels);
|
vgmstream_mixing_autodownmix(vgmstream, cfg->downmix_channels);
|
||||||
vgmstream_mixing_enable(vgmstream, SAMPLE_BUFFER_SIZE, &input_channels, &channels);
|
}
|
||||||
|
else if (cfg->only_stereo >= 0) {
|
||||||
|
vgmstream_mixing_stereo_only(vgmstream, cfg->only_stereo);
|
||||||
|
}
|
||||||
|
vgmstream_mixing_enable(vgmstream, SAMPLE_BUFFER_SIZE, NULL, NULL);
|
||||||
|
|
||||||
/* get final play config */
|
/* get final play config */
|
||||||
len_samples = vgmstream_get_samples(vgmstream);
|
len_samples = vgmstream_get_samples(vgmstream);
|
||||||
if (len_samples <= 0)
|
if (len_samples <= 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
if (cfg->seek_samples1 < -1) /* ex value for loop testing */
|
||||||
|
cfg->seek_samples1 = vgmstream->loop_start_sample;
|
||||||
|
if (cfg->seek_samples1 >= len_samples)
|
||||||
|
cfg->seek_samples1 = -1;
|
||||||
|
if (cfg->seek_samples2 >= len_samples)
|
||||||
|
cfg->seek_samples2 = -1;
|
||||||
|
|
||||||
if (cfg->play_forever && !vgmstream_get_play_forever(vgmstream)) {
|
if (cfg->play_forever && !vgmstream_get_play_forever(vgmstream)) {
|
||||||
fprintf(stderr, "file can't be played forever");
|
fprintf(stderr, "file can't be played forever");
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -661,10 +665,7 @@ static int convert_file(cli_config* cfg) {
|
|||||||
|
|
||||||
|
|
||||||
/* prepare output */
|
/* prepare output */
|
||||||
if (cfg->play_sdtout) {
|
{
|
||||||
outfile = stdout;
|
|
||||||
}
|
|
||||||
else if (!cfg->print_metaonly && !cfg->decode_only) {
|
|
||||||
if (cfg->outfilename_config) {
|
if (cfg->outfilename_config) {
|
||||||
/* special substitution */
|
/* special substitution */
|
||||||
replace_filename(outfilename_temp, sizeof(outfilename_temp), cfg->outfilename_config, cfg->infilename, vgmstream);
|
replace_filename(outfilename_temp, sizeof(outfilename_temp), cfg->outfilename_config, cfg->infilename, vgmstream);
|
||||||
@ -684,16 +685,6 @@ static int convert_file(cli_config* cfg) {
|
|||||||
fprintf(stderr, "same infile and outfile name: %s\n", cfg->outfilename);
|
fprintf(stderr, "same infile and outfile name: %s\n", cfg->outfilename);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
outfile = fopen(cfg->outfilename,"wb");
|
|
||||||
if (!outfile) {
|
|
||||||
fprintf(stderr, "failed to open %s for output\n", cfg->outfilename);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no improvement */
|
|
||||||
//setvbuf(outfile, NULL, _IOFBF, SAMPLE_BUFFER_SIZE * sizeof(sample_t) * input_channels);
|
|
||||||
//setvbuf(outfile, NULL, _IONBF, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -713,26 +704,49 @@ static int convert_file(cli_config* cfg) {
|
|||||||
|
|
||||||
/* prints done */
|
/* prints done */
|
||||||
if (cfg->print_metaonly) {
|
if (cfg->print_metaonly) {
|
||||||
if (!cfg->play_sdtout) {
|
|
||||||
if (outfile != NULL)
|
|
||||||
fclose(outfile);
|
|
||||||
}
|
|
||||||
close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg->seek_samples1 < -1) /* ex value for loop testing */
|
|
||||||
cfg->seek_samples1 = vgmstream->loop_start_sample;
|
|
||||||
if (cfg->seek_samples1 >= len_samples)
|
|
||||||
cfg->seek_samples1 = -1;
|
|
||||||
if (cfg->seek_samples2 >= len_samples)
|
|
||||||
cfg->seek_samples2 = -1;
|
|
||||||
|
|
||||||
if (cfg->seek_samples2 >= 0)
|
/* main decode */
|
||||||
len_samples -= cfg->seek_samples2;
|
write_file(vgmstream, cfg);
|
||||||
else if (cfg->seek_samples1 >= 0)
|
|
||||||
len_samples -= cfg->seek_samples1;
|
|
||||||
|
|
||||||
|
/* try again with (for testing reset_vgmstream, simulates a seek to 0 after changing internal state)
|
||||||
|
* (could simulate by seeking to last sample then to 0, too */
|
||||||
|
if (cfg->test_reset) {
|
||||||
|
char outfilename_reset[PATH_LIMIT];
|
||||||
|
strcpy(outfilename_reset, cfg->outfilename);
|
||||||
|
strcat(outfilename_reset, ".reset.wav");
|
||||||
|
|
||||||
|
cfg->outfilename = outfilename_reset;
|
||||||
|
|
||||||
|
reset_vgmstream(vgmstream);
|
||||||
|
|
||||||
|
write_file(vgmstream, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
close_vgmstream(vgmstream);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
close_vgmstream(vgmstream);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int write_file(VGMSTREAM* vgmstream, cli_config* cfg) {
|
||||||
|
FILE* outfile = NULL;
|
||||||
|
int32_t len_samples;
|
||||||
|
sample_t* buf = NULL;
|
||||||
|
int i;
|
||||||
|
int channels, input_channels;
|
||||||
|
|
||||||
|
|
||||||
|
channels = vgmstream->channels;
|
||||||
|
input_channels = vgmstream->channels;
|
||||||
|
|
||||||
|
vgmstream_mixing_enable(vgmstream, 0, &input_channels, &channels);
|
||||||
|
|
||||||
/* last init */
|
/* last init */
|
||||||
buf = malloc(SAMPLE_BUFFER_SIZE * sizeof(sample_t) * input_channels);
|
buf = malloc(SAMPLE_BUFFER_SIZE * sizeof(sample_t) * input_channels);
|
||||||
@ -741,6 +755,36 @@ static int convert_file(cli_config* cfg) {
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* simulate seek */
|
||||||
|
len_samples = vgmstream_get_samples(vgmstream);
|
||||||
|
if (cfg->seek_samples2 >= 0)
|
||||||
|
len_samples -= cfg->seek_samples2;
|
||||||
|
else if (cfg->seek_samples1 >= 0)
|
||||||
|
len_samples -= cfg->seek_samples1;
|
||||||
|
|
||||||
|
if (cfg->seek_samples1 >= 0)
|
||||||
|
seek_vgmstream(vgmstream, cfg->seek_samples1);
|
||||||
|
if (cfg->seek_samples2 >= 0)
|
||||||
|
seek_vgmstream(vgmstream, cfg->seek_samples2);
|
||||||
|
|
||||||
|
|
||||||
|
/* output file */
|
||||||
|
if (cfg->play_sdtout) {
|
||||||
|
outfile = stdout;
|
||||||
|
}
|
||||||
|
else if (!cfg->decode_only) {
|
||||||
|
outfile = fopen(cfg->outfilename, "wb");
|
||||||
|
if (!outfile) {
|
||||||
|
fprintf(stderr, "failed to open %s for output\n", cfg->outfilename);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no improvement */
|
||||||
|
//setvbuf(outfile, NULL, _IOFBF, SAMPLE_BUFFER_SIZE * sizeof(sample_t) * input_channels);
|
||||||
|
//setvbuf(outfile, NULL, _IONBF, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* decode forever */
|
/* decode forever */
|
||||||
while (cfg->play_forever) {
|
while (cfg->play_forever) {
|
||||||
int to_get = SAMPLE_BUFFER_SIZE;
|
int to_get = SAMPLE_BUFFER_SIZE;
|
||||||
@ -748,35 +792,24 @@ static int convert_file(cli_config* cfg) {
|
|||||||
render_vgmstream(buf, to_get, vgmstream);
|
render_vgmstream(buf, to_get, vgmstream);
|
||||||
|
|
||||||
swap_samples_le(buf, channels * to_get); /* write PC endian */
|
swap_samples_le(buf, channels * to_get); /* write PC endian */
|
||||||
if (cfg->only_stereo != -1) {
|
fwrite(buf, sizeof(sample_t) * channels, to_get, outfile);
|
||||||
for (j = 0; j < to_get; j++) {
|
/* should write infinitely until program kill */
|
||||||
fwrite(buf + j*channels + (cfg->only_stereo*2), sizeof(sample_t), 2, outfile);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fwrite(buf, sizeof(sample_t) * channels, to_get, outfile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* slap on a .wav header */
|
/* slap on a .wav header */
|
||||||
if (!cfg->decode_only) {
|
if (!cfg->decode_only) {
|
||||||
uint8_t wav_buf[0x100];
|
uint8_t wav_buf[0x100];
|
||||||
int channels_write = (cfg->only_stereo != -1) ? 2 : channels;
|
|
||||||
size_t bytes_done;
|
size_t bytes_done;
|
||||||
|
|
||||||
bytes_done = make_wav_header(wav_buf,0x100,
|
bytes_done = make_wav_header(wav_buf,0x100,
|
||||||
len_samples, vgmstream->sample_rate, channels_write,
|
len_samples, vgmstream->sample_rate, channels,
|
||||||
cfg->write_lwav, cfg->lwav_loop_start, cfg->lwav_loop_end);
|
cfg->write_lwav, cfg->lwav_loop_start, cfg->lwav_loop_end);
|
||||||
|
|
||||||
fwrite(wav_buf,sizeof(uint8_t),bytes_done,outfile);
|
fwrite(wav_buf, sizeof(uint8_t), bytes_done, outfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (cfg->seek_samples1 >= 0)
|
|
||||||
seek_vgmstream(vgmstream, cfg->seek_samples1);
|
|
||||||
if (cfg->seek_samples2 >= 0)
|
|
||||||
seek_vgmstream(vgmstream, cfg->seek_samples2);
|
|
||||||
|
|
||||||
/* decode */
|
/* decode */
|
||||||
for (i = 0; i < len_samples; i += SAMPLE_BUFFER_SIZE) {
|
for (i = 0; i < len_samples; i += SAMPLE_BUFFER_SIZE) {
|
||||||
int to_get = SAMPLE_BUFFER_SIZE;
|
int to_get = SAMPLE_BUFFER_SIZE;
|
||||||
@ -787,96 +820,22 @@ static int convert_file(cli_config* cfg) {
|
|||||||
|
|
||||||
if (!cfg->decode_only) {
|
if (!cfg->decode_only) {
|
||||||
swap_samples_le(buf, channels * to_get); /* write PC endian */
|
swap_samples_le(buf, channels * to_get); /* write PC endian */
|
||||||
if (cfg->only_stereo != -1) {
|
fwrite(buf, sizeof(sample_t) * channels, to_get, outfile);
|
||||||
for (j = 0; j < to_get; j++) {
|
|
||||||
fwrite(buf + j*channels + (cfg->only_stereo*2), sizeof(sample_t), 2, outfile);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fwrite(buf, sizeof(sample_t), to_get * channels, outfile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outfile != NULL) {
|
if (outfile && !cfg->play_sdtout)
|
||||||
fclose(outfile);
|
fclose(outfile);
|
||||||
outfile = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* try again with (for testing reset_vgmstream, simulates a seek to 0 after changing internal state) */
|
|
||||||
if (cfg->test_reset) {
|
|
||||||
char outfilename_reset[PATH_LIMIT];
|
|
||||||
strcpy(outfilename_reset, cfg->outfilename);
|
|
||||||
strcat(outfilename_reset, ".reset.wav");
|
|
||||||
|
|
||||||
outfile = fopen(outfilename_reset,"wb");
|
|
||||||
if (!outfile) {
|
|
||||||
fprintf(stderr, "failed to open %s for output\n", outfilename_reset);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* slap on a .wav header */
|
|
||||||
if (!cfg->decode_only) {
|
|
||||||
uint8_t wav_buf[0x100];
|
|
||||||
int channels_write = (cfg->only_stereo != -1) ? 2 : channels;
|
|
||||||
size_t bytes_done;
|
|
||||||
|
|
||||||
bytes_done = make_wav_header(wav_buf,0x100,
|
|
||||||
len_samples, vgmstream->sample_rate, channels_write,
|
|
||||||
cfg->write_lwav, cfg->lwav_loop_start, cfg->lwav_loop_end);
|
|
||||||
|
|
||||||
fwrite(wav_buf,sizeof(uint8_t),bytes_done,outfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
reset_vgmstream(vgmstream);
|
|
||||||
|
|
||||||
if (cfg->seek_samples1 >= 0)
|
|
||||||
seek_vgmstream(vgmstream, cfg->seek_samples1);
|
|
||||||
if (cfg->seek_samples2 >= 0)
|
|
||||||
seek_vgmstream(vgmstream, cfg->seek_samples2);
|
|
||||||
|
|
||||||
/* decode */
|
|
||||||
for (i = 0; i < len_samples; i += SAMPLE_BUFFER_SIZE) {
|
|
||||||
int to_get = SAMPLE_BUFFER_SIZE;
|
|
||||||
if (i + SAMPLE_BUFFER_SIZE > len_samples)
|
|
||||||
to_get = len_samples - i;
|
|
||||||
|
|
||||||
render_vgmstream(buf, to_get, vgmstream);
|
|
||||||
|
|
||||||
if (!cfg->decode_only) {
|
|
||||||
swap_samples_le(buf, channels * to_get); /* write PC endian */
|
|
||||||
if (cfg->only_stereo != -1) {
|
|
||||||
for (j = 0; j < to_get; j++) {
|
|
||||||
fwrite(buf + j*channels + (cfg->only_stereo*2), sizeof(sample_t), 2, outfile);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fwrite(buf, sizeof(sample_t) * channels, to_get, outfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outfile != NULL) {
|
|
||||||
fclose(outfile);
|
|
||||||
outfile = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close_vgmstream(vgmstream);
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (!cfg->play_sdtout) {
|
if (outfile && !cfg->play_sdtout)
|
||||||
if (outfile != NULL)
|
fclose(outfile);
|
||||||
fclose(outfile);
|
|
||||||
}
|
|
||||||
close_vgmstream(vgmstream);
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_JSON
|
#ifdef HAVE_JSON
|
||||||
static void print_json_info(VGMSTREAM* vgm, cli_config* cfg) {
|
static void print_json_info(VGMSTREAM* vgm, cli_config* cfg) {
|
||||||
json_t* version_string = json_string(VERSION);
|
json_t* version_string = json_string(VERSION);
|
||||||
|
@ -358,7 +358,7 @@ size_t ps_find_padding(STREAMFILE *streamFile, off_t start_offset, size_t data_s
|
|||||||
size_t interleave_consumed = 0;
|
size_t interleave_consumed = 0;
|
||||||
|
|
||||||
|
|
||||||
if (data_size == 0 || channels == 0 || (channels > 0 && interleave == 0))
|
if (data_size == 0 || channels == 0 || (channels > 1 && interleave == 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
offset = start_offset + data_size;
|
offset = start_offset + data_size;
|
||||||
@ -405,7 +405,7 @@ size_t ps_find_padding(STREAMFILE *streamFile, off_t start_offset, size_t data_s
|
|||||||
interleave_consumed += 0x10;
|
interleave_consumed += 0x10;
|
||||||
if (interleave_consumed == interleave) {
|
if (interleave_consumed == interleave) {
|
||||||
interleave_consumed = 0;
|
interleave_consumed = 0;
|
||||||
offset -= interleave*(channels - 1);
|
offset -= interleave * (channels - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +311,7 @@ static const char* extension_list[] = {
|
|||||||
"mdsp",
|
"mdsp",
|
||||||
"med",
|
"med",
|
||||||
"mjb",
|
"mjb",
|
||||||
"mi4",
|
"mi4", //fake extension for .mib (renamed, to be removed)
|
||||||
"mib",
|
"mib",
|
||||||
"mic",
|
"mic",
|
||||||
"mihb",
|
"mihb",
|
||||||
@ -581,7 +581,6 @@ static const char* extension_list[] = {
|
|||||||
"wii",
|
"wii",
|
||||||
"wip", //txth/reserved [Colin McRae DiRT (PC)]
|
"wip", //txth/reserved [Colin McRae DiRT (PC)]
|
||||||
"wlv", //txth/reserved [ToeJam & Earl III: Mission to Earth (DC)]
|
"wlv", //txth/reserved [ToeJam & Earl III: Mission to Earth (DC)]
|
||||||
"wma", //common
|
|
||||||
"wmus",
|
"wmus",
|
||||||
"wp2",
|
"wp2",
|
||||||
"wpd",
|
"wpd",
|
||||||
@ -658,6 +657,7 @@ static const char* common_extension_list[] = {
|
|||||||
"ogg", //common
|
"ogg", //common
|
||||||
"opus", //common
|
"opus", //common
|
||||||
"wav", //common
|
"wav", //common
|
||||||
|
"wma", //common
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +8,9 @@ VGMSTREAM* init_vgmstream_msb_msh(STREAMFILE* sf) {
|
|||||||
off_t start_offset, header_offset = 0;
|
off_t start_offset, header_offset = 0;
|
||||||
size_t stream_size;
|
size_t stream_size;
|
||||||
int loop_flag, channels, sample_rate;
|
int loop_flag, channels, sample_rate;
|
||||||
|
int32_t loop_start, loop_end;
|
||||||
int total_subsongs, target_subsong = sf->stream_index;
|
int total_subsongs, target_subsong = sf->stream_index;
|
||||||
|
uint32_t config;
|
||||||
|
|
||||||
|
|
||||||
/* checks */
|
/* checks */
|
||||||
@ -20,12 +22,12 @@ VGMSTREAM* init_vgmstream_msb_msh(STREAMFILE* sf) {
|
|||||||
|
|
||||||
if (read_u32le(0x00,sh) != get_streamfile_size(sh))
|
if (read_u32le(0x00,sh) != get_streamfile_size(sh))
|
||||||
goto fail;
|
goto fail;
|
||||||
/* 0x04: unknown */
|
/* 0x04: flags? (0x04/34*/
|
||||||
|
|
||||||
/* parse entries */
|
/* parse entries */
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int entries = read_s32le(0x08,sh);
|
int entries = read_s32le(0x08,sh); /* may be less than file size, or include dummies (all dummies is possible too) */
|
||||||
|
|
||||||
total_subsongs = 0;
|
total_subsongs = 0;
|
||||||
if (target_subsong == 0) target_subsong = 1;
|
if (target_subsong == 0) target_subsong = 1;
|
||||||
@ -45,15 +47,20 @@ VGMSTREAM* init_vgmstream_msb_msh(STREAMFILE* sf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
loop_flag = 0;
|
|
||||||
channels = 1;
|
|
||||||
|
|
||||||
stream_size = read_u32le(header_offset+0x00, sh);
|
stream_size = read_u32le(header_offset+0x00, sh);
|
||||||
if (read_u32le(header_offset+0x04, sh) != 0) /* stereo flag? */
|
config = read_u32le(header_offset+0x04, sh); /* volume (0~100), null, null, loop (0/1) */
|
||||||
goto fail;
|
|
||||||
start_offset = read_u32le(header_offset+0x08, sh);
|
start_offset = read_u32le(header_offset+0x08, sh);
|
||||||
sample_rate = read_u32le(header_offset+0x0c, sh); /* Ace Combat 2 seems to set wrong values but probably their bug */
|
sample_rate = read_u32le(header_offset+0x0c, sh); /* Ace Combat 2 seems to set wrong values but probably their bug */
|
||||||
|
|
||||||
|
loop_flag = (config & 1);
|
||||||
|
channels = 1;
|
||||||
|
|
||||||
|
/* rare [Dr. Seuss Cat in the Hat (PS2)] */
|
||||||
|
if (loop_flag) {
|
||||||
|
/* when loop is set ADPCM has loop flags, but rarely appear too without loop set */
|
||||||
|
loop_flag = ps_find_loop_offsets(sf, start_offset, stream_size, channels, 0, &loop_start, &loop_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||||
@ -62,6 +69,8 @@ VGMSTREAM* init_vgmstream_msb_msh(STREAMFILE* sf) {
|
|||||||
vgmstream->meta_type = meta_MSB_MSH;
|
vgmstream->meta_type = meta_MSB_MSH;
|
||||||
vgmstream->sample_rate = sample_rate;
|
vgmstream->sample_rate = sample_rate;
|
||||||
vgmstream->num_samples = ps_bytes_to_samples(stream_size, channels);
|
vgmstream->num_samples = ps_bytes_to_samples(stream_size, channels);
|
||||||
|
vgmstream->loop_start_sample = loop_start;
|
||||||
|
vgmstream->loop_end_sample = loop_end;
|
||||||
|
|
||||||
vgmstream->num_streams = total_subsongs;
|
vgmstream->num_streams = total_subsongs;
|
||||||
vgmstream->stream_size = stream_size;
|
vgmstream->stream_size = stream_size;
|
||||||
|
@ -532,3 +532,17 @@ void vgmstream_mixing_autodownmix(VGMSTREAM *vgmstream, int max_channels) {
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vgmstream_mixing_stereo_only(VGMSTREAM *vgmstream, int start) {
|
||||||
|
if (start < 0)
|
||||||
|
return;
|
||||||
|
/* could check to avoid making mono files in edge cases but meh */
|
||||||
|
|
||||||
|
/* remove channels before start */
|
||||||
|
while (start) {
|
||||||
|
mixing_push_downmix(vgmstream, 0);
|
||||||
|
start--;
|
||||||
|
}
|
||||||
|
/* remove channels after stereo */
|
||||||
|
mixing_push_killmix(vgmstream, start + 2);
|
||||||
|
}
|
||||||
|
@ -215,7 +215,10 @@ void vgmstream_tags_close(VGMSTREAM_TAGS* tags);
|
|||||||
void vgmstream_mixing_enable(VGMSTREAM* vgmstream, int32_t max_sample_count, int *input_channels, int *output_channels);
|
void vgmstream_mixing_enable(VGMSTREAM* vgmstream, int32_t max_sample_count, int *input_channels, int *output_channels);
|
||||||
|
|
||||||
/* sets automatic downmixing if vgmstream's channels are higher than max_channels */
|
/* sets automatic downmixing if vgmstream's channels are higher than max_channels */
|
||||||
void vgmstream_mixing_autodownmix(VGMSTREAM *vgmstream, int max_channels);
|
void vgmstream_mixing_autodownmix(VGMSTREAM* vgmstream, int max_channels);
|
||||||
|
|
||||||
|
/* downmixes to get stereo from start channel */
|
||||||
|
void vgmstream_mixing_stereo_only(VGMSTREAM* vgmstream, int start);
|
||||||
|
|
||||||
/* sets a fadeout */
|
/* sets a fadeout */
|
||||||
//void vgmstream_mixing_fadeout(VGMSTREAM *vgmstream, float start_second, float duration_seconds);
|
//void vgmstream_mixing_fadeout(VGMSTREAM *vgmstream, float start_second, float duration_seconds);
|
||||||
|
@ -1409,7 +1409,7 @@ static int get_vgmstream_file_bitrate_from_streamfile(STREAMFILE* sf, int sample
|
|||||||
return get_vgmstream_file_bitrate_from_size(get_streamfile_size(sf), sample_rate, length_samples);
|
return get_vgmstream_file_bitrate_from_size(get_streamfile_size(sf), sample_rate, length_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_vgmstream_file_bitrate_main(VGMSTREAM* vgmstream, bitrate_info_t* br) {
|
static int get_vgmstream_file_bitrate_main(VGMSTREAM* vgmstream, bitrate_info_t* br, int* p_uniques) {
|
||||||
int i, ch;
|
int i, ch;
|
||||||
int bitrate = 0;
|
int bitrate = 0;
|
||||||
|
|
||||||
@ -1423,15 +1423,18 @@ static int get_vgmstream_file_bitrate_main(VGMSTREAM* vgmstream, bitrate_info_t*
|
|||||||
* become a bit high since its hard to detect only part of the file is needed. */
|
* become a bit high since its hard to detect only part of the file is needed. */
|
||||||
|
|
||||||
if (vgmstream->layout_type == layout_segmented) {
|
if (vgmstream->layout_type == layout_segmented) {
|
||||||
|
int uniques = 0;
|
||||||
segmented_layout_data *data = (segmented_layout_data *) vgmstream->layout_data;
|
segmented_layout_data *data = (segmented_layout_data *) vgmstream->layout_data;
|
||||||
for (i = 0; i < data->segment_count; i++) {
|
for (i = 0; i < data->segment_count; i++) {
|
||||||
bitrate += get_vgmstream_file_bitrate_main(data->segments[i], br);
|
bitrate += get_vgmstream_file_bitrate_main(data->segments[i], br, &uniques);
|
||||||
}
|
}
|
||||||
|
if (uniques)
|
||||||
|
bitrate /= uniques; /* average */
|
||||||
}
|
}
|
||||||
else if (vgmstream->layout_type == layout_layered) {
|
else if (vgmstream->layout_type == layout_layered) {
|
||||||
layered_layout_data *data = vgmstream->layout_data;
|
layered_layout_data *data = vgmstream->layout_data;
|
||||||
for (i = 0; i < data->layer_count; i++) {
|
for (i = 0; i < data->layer_count; i++) {
|
||||||
bitrate += get_vgmstream_file_bitrate_main(data->layers[i], br);
|
bitrate += get_vgmstream_file_bitrate_main(data->layers[i], br, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1467,6 +1470,8 @@ static int get_vgmstream_file_bitrate_main(VGMSTREAM* vgmstream, bitrate_info_t*
|
|||||||
br->subsong[br->count] = subsong_cur;
|
br->subsong[br->count] = subsong_cur;
|
||||||
|
|
||||||
br->count++;
|
br->count++;
|
||||||
|
if (p_uniques)
|
||||||
|
(*p_uniques)++;
|
||||||
|
|
||||||
if (vgmstream->stream_size) {
|
if (vgmstream->stream_size) {
|
||||||
/* stream_size applies to both channels but should add once and detect repeats (for current subsong) */
|
/* stream_size applies to both channels but should add once and detect repeats (for current subsong) */
|
||||||
@ -1494,7 +1499,7 @@ int get_vgmstream_average_bitrate(VGMSTREAM* vgmstream) {
|
|||||||
bitrate_info_t br = {0};
|
bitrate_info_t br = {0};
|
||||||
br.count_max = BITRATE_FILES_MAX;
|
br.count_max = BITRATE_FILES_MAX;
|
||||||
|
|
||||||
return get_vgmstream_file_bitrate_main(vgmstream, &br);
|
return get_vgmstream_file_bitrate_main(vgmstream, &br, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user