diff --git a/src/coding/coding.h b/src/coding/coding.h index 9911d3cb..5f23599c 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -207,6 +207,9 @@ typedef struct { void xma_get_samples(xma_sample_data * msd, STREAMFILE *streamFile); void wmapro_get_samples(xma_sample_data * msd, STREAMFILE *streamFile, int block_align, int sample_rate, uint32_t decode_flags); +size_t atrac3_bytes_to_samples(size_t bytes, int full_block_align); +size_t atrac3plus_bytes_to_samples(size_t bytes, int full_block_align); + #endif #endif /*_CODING_H*/ diff --git a/src/coding/ffmpeg_decoder_utils.c b/src/coding/ffmpeg_decoder_utils.c index 83598e6c..13bbde36 100644 --- a/src/coding/ffmpeg_decoder_utils.c +++ b/src/coding/ffmpeg_decoder_utils.c @@ -631,4 +631,16 @@ void wmapro_get_samples(xma_sample_data * msd, STREAMFILE *streamFile, int block } +size_t atrac3_bytes_to_samples(size_t bytes, int full_block_align) { + /* ATRAC3 expects full block align since as is can mix joint stereo with mono blocks; + * so (full_block_align / channels) DOESN'T give the size of a single channel (uncommon in ATRAC3 though) */ + return (bytes / full_block_align) * 1024; +} + +size_t atrac3plus_bytes_to_samples(size_t bytes, int full_block_align) { + /* ATRAC3plus expects full block align since as is can mix joint stereo with mono blocks; + * so (full_block_align / channels) DOESN'T give the size of a single channel (common in ATRAC3plus) */ + return (bytes / full_block_align) * 2048; +} + #endif diff --git a/src/meta/gsp_gsb.c b/src/meta/gsp_gsb.c index 549707b8..17b636fc 100644 --- a/src/meta/gsp_gsb.c +++ b/src/meta/gsp_gsb.c @@ -82,9 +82,9 @@ VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) { uint8_t buf[100]; int32_t bytes, block_size, encoder_delay, joint_stereo, max_samples; - block_size = 0x98 * vgmstream->channels; - joint_stereo = 0; - max_samples = (datasize / block_size) * 1024; + block_size = 0x98 * vgmstream->channels; + joint_stereo = 0; + max_samples = atrac3_bytes_to_samples(datasize, block_size);; encoder_delay = max_samples - vgmstream->num_samples; /* todo guessed */ vgmstream->num_samples += encoder_delay; diff --git a/src/meta/ps3_msf.c b/src/meta/ps3_msf.c index 5a5ceb2e..226f07e7 100644 --- a/src/meta/ps3_msf.c +++ b/src/meta/ps3_msf.c @@ -104,12 +104,12 @@ VGMSTREAM * init_vgmstream_ps3_msf(STREAMFILE *streamFile) { case 0x6: { /* ATRAC3 high (132 kbps, frame size 192) */ ffmpeg_codec_data *ffmpeg_data = NULL; uint8_t buf[100]; - int32_t bytes, samples_size = 1024, block_size, encoder_delay, joint_stereo, max_samples; + int32_t bytes, block_size, encoder_delay, joint_stereo, max_samples; - block_size = (codec_id==4 ? 0x60 : (codec_id==5 ? 0x98 : 0xC0)) * vgmstream->channels; + block_size = (codec_id==4 ? 0x60 : (codec_id==5 ? 0x98 : 0xC0)) * vgmstream->channels; encoder_delay = 0x0; //todo MSF encoder delay (around 440-450*2) - max_samples = (data_size / block_size) * samples_size; - joint_stereo = codec_id==4; /* interleaved joint stereo (ch must be even) */ + max_samples = atrac3_bytes_to_samples(data_size, block_size); + joint_stereo = codec_id==4; /* interleaved joint stereo (ch must be even) */ if (vgmstream->sample_rate==0xFFFFFFFF) /* some MSFv1 (Digi World SP) */ vgmstream->sample_rate = 44100;//voice tracks seems to use 44khz, not sure about other tracks @@ -126,8 +126,8 @@ VGMSTREAM * init_vgmstream_ps3_msf(STREAMFILE *streamFile) { vgmstream->num_samples = max_samples; if (loop_flag) { - vgmstream->loop_start_sample = (loop_start / block_size) * samples_size; - vgmstream->loop_end_sample = (loop_end / block_size) * samples_size; + vgmstream->loop_start_sample = atrac3_bytes_to_samples(loop_start, block_size); + vgmstream->loop_end_sample = atrac3_bytes_to_samples(loop_end, block_size); } break; diff --git a/src/meta/xwb.c b/src/meta/xwb.c index 105111a8..7bf5c963 100644 --- a/src/meta/xwb.c +++ b/src/meta/xwb.c @@ -226,7 +226,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { /* num samples uses a modified entry_info format (maybe skip samples + samples? sfx use the standard format) * ignore for now and just calc max samples */ //todo - xwb.num_samples = xwb.stream_size / (xwb.block_align * xwb.channels) * 1024; + xwb.num_samples = atrac3_bytes_to_samples(xwb.stream_size, xwb.block_align * xwb.channels); }