cleanup: blocked layout stuff

This commit is contained in:
bnnm 2024-08-18 15:19:13 +02:00
parent d253f90d25
commit 01661a0d99
16 changed files with 131 additions and 117 deletions

View File

@ -4,6 +4,7 @@
#include "decode.h"
#include "mixing.h"
#include "plugins.h"
#include "sbuf.h"
/* custom codec handling, not exactly "decode" stuff but here to simplify adding new codecs */
@ -824,7 +825,7 @@ bool decode_uses_internal_offset_updates(VGMSTREAM* vgmstream) {
return vgmstream->coding_type == coding_MS_IMA || vgmstream->coding_type == coding_MS_IMA_mono;
}
/* Decode samples into the buffer. Assume that we have written samples_written into the
/* Decode samples into the buffer. Assume that we have written samples_filled into the
* buffer already, and we have samples_to_do consecutive samples ahead of us (won't call
* more than one frame if configured above to do so).
* Called by layouts since they handle samples written/to_do */
@ -832,10 +833,11 @@ void decode_vgmstream(VGMSTREAM* vgmstream, int samples_filled, int samples_to_d
int ch;
buffer += samples_filled * vgmstream->channels; /* passed externally to simplify I guess */
//samples_to_do -= samples_filled; /* pre-adjusted */
switch (vgmstream->coding_type) {
case coding_SILENCE:
memset(buffer, 0, samples_to_do * vgmstream->channels * sizeof(sample_t));
sbuf_silence(buffer, samples_to_do, vgmstream->channels, 0);
break;
case coding_CRI_ADX:

View File

@ -7,9 +7,9 @@ void decode_free(VGMSTREAM* vgmstream);
void decode_seek(VGMSTREAM* vgmstream);
void decode_reset(VGMSTREAM* vgmstream);
/* Decode samples into the buffer. Assume that we have written samples_written into the
/* Decode samples into the buffer. Assume that we have written samples_filled into the
* buffer already, and we have samples_to_do consecutive samples ahead of us. */
void decode_vgmstream(VGMSTREAM* vgmstream, int samples_written, int samples_to_do, sample_t* buffer);
void decode_vgmstream(VGMSTREAM* vgmstream, int samples_filled, int samples_to_do, sample_t* buffer);
/* Detect loop start and save values, or detect loop end and restore (loop back). Returns true if loop was done. */
bool decode_do_loop(VGMSTREAM* vgmstream);

View File

@ -106,7 +106,7 @@ int render_layout(sample_t* buf, int32_t sample_count, VGMSTREAM* vgmstream) {
case layout_blocked_str_snds:
case layout_blocked_ws_aud:
case layout_blocked_dec:
case layout_blocked_vs:
case layout_blocked_vs_mh:
case layout_blocked_mul:
case layout_blocked_gsb:
case layout_blocked_xvas:

View File

@ -36,7 +36,7 @@ void sbuf_copy_s16_to_f32(float* buf_f32, int16_t* buf_s16, int samples, int cha
void sbuf_copy_f32_to_s16(int16_t* buf_s16, float* buf_f32, int samples, int channels);
void sbuf_copy_samples(sample_t* dst, int dst_channels, sample_t* src, int src_channels, int samples_to_do, int samples_written);
void sbuf_copy_samples(sample_t* dst, int dst_channels, sample_t* src, int src_channels, int samples_to_do, int samples_filled);
void sbuf_copy_layers(sample_t* dst, int dst_channels, sample_t* src, int src_channels, int samples_to_do, int samples_filled, int dst_ch_start);

View File

@ -956,7 +956,7 @@ static const layout_info layout_info_list[] = {
{layout_blocked_str_snds, "blocked (.str SNDS)"},
{layout_blocked_ws_aud, "blocked (Westwood Studios .aud)"},
{layout_blocked_dec, "blocked (DEC)"},
{layout_blocked_vs, "blocked (Melbourne House VS)"},
{layout_blocked_vs_mh, "blocked (Melbourne House VS)"},
{layout_blocked_mul, "blocked (MUL)"},
{layout_blocked_gsb, "blocked (GSB)"},
{layout_blocked_thp, "blocked (THP)"},
@ -1102,7 +1102,7 @@ static const meta_info meta_info_list[] = {
{meta_SDT, "High Voltage .sdt header"},
{meta_WVS, "Swingin' Ape .WVS header"},
{meta_DEC, "Falcom .DEC RIFF header"},
{meta_VS, "Melbourne House .VS header"},
{meta_VS_MH, "Melbourne House .VS header"},
{meta_STR_SEGA, "Sega Stream Asset Builder header"},
{meta_STR_SEGA_custom, "Sega Stream Asset Builder header (custom)"},
{meta_XMU, "Outrage XMU header"},

View File

@ -16,9 +16,12 @@ void render_vgmstream_blocked(sample_t* outbuf, int32_t sample_count, VGMSTREAM*
if (vgmstream->current_block_samples) {
samples_this_block = vgmstream->current_block_samples;
} else if (frame_size == 0) { /* assume 4 bit */
}
else if (frame_size == 0) {
//TO-DO: this case doesn't seem possible, codecs that return frame_size 0 (should) set current_block_samples
samples_this_block = vgmstream->current_block_size * 2 * samples_per_frame;
} else {
}
else {
samples_this_block = vgmstream->current_block_size / frame_size * samples_per_frame;
}
@ -74,9 +77,12 @@ void render_vgmstream_blocked(sample_t* outbuf, int32_t sample_count, VGMSTREAM*
samples_per_frame = decode_get_samples_per_frame(vgmstream);
if (vgmstream->current_block_samples) {
samples_this_block = vgmstream->current_block_samples;
} else if (frame_size == 0) { /* assume 4 bit */
}
else if (frame_size == 0) {
//TO-DO: this case doesn't seem possible, codecs that return frame_size 0 (should) set current_block_samples
samples_this_block = vgmstream->current_block_size * 2 * samples_per_frame;
} else {
}
else {
samples_this_block = vgmstream->current_block_size / frame_size * samples_per_frame;
}
@ -131,8 +137,8 @@ void block_update(off_t block_offset, VGMSTREAM* vgmstream) {
case layout_blocked_gsb:
block_update_gsb(block_offset,vgmstream);
break;
case layout_blocked_vs:
block_update_vs(block_offset,vgmstream);
case layout_blocked_vs_mh:
block_update_vs_mh(block_offset,vgmstream);
break;
case layout_blocked_xvas:
block_update_xvas(block_offset,vgmstream);
@ -213,43 +219,3 @@ void block_update(off_t block_offset, VGMSTREAM* vgmstream) {
break;
}
}
void blocked_count_samples(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t offset) {
if (vgmstream == NULL)
return;
int block_samples;
off_t max_offset = get_streamfile_size(sf);
vgmstream->next_block_offset = offset;
do {
block_update(vgmstream->next_block_offset, vgmstream);
if (vgmstream->current_block_samples < 0 || vgmstream->current_block_size == 0xFFFFFFFF)
break;
if (vgmstream->current_block_samples) {
block_samples = vgmstream->current_block_samples;
}
else {
switch(vgmstream->coding_type) {
case coding_PCM16LE:
case coding_PCM16_int: block_samples = pcm16_bytes_to_samples(vgmstream->current_block_size, 1); break;
case coding_PCM8_int:
case coding_PCM8_U_int: block_samples = pcm8_bytes_to_samples(vgmstream->current_block_size, 1); break;
case coding_XBOX_IMA_mono:
case coding_XBOX_IMA: block_samples = xbox_ima_bytes_to_samples(vgmstream->current_block_size, 1); break;
case coding_NGC_DSP: block_samples = dsp_bytes_to_samples(vgmstream->current_block_size, 1); break;
case coding_PSX: block_samples = ps_bytes_to_samples(vgmstream->current_block_size,1); break;
default:
VGM_LOG("BLOCKED: missing codec\n");
return;
}
}
vgmstream->num_samples += block_samples;
}
while (vgmstream->next_block_offset < max_offset);
block_update(offset, vgmstream); /* reset */
}

View File

@ -2,13 +2,12 @@
#include "../vgmstream.h"
/* mini-blocks of size + data */
void block_update_vs(off_t block_offset, VGMSTREAM * vgmstream) {
STREAMFILE* streamFile = vgmstream->ch[0].streamfile;
int i;
void block_update_vs_mh(off_t block_offset, VGMSTREAM* vgmstream) {
STREAMFILE* sf = vgmstream->ch[0].streamfile;
for (i = 0; i < vgmstream->channels; i++) {
for (int i = 0; i < vgmstream->channels; i++) {
vgmstream->current_block_offset = block_offset;
vgmstream->current_block_size = read_32bitLE(vgmstream->current_block_offset,streamFile);
vgmstream->current_block_size = read_32bitLE(vgmstream->current_block_offset,sf);
vgmstream->next_block_offset = vgmstream->current_block_offset + vgmstream->current_block_size + 0x04;
vgmstream->ch[i].offset = vgmstream->current_block_offset + 0x04;
if (i == 0) block_offset=vgmstream->next_block_offset;

View File

@ -57,7 +57,6 @@ void loop_layout_layered(VGMSTREAM* vgmstream, int32_t loop_sample);
/* blocked layouts */
void render_vgmstream_blocked(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
void block_update(off_t block_offset, VGMSTREAM* vgmstream);
void blocked_count_samples(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t offset);
void block_update_ast(off_t block_ofset, VGMSTREAM* vgmstream);
void block_update_mxch(off_t block_ofset, VGMSTREAM* vgmstream);
@ -70,7 +69,7 @@ void block_update_wsi(off_t block_offset, VGMSTREAM* vgmstream);
void block_update_str_snds(off_t block_offset, VGMSTREAM* vgmstream);
void block_update_ws_aud(off_t block_offset, VGMSTREAM* vgmstream);
void block_update_dec(off_t block_offset, VGMSTREAM* vgmstream);
void block_update_vs(off_t block_offset, VGMSTREAM* vgmstream);
void block_update_vs_mh(off_t block_offset, VGMSTREAM* vgmstream);
void block_update_mul(off_t block_offset, VGMSTREAM* vgmstream);
void block_update_gsb(off_t block_offset, VGMSTREAM* vgmstream);
void block_update_xvas(off_t block_offset, VGMSTREAM* vgmstream);

View File

@ -2,46 +2,48 @@
#include "../coding/coding.h"
#include "../layout/layout.h"
#include "../util/endianness.h"
#include "../util/layout_utils.h"
/* EA WVE (Ad10) - from early Electronic Arts movies [Wing Commander 3/4 (PS1), Madden NHL 97 (PC)-w95] */
VGMSTREAM* init_vgmstream_ea_wve_ad10(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
off_t start_offset;
int loop_flag, channels;
int big_endian, is_ps1;
/* checks */
/* .wve: common
* .mov: Madden NHL 97 (also uses .wve) */
if (!check_extensions(sf, "wve,mov"))
goto fail;
start_offset = 0x00;
if (!is_id32be(0x00, sf, "AABB") && /* video block */
!is_id32be(0x00, sf, "Ad10") && /* audio block */
!is_id32be(0x00, sf, "Ad11")) /* last audio block, but could be first */
goto fail;
return NULL;
big_endian = guess_endian32(0x04, sf);
/* .wve: common
* .mov: Madden NHL 97 (also uses .wve) */
if (!check_extensions(sf, "wve,mov"))
return NULL;
if (is_id32be(0x00, sf, "AABB"))
bool big_endian = guess_endian32(0x04, sf);
start_offset = 0x00;
if (is_id32be(0x00, sf, "AABB")){
start_offset += big_endian ? read_u32be(0x04, sf) : read_u32le(0x04, sf);
}
loop_flag = 0;
bool is_ps1;
if (ps_check_format(sf, start_offset + 0x08, 0x40)) {
/* no header = no channels, but seems if the first PS-ADPCM header is 00 then it's mono, somehow
* (ex. Wing Commander 3 intro / Wing Commander 4 = stereo, rest of Wing Commander 3 = mono) */
channels = read_u8(start_offset + 0x08,sf) != 0 ? 2 : 1;
is_ps1 = 1;
VGM_LOG("ps1");
is_ps1 = true;
}
else {
channels = 1;
is_ps1 = 0;
is_ps1 = false;
}
loop_flag = false;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channels, loop_flag);
@ -59,10 +61,14 @@ VGMSTREAM* init_vgmstream_ea_wve_ad10(STREAMFILE* sf) {
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
goto fail;
blocked_count_samples(vgmstream, sf, start_offset);
{
blocked_counter_t cfg = {0};
cfg.offset = start_offset;
blocked_count_samples(vgmstream, sf, &cfg);
}
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;

View File

@ -267,7 +267,7 @@ VGMSTREAM* init_vgmstream_str_sega_custom(STREAMFILE* sf);
VGMSTREAM * init_vgmstream_dec(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_vs(STREAMFILE *streamFile);
VGMSTREAM* init_vgmstream_vs_mh(STREAMFILE* sf);
VGMSTREAM * init_vgmstream_xmu(STREAMFILE *streamFile);

View File

@ -2,6 +2,7 @@
#include "../coding/coding.h"
#include "../layout/layout.h"
#include "../util/endianness.h"
#include "../util/layout_utils.h"
/* VID1 - Factor 5/DivX format GC/Xbox games [Gun (GC), Tony Hawk's American Wasteland (GC), Enter The Matrix (Xbox)]*/
@ -10,16 +11,16 @@ VGMSTREAM* init_vgmstream_vid1(STREAMFILE* sf) {
uint32_t start_offset, header_offset;
int loop_flag = 0, channels, sample_rate;
uint32_t codec;
int big_endian;
bool big_endian;
read_u32_t read_u32;
/* checks */
if (is_id32be(0x00, sf, "VID1")) { /* BE (GC) */
big_endian = 1;
big_endian = true;
}
else if (is_id32le(0x00,sf, "VID1")) { /* LE (Xbox) */
big_endian = 0;
big_endian = false;
}
else {
return NULL;
@ -110,24 +111,10 @@ VGMSTREAM* init_vgmstream_vid1(STREAMFILE* sf) {
/* calc num_samples as playable data size varies between files/blocks */
if (vgmstream->layout_type == layout_blocked_vid1) {
int block_samples;
blocked_counter_t cfg = {0};
cfg.offset = start_offset;
vgmstream->next_block_offset = start_offset;
do {
block_update(vgmstream->next_block_offset, vgmstream);
if (vgmstream->current_block_samples < 0)
break;
switch(vgmstream->coding_type) {
case coding_PCM16_int: block_samples = pcm_bytes_to_samples(vgmstream->current_block_size, 1, 16); break;
case coding_XBOX_IMA: block_samples = xbox_ima_bytes_to_samples(vgmstream->current_block_size, 1); break;
case coding_NGC_DSP: block_samples = dsp_bytes_to_samples(vgmstream->current_block_size, 1); break;
default: goto fail;
}
vgmstream->num_samples += block_samples;
}
while (vgmstream->next_block_offset < get_streamfile_size(sf));
block_update(start_offset, vgmstream);
blocked_count_samples(vgmstream, sf, &cfg);
}
return vgmstream;

View File

@ -1,19 +1,31 @@
#include "meta.h"
#include "../layout/layout.h"
#include "../coding/coding.h"
#include "../util/layout_utils.h"
/* .VS - from Melbourne House games [Men in Black II (PS2), Grand Prix Challenge (PS2) */
VGMSTREAM* init_vgmstream_vs(STREAMFILE* sf) {
VGMSTREAM* init_vgmstream_vs_mh(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
off_t start_offset;
int loop_flag, channels;
/* checks */
if (!check_extensions(sf, "vs"))
goto fail;
if (read_u32be(0x00,sf) != 0xC8000000)
goto fail;
return NULL;
if (!check_extensions(sf, "vs"))
return NULL;
/* extra checks since format is too simple */
int sample_rate = read_s32le(0x04,sf);
if (sample_rate != 48000 && sample_rate != 44100)
return NULL;
if (read_u32le(0x08,sf) != 0x1000)
return NULL;
if (!ps_check_format(sf, 0x0c, 0x1000))
return NULL;
loop_flag = 0;
channels = 2;
@ -24,24 +36,19 @@ VGMSTREAM* init_vgmstream_vs(STREAMFILE* sf) {
vgmstream = allocate_vgmstream(channels,loop_flag);
if (!vgmstream) goto fail;
vgmstream->meta_type = meta_VS;
vgmstream->sample_rate = read_s32le(0x04,sf);
vgmstream->meta_type = meta_VS_MH;
vgmstream->sample_rate = sample_rate;
vgmstream->coding_type = coding_PSX;
vgmstream->layout_type = layout_blocked_vs;
vgmstream->layout_type = layout_blocked_vs_mh;
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
goto fail;
/* calc num_samples */
{
vgmstream->next_block_offset = start_offset;
do {
block_update(vgmstream->next_block_offset,vgmstream);
vgmstream->num_samples += ps_bytes_to_samples(vgmstream->current_block_size, 1);
}
while (vgmstream->next_block_offset < get_streamfile_size(sf));
block_update(start_offset, vgmstream);
blocked_counter_t cfg = {0};
cfg.offset = start_offset;
blocked_count_samples(vgmstream, sf, &cfg);
}
return vgmstream;

View File

@ -293,3 +293,44 @@ fail:
close_vgmstream(vgmstream);
return NULL;
}
void blocked_count_samples(VGMSTREAM* vgmstream, STREAMFILE* sf, blocked_counter_t* cfg) {
if (vgmstream == NULL)
return;
int block_samples;
off_t max_offset = get_streamfile_size(sf);
vgmstream->next_block_offset = cfg->offset;
do {
block_update(vgmstream->next_block_offset, vgmstream);
if (vgmstream->current_block_samples < 0 || vgmstream->current_block_size == 0xFFFFFFFF)
break;
if (vgmstream->current_block_samples) {
block_samples = vgmstream->current_block_samples;
}
else {
switch(vgmstream->coding_type) {
case coding_PCM16LE:
case coding_PCM16_int: block_samples = pcm16_bytes_to_samples(vgmstream->current_block_size, 1); break;
case coding_PCM8_int:
case coding_PCM8_U_int: block_samples = pcm8_bytes_to_samples(vgmstream->current_block_size, 1); break;
case coding_XBOX_IMA_mono:
case coding_XBOX_IMA: block_samples = xbox_ima_bytes_to_samples(vgmstream->current_block_size, 1); break;
case coding_NGC_DSP: block_samples = dsp_bytes_to_samples(vgmstream->current_block_size, 1); break;
case coding_PSX: block_samples = ps_bytes_to_samples(vgmstream->current_block_size,1); break;
default:
VGM_LOG("BLOCKED: missing codec\n");
return;
}
}
vgmstream->num_samples += block_samples;
}
while (vgmstream->next_block_offset < max_offset);
block_update(cfg->offset, vgmstream); /* reset */
}

View File

@ -22,4 +22,11 @@ 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);
typedef struct {
off_t offset;
} blocked_counter_t;
void blocked_count_samples(VGMSTREAM* vgmstream, STREAMFILE* sf, blocked_counter_t* cfg);
#endif

View File

@ -89,7 +89,6 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_str_sega,
init_vgmstream_str_sega_custom,
init_vgmstream_dec,
init_vgmstream_vs,
init_vgmstream_xmu,
init_vgmstream_xvas,
init_vgmstream_sat_sap,
@ -526,6 +525,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_rage_aud,
init_vgmstream_asd_naxat,
init_vgmstream_pcm_kceje,
init_vgmstream_vs_mh,
/* need companion files */
init_vgmstream_pos,
init_vgmstream_sli_loops,

View File

@ -208,7 +208,7 @@ typedef enum {
layout_blocked_ws_aud,
layout_blocked_dec,
layout_blocked_xvas,
layout_blocked_vs,
layout_blocked_vs_mh,
layout_blocked_mul,
layout_blocked_gsb,
layout_blocked_thp,
@ -427,7 +427,7 @@ typedef enum {
meta_ACM, /* InterPlay ACM header */
meta_MUS_ACM, /* MUS playlist of InterPlay ACM files */
meta_DEC, /* Falcom PC games (Xanadu Next, Gurumin) */
meta_VS, /* Men in Black .vs */
meta_VS_MH,
meta_BGW,
meta_SPW,
meta_STS,