From a3f2231ba1d618d698df31ab874263e8d1a5f7ed Mon Sep 17 00:00:00 2001 From: bnnm Date: Sun, 9 Sep 2018 00:51:35 +0200 Subject: [PATCH] Update EA-MT API a bit --- src/coding/ea_mt_decoder.c | 37 +++++++++++++++------ src/coding/ea_mt_decoder_utk.h | 61 ++++++++++++---------------------- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/coding/ea_mt_decoder.c b/src/coding/ea_mt_decoder.c index 8b2f644f..7f7e0183 100644 --- a/src/coding/ea_mt_decoder.c +++ b/src/coding/ea_mt_decoder.c @@ -17,7 +17,12 @@ #define UTK_MAX(x,y) ((x)>(y)?(x):(y)) #define UTK_CLAMP(x,min,max) UTK_MIN(UTK_MAX(x,min),max) +#define UTK_BUFFER_SIZE 0x1000 + struct ea_mt_codec_data { + STREAMFILE *streamfile; + uint8_t buffer[UTK_BUFFER_SIZE]; + off_t offset; int pcm_blocks; int samples_filled; int samples_used; @@ -27,6 +32,8 @@ struct ea_mt_codec_data { 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 *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].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; @@ -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) { ea_mt_codec_data *data = vgmstream->codec_data; int i; - size_t bytes; 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++) { 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) - ctx->offset = vgmstream->ch[i].channel_start_offset; + data[i].offset = vgmstream->ch[i].channel_start_offset; else - ctx->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; + data[i].offset = vgmstream->ch[i].offset; - ctx->ptr = ctx->buffer; - ctx->end = ctx->buffer + bytes; - ctx->bits_count = 0; + utk_set_ptr(ctx, 0, 0); /* reset the buffer reader */ if (is_start) { + //utk_reset(ctx); //todo ctx->parsed_header = 0; data[i].samples_done = 0; } @@ -179,3 +183,16 @@ void free_ea_mt(ea_mt_codec_data *data, int channels) { } 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; + +} diff --git a/src/coding/ea_mt_decoder_utk.h b/src/coding/ea_mt_decoder_utk.h index 624d84b4..3034bc94 100644 --- a/src/coding/ea_mt_decoder_utk.h +++ b/src/coding/ea_mt_decoder_utk.h @@ -7,11 +7,10 @@ /* Note: This struct assumes a member alignment of 4 bytes. ** This matters when pitch_lag > 216 on the first subframe of any given frame. */ typedef struct UTKContext { - uint8_t buffer[4096]; //vgmstream extra - STREAMFILE * streamfile; //vgmstream extra - unsigned int offset; //vgmstream extra - - FILE *fp; + uint8_t *buffer; + size_t buffer_size; + void *arg; + size_t (*read_callback)(void *dest, int size, void *arg); const uint8_t *ptr, *end; int parsed_header; @@ -131,14 +130,9 @@ static int utk_read_byte(UTKContext *ctx) if (ctx->ptr < ctx->end) return *ctx->ptr++; - //vgmstream extra: this reads from FILE if static buffer was exhausted, now from a context buffer and STREAMFILE instead - if (ctx->streamfile) { //if (ctx->fp) { - //static uint8_t buffer[4096]; - //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)) { + if (ctx->read_callback) { + size_t bytes_copied = ctx->read_callback(ctx->buffer, ctx->buffer_size, ctx->arg); + if (bytes_copied > 0 && bytes_copied <= ctx->buffer_size) { ctx->ptr = ctx->buffer; ctx->end = ctx->buffer + bytes_copied; return *ctx->ptr++; @@ -394,9 +388,10 @@ static void utk_init(UTKContext *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->bits_value = 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->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 */ 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) { + /* 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->end = end; /* reset the bit reader */ ctx->bits_count = 0; } -#endif /* ** 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. ** We will throw an error instead. */ if (offset < 0 || offset > 432) { - //fprintf(stderr, "error: invalid PCM offset %d\n", offset); - //exit(EXIT_FAILURE); - return -1; //vgmstream extra + return -1; /* invalid PCM offset */ } if (count < 0 || count > 432 - offset) { - //fprintf(stderr, "error: invalid PCM count %d\n", count); - //exit(EXIT_FAILURE); - return -2; //vgmstream extra + return -2; /* invalid PCM count */ } for (i = 0; i < count; i++) 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_ */