mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-18 07:44:43 +01:00
debug decoder stuff
This commit is contained in:
parent
edcfe5b16d
commit
c1520530a7
@ -6,10 +6,34 @@
|
||||
#include "plugins.h"
|
||||
#include "sbuf.h"
|
||||
|
||||
#if VGM_TEST_DECODER
|
||||
#include "../util/log.h"
|
||||
#include "decode_state.h"
|
||||
|
||||
|
||||
static void* decode_state_init() {
|
||||
return calloc(1, sizeof(decode_state_t));
|
||||
}
|
||||
|
||||
static void decode_state_reset(VGMSTREAM* vgmstream) {
|
||||
memset(vgmstream->decode_state, 0, sizeof(decode_state_t));
|
||||
}
|
||||
|
||||
// this could be part of the VGMSTREAM but for now keep separate as it simplifies
|
||||
// some loop-related stuff
|
||||
void* decode_init() {
|
||||
return decode_state_init();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* custom codec handling, not exactly "decode" stuff but here to simplify adding new codecs */
|
||||
|
||||
|
||||
void decode_free(VGMSTREAM* vgmstream) {
|
||||
#if VGM_TEST_DECODER
|
||||
free(vgmstream->decode_state);
|
||||
#endif
|
||||
|
||||
if (!vgmstream->codec_data)
|
||||
return;
|
||||
|
||||
@ -127,6 +151,10 @@ void decode_free(VGMSTREAM* vgmstream) {
|
||||
|
||||
|
||||
void decode_seek(VGMSTREAM* vgmstream) {
|
||||
#if VGM_TEST_DECODER
|
||||
decode_state_reset(vgmstream);
|
||||
#endif
|
||||
|
||||
if (!vgmstream->codec_data)
|
||||
return;
|
||||
|
||||
@ -228,6 +256,10 @@ void decode_seek(VGMSTREAM* vgmstream) {
|
||||
|
||||
|
||||
void decode_reset(VGMSTREAM* vgmstream) {
|
||||
#if VGM_TEST_DECODER
|
||||
decode_state_reset(vgmstream);
|
||||
#endif
|
||||
|
||||
if (!vgmstream->codec_data)
|
||||
return;
|
||||
|
||||
@ -825,11 +857,74 @@ bool decode_uses_internal_offset_updates(VGMSTREAM* vgmstream) {
|
||||
return vgmstream->coding_type == coding_MS_IMA || vgmstream->coding_type == coding_MS_IMA_mono;
|
||||
}
|
||||
|
||||
#if VGM_TEST_DECODER
|
||||
// decode frames for decoders which have their own sample buffer
|
||||
static void decode_frames(sbuf_t* sbuf, VGMSTREAM* vgmstream) {
|
||||
const int max_empty = 10000;
|
||||
int num_empty = 0;
|
||||
|
||||
decode_state_t* ds = vgmstream->decode_state;
|
||||
|
||||
while (sbuf->filled < sbuf->samples) {
|
||||
|
||||
// decode new frame if all was consumed
|
||||
if (ds->sbuf.filled == 0) {
|
||||
bool ok = false;
|
||||
switch (vgmstream->coding_type) {
|
||||
case coding_TAC:
|
||||
ok = decode_tac_frame(vgmstream);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
goto decode_fail;
|
||||
}
|
||||
|
||||
if (ds->discard) {
|
||||
// decode may signal that decoded samples need to be discarded, because of encoder delay
|
||||
// (first samples of a file need to be ignored) or a loop
|
||||
int current_discard = ds->discard;
|
||||
if (current_discard > ds->sbuf.filled)
|
||||
current_discard = ds->sbuf.filled;
|
||||
|
||||
sbuf_consume(&ds->sbuf, current_discard);
|
||||
|
||||
ds->discard -= current_discard;
|
||||
}
|
||||
else {
|
||||
// copy + consume
|
||||
int samples_copy = ds->sbuf.filled;
|
||||
if (samples_copy > sbuf->samples - sbuf->filled)
|
||||
samples_copy = sbuf->samples - sbuf->filled;
|
||||
|
||||
sbuf_copy_segments(sbuf, &ds->sbuf);
|
||||
sbuf_consume(&ds->sbuf, samples_copy);
|
||||
|
||||
sbuf->filled += samples_copy;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
decode_fail:
|
||||
/* on error just put some 0 samples */
|
||||
VGM_LOG("VGMSTREAM: decode fail, missing %i samples\n", sbuf->samples - sbuf->filled);
|
||||
sbuf_silence_rest(sbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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 */
|
||||
void decode_vgmstream(VGMSTREAM* vgmstream, int samples_filled, int samples_to_do, sample_t* buffer) {
|
||||
#if VGM_TEST_DECODER
|
||||
sbuf_t sbuf_tmp = {0};
|
||||
sbuf_t* sbuf = &sbuf_tmp;
|
||||
sbuf_init_s16(sbuf, buffer, samples_filled + samples_to_do, vgmstream->channels);
|
||||
sbuf->filled = samples_filled;
|
||||
#endif
|
||||
int ch;
|
||||
|
||||
buffer += samples_filled * vgmstream->channels; /* passed externally to simplify I guess */
|
||||
@ -1566,6 +1661,9 @@ void decode_vgmstream(VGMSTREAM* vgmstream, int samples_filled, int samples_to_d
|
||||
}
|
||||
break;
|
||||
default:
|
||||
#if VGM_TEST_DECODER
|
||||
decode_frames(sbuf, vgmstream);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,9 @@
|
||||
|
||||
#include "../vgmstream.h"
|
||||
|
||||
#if VGM_TEST_DECODER
|
||||
void* decode_init();
|
||||
#endif
|
||||
void decode_free(VGMSTREAM* vgmstream);
|
||||
void decode_seek(VGMSTREAM* vgmstream);
|
||||
void decode_reset(VGMSTREAM* vgmstream);
|
||||
|
13
src/base/decode_state.h
Normal file
13
src/base/decode_state.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef _DECODE_STATE_H
|
||||
#define _DECODE_STATE_H
|
||||
|
||||
#if VGM_TEST_DECODER
|
||||
#include "sbuf.h"
|
||||
|
||||
typedef struct {
|
||||
int discard;
|
||||
sbuf_t sbuf;
|
||||
} decode_state_t;
|
||||
#endif
|
||||
|
||||
#endif
|
@ -372,6 +372,9 @@ typedef struct tac_codec_data tac_codec_data;
|
||||
|
||||
tac_codec_data* init_tac(STREAMFILE* sf);
|
||||
void decode_tac(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do);
|
||||
#if VGM_TEST_DECODER
|
||||
bool decode_tac_frame(VGMSTREAM* vgmstream);
|
||||
#endif
|
||||
void reset_tac(tac_codec_data* data);
|
||||
void seek_tac(tac_codec_data* data, int32_t num_sample);
|
||||
void free_tac(tac_codec_data* data);
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "coding.h"
|
||||
#include "coding_utils_samples.h"
|
||||
|
||||
#if VGM_TEST_DECODER
|
||||
#include "../base/decode_state.h"
|
||||
#endif
|
||||
#include "libs/tac_lib.h"
|
||||
|
||||
|
||||
@ -129,6 +131,34 @@ fail:
|
||||
s16buf_silence(&outbuf, &samples_to_do, data->sbuf.channels);
|
||||
}
|
||||
|
||||
#if VGM_TEST_DECODER
|
||||
bool decode_tac_frame(VGMSTREAM* vgmstream) {
|
||||
VGMSTREAMCHANNEL* stream = &vgmstream->ch[0];
|
||||
tac_codec_data* data = vgmstream->codec_data;
|
||||
decode_state_t* ds = vgmstream->decode_state;
|
||||
|
||||
sbuf_init_s16(&ds->sbuf, data->samples, TAC_FRAME_SAMPLES, vgmstream->channels);
|
||||
|
||||
bool ok;
|
||||
|
||||
ok = read_frame(data, stream->streamfile);
|
||||
if (!ok) return false;
|
||||
|
||||
ok = decode_frame(data);
|
||||
if (!ok) return false;
|
||||
|
||||
ds->sbuf.filled = TAC_FRAME_SAMPLES; //TODO call sbuf_fill(samples);
|
||||
|
||||
// copy and let decoder handle
|
||||
if (data->samples_discard) {
|
||||
ds->discard = data->samples_discard;
|
||||
data->samples_discard = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void reset_tac(tac_codec_data* data) {
|
||||
if (!data) return;
|
||||
|
@ -242,6 +242,9 @@ typedef struct {
|
||||
void* tmpbuf; /* garbage buffer used for seeking/trimming */
|
||||
size_t tmpbuf_size; /* for all channels (samples = tmpbuf_size / channels / sample_size) */
|
||||
|
||||
#if VGM_TEST_DECODER
|
||||
void* decode_state; /* for some decoders (TO-DO: to be mover around) */
|
||||
#endif
|
||||
} VGMSTREAM;
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user