Clean MSADPCM frame size and add extra check

This commit is contained in:
bnnm 2019-10-20 16:35:52 +02:00
parent 8ca481e347
commit c4b259f5d8
20 changed files with 130 additions and 66 deletions

View File

@ -128,6 +128,7 @@ void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample_t * outbuf, int32_t fir
void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
void decode_msadpcm_ck(VGMSTREAM * vgmstream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
long msadpcm_bytes_to_samples(long bytes, int block_size, int channels);
int msadpcm_check_coefs(STREAMFILE *sf, off_t offset);
/* yamaha_decoder */
void decode_aica(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo);

View File

@ -2,14 +2,14 @@
#include "coding.h"
static const int msadpcm_steps[16] = {
static const int16_t msadpcm_steps[16] = {
230, 230, 230, 230,
307, 409, 512, 614,
768, 614, 512, 409,
307, 230, 230, 230
};
static const int msadpcm_coefs[7][2] = {
static const int16_t msadpcm_coefs[7][2] = {
{ 256, 0 },
{ 512, -256 },
{ 0, 0 },
@ -226,3 +226,29 @@ long msadpcm_bytes_to_samples(long bytes, int block_size, int channels) {
return (bytes / block_size) * (block_size - (7-1)*channels) * 2 / channels
+ ((bytes % block_size) ? ((bytes % block_size) - (7-1)*channels) * 2 / channels : 0);
}
/* test if MSADPCM coefs were re-defined (possible in theory but not used in practice) */
int msadpcm_check_coefs(STREAMFILE *sf, off_t offset) {
int i;
int count = read_16bitLE(offset, sf);
if (count != 7) {
VGM_LOG("MSADPCM: bad count %i at %lx\n", count, offset);
goto fail;
}
offset += 0x02;
for (i = 0; i < 7; i++) {
int16_t coef1 = read_16bitLE(offset + 0x00, sf);
int16_t coef2 = read_16bitLE(offset + 0x02, sf);
if (coef1 != msadpcm_coefs[i][0] || coef2 != msadpcm_coefs[i][1]) {
VGM_LOG("MSADPCM: bad coef %i/%i vs %i/%i\n", coef1, coef2, msadpcm_coefs[i][0], msadpcm_coefs[i][1]);
goto fail;
}
offset += 0x02 + 0x02;
}
return 1;
fail:
return 0;
}

View File

@ -1,5 +1,5 @@
#include "meta.h"
#include "../util.h"
#include "../coding/coding.h"
/* 2DX9 - from Konami arcade games [beatmaniaIIDX16: EMPRESS (AC), BeatStream (AC), REFLEC BEAT (AC)] */
VGMSTREAM * init_vgmstream_2dx9(STREAMFILE *streamFile) {
@ -38,7 +38,9 @@ VGMSTREAM * init_vgmstream_2dx9(STREAMFILE *streamFile) {
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->frame_size = read_16bitLE(0x38,streamFile);
if (!msadpcm_check_coefs(streamFile, 0x40))
goto fail;
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
goto fail;
return vgmstream;

View File

@ -91,7 +91,7 @@ VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile) {
case 0x02: { /* MSADPCM [Dragon Quest II (iOS) sfx] */
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = read_16bitLE(extradata_offset + 0x02,streamFile);
vgmstream->frame_size = read_16bitLE(extradata_offset + 0x02,streamFile);
/* adjusted samples; bigger or smaller than base samples, akb lib uses these fields instead
* (base samples may have more than possible and read over file size otherwise, very strange)
@ -277,7 +277,7 @@ VGMSTREAM * init_vgmstream_akb2(STREAMFILE *streamFile) {
case 0x02: { /* MSADPCM [The Irregular at Magic High School Lost Zero (Android)] */
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = read_16bitLE(extradata_offset + 0x02, streamFile);
vgmstream->frame_size = read_16bitLE(extradata_offset + 0x02, streamFile);
/* adjusted samples; bigger or smaller than base samples, akb lib uses these fields instead
* (base samples may have more than possible and read over file size otherwise, very strange)

View File

@ -56,7 +56,7 @@ VGMSTREAM * init_vgmstream_cks(STREAMFILE *streamFile) {
break;
case 0x02: /* adpcm [Part Time UFO (Android), Mega Man 1-6 (Android)] */
vgmstream->coding_type = coding_MSADPCM_ck;
/* frame_size is always 0x18 */
vgmstream->frame_size = block_size / channel_count; /* always 0x18 */
break;
default:
goto fail;

View File

@ -76,7 +76,7 @@ VGMSTREAM * init_vgmstream_dec(STREAMFILE *streamFile) {
vgmstream->loop_end_sample = loop_end;
vgmstream->coding_type = coding_MSADPCM;
vgmstream->interleave_block_size = 0x800;
vgmstream->frame_size = 0x800;
vgmstream->layout_type = layout_blocked_dec;
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )

View File

@ -225,13 +225,15 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
vgmstream->interleave_block_size = genh.interleave;
vgmstream->layout_type = layout_none;
break;
case coding_MSADPCM:
if (vgmstream->channels > 2) goto fail;
if (!genh.interleave) goto fail; /* creates garbage */
if (!genh.interleave) goto fail;
vgmstream->interleave_block_size = genh.interleave;
vgmstream->frame_size = genh.interleave;
vgmstream->layout_type = layout_none;
break;
case coding_XBOX_IMA:
if (genh.codec_mode == 1) { /* mono interleave */
coding = coding_XBOX_IMA_int;

View File

@ -45,15 +45,22 @@ VGMSTREAM * init_vgmstream_mzrt(STREAMFILE *streamFile) {
goto fail;
}
/* skip fmt-extra data */
if (codec == 0x0002 || codec == 0x0166) {
/* skip MSADPCM data */
if (codec == 0x0002) {
if (!msadpcm_check_coefs(streamFile, start_offset + 0x02 + 0x02))
goto fail;
start_offset += 0x02 + read_16bitLE(start_offset, streamFile);
}
/* skip extra data */
if (codec == 0x0166) {
start_offset += 0x02 + read_16bitLE(start_offset, streamFile);
}
/* skip unknown table */
if (codec == 0x0000) {
start_offset += 0x04 + read_32bitBE(start_offset, streamFile) * 0x04;
}
/* skip unknown table */
@ -95,7 +102,7 @@ VGMSTREAM * init_vgmstream_mzrt(STREAMFILE *streamFile) {
if (bps != 4) goto fail;
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = block_size;
vgmstream->frame_size = block_size;
break;
#ifdef VGM_USE_FFMPEG

View File

@ -157,6 +157,8 @@ static int read_fmt(int big_endian, STREAMFILE * streamFile, off_t current_chunk
case 0x02: /* MSADPCM */
if (fmt->bps == 4) {
fmt->coding_type = coding_MSADPCM;
if (!msadpcm_check_coefs(streamFile, fmt->offset + 0x08 + 0x14))
goto fail;
}
else if (fmt->bps == 16 && fmt->block_size == 0x02 * fmt->channel_count && fmt->size == 0x14) {
fmt->coding_type = coding_IMA; /* MX vs ATV Unleashed (PC) codec hijack */
@ -546,7 +548,6 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
/* coding, layout, interleave */
vgmstream->coding_type = fmt.coding_type;
switch (fmt.coding_type) {
case coding_MSADPCM:
case coding_MS_IMA:
case coding_AICA:
case coding_XBOX_IMA:
@ -566,6 +567,12 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = fmt.block_size;
break;
case coding_MSADPCM:
vgmstream->layout_type = layout_none;
vgmstream->frame_size = fmt.block_size;
break;
default:
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = fmt.interleave;

View File

@ -1,17 +1,16 @@
#include "meta.h"
#include "../util.h"
#include "../coding/coding.h"
/* SD9 (found in beatmania IIDX Arcade games) */
/* SD9 - from Konami arcade games [beatmania IIDX series (AC), BeatStream (AC)] */
VGMSTREAM * init_vgmstream_sd9(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int loop_flag, channel_count;
/* check extension */
/* checks */
if (!check_extensions(streamFile, "sd9"))
goto fail;
/* check header */
if (read_32bitBE(0x0, streamFile) != 0x53443900) /* SD9 */
goto fail;
if (read_32bitBE(0x20, streamFile) != 0x52494646) /* RIFF */
@ -30,27 +29,26 @@ VGMSTREAM * init_vgmstream_sd9(STREAMFILE *streamFile) {
//loop_flag = (read_16bitLE(0x0e,streamFile)==0x1);
loop_flag = read_32bitLE(0x18, streamFile); // use loop end
channel_count = read_16bitLE(0x36, streamFile);
start_offset = 0x7a;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count, loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
start_offset = 0x7a;
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x38, streamFile);
vgmstream->coding_type = coding_MSADPCM;
vgmstream->num_samples = read_32bitLE(0x6e, streamFile);
if (loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x14, streamFile) / 2 / channel_count;
vgmstream->loop_end_sample = read_32bitLE(0x18, streamFile) / 2 / channel_count;
}
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = read_16bitLE(0x40, streamFile);
vgmstream->frame_size = read_16bitLE(0x40, streamFile);
vgmstream->meta_type = meta_SD9;
if (!msadpcm_check_coefs(streamFile, 0x48))
goto fail;
/* open the file for reading */
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
goto fail;
return vgmstream;
@ -58,4 +56,4 @@ VGMSTREAM * init_vgmstream_sd9(STREAMFILE *streamFile) {
fail:
close_vgmstream(vgmstream);
return NULL;
}
}

View File

@ -74,11 +74,12 @@ VGMSTREAM * init_vgmstream_smp(STREAMFILE *streamFile) {
case 0x04:
if (bps != 4) goto fail;
/* 0x34: standard MSADPCM coef table */
if (!msadpcm_check_coefs(streamFile, 0x36))
goto fail;
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = 0x86*channel_count;
vgmstream->frame_size = 0x86*channel_count;
break;
case 0x06:

View File

@ -270,13 +270,15 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
case 0x0C: /* MS ADPCM [Final Fantasy XIV (PC) sfx] */
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = read_16bit(extradata_offset+0x0c,streamFile);
/* in extradata_offset is a WAVEFORMATEX (including coefs and all) */
vgmstream->frame_size = read_16bit(extradata_offset + 0x0c, streamFile);
/* WAVEFORMATEX in extradata_offset */
if (!msadpcm_check_coefs(streamFile, extradata_offset + 0x14))
goto fail;
vgmstream->num_samples = msadpcm_bytes_to_samples(stream_size, vgmstream->interleave_block_size, vgmstream->channels);
vgmstream->num_samples = msadpcm_bytes_to_samples(stream_size, vgmstream->frame_size, vgmstream->channels);
if (loop_flag) {
vgmstream->loop_start_sample = msadpcm_bytes_to_samples(loop_start, vgmstream->interleave_block_size, vgmstream->channels);
vgmstream->loop_end_sample = msadpcm_bytes_to_samples(loop_end, vgmstream->interleave_block_size, vgmstream->channels);
vgmstream->loop_start_sample = msadpcm_bytes_to_samples(loop_start, vgmstream->frame_size, vgmstream->channels);
vgmstream->loop_end_sample = msadpcm_bytes_to_samples(loop_end, vgmstream->frame_size, vgmstream->channels);
}
break;

View File

@ -125,11 +125,11 @@ VGMSTREAM * init_vgmstream_sqex_sead(STREAMFILE * streamFile) {
/* 0x00 (2): null?, 0x02(2): entry size? */
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = read_16bit(sead.extradata_offset+0x04,streamFile);
vgmstream->frame_size = read_16bit(sead.extradata_offset+0x04,streamFile);
/* much like AKBs, there are slightly different loop values here, probably more accurate
* (if no loop, loop_end doubles as num_samples) */
vgmstream->num_samples = msadpcm_bytes_to_samples(sead.stream_size, vgmstream->interleave_block_size, vgmstream->channels);
vgmstream->num_samples = msadpcm_bytes_to_samples(sead.stream_size, vgmstream->frame_size, vgmstream->channels);
vgmstream->loop_start_sample = read_32bit(sead.extradata_offset+0x08, streamFile); //loop_start
vgmstream->loop_end_sample = read_32bit(sead.extradata_offset+0x0c, streamFile); //loop_end
break;

View File

@ -337,13 +337,15 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) {
vgmstream->interleave_block_size = txth.interleave;
vgmstream->layout_type = layout_none;
break;
case coding_MSADPCM:
if (vgmstream->channels > 2) goto fail;
if (!txth.interleave) goto fail; /* creates garbage */
if (!txth.interleave) goto fail;
vgmstream->interleave_block_size = txth.interleave;
vgmstream->frame_size = txth.interleave;
vgmstream->layout_type = layout_none;
break;
case coding_XBOX_IMA:
if (txth.codec_mode == 1) { /* mono interleave */
coding = coding_XBOX_IMA_int;

View File

@ -209,9 +209,9 @@ VGMSTREAM * init_vgmstream_ubi_jade(STREAMFILE *streamFile) {
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = 0x24*channel_count;
vgmstream->frame_size = block_size;
vgmstream->num_samples = msadpcm_bytes_to_samples(data_size, vgmstream->interleave_block_size, channel_count);
vgmstream->num_samples = msadpcm_bytes_to_samples(data_size, vgmstream->frame_size, channel_count);
if (!is_jade_v2) {
vgmstream->loop_start_sample = 0;
vgmstream->loop_end_sample = vgmstream->num_samples;
@ -221,7 +221,7 @@ VGMSTREAM * init_vgmstream_ubi_jade(STREAMFILE *streamFile) {
case 0x0001: { /* PS3 */
VGMSTREAM *temp_vgmstream = NULL;
STREAMFILE *temp_streamFile = NULL;
STREAMFILE *temp_sf = NULL;
if (fmt_size != 0x10) goto fail;
if (block_size != 0x02*channel_count) goto fail;
@ -230,11 +230,11 @@ VGMSTREAM * init_vgmstream_ubi_jade(STREAMFILE *streamFile) {
if (read_32bitBE(start_offset, streamFile) != 0x4D534643) /* "MSF\43" */
goto fail;
temp_streamFile = setup_subfile_streamfile(streamFile, start_offset, data_size, "msf");
if (!temp_streamFile) goto fail;
temp_sf = setup_subfile_streamfile(streamFile, start_offset, data_size, "msf");
if (!temp_sf) goto fail;
temp_vgmstream = init_vgmstream_msf(temp_streamFile);
close_streamfile(temp_streamFile);
temp_vgmstream = init_vgmstream_msf(temp_sf);
close_streamfile(temp_sf);
if (!temp_vgmstream) goto fail;
temp_vgmstream->meta_type = vgmstream->meta_type;

View File

@ -94,9 +94,12 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *streamFile) {
/* chunks: "data" */
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = block_align;
vgmstream->frame_size = block_align;
vgmstream->num_samples = msadpcm_bytes_to_samples(data_size, vgmstream->interleave_block_size, channel_count);
vgmstream->num_samples = msadpcm_bytes_to_samples(data_size, vgmstream->frame_size, channel_count);
if (!msadpcm_check_coefs(streamFile, fmt_offset + 0x14))
goto fail;
break;
case 0x5769692061647063: /* "Wii adpc" */

View File

@ -9,23 +9,23 @@ VGMSTREAM * init_vgmstream_vxn(STREAMFILE *streamFile) {
size_t stream_size;
int total_subsongs, target_subsong = streamFile->stream_index;
/* check extensions */
/* checks */
if (!check_extensions(streamFile,"vxn"))
goto fail;
/* check header/version chunk (RIFF-like format with many custom chunks) */
if (read_32bitBE(0x00,streamFile) != 0x566F784E) /* "VoxN" */
goto fail;
if (read_32bitLE(0x10,streamFile) != get_streamfile_size(streamFile) )
goto fail;
/* header is RIFF-like with many custom chunks */
if (!find_chunk_le(streamFile, 0x41666D74,first_offset,0, &chunk_offset,NULL)) /* "Afmt" */
goto fail;
codec = (uint16_t)read_16bitLE(chunk_offset+0x00, streamFile);
channel_count = (uint16_t)read_16bitLE(chunk_offset+0x02, streamFile);
sample_rate = read_32bitLE(chunk_offset+0x04, streamFile);
block_align = (uint16_t)read_16bitLE(chunk_offset+0x08, streamFile);
bits = (uint16_t)read_16bitLE(chunk_offset+0x0a, streamFile);
bits = read_16bitLE(chunk_offset+0x0a, streamFile);
/* files are divided into segment subsongs, often a leadout and loop in that order
* (the "Plst" and "Rule" chunks may have order info) */
@ -67,8 +67,13 @@ VGMSTREAM * init_vgmstream_vxn(STREAMFILE *streamFile) {
if (bits != 4) goto fail;
vgmstream->coding_type = coding_MSADPCM;
vgmstream->interleave_block_size = block_align;
vgmstream->frame_size = block_align;
vgmstream->layout_type = layout_none;
if (find_chunk_le(streamFile, 0x4D736165,first_offset,0, &chunk_offset,NULL)) { /* "Msae" */
if (!msadpcm_check_coefs(streamFile, chunk_offset + 0x02))
goto fail;
}
break;
case 0x0011: /* MS-IMA (ex. Asphalt 6) */
@ -80,17 +85,17 @@ VGMSTREAM * init_vgmstream_vxn(STREAMFILE *streamFile) {
break;
#ifdef VGM_USE_FFMPEG
case 0x0800: { /* Musepack (ex. Asphalt Xtreme) */
ffmpeg_codec_data * ffmpeg_data = NULL;
if (bits != 0xFFFF) goto fail;
case 0x0800: /* Musepack (ex. Asphalt Xtreme) */
if (bits != -1) goto fail;
ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset,stream_size);
if (!ffmpeg_data) goto fail;
vgmstream->codec_data = ffmpeg_data;
vgmstream->codec_data = init_ffmpeg_offset(streamFile, start_offset,stream_size);
if (!vgmstream->codec_data) goto fail;
vgmstream->coding_type = coding_FFmpeg;
vgmstream->layout_type = layout_none;
/* unlike standard .mpc, .vxn has no seek table so no need to fix */
//ffmpeg_set_force_seek(vgmstream->codec_data);
break;
}
#endif
default:
@ -98,7 +103,6 @@ VGMSTREAM * init_vgmstream_vxn(STREAMFILE *streamFile) {
goto fail;
}
/* open the file for reading */
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
goto fail;
return vgmstream;

View File

@ -12,7 +12,7 @@ VGMSTREAM * init_vgmstream_waf(STREAMFILE *streamFile) {
if (!check_extensions(streamFile, "waf"))
goto fail;
if (read_32bitBE(0x00,streamFile) != 0x57414600) /* "WAF\0" "*/
if (read_32bitBE(0x00,streamFile) != 0x57414600) /* "WAF\0" */
goto fail;
if (read_32bitLE(0x34,streamFile) + 0x38 != get_streamfile_size(streamFile))
goto fail;
@ -25,13 +25,17 @@ VGMSTREAM * init_vgmstream_waf(STREAMFILE *streamFile) {
vgmstream = allocate_vgmstream(channel_count, loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = read_32bitLE(0x08, streamFile);
vgmstream->meta_type = meta_WAF;
vgmstream->sample_rate = read_32bitLE(0x08, streamFile);
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = read_16bitLE(0x10, streamFile);
vgmstream->num_samples = msadpcm_bytes_to_samples(read_32bitLE(0x34,streamFile), vgmstream->interleave_block_size, channel_count);
/* 0x04: null?, 0x0c: avg br, 0x12: bps, 0x14: s_p_f, 0x16~34: count + standard MSADPCM coefs (a modified RIFF fmt) */
vgmstream->frame_size = read_16bitLE(0x10, streamFile);
/* 0x04: null?, 0x0c: avg br, 0x12: bps, 0x14: s_p_f, 0x16~34: coefs (a modified RIFF fmt) */
if (!msadpcm_check_coefs(streamFile, 0x16))
goto fail;
vgmstream->num_samples = msadpcm_bytes_to_samples(read_32bitLE(0x34,streamFile), vgmstream->frame_size, channel_count);
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
goto fail;

View File

@ -79,7 +79,12 @@ VGMSTREAM * init_vgmstream_xnb(STREAMFILE *streamFile) {
block_align = read_16bit(current_offset+0x0c, streamFile);
bps = read_16bit(current_offset+0x0e, streamFile);
if (codec == 0x166) {
if (codec == 0x0002) {
if (!msadpcm_check_coefs(streamFile, current_offset + 0x14))
goto fail;
}
if (codec == 0x0166) {
xma2_parse_fmt_chunk_extra(streamFile, current_offset, &loop_flag, &num_samples, &loop_start, &loop_end, big_endian);
xma_chunk_offset = current_offset;
}
@ -122,7 +127,7 @@ VGMSTREAM * init_vgmstream_xnb(STREAMFILE *streamFile) {
if (!block_align) goto fail;
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = block_align;
vgmstream->frame_size = block_align;
vgmstream->num_samples = msadpcm_bytes_to_samples(data_size, block_align, channel_count);
break;

View File

@ -449,7 +449,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
case MS_ADPCM: /* Persona 4 Ultimax (AC) */
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = (xwb.block_align + 22) * xwb.channels; /*22=CONVERSION_OFFSET (?)*/
vgmstream->frame_size = (xwb.block_align + 22) * xwb.channels; /*22=CONVERSION_OFFSET (?)*/
break;
#ifdef VGM_USE_FFMPEG