mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-31 04:13:47 +01:00
debug decoder stuff
This commit is contained in:
parent
edcfe5b16d
commit
c1520530a7
@ -6,10 +6,34 @@
|
|||||||
#include "plugins.h"
|
#include "plugins.h"
|
||||||
#include "sbuf.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 */
|
/* custom codec handling, not exactly "decode" stuff but here to simplify adding new codecs */
|
||||||
|
|
||||||
|
|
||||||
void decode_free(VGMSTREAM* vgmstream) {
|
void decode_free(VGMSTREAM* vgmstream) {
|
||||||
|
#if VGM_TEST_DECODER
|
||||||
|
free(vgmstream->decode_state);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!vgmstream->codec_data)
|
if (!vgmstream->codec_data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -127,6 +151,10 @@ void decode_free(VGMSTREAM* vgmstream) {
|
|||||||
|
|
||||||
|
|
||||||
void decode_seek(VGMSTREAM* vgmstream) {
|
void decode_seek(VGMSTREAM* vgmstream) {
|
||||||
|
#if VGM_TEST_DECODER
|
||||||
|
decode_state_reset(vgmstream);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!vgmstream->codec_data)
|
if (!vgmstream->codec_data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -228,6 +256,10 @@ void decode_seek(VGMSTREAM* vgmstream) {
|
|||||||
|
|
||||||
|
|
||||||
void decode_reset(VGMSTREAM* vgmstream) {
|
void decode_reset(VGMSTREAM* vgmstream) {
|
||||||
|
#if VGM_TEST_DECODER
|
||||||
|
decode_state_reset(vgmstream);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!vgmstream->codec_data)
|
if (!vgmstream->codec_data)
|
||||||
return;
|
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;
|
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
|
/* 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
|
* 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).
|
* more than one frame if configured above to do so).
|
||||||
* Called by layouts since they handle samples written/to_do */
|
* 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) {
|
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;
|
int ch;
|
||||||
|
|
||||||
buffer += samples_filled * vgmstream->channels; /* passed externally to simplify I guess */
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
|
#if VGM_TEST_DECODER
|
||||||
|
decode_frames(sbuf, vgmstream);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
#include "../vgmstream.h"
|
#include "../vgmstream.h"
|
||||||
|
|
||||||
|
#if VGM_TEST_DECODER
|
||||||
|
void* decode_init();
|
||||||
|
#endif
|
||||||
void decode_free(VGMSTREAM* vgmstream);
|
void decode_free(VGMSTREAM* vgmstream);
|
||||||
void decode_seek(VGMSTREAM* vgmstream);
|
void decode_seek(VGMSTREAM* vgmstream);
|
||||||
void decode_reset(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);
|
tac_codec_data* init_tac(STREAMFILE* sf);
|
||||||
void decode_tac(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do);
|
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 reset_tac(tac_codec_data* data);
|
||||||
void seek_tac(tac_codec_data* data, int32_t num_sample);
|
void seek_tac(tac_codec_data* data, int32_t num_sample);
|
||||||
void free_tac(tac_codec_data* data);
|
void free_tac(tac_codec_data* data);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "coding.h"
|
#include "coding.h"
|
||||||
#include "coding_utils_samples.h"
|
#include "coding_utils_samples.h"
|
||||||
|
#if VGM_TEST_DECODER
|
||||||
|
#include "../base/decode_state.h"
|
||||||
|
#endif
|
||||||
#include "libs/tac_lib.h"
|
#include "libs/tac_lib.h"
|
||||||
|
|
||||||
|
|
||||||
@ -129,6 +131,34 @@ fail:
|
|||||||
s16buf_silence(&outbuf, &samples_to_do, data->sbuf.channels);
|
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) {
|
void reset_tac(tac_codec_data* data) {
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
@ -242,6 +242,9 @@ typedef struct {
|
|||||||
void* tmpbuf; /* garbage buffer used for seeking/trimming */
|
void* tmpbuf; /* garbage buffer used for seeking/trimming */
|
||||||
size_t tmpbuf_size; /* for all channels (samples = tmpbuf_size / channels / sample_size) */
|
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;
|
} VGMSTREAM;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user