mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-13 18:20:50 +01:00
Added new GENH codecs: ATRAC3/plus, XMA1/2, FFMPEG
Also some extra fields: total samples, skip samples, data size, atrac3/xma modes
This commit is contained in:
parent
2cdef093cb
commit
ce591bbe12
@ -23,6 +23,11 @@ typedef enum {
|
|||||||
MS_IMA = 15, /* Microsoft IMA ADPCM */
|
MS_IMA = 15, /* Microsoft IMA ADPCM */
|
||||||
PCM8_U = 16, /* 8bit unsigned PCM */
|
PCM8_U = 16, /* 8bit unsigned PCM */
|
||||||
APPLE_IMA4 = 17, /* Apple Quicktime 4-bit IMA ADPCM */
|
APPLE_IMA4 = 17, /* Apple Quicktime 4-bit IMA ADPCM */
|
||||||
|
ATRAC3 = 18, /* raw ATRAC3 */
|
||||||
|
ATRAC3PLUS = 19, /* raw ATRAC3PLUS */
|
||||||
|
XMA1 = 20, /* raw XMA1 */
|
||||||
|
XMA2 = 21, /* raw XMA2 */
|
||||||
|
FFMPEG = 22, /* any headered FFmpeg format */
|
||||||
} genh_type;
|
} genh_type;
|
||||||
|
|
||||||
/* GENH is an artificial "generic" header for headerless streams */
|
/* GENH is an artificial "generic" header for headerless streams */
|
||||||
@ -30,12 +35,15 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
|
||||||
int channel_count, loop_flag, sample_rate, interleave;
|
int channel_count, loop_flag, sample_rate, interleave;
|
||||||
int32_t num_samples = 0, loop_start, loop_end;
|
int32_t num_samples = 0, loop_start, loop_end, skip_samples = 0;
|
||||||
int32_t start_offset, header_size;
|
int32_t start_offset, header_size;
|
||||||
|
off_t datasize = 0;
|
||||||
|
|
||||||
int32_t coef[2];
|
int32_t coef[2];
|
||||||
int32_t coef_splitted[2];
|
int32_t coef_splitted[2];
|
||||||
int32_t dsp_interleave_type;
|
int32_t dsp_interleave_type;
|
||||||
int32_t coef_type;
|
int32_t coef_type;
|
||||||
|
int skip_samples_mode, atrac3_mode, xma_mode;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
coding_t coding;
|
coding_t coding;
|
||||||
@ -73,6 +81,13 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
case MS_IMA: coding = coding_MS_IMA; break;
|
case MS_IMA: coding = coding_MS_IMA; break;
|
||||||
case PCM8_U: coding = coding_PCM8_U; break;
|
case PCM8_U: coding = coding_PCM8_U; break;
|
||||||
case APPLE_IMA4: coding = coding_APPLE_IMA4; break;
|
case APPLE_IMA4: coding = coding_APPLE_IMA4; break;
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case ATRAC3:
|
||||||
|
case ATRAC3PLUS:
|
||||||
|
case XMA1:
|
||||||
|
case XMA2:
|
||||||
|
case FFMPEG: coding = coding_FFmpeg; break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -106,6 +121,16 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
coef_splitted[0] = read_32bitLE(0x34,streamFile);
|
coef_splitted[0] = read_32bitLE(0x34,streamFile);
|
||||||
coef_splitted[1] = read_32bitLE(0x38,streamFile);
|
coef_splitted[1] = read_32bitLE(0x38,streamFile);
|
||||||
|
|
||||||
|
/* other fields */
|
||||||
|
num_samples = read_32bitLE(0x40,streamFile);
|
||||||
|
skip_samples = read_32bitLE(0x44,streamFile); /* for FFmpeg based codecs */
|
||||||
|
skip_samples_mode = read_8bit(0x48,streamFile); /* 0=autodetect, 1=force manual value @ 0x44 */
|
||||||
|
atrac3_mode = read_8bit(0x49,streamFile); /* 0=autodetect, 1=force joint stereo, 2=force full stereo */
|
||||||
|
xma_mode = read_8bit(0x4a,streamFile); /* 0=default (4ch = 2ch + 2ch), 1=single (4ch = 1ch + 1ch + 1ch + 1ch) */
|
||||||
|
datasize = read_32bitLE(0x50,streamFile);
|
||||||
|
if (!datasize)
|
||||||
|
datasize = get_streamfile_size(streamFile)-start_offset;
|
||||||
|
|
||||||
num_samples = num_samples > 0 ? num_samples : loop_end;
|
num_samples = num_samples > 0 ? num_samples : loop_end;
|
||||||
loop_flag = loop_start != -1;
|
loop_flag = loop_start != -1;
|
||||||
|
|
||||||
@ -223,6 +248,68 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
if (!vgmstream->codec_data) goto fail;
|
if (!vgmstream->codec_data) goto fail;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case coding_FFmpeg: {
|
||||||
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
|
|
||||||
|
if (type == FFMPEG) {
|
||||||
|
/* default FFmpeg */
|
||||||
|
ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset,datasize);
|
||||||
|
if ( !ffmpeg_data ) goto fail;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* fake header FFmpeg */
|
||||||
|
uint8_t buf[200];
|
||||||
|
int32_t bytes;
|
||||||
|
|
||||||
|
if (type == ATRAC3) {
|
||||||
|
int block_size = interleave;
|
||||||
|
int joint_stereo;
|
||||||
|
switch(atrac3_mode) {
|
||||||
|
case 0: joint_stereo = vgmstream->channels > 1 && interleave/vgmstream->channels==0x60 ? 1 : 0; break; /* autodetect */
|
||||||
|
case 1: joint_stereo = 1; break; /* force joint stereo */
|
||||||
|
case 2: joint_stereo = 0; break; /* force stereo */
|
||||||
|
default: goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes = ffmpeg_make_riff_atrac3(buf, 200, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, skip_samples);
|
||||||
|
}
|
||||||
|
else if (type == ATRAC3PLUS) {
|
||||||
|
int block_size = interleave;
|
||||||
|
|
||||||
|
bytes = ffmpeg_make_riff_atrac3plus(buf, 200, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_size, skip_samples);
|
||||||
|
}
|
||||||
|
else if (type == XMA1) {
|
||||||
|
int xma_stream_mode = xma_mode == 1 ? 1 : 0;
|
||||||
|
|
||||||
|
bytes = ffmpeg_make_riff_xma1(buf, 100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode);
|
||||||
|
}
|
||||||
|
else if (type == XMA2) {
|
||||||
|
int block_size = interleave ? interleave : 2048;
|
||||||
|
int block_count = datasize / block_size;
|
||||||
|
|
||||||
|
bytes = ffmpeg_make_riff_xma2(buf, 200, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
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->layout_type = layout_none;
|
||||||
|
|
||||||
|
/* force encoder delay */
|
||||||
|
if (skip_samples_mode) {
|
||||||
|
ffmpeg_set_skip_samples(ffmpeg_data, skip_samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user