Remove custom ATRAC9 in favor of custom IO

Formats using custom layouts tend to be weird enough that it's a pain to
add support directly in the decoder.
Instead should use custom layouts and I/O streamfiles that, though a bit
wordy and unwieldy at the moment, are a lot more flexible.
This commit is contained in:
bnnm 2018-08-25 17:48:01 +02:00
parent f86c90c5f9
commit a734e9c5cb
3 changed files with 21 additions and 63 deletions

View File

@ -4,6 +4,22 @@
#include "libatrac9.h"
/* opaque struct */
struct atrac9_codec_data {
uint8_t *data_buffer;
size_t data_buffer_size;
sample *sample_buffer;
size_t samples_filled; /* number of samples in the buffer */
size_t samples_used; /* number of samples extracted from the buffer */
int samples_to_discard;
atrac9_config config;
void *handle; /* decoder handle */
};
atrac9_codec_data *init_atrac9(atrac9_config *cfg) {
int status;
uint8_t config_data[4];
@ -93,23 +109,6 @@ void decode_atrac9(VGMSTREAM *vgmstream, sample * outbuf, int32_t samples_to_do,
status = Atrac9GetCodecInfo(data->handle, &info);
if (status < 0) goto decode_fail;
/* preadjust */ //todo improve
switch(data->config.type) {
case ATRAC9_XVAG:
/* PS4 (ex. The Last of Us) has a RIFF AT9 (can be ignored) instead of the first superframe.
* As subsongs do too, needs to be skipped here instead of adjusting start_offset */
if (stream->offset == stream->channel_start_offset) {
if (read_32bitBE(stream->offset, stream->streamfile) == 0x00000000 /* padding before RIFF */
&& read_32bitBE(stream->offset + info.superframeSize - 0x08,stream->streamfile) == 0x64617461) { /* RIFF's "data" */
stream->offset += info.superframeSize;
}
}
break;
default:
break;
}
/* read one raw block (superframe) and advance offsets */
bytes = read_streamfile(data->data_buffer,stream->offset, info.superframeSize,stream->streamfile);
if (bytes != data->data_buffer_size) {
@ -119,20 +118,6 @@ void decode_atrac9(VGMSTREAM *vgmstream, sample * outbuf, int32_t samples_to_do,
stream->offset += bytes;
/* postadjust */ //todo improve
switch(data->config.type) {
case ATRAC9_XVAG:
case ATRAC9_KMA9:
/* skip other subsong blocks */
if (data->config.interleave_skip && ((stream->offset - stream->channel_start_offset) % data->config.interleave_skip == 0)) {
stream->offset += data->config.interleave_skip * (data->config.subsong_skip - 1);
}
break;
default:
break;
}
/* decode all frames in the superframe block */
for (iframe = 0; iframe < info.framesInSuperframe; iframe++) {
status = Atrac9Decode(data->handle, buffer, data->sample_buffer + data->samples_filled*channels, &bytes_used);

View File

@ -47,7 +47,6 @@ VGMSTREAM * init_vgmstream_kma9(STREAMFILE *streamFile) {
{
atrac9_config cfg = {0};
cfg.type = ATRAC9_DEFAULT;
cfg.channels = vgmstream->channels;
cfg.encoder_delay = read_32bitLE(0x20,streamFile);
cfg.config_data = read_32bitBE(0x5c,streamFile);

View File

@ -1019,39 +1019,13 @@ typedef struct {
#endif
#ifdef VGM_USE_ATRAC9
/* custom ATRAC9 modes */
typedef enum {
ATRAC9_DEFAULT = 0, /* ATRAC9 standard */
ATRAC9_XVAG, /* Sony XVAG: interleaved subsongs, Vita multichannel interleaves 2ch xN superframes */
ATRAC9_KMA9, /* Koei Tecmo KMA9: interleaved subsongs */
} atrac9_custom_t;
/* ATRAC9 config */
typedef struct {
atrac9_custom_t type;
int channels; /* to detect weird multichannel */
uint32_t config_data; /* ATRAC9 config header */
int encoder_delay; /* initial samples to discard */
size_t interleave_skip; /* XVAG */
size_t subsong_skip; /* XVAG */
int channels; /* to detect weird multichannel */
uint32_t config_data; /* ATRAC9 config header */
int encoder_delay; /* initial samples to discard */
} atrac9_config;
typedef struct {
uint8_t *data_buffer;
size_t data_buffer_size;
sample *sample_buffer;
size_t samples_filled; /* number of samples in the buffer */
size_t samples_used; /* number of samples extracted from the buffer */
int samples_to_discard;
atrac9_config config;
void *handle; /* decoder handle */
} atrac9_codec_data;
typedef struct atrac9_codec_data atrac9_codec_data;
#endif
#ifdef VGM_USE_CELT