Add AAX HCA [Binary Domain (PS3)]

This commit is contained in:
bnnm 2018-03-10 17:33:48 +01:00
parent 3ad6261208
commit 66c9a06351
4 changed files with 66 additions and 32 deletions

View File

@ -26,7 +26,8 @@ fail:
void render_vgmstream_aax(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream) { void render_vgmstream_aax(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream) {
int samples_written=0; int samples_written=0;
aax_codec_data *data = vgmstream->codec_data; aax_codec_data *data = vgmstream->layout_data;
//int samples_per_frame = get_vgmstream_samples_per_frame(vgmstream);
while (samples_written<sample_count) { while (samples_written<sample_count) {
int samples_to_do; int samples_to_do;
@ -55,8 +56,6 @@ void render_vgmstream_aax(sample * buffer, int32_t sample_count, VGMSTREAM * vgm
samples_to_do = vgmstream_samples_to_do(samples_this_block, 1, vgmstream); samples_to_do = vgmstream_samples_to_do(samples_this_block, 1, vgmstream);
/*printf("samples_to_do=%d,samples_this_block=%d,samples_written=%d,sample_count=%d\n",samples_to_do,samples_this_block,samples_written,sample_count);*/
if (samples_written+samples_to_do > sample_count) if (samples_written+samples_to_do > sample_count)
samples_to_do=sample_count-samples_written; samples_to_do=sample_count-samples_written;
@ -64,7 +63,6 @@ void render_vgmstream_aax(sample * buffer, int32_t sample_count, VGMSTREAM * vgm
{ {
int i; int i;
data->current_segment++; data->current_segment++;
/*printf("advance to %d at %d samples\n",data->current_segment,vgmstream->current_sample);*/
reset_vgmstream(data->segments[data->current_segment]); reset_vgmstream(data->segments[data->current_segment]);
/* carry over the history from the previous segment */ /* carry over the history from the previous segment */

View File

@ -1,17 +1,17 @@
#include "meta.h" #include "meta.h"
#include "../layout/layout.h" #include "../layout/layout.h"
#include "../coding/coding.h" #include "../coding/coding.h"
#include "aax_streamfile.h"
#include "aax_utf.h" #include "aax_utf.h"
static STREAMFILE* setup_aax_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size, const char* fake_ext);
#define MAX_SEGMENTS 2 /* usually segment0=intro, segment1=loop/main */ #define MAX_SEGMENTS 2 /* usually segment0=intro, segment1=loop/main */
/* AAX - segmented ADX [Bayonetta (PS3), Pandora's Tower (Wii), Catherine (X360), Binary Domain (PS3)] */ /* AAX - segmented ADX [Bayonetta (PS3), Pandora's Tower (Wii), Catherine (X360), Binary Domain (PS3)] */
VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT]; int is_hca;
STREAMFILE * streamFileAAX = NULL;
int loop_flag = 0, channel_count = 0; int loop_flag = 0, channel_count = 0;
int32_t sample_count, loop_start_sample = 0, loop_end_sample = 0; int32_t sample_count, loop_start_sample = 0, loop_end_sample = 0;
@ -51,7 +51,12 @@ VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile) {
if (result.name_offset+0x04 > aax_string_table_size) if (result.name_offset+0x04 > aax_string_table_size)
goto fail; goto fail;
if (read_32bitBE(aax_string_table_offset + result.name_offset, streamFile) != 0x41415800) /* "AAX\0" */
if (read_32bitBE(aax_string_table_offset + result.name_offset, streamFile) == 0x41415800) /* "AAX\0" */
is_hca = 0;
else if (read_32bitBE(aax_string_table_offset + result.name_offset, streamFile) == 0x48434100) /* "HCA\0" */
is_hca = 1;
else
goto fail; goto fail;
/* get offsets of constituent segments */ /* get offsets of constituent segments */
@ -70,17 +75,14 @@ VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile) {
data = init_layout_aax(segment_count); data = init_layout_aax(segment_count);
if (!data) goto fail; if (!data) goto fail;
/* get temp file */
streamFile->get_name(streamFile,filename,sizeof(filename));
streamFileAAX = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!streamFileAAX) goto fail;
/* open each segment subfile */ /* open each segment subfile */
for (i = 0; i < segment_count; i++) { for (i = 0; i < segment_count; i++) {
STREAMFILE* temp_streamFile = open_aax_with_STREAMFILE(streamFileAAX,segment_offset[i],segment_size[i]); STREAMFILE* temp_streamFile = setup_aax_streamfile(streamFile, segment_offset[i],segment_size[i], (is_hca ? "hca" : "adx"));
if (!temp_streamFile) goto fail; if (!temp_streamFile) goto fail;
data->segments[i] = init_vgmstream_adx(temp_streamFile); data->segments[i] = is_hca ?
init_vgmstream_hca(temp_streamFile) :
init_vgmstream_adx(temp_streamFile);
close_streamfile(temp_streamFile); close_streamfile(temp_streamFile);
@ -138,18 +140,40 @@ VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile) {
vgmstream->coding_type = data->segments[0]->coding_type; vgmstream->coding_type = data->segments[0]->coding_type;
vgmstream->layout_type = layout_aax; vgmstream->layout_type = layout_aax;
vgmstream->codec_data = data; vgmstream->layout_data = data;
data->loop_segment = loop_segment; data->loop_segment = loop_segment;
return vgmstream; return vgmstream;
fail: fail:
close_streamfile(streamFileAAX);
close_vgmstream(vgmstream); close_vgmstream(vgmstream);
free_layout_aax(data); free_layout_aax(data);
return NULL; return NULL;
} }
static STREAMFILE* setup_aax_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size, const char* fake_ext) {
STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
/* setup subfile */
new_streamFile = open_wrap_streamfile(streamFile);
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;
new_streamFile = open_clamp_streamfile(temp_streamFile, subfile_offset,subfile_size);
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;
new_streamFile = open_fakename_streamfile(temp_streamFile, NULL,fake_ext);
if (!new_streamFile) goto fail;
temp_streamFile = new_streamFile;
return temp_streamFile;
fail:
close_streamfile(temp_streamFile);
return NULL;
}
/* CRI's UTF wrapper around DSP [Sonic Colors sfx (Wii), NiGHTS: Journey of Dreams sfx (Wii)] */ /* CRI's UTF wrapper around DSP [Sonic Colors sfx (Wii), NiGHTS: Journey of Dreams sfx (Wii)] */
VGMSTREAM * init_vgmstream_utf_dsp(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_utf_dsp(STREAMFILE *streamFile) {

View File

@ -570,12 +570,13 @@ void reset_vgmstream(VGMSTREAM * vgmstream) {
if (vgmstream->coding_type==coding_ACM) { if (vgmstream->coding_type==coding_ACM) {
mus_acm_codec_data *data = vgmstream->codec_data; mus_acm_codec_data *data = vgmstream->codec_data;
int i; int i;
if (data) {
data->current_file = 0; data->current_file = 0;
for (i=0;i<data->file_count;i++) { for (i=0;i<data->file_count;i++) {
acm_reset(data->files[i]); acm_reset(data->files[i]);
} }
} }
}
if ( if (
vgmstream->coding_type == coding_NWA0 || vgmstream->coding_type == coding_NWA0 ||
@ -586,6 +587,7 @@ void reset_vgmstream(VGMSTREAM * vgmstream) {
vgmstream->coding_type == coding_NWA5 vgmstream->coding_type == coding_NWA5
) { ) {
nwa_codec_data *data = vgmstream->codec_data; nwa_codec_data *data = vgmstream->codec_data;
if (data)
reset_nwa(data->nwa); reset_nwa(data->nwa);
} }
@ -601,7 +603,7 @@ void reset_vgmstream(VGMSTREAM * vgmstream) {
} }
if (vgmstream->layout_type==layout_aax) { if (vgmstream->layout_type==layout_aax) {
reset_layout_aax(vgmstream->codec_data); reset_layout_aax(vgmstream->layout_data);
} }
if (vgmstream->layout_type==layout_scd_int) { if (vgmstream->layout_type==layout_scd_int) {
@ -819,7 +821,7 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
} }
if (vgmstream->layout_type==layout_aax) { if (vgmstream->layout_type==layout_aax) {
free_layout_aax(vgmstream->codec_data); free_layout_aax(vgmstream->layout_data);
vgmstream->codec_data = NULL; vgmstream->codec_data = NULL;
} }
@ -2047,6 +2049,7 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream) {
vgmstream->coding_type == coding_NWA5) vgmstream->coding_type == coding_NWA5)
{ {
nwa_codec_data *data = vgmstream->codec_data; nwa_codec_data *data = vgmstream->codec_data;
if (data)
seek_nwa(data->nwa, vgmstream->loop_sample); seek_nwa(data->nwa, vgmstream->loop_sample);
} }
@ -2435,11 +2438,6 @@ static STREAMFILE * get_vgmstream_average_bitrate_channel_streamfile(VGMSTREAM *
{ {
//AAX, AIX, ACM? //AAX, AIX, ACM?
if (vgmstream->layout_type==layout_aax) {
aax_codec_data *data = (aax_codec_data *) vgmstream->codec_data;
return data->segments[0]->ch[channel].streamfile; //todo not correct with multifile segments (ex. .ACM Ogg)
}
if (vgmstream->layout_type==layout_scd_int) { if (vgmstream->layout_type==layout_scd_int) {
scd_int_codec_data *data = (scd_int_codec_data *) vgmstream->codec_data; scd_int_codec_data *data = (scd_int_codec_data *) vgmstream->codec_data;
return data->intfiles[channel]; return data->intfiles[channel];
@ -2485,10 +2483,10 @@ int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream) {
int bitrate = 0; int bitrate = 0;
int sample_rate = vgmstream->sample_rate; int sample_rate = vgmstream->sample_rate;
int length_samples = vgmstream->num_samples; int length_samples = vgmstream->num_samples;
int channels = get_vgmstream_average_bitrate_channel_count(vgmstream); int channels;
STREAMFILE * streamFile; STREAMFILE * streamFile;
if (!sample_rate || !channels || !length_samples) if (!sample_rate || !length_samples)
return 0; return 0;
/* subsongs need to report this to properly calculate */ /* subsongs need to report this to properly calculate */
@ -2496,6 +2494,16 @@ int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream) {
return get_vgmstream_average_bitrate_from_size(vgmstream->stream_size, sample_rate, length_samples); return get_vgmstream_average_bitrate_from_size(vgmstream->stream_size, sample_rate, length_samples);
} }
/* AAX layout is handled differently as it has multiple sub-VGMSTREAMs (may include special codecs) */
//todo not correct with multifile segments (ex. .ACM Ogg)
if (vgmstream->layout_type==layout_aax) {
aax_codec_data *data = (aax_codec_data *) vgmstream->layout_data;
return get_vgmstream_average_bitrate(data->segments[0]);
}
channels = get_vgmstream_average_bitrate_channel_count(vgmstream);
if (!channels) return 0;
if (channels >= 1) { if (channels >= 1) {
streamFile = get_vgmstream_average_bitrate_channel_streamfile(vgmstream, 0); streamFile = get_vgmstream_average_bitrate_channel_streamfile(vgmstream, 0);
if (streamFile) { if (streamFile) {

View File

@ -797,6 +797,10 @@ typedef struct {
* Note also that support must be added for resetting, looping and * Note also that support must be added for resetting, looping and
* closing for every codec that uses this, as it will not be handled. */ * closing for every codec that uses this, as it will not be handled. */
void * codec_data; void * codec_data;
/* Same, for special layouts.
* Reusing the above pointer causes bugs when it's using special layout + codec
* (vgmstream may try to free/loop/etc codec_data). */
void * layout_data;
} VGMSTREAM; } VGMSTREAM;
#ifdef VGM_USE_VORBIS #ifdef VGM_USE_VORBIS