mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-12-01 09:37:21 +01:00
Update EA-MT API a bit
This commit is contained in:
parent
47b5a189cf
commit
a3f2231ba1
@ -17,7 +17,12 @@
|
|||||||
#define UTK_MAX(x,y) ((x)>(y)?(x):(y))
|
#define UTK_MAX(x,y) ((x)>(y)?(x):(y))
|
||||||
#define UTK_CLAMP(x,min,max) UTK_MIN(UTK_MAX(x,min),max)
|
#define UTK_CLAMP(x,min,max) UTK_MIN(UTK_MAX(x,min),max)
|
||||||
|
|
||||||
|
#define UTK_BUFFER_SIZE 0x1000
|
||||||
|
|
||||||
struct ea_mt_codec_data {
|
struct ea_mt_codec_data {
|
||||||
|
STREAMFILE *streamfile;
|
||||||
|
uint8_t buffer[UTK_BUFFER_SIZE];
|
||||||
|
off_t offset;
|
||||||
int pcm_blocks;
|
int pcm_blocks;
|
||||||
int samples_filled;
|
int samples_filled;
|
||||||
int samples_used;
|
int samples_used;
|
||||||
@ -27,6 +32,8 @@ struct ea_mt_codec_data {
|
|||||||
void* utk_context;
|
void* utk_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static size_t ea_mt_read_callback(void *dest, int size, void *arg);
|
||||||
|
|
||||||
|
|
||||||
ea_mt_codec_data *init_ea_mt(int channels, int pcm_blocks, int reset_sample) {
|
ea_mt_codec_data *init_ea_mt(int channels, int pcm_blocks, int reset_sample) {
|
||||||
ea_mt_codec_data *data = NULL;
|
ea_mt_codec_data *data = NULL;
|
||||||
@ -42,6 +49,8 @@ ea_mt_codec_data *init_ea_mt(int channels, int pcm_blocks, int reset_sample) {
|
|||||||
|
|
||||||
data[i].pcm_blocks = pcm_blocks;
|
data[i].pcm_blocks = pcm_blocks;
|
||||||
data[i].reset_sample = reset_sample;
|
data[i].reset_sample = reset_sample;
|
||||||
|
|
||||||
|
utk_set_callback(data[i].utk_context, data[i].buffer, UTK_BUFFER_SIZE, &data[i], &ea_mt_read_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
@ -121,7 +130,6 @@ void decode_ea_mt(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, in
|
|||||||
static void flush_ea_mt_offsets(VGMSTREAM *vgmstream, int is_start, int samples_discard) {
|
static void flush_ea_mt_offsets(VGMSTREAM *vgmstream, int is_start, int samples_discard) {
|
||||||
ea_mt_codec_data *data = vgmstream->codec_data;
|
ea_mt_codec_data *data = vgmstream->codec_data;
|
||||||
int i;
|
int i;
|
||||||
size_t bytes;
|
|
||||||
|
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
@ -133,20 +141,16 @@ static void flush_ea_mt_offsets(VGMSTREAM *vgmstream, int is_start, int samples_
|
|||||||
for (i = 0; i < vgmstream->channels; i++) {
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
UTKContext* ctx = data[i].utk_context;
|
UTKContext* ctx = data[i].utk_context;
|
||||||
|
|
||||||
ctx->streamfile = vgmstream->ch[i].streamfile; /* maybe should keep its own STREAMFILE? */
|
data[i].streamfile = vgmstream->ch[i].streamfile; /* maybe should keep its own STREAMFILE? */
|
||||||
if (is_start)
|
if (is_start)
|
||||||
ctx->offset = vgmstream->ch[i].channel_start_offset;
|
data[i].offset = vgmstream->ch[i].channel_start_offset;
|
||||||
else
|
else
|
||||||
ctx->offset = vgmstream->ch[i].offset;
|
data[i].offset = vgmstream->ch[i].offset;
|
||||||
//todo no need to read, allow to do it manually?
|
|
||||||
bytes = read_streamfile(ctx->buffer,ctx->offset,sizeof(ctx->buffer),ctx->streamfile);
|
|
||||||
ctx->offset = ctx->offset + bytes;
|
|
||||||
|
|
||||||
ctx->ptr = ctx->buffer;
|
utk_set_ptr(ctx, 0, 0); /* reset the buffer reader */
|
||||||
ctx->end = ctx->buffer + bytes;
|
|
||||||
ctx->bits_count = 0;
|
|
||||||
|
|
||||||
if (is_start) {
|
if (is_start) {
|
||||||
|
//utk_reset(ctx); //todo
|
||||||
ctx->parsed_header = 0;
|
ctx->parsed_header = 0;
|
||||||
data[i].samples_done = 0;
|
data[i].samples_done = 0;
|
||||||
}
|
}
|
||||||
@ -179,3 +183,16 @@ void free_ea_mt(ea_mt_codec_data *data, int channels) {
|
|||||||
}
|
}
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ********************** */
|
||||||
|
|
||||||
|
static size_t ea_mt_read_callback(void *dest, int size, void *arg) {
|
||||||
|
ea_mt_codec_data *ch_data = arg;
|
||||||
|
int bytes_read;
|
||||||
|
|
||||||
|
bytes_read = read_streamfile(dest,ch_data->offset,size,ch_data->streamfile);
|
||||||
|
ch_data->offset += bytes_read;
|
||||||
|
|
||||||
|
return bytes_read;
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -7,11 +7,10 @@
|
|||||||
/* Note: This struct assumes a member alignment of 4 bytes.
|
/* Note: This struct assumes a member alignment of 4 bytes.
|
||||||
** This matters when pitch_lag > 216 on the first subframe of any given frame. */
|
** This matters when pitch_lag > 216 on the first subframe of any given frame. */
|
||||||
typedef struct UTKContext {
|
typedef struct UTKContext {
|
||||||
uint8_t buffer[4096]; //vgmstream extra
|
uint8_t *buffer;
|
||||||
STREAMFILE * streamfile; //vgmstream extra
|
size_t buffer_size;
|
||||||
unsigned int offset; //vgmstream extra
|
void *arg;
|
||||||
|
size_t (*read_callback)(void *dest, int size, void *arg);
|
||||||
FILE *fp;
|
|
||||||
const uint8_t *ptr, *end;
|
const uint8_t *ptr, *end;
|
||||||
|
|
||||||
int parsed_header;
|
int parsed_header;
|
||||||
@ -131,14 +130,9 @@ static int utk_read_byte(UTKContext *ctx)
|
|||||||
if (ctx->ptr < ctx->end)
|
if (ctx->ptr < ctx->end)
|
||||||
return *ctx->ptr++;
|
return *ctx->ptr++;
|
||||||
|
|
||||||
//vgmstream extra: this reads from FILE if static buffer was exhausted, now from a context buffer and STREAMFILE instead
|
if (ctx->read_callback) {
|
||||||
if (ctx->streamfile) { //if (ctx->fp) {
|
size_t bytes_copied = ctx->read_callback(ctx->buffer, ctx->buffer_size, ctx->arg);
|
||||||
//static uint8_t buffer[4096];
|
if (bytes_copied > 0 && bytes_copied <= ctx->buffer_size) {
|
||||||
//size_t bytes_copied = fread(buffer, 1, sizeof(buffer), ctx->fp);
|
|
||||||
size_t bytes_copied = read_streamfile(ctx->buffer, ctx->offset, sizeof(ctx->buffer), ctx->streamfile);
|
|
||||||
|
|
||||||
ctx->offset += bytes_copied;
|
|
||||||
if (bytes_copied > 0 && bytes_copied <= sizeof(ctx->buffer)) {
|
|
||||||
ctx->ptr = ctx->buffer;
|
ctx->ptr = ctx->buffer;
|
||||||
ctx->end = ctx->buffer + bytes_copied;
|
ctx->end = ctx->buffer + bytes_copied;
|
||||||
return *ctx->ptr++;
|
return *ctx->ptr++;
|
||||||
@ -394,9 +388,10 @@ static void utk_init(UTKContext *ctx)
|
|||||||
memset(ctx, 0, sizeof(*ctx));
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void utk_reset(UTKContext *ctx) //vgmstream extra
|
static void utk_reset(UTKContext *ctx)
|
||||||
{
|
{
|
||||||
/* resets the internal state, leaving the external config/buffers set */
|
/* resets the internal state, leaving the external config/buffers
|
||||||
|
* untouched (could be reset externally or using utk_set_x) */
|
||||||
ctx->parsed_header = 0;
|
ctx->parsed_header = 0;
|
||||||
ctx->bits_value = 0;
|
ctx->bits_value = 0;
|
||||||
ctx->bits_count = 0;
|
ctx->bits_count = 0;
|
||||||
@ -408,10 +403,14 @@ static void utk_reset(UTKContext *ctx) //vgmstream extra
|
|||||||
memset(ctx->adapt_cb, 0, sizeof(ctx->adapt_cb));
|
memset(ctx->adapt_cb, 0, sizeof(ctx->adapt_cb));
|
||||||
memset(ctx->decompressed_frame, 0, sizeof(ctx->decompressed_frame));
|
memset(ctx->decompressed_frame, 0, sizeof(ctx->decompressed_frame));
|
||||||
}
|
}
|
||||||
#if 0 //vgmstream extra
|
|
||||||
static void utk_set_fp(UTKContext *ctx, FILE *fp)
|
static void utk_set_callback(UTKContext *ctx, uint8_t *buffer, size_t buffer_size, void *arg, size_t (*read_callback)(void *, int , void *))
|
||||||
{
|
{
|
||||||
ctx->fp = fp;
|
/* prepares for external reading */
|
||||||
|
ctx->buffer = buffer;
|
||||||
|
ctx->buffer_size = buffer_size;
|
||||||
|
ctx->arg = arg;
|
||||||
|
ctx->read_callback = read_callback;
|
||||||
|
|
||||||
/* reset the bit reader */
|
/* reset the bit reader */
|
||||||
ctx->bits_count = 0;
|
ctx->bits_count = 0;
|
||||||
@ -419,13 +418,14 @@ static void utk_set_fp(UTKContext *ctx, FILE *fp)
|
|||||||
|
|
||||||
static void utk_set_ptr(UTKContext *ctx, const uint8_t *ptr, const uint8_t *end)
|
static void utk_set_ptr(UTKContext *ctx, const uint8_t *ptr, const uint8_t *end)
|
||||||
{
|
{
|
||||||
|
/* sets the pointer to an external data buffer (can also be used to
|
||||||
|
* reset the buffered data if set to ptr/end 0) */
|
||||||
ctx->ptr = ptr;
|
ctx->ptr = ptr;
|
||||||
ctx->end = end;
|
ctx->end = end;
|
||||||
|
|
||||||
/* reset the bit reader */
|
/* reset the bit reader */
|
||||||
ctx->bits_count = 0;
|
ctx->bits_count = 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** MicroTalk Revision 3 decoding function.
|
** MicroTalk Revision 3 decoding function.
|
||||||
@ -453,34 +453,17 @@ static int utk_rev3_decode_frame(UTKContext *ctx)
|
|||||||
** crafted MT5:1 file can crash sx.exe.
|
** crafted MT5:1 file can crash sx.exe.
|
||||||
** We will throw an error instead. */
|
** We will throw an error instead. */
|
||||||
if (offset < 0 || offset > 432) {
|
if (offset < 0 || offset > 432) {
|
||||||
//fprintf(stderr, "error: invalid PCM offset %d\n", offset);
|
return -1; /* invalid PCM offset */
|
||||||
//exit(EXIT_FAILURE);
|
|
||||||
return -1; //vgmstream extra
|
|
||||||
}
|
}
|
||||||
if (count < 0 || count > 432 - offset) {
|
if (count < 0 || count > 432 - offset) {
|
||||||
//fprintf(stderr, "error: invalid PCM count %d\n", count);
|
return -2; /* invalid PCM count */
|
||||||
//exit(EXIT_FAILURE);
|
|
||||||
return -2; //vgmstream extra
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
ctx->decompressed_frame[offset+i] = (float)utk_read_i16(ctx);
|
ctx->decompressed_frame[offset+i] = (float)utk_read_i16(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; //vgmstream extra
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 //vgmstream extra
|
|
||||||
static const char * utk_get_error_string(int error)
|
|
||||||
{
|
|
||||||
switch(error) {
|
|
||||||
case -1:
|
|
||||||
return "invalid rev3 PCM offset";
|
|
||||||
case -2:
|
|
||||||
return "invalid rev3 PCM count";
|
|
||||||
default:
|
|
||||||
return "unknown error";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* _EA_MT_DECODER_UTK_H_ */
|
#endif /* _EA_MT_DECODER_UTK_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user