mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-12-01 09:37:21 +01:00
Fix XMA gapless/looping/samples
fixes: standard, wem, xwc, xwb, xnb, xwx, rak, pk, txth, genh, seg, rsd, past, p3d, nub-xma, gtd, gsp, fsb, eaac, cxs, awc, aac
This commit is contained in:
parent
ef64889a28
commit
467ca19450
@ -110,6 +110,8 @@ VGMSTREAM * init_vgmstream_awc(STREAMFILE *streamFile) {
|
||||
bytes = ffmpeg_make_riff_xma2(buf, 0x100, awc.num_samples, substream_size, layer_channels, awc.sample_rate, block_count, block_size);
|
||||
data->layers[i]->codec_data = init_ffmpeg_header_offset(temp_streamFile, buf,bytes, substream_offset,substream_size);
|
||||
|
||||
xma_fix_raw_samples(data->layers[i], temp_streamFile, substream_offset,substream_size, 0, 0,0); /* samples are ok? */
|
||||
|
||||
close_streamfile(temp_streamFile);
|
||||
if (!data->layers[i]->codec_data) goto fail;
|
||||
}
|
||||
@ -128,6 +130,8 @@ VGMSTREAM * init_vgmstream_awc(STREAMFILE *streamFile) {
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, awc.stream_offset,awc.stream_size, 0, 0,0); /* samples are ok? */
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -849,6 +849,8 @@ static layered_layout_data* build_layered_eaaudiocore_eaxma(STREAMFILE *streamDa
|
||||
|
||||
data->layers[i]->coding_type = coding_FFmpeg;
|
||||
data->layers[i]->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(data->layers[i], temp_streamFile, 0x00,stream_size, 0, 0,0); /* samples are ok? */
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
|
@ -363,6 +363,8 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) {
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, fsb.stream_offset,fsb.stream_size, 0, 0,0); /* samples look ok */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -314,7 +314,7 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
|
||||
break;
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case 0x0A: {/* FMOD_SOUND_FORMAT_XMA [Dark Souls 2 (X360)] */
|
||||
case 0x0A: {/* FMOD_SOUND_FORMAT_XMA [Minecraft Story Mode (X360)] */
|
||||
uint8_t buf[0x100];
|
||||
int bytes, block_size, block_count;
|
||||
|
||||
@ -323,9 +323,11 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
|
||||
|
||||
bytes = ffmpeg_make_riff_xma2(buf, 0x100, vgmstream->num_samples, fsb5.stream_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, fsb5.stream_offset,fsb5.stream_size);
|
||||
if ( !vgmstream->codec_data ) goto fail;
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, fsb5.stream_offset,fsb5.stream_size, 0, 0,0); /* samples look ok */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -304,7 +304,6 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
else {
|
||||
goto fail;
|
||||
}
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, genh.start_offset,genh.data_size);
|
||||
if ( !ffmpeg_data ) goto fail;
|
||||
@ -313,8 +312,9 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
/* force encoder delay */
|
||||
if (genh.skip_samples_mode && genh.skip_samples >= 0) {
|
||||
if (genh.codec == XMA1 || genh.codec == XMA2) {
|
||||
xma_fix_raw_samples(vgmstream, streamFile, genh.start_offset,genh.data_size, 0, 0,0);
|
||||
} else if (genh.skip_samples_mode && genh.skip_samples >= 0) { /* force encoder delay */
|
||||
ffmpeg_set_skip_samples(ffmpeg_data, genh.skip_samples);
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) {
|
||||
int codec_id;
|
||||
|
||||
|
||||
/* check extensions */
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile,"gsb"))
|
||||
goto fail;
|
||||
|
||||
@ -116,14 +116,13 @@ VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) {
|
||||
/* 0x00: fmt0x166 header (BE), 0x34: seek table */
|
||||
|
||||
bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,200, chunk_offset,0x34, datasize, streamHeader, 1);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);
|
||||
if ( !ffmpeg_data ) goto fail;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset,datasize, 0, 0,0); /* samples are ok */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -94,6 +94,8 @@ VGMSTREAM * init_vgmstream_gtd(STREAMFILE *streamFile) {
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->num_samples = num_samples;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset, data_size, chunk_offset, 1,1);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -10,10 +10,9 @@ VGMSTREAM * init_vgmstream_nub_xma(STREAMFILE *streamFile) {
|
||||
int num_samples, loop_start_sample, loop_end_sample;
|
||||
|
||||
|
||||
/* check extension, case insensitive */
|
||||
/* checks */
|
||||
if ( !check_extensions(streamFile,"xma")) /* (probably meant to be .nub) */
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00,streamFile) != 0x786D6100) /* "xma\0" */
|
||||
goto fail;
|
||||
|
||||
@ -55,19 +54,17 @@ VGMSTREAM * init_vgmstream_nub_xma(STREAMFILE *streamFile) {
|
||||
} else { /* "fmt " */
|
||||
bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,0x100, chunk_offset,chunk_size, data_size, streamFile, 1);
|
||||
}
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size);;
|
||||
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size);
|
||||
if ( !vgmstream->codec_data ) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset, data_size, chunk_offset, 1,1); /* samples needs adjustment */
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
|
||||
/* open the file for reading */
|
||||
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
@ -11,11 +11,9 @@ VGMSTREAM * init_vgmstream_p3d(STREAMFILE *streamFile) {
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
||||
|
||||
|
||||
/* check extension, case insensitive */
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile,"p3d"))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x0,streamFile) != 0x503344FF && /* "P3D"\FF (LE: PC) */
|
||||
read_32bitBE(0x0,streamFile) != 0xFF443350) /* \FF"D3P" (BE: PS3, X360) */
|
||||
goto fail;
|
||||
@ -164,12 +162,12 @@ VGMSTREAM * init_vgmstream_p3d(STREAMFILE *streamFile) {
|
||||
size_t bytes;
|
||||
|
||||
bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size);
|
||||
if ( !vgmstream->codec_data ) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset, data_size, 0, 1,1); /* samples needs adjustment */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -1025,13 +1025,15 @@ VGMSTREAM * init_vgmstream_rsd6xma(STREAMFILE *streamFile) {
|
||||
datasize = read_32bitBE(0x808, streamFile);
|
||||
|
||||
bytes = ffmpeg_make_riff_xma2(buf, 100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf, bytes, start_offset, datasize);
|
||||
if (!ffmpeg_data) goto fail;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
/* for some reason (dev trickery?) .rsd don't set skip in the bitstream, though they should */
|
||||
//xma_fix_raw_samples(vgmstream, streamFile, start_offset,datasize, 0, 0,0);
|
||||
ffmpeg_set_skip_samples(ffmpeg_data, 512+64);
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
@ -1053,13 +1055,15 @@ VGMSTREAM * init_vgmstream_rsd6xma(STREAMFILE *streamFile) {
|
||||
datasize = read_32bitBE(0x808, streamFile);
|
||||
|
||||
bytes = ffmpeg_make_riff_xma2(buf, 100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf, bytes, start_offset, datasize);
|
||||
if (!ffmpeg_data) goto fail;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
/* for some reason (dev trickery?) .rsd don't set skip in the bitstream, though they should */
|
||||
//xma_fix_raw_samples(vgmstream, streamFile, start_offset,datasize, 0, 0,0);
|
||||
ffmpeg_set_skip_samples(ffmpeg_data, 512+64);
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
|
@ -92,6 +92,8 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) {
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, 0, 0,0); /* samples are ok */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -334,23 +334,23 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case 0x0B: { /* XMA2 [Final Fantasy (X360), Lightning Returns (X360) sfx, Kingdom Hearts 2.8 (X1)] */
|
||||
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||
uint8_t buf[200];
|
||||
int32_t bytes;
|
||||
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||
uint8_t buf[200];
|
||||
int32_t bytes;
|
||||
|
||||
/* extradata_offset+0x00: fmt0x166 header (BE), extradata_offset+0x34: seek table */
|
||||
bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,200, extradata_offset,0x34, stream_size, streamFile, 1);
|
||||
if (bytes <= 0) goto fail;
|
||||
/* extradata_offset+0x00: fmt0x166 header (BE), extradata_offset+0x34: seek table */
|
||||
bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,200, extradata_offset,0x34, stream_size, streamFile, 1);
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,stream_size);
|
||||
if (!ffmpeg_data) goto fail;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,stream_size);
|
||||
if (!ffmpeg_data) goto fail;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->num_samples = ffmpeg_data->totalSamples;
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = loop_end;
|
||||
|
||||
vgmstream->num_samples = ffmpeg_data->totalSamples;
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = loop_end;
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset,stream_size, 0, 0,0); /* samples are ok, loops? */
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -108,13 +108,17 @@ VGMSTREAM * init_vgmstream_ta_aac_x360(STREAMFILE *streamFile) {
|
||||
datasize = dataSize;
|
||||
|
||||
bytes = ffmpeg_make_riff_xma2(buf,100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);
|
||||
if ( !ffmpeg_data ) goto fail;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset, datasize, 0, 1,1);
|
||||
if (loop_flag) { /* reapply adjusted samples */
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
|
@ -335,7 +335,6 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) {
|
||||
else {
|
||||
goto fail;
|
||||
}
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, txth.start_offset,txth.data_size);
|
||||
if ( !ffmpeg_data ) goto fail;
|
||||
@ -344,8 +343,9 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) {
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
/* force encoder delay */
|
||||
if (txth.skip_samples_set) {
|
||||
if (txth.codec == XMA1 || txth.codec == XMA2) {
|
||||
xma_fix_raw_samples(vgmstream, streamFile, txth.start_offset,txth.data_size, 0, 0,0);
|
||||
} else if (txth.skip_samples_set) { /* force encoder delay */
|
||||
ffmpeg_set_skip_samples(ffmpeg_data, txth.skip_samples);
|
||||
}
|
||||
|
||||
|
@ -190,6 +190,8 @@ static VGMSTREAM * init_vgmstream_ubi_bao_main(ubi_bao_header * bao, STREAMFILE
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->stream_size = data_size;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamData, start_offset,data_size, 0, 0,0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
/* RAKI - Ubisoft audio format [Rayman Legends, Just Dance 2017 (multi)] */
|
||||
VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset, off, fmt_offset;
|
||||
off_t start_offset, offset, fmt_offset;
|
||||
size_t header_size, data_size;
|
||||
int big_endian;
|
||||
int loop_flag, channel_count, block_align, bits_per_sample;
|
||||
@ -15,22 +15,24 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *streamFile) {
|
||||
int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL;
|
||||
|
||||
|
||||
/* basic checks */
|
||||
/* .rak: Just Dance 2017; .ckd: Rayman Legends (technically .wav.ckd/rak) */
|
||||
if (!check_extensions(streamFile,"rak,ckd")) goto fail;
|
||||
/* checks */
|
||||
/* .rak: Just Dance 2017
|
||||
* .ckd: Rayman Legends (technically .wav.ckd/rak) */
|
||||
if (!check_extensions(streamFile,"rak,ckd"))
|
||||
goto fail;
|
||||
|
||||
/* some games (ex. Rayman Legends PS3) have a 32b file type before the RAKI data. However
|
||||
* offsets are absolute and expect the type exists, so it's part of the file and not an extraction defect. */
|
||||
if ((read_32bitBE(0x00,streamFile) == 0x52414B49)) /* "RAKI" */
|
||||
off = 0x0;
|
||||
offset = 0x00;
|
||||
else if ((read_32bitBE(0x04,streamFile) == 0x52414B49)) /* type varies between platforms (0x09, 0x0b) so ignore */
|
||||
off = 0x4;
|
||||
offset = 0x04;
|
||||
else
|
||||
goto fail;
|
||||
|
||||
/* 0x04: version? (0x00, 0x07, 0x0a, etc); */
|
||||
platform = read_32bitBE(off+0x08,streamFile); /* string */
|
||||
type = read_32bitBE(off+0x0c,streamFile); /* string */
|
||||
platform = read_32bitBE(offset+0x08,streamFile); /* string */
|
||||
type = read_32bitBE(offset+0x0c,streamFile); /* string */
|
||||
|
||||
switch(platform) {
|
||||
case 0x57696920: /* "Wii " */
|
||||
@ -48,15 +50,15 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *streamFile) {
|
||||
break;
|
||||
}
|
||||
|
||||
header_size = read_32bit(off+0x10,streamFile);
|
||||
start_offset = read_32bit(off+0x14,streamFile);
|
||||
header_size = read_32bit(offset+0x10,streamFile);
|
||||
start_offset = read_32bit(offset+0x14,streamFile);
|
||||
/* 0x18: number of chunks */
|
||||
/* 0x1c: unk */
|
||||
|
||||
/* the format has a chunk offset table, and the first one always "fmt" and points
|
||||
* to a RIFF "fmt" chunk (even for WiiU or PS3) */
|
||||
if (read_32bitBE(off+0x20,streamFile) != 0x666D7420) goto fail; /*"fmt "*/
|
||||
fmt_offset = read_32bit(off+0x24,streamFile);
|
||||
* to a RIFF "fmt"-style chunk (even for WiiU or PS3) */
|
||||
if (read_32bitBE(offset+0x20,streamFile) != 0x666D7420) goto fail; /* "fmt " */
|
||||
fmt_offset = read_32bit(offset+0x24,streamFile);
|
||||
//fmt_size = read_32bit(off+0x28,streamFile);
|
||||
|
||||
loop_flag = 0; /* not seen */
|
||||
@ -106,7 +108,7 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *streamFile) {
|
||||
|
||||
/* we need to know if the file uses "datL" and is full-interleave */
|
||||
if (channel_count > 1) {
|
||||
off_t chunk_off = off+ 0x20 + 0xc; /* after "fmt" */
|
||||
off_t chunk_off = offset+ 0x20 + 0xc; /* after "fmt" */
|
||||
while (chunk_off < header_size) {
|
||||
if (read_32bitBE(chunk_off,streamFile) == 0x6461744C) { /*"datL" found */
|
||||
size_t chunk_size = read_32bit(chunk_off+0x8,streamFile);
|
||||
@ -122,7 +124,7 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *streamFile) {
|
||||
|
||||
{
|
||||
/* get coef offsets; could check "dspL" and "dspR" chunks after "fmt " better but whatevs (only "dspL" if mono) */
|
||||
off_t dsp_coefs = read_32bitBE(off+0x30,streamFile); /* after "dspL"; spacing is consistent but could vary */
|
||||
off_t dsp_coefs = read_32bitBE(offset+0x30,streamFile); /* after "dspL"; spacing is consistent but could vary */
|
||||
dsp_read_coefs(vgmstream,streamFile, dsp_coefs+0x1c, 0x60, big_endian);
|
||||
/* dsp_coefs + 0x00-0x1c: ? (special coefs or adpcm history?) */
|
||||
}
|
||||
@ -149,15 +151,16 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *streamFile) {
|
||||
int bytes, block_count;
|
||||
|
||||
block_count = data_size / block_align + (data_size % block_align ? 1 : 0);
|
||||
bytes = ffmpeg_make_riff_xma2(buf, 100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_align);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
bytes = ffmpeg_make_riff_xma2(buf, 100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_align);
|
||||
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size);
|
||||
if ( !vgmstream->codec_data ) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->num_samples = read_32bit(fmt_offset+0x18,streamFile);
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, 0, 0,0); /* should apply to num_samples? */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -199,7 +202,7 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *streamFile) {
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
{
|
||||
off_t chunk_offset = off + 0x20 + 0xc; /* after "fmt" */
|
||||
off_t chunk_offset = offset + 0x20 + 0xc; /* after "fmt" */
|
||||
while (chunk_offset < header_size) {
|
||||
if (read_32bitBE(chunk_offset,streamFile) == 0x4164496E) { /*"AdIn" additional info */
|
||||
off_t adin_offset = read_32bitLE(chunk_offset+0x04,streamFile);
|
||||
|
@ -36,9 +36,9 @@ VGMSTREAM * init_vgmstream_vawx(STREAMFILE *streamFile) {
|
||||
vgmstream->meta_type = meta_VAWX;
|
||||
|
||||
switch(codec) {
|
||||
case 2: /* VAG */
|
||||
case 2: /* PS-ADPCM */
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->layout_type = channel_count == 6 ? layout_blocked_vawx : layout_interleave ;
|
||||
vgmstream->layout_type = channel_count == 6 ? layout_blocked_vawx : layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x10;
|
||||
|
||||
vgmstream->loop_start_sample = read_32bitBE(0x44,streamFile);
|
||||
@ -66,6 +66,8 @@ VGMSTREAM * init_vgmstream_vawx(STREAMFILE *streamFile) {
|
||||
vgmstream->loop_start_sample = read_32bitBE(0x44,streamFile);
|
||||
vgmstream->loop_end_sample = read_32bitBE(0x48,streamFile);
|
||||
|
||||
/* may be only applying end_skip to num_samples? */
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, 0, 0,0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ typedef struct {
|
||||
size_t fmt_size;
|
||||
off_t data_offset;
|
||||
size_t data_size;
|
||||
off_t chunk_offset;
|
||||
|
||||
/* standard fmt stuff */
|
||||
wwise_codec codec;
|
||||
@ -104,9 +105,9 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
ww.format = (uint16_t)read_16bit(ww.fmt_offset+0x00,streamFile);
|
||||
|
||||
if (ww.format == 0x0165) { /* XMA2WAVEFORMAT (always "fmt"+"XMA2", unlike .xma that may only have "XMA2") */
|
||||
off_t xma2_offset;
|
||||
if (!find_chunk(streamFile, 0x584D4132,first_offset,0, &xma2_offset,NULL, ww.big_endian, 0)) goto fail;
|
||||
xma2_parse_xma2_chunk(streamFile, xma2_offset,&ww.channels,&ww.sample_rate, &ww.loop_flag, &ww.num_samples, &ww.loop_start_sample, &ww.loop_end_sample);
|
||||
if (!find_chunk(streamFile, 0x584D4132,first_offset,0, &ww.chunk_offset,NULL, ww.big_endian, 0))
|
||||
goto fail;
|
||||
xma2_parse_xma2_chunk(streamFile, ww.chunk_offset,&ww.channels,&ww.sample_rate, &ww.loop_flag, &ww.num_samples, &ww.loop_start_sample, &ww.loop_end_sample);
|
||||
} else { /* WAVEFORMATEX */
|
||||
ww.channels = read_16bit(ww.fmt_offset+0x02,streamFile);
|
||||
ww.sample_rate = read_32bit(ww.fmt_offset+0x04,streamFile);
|
||||
@ -122,9 +123,10 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
|
||||
/* find loop info */
|
||||
if (ww.format == 0x0166) { /* XMA2WAVEFORMATEX */
|
||||
xma2_parse_fmt_chunk_extra(streamFile, ww.fmt_offset, &ww.loop_flag, &ww.num_samples, &ww.loop_start_sample, &ww.loop_end_sample, ww.big_endian);
|
||||
ww.chunk_offset = ww.fmt_offset;
|
||||
xma2_parse_fmt_chunk_extra(streamFile, ww.chunk_offset, &ww.loop_flag, &ww.num_samples, &ww.loop_start_sample, &ww.loop_end_sample, ww.big_endian);
|
||||
}
|
||||
else if (find_chunk(streamFile, 0x736D706C,first_offset,0, &loop_offset,&loop_size, ww.big_endian, 0)) { /*"smpl". common */
|
||||
else if (find_chunk(streamFile, 0x736D706C,first_offset,0, &loop_offset,&loop_size, ww.big_endian, 0)) { /*"smpl", common */
|
||||
if (loop_size >= 0x34
|
||||
&& read_32bit(loop_offset+0x1c, streamFile)==1 /*loop count*/
|
||||
&& read_32bit(loop_offset+0x24+4, streamFile)==0) {
|
||||
@ -139,7 +141,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
//}
|
||||
|
||||
/* other Wwise specific: */
|
||||
//"JUNK": optional padding for usually aligment (0-size JUNK exists too)
|
||||
//"JUNK": optional padding for aligment (0-size JUNK exists too)
|
||||
//"akd ": seem to store extra info for Wwise editor (wave peaks/loudness/HDR envelope?)
|
||||
}
|
||||
|
||||
@ -162,7 +164,6 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
case 0xFFFE: ww.codec = PCM; break; /* "PCM for Wwise Authoring" */
|
||||
case 0xFFFF: ww.codec = VORBIS; break;
|
||||
default:
|
||||
VGM_LOG("WWISE: unknown codec 0x%x \n", ww.format);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -250,7 +251,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
|
||||
if (ww.block_align != 0 || ww.bits_per_sample != 0) goto fail; /* always 0 for Worbis */
|
||||
|
||||
/* autodetect format (field are mostly common, see the end of the file) */
|
||||
/* autodetect format (fields are mostly common, see the end of the file) */
|
||||
if (find_chunk(streamFile, 0x766F7262,first_offset,0, &vorb_offset,&vorb_size, ww.big_endian, 0)) { /*"vorb"*/
|
||||
/* older Wwise (~<2012) */
|
||||
|
||||
@ -273,7 +274,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
cfg.setup_type = WWV_EXTERNAL_CODEBOOKS; /* setup_type will be corrected later */
|
||||
break;
|
||||
|
||||
case 0x2a: /* uncommon (mid 2011), [inFamous 2 (PS3)] */
|
||||
case 0x2a: /* uncommon (mid 2011) [inFamous 2 (PS3)] */
|
||||
data_offsets = 0x10;
|
||||
block_offsets = 0x28;
|
||||
cfg.header_type = WWV_TYPE_2;
|
||||
@ -296,9 +297,9 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
ww.data_size -= audio_offset;
|
||||
|
||||
/* detect setup type:
|
||||
* - full inline: ~2009, ex. The King of Fighters XII X360, The Saboteur PC
|
||||
* - trimmed inline: ~2010, ex. Army of Two: 40 days X360 (some multiplayer files)
|
||||
* - external: ~2010, ex. Assassin's Creed Brotherhood X360, Dead Nation X360 */
|
||||
* - full inline: ~2009, ex. The King of Fighters XII (X360), The Saboteur (PC)
|
||||
* - trimmed inline: ~2010, ex. Army of Two: 40 days (X360) some multiplayer files
|
||||
* - external: ~2010, ex. Assassin's Creed Brotherhood (X360), Dead Nation (X360) */
|
||||
if (vorb_size == 0x34) {
|
||||
size_t setup_size = (uint16_t)read_16bit(start_offset + setup_offset, streamFile);
|
||||
uint32_t id = (uint32_t)read_32bitBE(start_offset + setup_offset + 0x06, streamFile);
|
||||
@ -329,12 +330,12 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
cfg.packet_type = WWV_MODIFIED;
|
||||
|
||||
/* setup not detectable by header, so we'll try both; hopefully libvorbis will reject wrong codebooks
|
||||
* - standard: early (<2012), ex. The King of Fighters XIII X360 (2011/11), .ogg (cbs are from aoTuV, too)
|
||||
* - aoTuV603: later (>2012), ex. Sonic & All-Stars Racing Transformed PC (2012/11), .wem */
|
||||
* - standard: early (<2012), ex. The King of Fighters XIII (X360)-2011/11, .ogg (cbs are from aoTuV, too)
|
||||
* - aoTuV603: later (>2012), ex. Sonic & All-Stars Racing Transformed (PC)-2012/11, .wem */
|
||||
cfg.setup_type = is_wem ? WWV_AOTUV603_CODEBOOKS : WWV_EXTERNAL_CODEBOOKS; /* aoTuV came along .wem */
|
||||
break;
|
||||
|
||||
//case 0x2a: /* Rocksmith 2011 X360? */
|
||||
//case 0x2a: /* Rocksmith 2011 (X360)? */
|
||||
//non mod packets? TYPE_06? (possibly detectable by checking setup's granule, should be 0)
|
||||
default:
|
||||
VGM_LOG("WWISE: unknown extra size 0x%x\n", vorb_size);
|
||||
@ -348,10 +349,10 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
cfg.blocksize_0_exp = read_8bit(extra_offset + block_offsets + 0x01, streamFile); /* big */
|
||||
ww.data_size -= audio_offset;
|
||||
|
||||
/* Normal packets are used rarely (ex. Oddworld New 'n' Tasty! PSV). They are hard to detect (decoding
|
||||
/* Normal packets are used rarely (ex. Oddworld New 'n' Tasty! (PSV)). They are hard to detect (decoding
|
||||
* will mostly work with garbage results) but we'll try. Setup size and "fmt" bitrate fields may matter too. */
|
||||
if (ww.extra_size == 0x30) {
|
||||
/* all blocksizes I've seen are 0x08+0x0B except Oddworld PSV, that uses 0x09+0x09
|
||||
/* all blocksizes I've seen are 0x08+0x0B except Oddworld (PSV), that uses 0x09+0x09
|
||||
* (maybe lower spec machines = needs simpler packets) */
|
||||
if (cfg.blocksize_0_exp == cfg.blocksize_1_exp)
|
||||
cfg.packet_type = WWV_STANDARD;
|
||||
@ -395,7 +396,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
vgmstream->interleave_block_size = 0x08; /* ww.block_align = 0x8 in older Wwise, samples per block in newer Wwise */
|
||||
|
||||
/* find coef position */
|
||||
if (find_chunk(streamFile, 0x57696948,first_offset,0, &wiih_offset,&wiih_size, ww.big_endian, 0)) { /*"WiiH"*/ /* older Wwise */
|
||||
if (find_chunk(streamFile, 0x57696948,first_offset,0, &wiih_offset,&wiih_size, ww.big_endian, 0)) { /*"WiiH", older Wwise */
|
||||
vgmstream->num_samples = dsp_bytes_to_samples(ww.data_size, ww.channels);
|
||||
if (wiih_size != 0x2e * ww.channels) goto fail;
|
||||
}
|
||||
@ -442,6 +443,9 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
|
||||
|
||||
vgmstream->num_samples = ww.num_samples; /* set while parsing XMAWAVEFORMATs */
|
||||
|
||||
/* Wwise loops are always pre-adjusted (old or new) and only num_samples is off */
|
||||
xma_fix_raw_samples(vgmstream, streamFile, ww.data_offset,ww.data_size, ww.chunk_offset, 1,0);
|
||||
|
||||
/* "XMAc": rare Wwise extension, XMA2 physical loop regions (loop_start_b, loop_end_b, loop_subframe_data)
|
||||
* Can appear even in the file doesn't loop, maybe it's meant to be the playable physical region */
|
||||
//VGM_ASSERT(find_chunk(streamFile, 0x584D4163,first_offset,0, NULL,NULL, ww.big_endian, 0), "WWISE: XMAc chunk found\n");
|
||||
|
@ -55,7 +55,6 @@ VGMSTREAM * init_vgmstream_x360_ast(STREAMFILE *streamFile) {
|
||||
vgmstream->num_samples = msd.num_samples;
|
||||
vgmstream->loop_start_sample = msd.loop_start_sample;
|
||||
vgmstream->loop_end_sample = msd.loop_end_sample;
|
||||
//skip_samples = msd.skip_samples; //todo add skip samples
|
||||
}
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
@ -68,12 +67,12 @@ VGMSTREAM * init_vgmstream_x360_ast(STREAMFILE *streamFile) {
|
||||
|
||||
/* XMA1 "fmt" chunk @ 0x20 (BE, unlike the usual LE) */
|
||||
bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,100, fmt_offset,fmt_size, data_size, streamFile, 1);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size);
|
||||
if ( !vgmstream->codec_data ) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset, data_size, fmt_offset, 1,1);
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
|
@ -1,31 +1,29 @@
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* CXS - found in Eternal Sonata (Xbox 360) */
|
||||
/* CXS - found in Eternal Sonata (X360) */
|
||||
VGMSTREAM * init_vgmstream_x360_cxs(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
/* checks */
|
||||
if ( !check_extensions(streamFile,"cxs"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00,streamFile) != 0x43585320) /* "CXS " */
|
||||
goto fail;
|
||||
|
||||
loop_flag = read_32bitBE(0x18,streamFile) > 0;
|
||||
channel_count = read_32bitBE(0x0c,streamFile);
|
||||
start_offset = read_32bitBE(0x04,streamFile) + read_32bitBE(0x28,streamFile); /* assumed, seek table always at 0x800 */
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
start_offset = read_32bitBE(0x04,streamFile) + read_32bitBE(0x28,streamFile); /* assumed, seek table always at 0x800 */
|
||||
/* 0x04: data start? */
|
||||
vgmstream->sample_rate = read_32bitBE(0x08,streamFile);
|
||||
vgmstream->channels = channel_count; /*0x0c*/
|
||||
vgmstream->num_samples = read_32bitBE(0x10,streamFile) + 576; /*todo add proper encoder_delay*/
|
||||
vgmstream->num_samples = read_32bitBE(0x10,streamFile);
|
||||
vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile);
|
||||
vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile);
|
||||
/* 0x1c: below */
|
||||
@ -50,6 +48,8 @@ VGMSTREAM * init_vgmstream_x360_cxs(STREAMFILE *streamFile) {
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset,datasize, 0, 0,1); /* num samples are ok */
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
|
@ -10,10 +10,9 @@ VGMSTREAM * init_vgmstream_x360_pasx(STREAMFILE *streamFile) {
|
||||
int num_samples, loop_start_sample, loop_end_sample;
|
||||
|
||||
|
||||
/* check extension, case insensitive */
|
||||
/* checks */
|
||||
if ( !check_extensions(streamFile,"past"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00,streamFile) != 0x50415358) /* "PASX" */
|
||||
goto fail;
|
||||
|
||||
@ -51,6 +50,8 @@ VGMSTREAM * init_vgmstream_x360_pasx(STREAMFILE *streamFile) {
|
||||
if ( !vgmstream->codec_data ) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset, data_size, chunk_offset, 1,1);
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* XMA - Microsoft format derived from WMAPRO, found in X360/XBone games */
|
||||
/* XMA - Microsoft format derived from RIFF, found in X360/XBone games */
|
||||
VGMSTREAM * init_vgmstream_xma(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset, chunk_offset, first_offset = 0xc;
|
||||
@ -69,7 +69,7 @@ VGMSTREAM * init_vgmstream_xma(STREAMFILE *streamFile) {
|
||||
goto fail;
|
||||
|
||||
|
||||
/* fix samples; for now only XMA1 is fixed, but XMA2 num_samples don't include skip samples and xmaencode.exe doesn't use it */
|
||||
/* get xma1 samples, later fixed */
|
||||
if (is_xma1) {
|
||||
ms_sample_data msd = {0};
|
||||
|
||||
@ -96,12 +96,11 @@ VGMSTREAM * init_vgmstream_xma(STREAMFILE *streamFile) {
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_XMA_RIFF;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->loop_start_sample = loop_start_sample;
|
||||
vgmstream->loop_end_sample = loop_end_sample;
|
||||
vgmstream->meta_type = meta_XMA_RIFF;
|
||||
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
{
|
||||
@ -118,6 +117,8 @@ VGMSTREAM * init_vgmstream_xma(STREAMFILE *streamFile) {
|
||||
if ( !vgmstream->codec_data ) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset, data_size, chunk_offset, 1,1);
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
|
@ -4,18 +4,16 @@
|
||||
/* XNB - Microsoft XNA Game Studio 4.0 format */
|
||||
VGMSTREAM * init_vgmstream_xnb(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
off_t start_offset, xma_chunk_offset = 0;
|
||||
int loop_flag = 0, channel_count, num_samples = 0, loop_start = 0, loop_end = 0;
|
||||
int big_endian, flags, codec, sample_rate, block_size, bps;
|
||||
size_t data_size;
|
||||
char platform;
|
||||
|
||||
|
||||
/* check extension, case insensitive */
|
||||
if ( !check_extensions(streamFile,"xnb"))
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile,"xnb"))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
if ((read_32bitBE(0,streamFile) & 0xFFFFFF00) != 0x584E4200) /* "XNB" */
|
||||
goto fail;
|
||||
|
||||
@ -24,7 +22,7 @@ VGMSTREAM * init_vgmstream_xnb(STREAMFILE *streamFile) {
|
||||
platform = read_8bit(0x03,streamFile);
|
||||
big_endian = (platform == 'x');
|
||||
|
||||
if (read_8bit(0x04,streamFile) != 0x05) /* XNA 4.0 version only */
|
||||
if (read_8bit(0x04,streamFile) != 0x05) /* XNA 4.0 version only */
|
||||
goto fail;
|
||||
|
||||
flags = read_8bit(0x05,streamFile);
|
||||
@ -82,6 +80,7 @@ VGMSTREAM * init_vgmstream_xnb(STREAMFILE *streamFile) {
|
||||
|
||||
if (codec == 0x166) {
|
||||
xma2_parse_fmt_chunk_extra(streamFile, current_offset, &loop_flag, &num_samples, &loop_start, &loop_end, big_endian);
|
||||
xma_chunk_offset = current_offset;
|
||||
}
|
||||
}
|
||||
|
||||
@ -138,8 +137,6 @@ VGMSTREAM * init_vgmstream_xnb(STREAMFILE *streamFile) {
|
||||
block_count = data_size / block_size + (data_size % block_size ? 1 : 0);
|
||||
|
||||
bytes = ffmpeg_make_riff_xma2(buf,0x100, num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
@ -148,6 +145,8 @@ VGMSTREAM * init_vgmstream_xnb(STREAMFILE *streamFile) {
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = loop_end;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, xma_chunk_offset, 1,1);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -69,6 +69,8 @@ typedef struct {
|
||||
uint32_t loop_end_sample;
|
||||
|
||||
int is_crackdown;
|
||||
int fix_xma_num_samples;
|
||||
int fix_xma_loop_samples;
|
||||
} xwb_header;
|
||||
|
||||
static void get_name(char * buf, size_t maxsize, int target_subsong, xwb_header * xwb, STREAMFILE *streamFile);
|
||||
@ -366,7 +368,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
||||
xwb.loop_start_sample = msadpcm_bytes_to_samples(xwb.loop_start, block_size, xwb.channels);
|
||||
xwb.loop_end_sample = msadpcm_bytes_to_samples(xwb.loop_start + xwb.loop_end, block_size, xwb.channels);
|
||||
}
|
||||
else if (xwb.version <= XACT2_1_MAX && (xwb.codec == XMA1 || xwb.codec == XMA2) && xwb.loop_flag) {
|
||||
else if (xwb.version <= XACT2_1_MAX && (xwb.codec == XMA1 || xwb.codec == XMA2) && xwb.loop_flag) {
|
||||
/* v38: byte offset, v40+: sample offset, v39: ? */
|
||||
/* need to manually find sample offsets, thanks to Microsoft's dumb headers */
|
||||
ms_sample_data msd = {0};
|
||||
@ -386,44 +388,27 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
||||
xwb.loop_start_sample = msd.loop_start_sample;
|
||||
xwb.loop_end_sample = msd.loop_end_sample;
|
||||
|
||||
/* for XWB v22 (and below?) this seems normal [Project Gotham Racing (X360)] */
|
||||
if (xwb.num_samples == 0)
|
||||
xwb.num_samples = msd.num_samples;
|
||||
|
||||
/* if provided, xwb.num_samples is equal to msd.num_samples after proper adjustments (+ 128 - start_skip - end_skip) */
|
||||
xwb.fix_xma_loop_samples = 1;
|
||||
xwb.fix_xma_num_samples = 0;
|
||||
|
||||
#if 1
|
||||
//todo add padding back until FFmpeg decoding + msd.loops are fixed (affects edge loops)
|
||||
// (in rare cases this causes a glitch in FFmpeg due to missing samples)
|
||||
xwb.num_samples += 64 + 512;
|
||||
#endif
|
||||
/* for XWB v22 (and below?) this seems normal [Project Gotham Racing (X360)] */
|
||||
if (xwb.num_samples == 0) {
|
||||
xwb.num_samples = msd.num_samples;
|
||||
xwb.fix_xma_num_samples = 1;
|
||||
}
|
||||
}
|
||||
else if ((xwb.codec == XMA1 || xwb.codec == XMA2) && xwb.loop_flag) {
|
||||
/* unlike prev versions, xwb.num_samples is the full size without adjustments */
|
||||
xwb.fix_xma_loop_samples = 1;
|
||||
xwb.fix_xma_num_samples = 1;
|
||||
|
||||
#if 0 //todo apply once FFmpeg decode is ok
|
||||
/* apply extra output + skips (see ms_audio_get_samples, approximate as find out with first and last frames) */
|
||||
int start_skip = 512;
|
||||
int end_skip = 0;
|
||||
|
||||
xwb.num_samples += 128;
|
||||
xwb.num_samples -= start_skip;
|
||||
xwb.num_samples -= end_skip;
|
||||
if (xwb.loop_flag) {
|
||||
xwb.loop_start_sample += 128;
|
||||
xwb.loop_start_sample -= start_skip;
|
||||
|
||||
xwb.loop_end_sample += 128;
|
||||
xwb.loop_end_sample -= start_skip;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Crackdown does use xwb.num_samples after adjustments (but not loops), fix it back */
|
||||
/* Crackdown does use xwb.num_samples after adjustments (but not loops) */
|
||||
if (xwb.is_crackdown) {
|
||||
xwb.num_samples += 512 - 128;
|
||||
xwb.fix_xma_num_samples = 0;
|
||||
}
|
||||
}
|
||||
|
||||
VGM_LOG("fix: num=%i, loop=%i\n", xwb.fix_xma_num_samples,xwb.fix_xma_loop_samples);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(xwb.channels,xwb.loop_flag);
|
||||
@ -467,6 +452,15 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, xwb.stream_offset,xwb.stream_size, 0, xwb.fix_xma_num_samples,xwb.fix_xma_loop_samples);
|
||||
|
||||
/* this fixes some XMA1, perhaps the above isn't reading end_skip correctly (doesn't happen for all files though) */
|
||||
if (vgmstream->loop_flag &&
|
||||
vgmstream->loop_end_sample > vgmstream->num_samples) {
|
||||
VGM_LOG("XWB: fix XMA1 looping\n");
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -482,6 +476,8 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, xwb.stream_offset,xwb.stream_size, 0, xwb.fix_xma_num_samples,xwb.fix_xma_loop_samples);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,9 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) {
|
||||
size_t data_size;
|
||||
int loop_flag, channel_count, codec, num_samples;
|
||||
|
||||
/* check extensions (.xwc is the extension of the bigfile, individual files don't have one) */
|
||||
|
||||
/* checks */
|
||||
/* .xwc: extension of the bigfile, individual files don't have one */
|
||||
if ( !check_extensions(streamFile,"xwc"))
|
||||
goto fail;
|
||||
|
||||
@ -16,7 +18,7 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) {
|
||||
/* version */
|
||||
if (read_32bitBE(0x00,streamFile) == 0x00030000 &&
|
||||
read_32bitBE(0x04,streamFile) == 0x00900000) { /* The Darkness */
|
||||
data_size = read_32bitLE(0x08, streamFile); /* including subheader */
|
||||
data_size = read_32bitLE(0x08, streamFile) + 0x1c; /* not including subheader */
|
||||
channel_count = read_32bitLE(0x0c, streamFile);
|
||||
/* 0x10: num_samples */
|
||||
/* 0x14: 0x8000? */
|
||||
@ -28,7 +30,7 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) {
|
||||
}
|
||||
else if (read_32bitBE(0x00,streamFile) == 0x00040000 &&
|
||||
read_32bitBE(0x04,streamFile) == 0x00900000) { /* Riddick, Syndicate */
|
||||
data_size = read_32bitLE(0x08, streamFile); /* including subheader */
|
||||
data_size = read_32bitLE(0x08, streamFile) + 0x24; /* not including subheader */
|
||||
channel_count = read_32bitLE(0x0c, streamFile);
|
||||
/* 0x10: num_samples */
|
||||
/* 0x14: 0x8000? */
|
||||
@ -42,15 +44,15 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
loop_flag = 0; /* seemingly not in the file */
|
||||
loop_flag = 0;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->meta_type = meta_XWC;
|
||||
vgmstream->num_samples = num_samples;
|
||||
|
||||
switch(codec) {
|
||||
#ifdef VGM_USE_MPEG
|
||||
@ -59,7 +61,7 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) {
|
||||
|
||||
start_offset = 0x800;
|
||||
vgmstream->num_samples = read_32bitLE(extra_offset+0x00, streamFile); /* with encoder delay */ //todo improve
|
||||
cfg.data_size = read_32bitLE(extra_offset+0x04, streamFile); //data_size - 0x28;
|
||||
cfg.data_size = read_32bitLE(extra_offset+0x04, streamFile); /* without padding */
|
||||
|
||||
vgmstream->codec_data = init_mpeg_custom(streamFile, start_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_STANDARD, &cfg);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
@ -77,6 +79,7 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) {
|
||||
seek_size = read_32bitLE(extra_offset+0x00, streamFile);
|
||||
start_offset = extra_offset+0x04 + seek_size + read_32bitLE(extra_offset+0x04+seek_size, streamFile) + 0x08;
|
||||
start_offset += (start_offset % 0x800) ? 0x800 - (start_offset % 0x800) : 0; /* padded */
|
||||
data_size = data_size - start_offset;
|
||||
|
||||
sample_rate = read_32bitBE(extra_offset+0x04+seek_size+0x10, streamFile);
|
||||
block_size = read_32bitBE(extra_offset+0x04+seek_size+0x1c, streamFile);
|
||||
@ -84,21 +87,22 @@ VGMSTREAM * init_vgmstream_xwc(STREAMFILE *streamFile) {
|
||||
/* others: scrambled RIFF fmt BE values */
|
||||
|
||||
bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, sample_rate, block_count, block_size);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size - start_offset - 0x28);
|
||||
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
|
||||
xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, 0, 0,0); /* samples are ok, fix delay */
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x564F5242: { /* "VORB" (PC) */
|
||||
start_offset = 0x30;
|
||||
data_size = data_size - start_offset;
|
||||
|
||||
vgmstream->codec_data = init_ffmpeg_offset(streamFile, start_offset, data_size - start_offset - 0x28);
|
||||
vgmstream->codec_data = init_ffmpeg_offset(streamFile, start_offset,data_size);
|
||||
if ( !vgmstream->codec_data ) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
Loading…
Reference in New Issue
Block a user