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 */
|
||||
PCM8_U = 16, /* 8bit unsigned PCM */
|
||||
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 is an artificial "generic" header for headerless streams */
|
||||
@ -30,12 +35,15 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
|
||||
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;
|
||||
off_t datasize = 0;
|
||||
|
||||
int32_t coef[2];
|
||||
int32_t coef_splitted[2];
|
||||
int32_t dsp_interleave_type;
|
||||
int32_t coef_type;
|
||||
int skip_samples_mode, atrac3_mode, xma_mode;
|
||||
int i, j;
|
||||
|
||||
coding_t coding;
|
||||
@ -73,6 +81,13 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
case MS_IMA: coding = coding_MS_IMA; break;
|
||||
case PCM8_U: coding = coding_PCM8_U; 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:
|
||||
goto fail;
|
||||
}
|
||||
@ -106,6 +121,16 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
coef_splitted[0] = read_32bitLE(0x34,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;
|
||||
loop_flag = loop_start != -1;
|
||||
|
||||
@ -223,6 +248,68 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
|
||||
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
|
||||
default:
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user