Merge pull request #680 from bnnm/fix

fix
This commit is contained in:
bnnm 2020-08-01 20:30:10 +02:00 committed by GitHub
commit 471dadb43f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 239 additions and 243 deletions

View File

@ -64,12 +64,7 @@
*/ */
#define DOUBLE_INTERRUPT_TIME 1.0 #define DOUBLE_INTERRUPT_TIME 1.0
/* TODO: Make sure this whole mess works for big-endian systems #define LITTLE_ENDIAN_OUTPUT 1 /* untested in BE */
*/
#define LITTLE_ENDIAN_OUTPUT
#undef MIN
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
#define DEFAULT_PARAMS { 0, -1, 2.0, 10.0, 0.0, 0, 0, 0, 0 } #define DEFAULT_PARAMS { 0, -1, 2.0, 10.0, 0.0, 0, 0, 0, 0 }
@ -203,7 +198,7 @@ static int set_sample_format(int channels, int sample_rate) {
format.channels = channels; format.channels = channels;
format.rate = sample_rate; format.rate = sample_rate;
format.byte_format = format.byte_format =
#ifdef LITTLE_ENDIAN_OUTPUT #if LITTLE_ENDIAN_OUTPUT
AO_FMT_LITTLE AO_FMT_LITTLE
#else #else
AO_FMT_BIG AO_FMT_BIG
@ -397,7 +392,7 @@ static int play_vgmstream(const char *filename, song_settings_t *cfg) {
render_vgmstream(buffer, to_do, vgmstream); render_vgmstream(buffer, to_do, vgmstream);
#ifdef LITTLE_ENDIAN_OUTPUT #if LITTLE_ENDIAN_OUTPUT
swap_samples_le(buffer, output_channels * to_do); swap_samples_le(buffer, output_channels * to_do);
#endif #endif

View File

@ -3,42 +3,42 @@
typedef enum { ADX, HCA, VAG, RIFF, CWAV, DSP } awb_type; typedef enum { ADX, HCA, VAG, RIFF, CWAV, DSP } awb_type;
static void load_awb_name(STREAMFILE *streamFile, STREAMFILE *acbFile, VGMSTREAM *vgmstream, int waveid); static void load_awb_name(STREAMFILE* sf, STREAMFILE* sf_acb, VGMSTREAM* vgmstream, int waveid);
/* AFS2/AWB (Atom Wave Bank) - CRI container of streaming audio, often together with a .acb cue sheet */ /* AFS2/AWB (Atom Wave Bank) - CRI container of streaming audio, often together with a .acb cue sheet */
VGMSTREAM * init_vgmstream_awb(STREAMFILE *streamFile) { VGMSTREAM* init_vgmstream_awb(STREAMFILE* sf) {
return init_vgmstream_awb_memory(streamFile, NULL); return init_vgmstream_awb_memory(sf, NULL);
} }
VGMSTREAM * init_vgmstream_awb_memory(STREAMFILE *streamFile, STREAMFILE *acbFile) { VGMSTREAM* init_vgmstream_awb_memory(STREAMFILE* sf, STREAMFILE* sf_acb) {
VGMSTREAM* vgmstream = NULL; VGMSTREAM* vgmstream = NULL;
STREAMFILE *temp_streamFile = NULL; STREAMFILE* temp_sf = NULL;
off_t offset, subfile_offset, subfile_next; off_t offset, subfile_offset, subfile_next;
size_t subfile_size; size_t subfile_size;
int total_subsongs, target_subsong = streamFile->stream_index; int total_subsongs, target_subsong = sf->stream_index;
//uint32_t flags; //uint32_t flags;
uint8_t offset_size; uint8_t offset_size;
uint16_t alignment, subkey; uint16_t alignment, subkey;
awb_type type; awb_type type;
char *extension = NULL; const char* extension = NULL;
int waveid; int waveid;
/* checks /* checks
* .awb: standard * .awb: standard
* .afs2: sometimes [Okami HD (PS4)] */ * .afs2: sometimes [Okami HD (PS4)] */
if (!check_extensions(streamFile, "awb,afs2")) if (!check_extensions(sf, "awb,afs2"))
goto fail; goto fail;
if (read_u32be(0x00,streamFile) != 0x41465332) /* "AFS2" */ if (read_u32be(0x00,sf) != 0x41465332) /* "AFS2" */
goto fail; goto fail;
//flags = read_32bitLE(0x08,streamFile); //flags = read_32bitLE(0x08,sf);
/* 0x04(1): version? 0x01=common, 0x02=2018+ (no apparent differences) */ /* 0x04(1): version? 0x01=common, 0x02=2018+ (no apparent differences) */
offset_size = read_u8(0x05,streamFile); offset_size = read_u8(0x05,sf);
/* 0x06(2): always 0x0002? */ /* 0x06(2): always 0x0002? */
total_subsongs = read_s32le(0x08,streamFile); total_subsongs = read_s32le(0x08,sf);
alignment = read_u16le(0x0c,streamFile); alignment = read_u16le(0x0c,sf);
subkey = read_u16le(0x0e,streamFile); subkey = read_u16le(0x0e,sf);
if (target_subsong == 0) target_subsong = 1; if (target_subsong == 0) target_subsong = 1;
if (target_subsong > total_subsongs || total_subsongs <= 0) goto fail; if (target_subsong > total_subsongs || total_subsongs <= 0) goto fail;
@ -49,26 +49,26 @@ VGMSTREAM * init_vgmstream_awb_memory(STREAMFILE *streamFile, STREAMFILE *acbFil
{ {
off_t waveid_offset = offset + (target_subsong-1) * 0x02; off_t waveid_offset = offset + (target_subsong-1) * 0x02;
waveid = read_u16le(waveid_offset,streamFile); waveid = read_u16le(waveid_offset,sf);
offset += total_subsongs * 0x02; offset += total_subsongs * 0x02;
} }
/* offset table: find target */ /* offset table: find target */
{ {
off_t file_size = get_streamfile_size(streamFile); off_t file_size = get_streamfile_size(sf);
/* last sub-offset is always file end, so table entries = total_subsongs+1 */ /* last sub-offset is always file end, so table entries = total_subsongs+1 */
offset += (target_subsong-1) * offset_size; offset += (target_subsong-1) * offset_size;
switch(offset_size) { switch(offset_size) {
case 0x04: /* common */ case 0x04: /* common */
subfile_offset = read_u32le(offset+0x00,streamFile); subfile_offset = read_u32le(offset+0x00,sf);
subfile_next = read_u32le(offset+0x04,streamFile); subfile_next = read_u32le(offset+0x04,sf);
break; break;
case 0x02: /* mostly sfx in .acb */ case 0x02: /* mostly sfx in .acb */
subfile_offset = read_u16le(offset+0x00,streamFile); subfile_offset = read_u16le(offset+0x00,sf);
subfile_next = read_u16le(offset+0x02,streamFile); subfile_next = read_u16le(offset+0x02,sf);
break; break;
default: default:
VGM_LOG("AWB: unknown offset size\n"); VGM_LOG("AWB: unknown offset size\n");
@ -87,31 +87,32 @@ VGMSTREAM * init_vgmstream_awb_memory(STREAMFILE *streamFile, STREAMFILE *acbFil
/* autodetect as there isn't anything, plus can mix types /* autodetect as there isn't anything, plus can mix types
* (waveid<>codec info is usually in the companion .acb) */ * (waveid<>codec info is usually in the companion .acb) */
if (read_u16be(subfile_offset, streamFile) == 0x8000) { /* ADX id (type 0) */ if (read_u16be(subfile_offset, sf) == 0x8000) { /* ADX id (type 0) */
type = ADX; type = ADX;
extension = "adx"; extension = "adx";
} }
else if ((read_u32be(subfile_offset,streamFile) & 0x7f7f7f7f) == 0x48434100) { /* "HCA\0" (type 2=HCA, 6=HCA-MX) */ else if ((read_u32be(subfile_offset,sf) & 0x7f7f7f7f) == 0x48434100) { /* "HCA\0" (type 2=HCA, 6=HCA-MX) */
type = HCA; type = HCA;
extension = "hca"; extension = "hca";
} }
else if (read_u32be(subfile_offset,streamFile) == 0x56414770) { /* "VAGp" (type 7=VAG, 10=HEVAG) */ else if (read_u32be(subfile_offset,sf) == 0x56414770) { /* "VAGp" (type 7=VAG, 10=HEVAG) */
type = VAG; type = VAG;
extension = "vag"; extension = "vag";
} }
else if (read_u32be(subfile_offset,streamFile) == 0x52494646) { /* "RIFF" (type 8=ATRAC3, 11=ATRAC9) */ else if (read_u32be(subfile_offset,sf) == 0x52494646) { /* "RIFF" (type 8=ATRAC3, 11=ATRAC9) */
type = RIFF; type = RIFF;
extension = "wav"; extension = "wav";
subfile_size = read_u32le(subfile_offset + 0x04,sf) + 0x08; /* rough size, use RIFF's */
} }
else if (read_u32be(subfile_offset,streamFile) == 0x43574156) { /* "CWAV" (type 9) */ else if (read_u32be(subfile_offset,sf) == 0x43574156) { /* "CWAV" (type 9) */
type = CWAV; type = CWAV;
extension = "bcwav"; extension = "bcwav";
} }
else if (read_u32be(subfile_offset + 0x08,streamFile) >= 8000 && else if (read_u32be(subfile_offset + 0x08,sf) >= 8000 &&
read_u32be(subfile_offset + 0x08,streamFile) <= 48000 && read_u32be(subfile_offset + 0x08,sf) <= 48000 &&
read_u16be(subfile_offset + 0x0e,streamFile) == 0 && read_u16be(subfile_offset + 0x0e,sf) == 0 &&
read_u32be(subfile_offset + 0x18,streamFile) == 2 && read_u32be(subfile_offset + 0x18,sf) == 2 &&
read_u32be(subfile_offset + 0x50,streamFile) == 0) { /* probably should call some check function (type 13) */ read_u32be(subfile_offset + 0x50,sf) == 0) { /* probably should call some check function (type 13) */
type = DSP; type = DSP;
extension = "dsp"; extension = "dsp";
} }
@ -121,32 +122,32 @@ VGMSTREAM * init_vgmstream_awb_memory(STREAMFILE *streamFile, STREAMFILE *acbFil
} }
temp_streamFile = setup_subfile_streamfile(streamFile, subfile_offset,subfile_size, extension); temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, extension);
if (!temp_streamFile) goto fail; if (!temp_sf) goto fail;
switch(type) { switch(type) {
case HCA: /* most common */ case HCA: /* most common */
vgmstream = init_vgmstream_hca_subkey(temp_streamFile, subkey); vgmstream = init_vgmstream_hca_subkey(temp_sf, subkey);
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
break; break;
case ADX: /* Okami HD (PS4) */ case ADX: /* Okami HD (PS4) */
vgmstream = init_vgmstream_adx(temp_streamFile); vgmstream = init_vgmstream_adx(temp_sf);
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
break; break;
case VAG: /* Ukiyo no Roushi (Vita) */ case VAG: /* Ukiyo no Roushi (Vita) */
vgmstream = init_vgmstream_vag(temp_streamFile); vgmstream = init_vgmstream_vag(temp_sf);
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
break; break;
case RIFF: /* Ukiyo no Roushi (Vita) */ case RIFF: /* Ukiyo no Roushi (Vita) */
vgmstream = init_vgmstream_riff(temp_streamFile); vgmstream = init_vgmstream_riff(temp_sf);
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
break; break;
case CWAV: /* Sonic: Lost World (3DS) */ case CWAV: /* Sonic: Lost World (3DS) */
vgmstream = init_vgmstream_rwsd(temp_streamFile); vgmstream = init_vgmstream_rwsd(temp_sf);
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
break; break;
case DSP: /* Sonic: Lost World (WiiU) */ case DSP: /* Sonic: Lost World (WiiU) */
vgmstream = init_vgmstream_ngc_dsp_std(temp_streamFile); vgmstream = init_vgmstream_ngc_dsp_std(temp_sf);
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
break; break;
default: default:
@ -156,20 +157,20 @@ VGMSTREAM * init_vgmstream_awb_memory(STREAMFILE *streamFile, STREAMFILE *acbFil
vgmstream->num_streams = total_subsongs; vgmstream->num_streams = total_subsongs;
/* try to load cue names */ /* try to load cue names */
load_awb_name(streamFile, acbFile, vgmstream, waveid); load_awb_name(sf, sf_acb, vgmstream, waveid);
close_streamfile(temp_streamFile); close_streamfile(temp_sf);
return vgmstream; return vgmstream;
fail: fail:
close_streamfile(temp_streamFile); close_streamfile(temp_sf);
close_vgmstream(vgmstream); close_vgmstream(vgmstream);
return NULL; return NULL;
} }
static void load_awb_name(STREAMFILE *streamFile, STREAMFILE *acbFile, VGMSTREAM* vgmstream, int waveid) { static void load_awb_name(STREAMFILE* sf, STREAMFILE* sf_acb, VGMSTREAM* vgmstream, int waveid) {
int is_memory = (acbFile != NULL); int is_memory = (sf_acb != NULL);
/* .acb is passed when loading memory .awb inside .acb */ /* .acb is passed when loading memory .awb inside .acb */
if (!is_memory) { if (!is_memory) {
@ -179,40 +180,40 @@ static void load_awb_name(STREAMFILE *streamFile, STREAMFILE *acbFile, VGMSTREAM
/* try (name).awb + (name).awb */ /* try (name).awb + (name).awb */
acbFile = open_streamfile_by_ext(streamFile, "acb"); sf_acb = open_streamfile_by_ext(sf, "acb");
/* try (name)_streamfiles.awb + (name).acb */ /* try (name)_streamfiles.awb + (name).acb */
if (!acbFile) { if (!sf_acb) {
char *cmp = "_streamfiles"; char *cmp = "_streamfiles";
get_streamfile_basename(streamFile, filename, sizeof(filename)); get_streamfile_basename(sf, filename, sizeof(filename));
len_name = strlen(filename); len_name = strlen(filename);
len_cmp = strlen(cmp); len_cmp = strlen(cmp);
if (len_name > len_cmp && strcmp(filename + len_name - len_cmp, cmp) == 0) { if (len_name > len_cmp && strcmp(filename + len_name - len_cmp, cmp) == 0) {
filename[len_name - len_cmp] = '\0'; filename[len_name - len_cmp] = '\0';
strcat(filename, ".acb"); strcat(filename, ".acb");
acbFile = open_streamfile_by_filename(streamFile, filename); sf_acb = open_streamfile_by_filename(sf, filename);
} }
} }
/* try (name)_STR.awb + (name).acb */ /* try (name)_STR.awb + (name).acb */
if (!acbFile) { if (!sf_acb) {
char *cmp = "_STR"; char *cmp = "_STR";
get_streamfile_basename(streamFile, filename, sizeof(filename)); get_streamfile_basename(sf, filename, sizeof(filename));
len_name = strlen(filename); len_name = strlen(filename);
len_cmp = strlen(cmp); len_cmp = strlen(cmp);
if (len_name > len_cmp && strcmp(filename + len_name - len_cmp, cmp) == 0) { if (len_name > len_cmp && strcmp(filename + len_name - len_cmp, cmp) == 0) {
filename[len_name - len_cmp] = '\0'; filename[len_name - len_cmp] = '\0';
strcat(filename, ".acb"); strcat(filename, ".acb");
acbFile = open_streamfile_by_filename(streamFile, filename); sf_acb = open_streamfile_by_filename(sf, filename);
} }
} }
/* try (name)_(name)_R001.awb + (name).acb [Sengoku Basara Battle Party (Mobile)] */ /* try (name)_(name)_R001.awb + (name).acb [Sengoku Basara Battle Party (Mobile)] */
if (!acbFile) { if (!sf_acb) {
char *cmp = "_R001"; char *cmp = "_R001";
get_streamfile_basename(streamFile, filename, sizeof(filename)); get_streamfile_basename(sf, filename, sizeof(filename));
len_name = strlen(filename); len_name = strlen(filename);
len_cmp = strlen(cmp); len_cmp = strlen(cmp);
@ -220,16 +221,16 @@ static void load_awb_name(STREAMFILE *streamFile, STREAMFILE *acbFile, VGMSTREAM
filename[(len_name - len_cmp) / 2] = '\0'; filename[(len_name - len_cmp) / 2] = '\0';
strcat(filename, ".acb"); strcat(filename, ".acb");
VGM_LOG("%s\n", filename); VGM_LOG("%s\n", filename);
acbFile = open_streamfile_by_filename(streamFile, filename); sf_acb = open_streamfile_by_filename(sf, filename);
} }
} }
/* probably loaded */ /* probably loaded */
load_acb_wave_name(acbFile, vgmstream, waveid, is_memory); load_acb_wave_name(sf_acb, vgmstream, waveid, is_memory);
close_streamfile(acbFile); close_streamfile(sf_acb);
} }
else { else {
load_acb_wave_name(acbFile, vgmstream, waveid, is_memory); load_acb_wave_name(sf_acb, vgmstream, waveid, is_memory);
} }
} }