mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-16 11:33:20 +01:00
commit
a36bf19790
@ -538,6 +538,7 @@ DECLARE_MULTIPLE_FILE_TYPE("LWAV Audio File (*.LWAV)", lwav);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("MATX Audio File (*.MATX)", matx);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("MCA Audio File (*.MCA)", mca);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("MCG Audio File (*.MCG)", mcg);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("MDS Audio File (*.MDS)", mds);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("PS2 MI4 Audio File (*.MI4)", mi4);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("PS2 MIB Audio File (*.MIB)", mib);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("PS2 MIC Audio File (*.MIC)", mic);
|
||||
|
@ -166,6 +166,7 @@ void ffmpeg_set_skip_samples(ffmpeg_codec_data * data, int skip_samples);
|
||||
/* ffmpeg_decoder_utils */
|
||||
int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, uint16_t codec);
|
||||
int ffmpeg_make_riff_atrac3(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int joint_stereo, int encoder_delay);
|
||||
int ffmpeg_make_riff_atrac3plus(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int encoder_delay);
|
||||
int ffmpeg_make_riff_xma1(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int stream_mode);
|
||||
int ffmpeg_make_riff_xma2(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_count, int block_size);
|
||||
int ffmpeg_make_riff_xma2_from_fmt(uint8_t * buf, size_t buf_size, off_t fmt_offset, size_t fmt_size, size_t data_size, STREAMFILE *streamFile, int big_endian);
|
||||
|
@ -73,6 +73,49 @@ int ffmpeg_make_riff_atrac3(uint8_t * buf, size_t buf_size, size_t sample_count,
|
||||
return riff_size;
|
||||
}
|
||||
|
||||
int ffmpeg_make_riff_atrac3plus(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int encoder_delay) {
|
||||
uint16_t codec_ATRAC3plus = 0xfffe; /* wave format extensible */
|
||||
size_t riff_size = 4+4+ 4 + 0x3c + 0x14 + 4+4;
|
||||
|
||||
if (buf_size < riff_size)
|
||||
return -1;
|
||||
|
||||
memcpy(buf+0x00, "RIFF", 4);
|
||||
put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */
|
||||
memcpy(buf+0x08, "WAVE", 4);
|
||||
|
||||
memcpy(buf+0x0c, "fmt ", 4);
|
||||
put_32bitLE(buf+0x10, 0x34);/*fmt size*/
|
||||
put_16bitLE(buf+0x14, codec_ATRAC3plus);
|
||||
put_16bitLE(buf+0x16, channels);
|
||||
put_32bitLE(buf+0x18, sample_rate);
|
||||
put_32bitLE(buf+0x1c, sample_rate*channels / sizeof(sample)); /* average bytes per second (wrong) */
|
||||
put_32bitLE(buf+0x20, (int16_t)(block_align)); /* block align */
|
||||
|
||||
put_16bitLE(buf+0x24, 0x22); /* extra data size */
|
||||
put_16bitLE(buf+0x26, 0x0800); /* samples per block */
|
||||
put_32bitLE(buf+0x28, 0x0000003); /* unknown */
|
||||
put_32bitBE(buf+0x2c, 0xBFAA23E9); /* GUID1 */
|
||||
put_32bitBE(buf+0x30, 0x58CB7144); /* GUID2 */
|
||||
put_32bitBE(buf+0x34, 0xA119FFFA); /* GUID3 */
|
||||
put_32bitBE(buf+0x38, 0x01E4CE62); /* GUID4 */
|
||||
put_16bitBE(buf+0x3c, 0x0010); /* unknown */
|
||||
put_16bitBE(buf+0x3e, 0x0000); /* config */ //todo this varies with block size, but FFmpeg doesn't use it
|
||||
put_32bitBE(buf+0x40, 0x00000000); /* empty */
|
||||
put_32bitBE(buf+0x44, 0x00000000); /* empty */
|
||||
|
||||
memcpy(buf+0x48, "fact", 4);
|
||||
put_32bitLE(buf+0x4c, 0x0c); /* fact size */
|
||||
put_32bitLE(buf+0x50, sample_count);
|
||||
put_32bitLE(buf+0x54, 0); /* unknown */
|
||||
put_32bitLE(buf+0x58, encoder_delay);
|
||||
|
||||
memcpy(buf+0x5c, "data", 4);
|
||||
put_32bitLE(buf+0x60, data_size); /* data size */
|
||||
|
||||
return riff_size;
|
||||
}
|
||||
|
||||
int ffmpeg_make_riff_xma1(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int stream_mode) {
|
||||
uint16_t codec_XMA1 = 0x0165;
|
||||
size_t riff_size;
|
||||
|
@ -9,6 +9,11 @@
|
||||
* - interleave: blocks and channels are handled externally (layouts) or internally (mixed channels)
|
||||
* - block header: none (external), normal (4 bytes of history 16b + step 16b) or others; per channel/global
|
||||
* - expand type: ms-ima style or others; low or high nibble first
|
||||
*
|
||||
* todo:
|
||||
* MS IMAs have the last sample of the prev block in the block header. In Microsoft implementation, the header sample
|
||||
* is written first and last sample is skipped (since they match). vgmstream ignores the header sample and
|
||||
* writes the last one instead. This means the very first sample in the first header in a stream is incorrectly skipped.
|
||||
*/
|
||||
|
||||
static const int32_t ADPCMTable[89] =
|
||||
@ -34,9 +39,27 @@ static const int IMA_IndexTable[16] =
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* expands one nibble to one PCM sample, MS-IMA style
|
||||
*/
|
||||
/* Original IMA */
|
||||
static void ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
|
||||
int sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
//"original" ima nibble expansion
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = *hist1 << 3;
|
||||
step = ADPCMTable[*step_index];
|
||||
delta = step * (sample_nibble & 7) * 2 + step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
*hist1 = clamp16(sample_decoded >> 3);
|
||||
*step_index += IMA_IndexTable[sample_nibble];
|
||||
if (*step_index < 0) *step_index=0;
|
||||
if (*step_index > 88) *step_index=88;
|
||||
}
|
||||
|
||||
/* Microsoft's IMA (most common) */
|
||||
static void ms_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
|
||||
int sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
@ -58,6 +81,68 @@ static void ms_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, i
|
||||
if (*step_index > 88) *step_index=88;
|
||||
}
|
||||
|
||||
/* Apple's MS IMA variation. Exactly the same except it uses 16b history (probably more sensitive to overflow/sign extend) */
|
||||
static void ms_ima_expand_nibble_16(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int16_t * hist1, int32_t * step_index) {
|
||||
int sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = *hist1;
|
||||
step = ADPCMTable[*step_index];
|
||||
delta = step >> 3;
|
||||
if (sample_nibble & 1) delta += step >> 2;
|
||||
if (sample_nibble & 2) delta += step >> 1;
|
||||
if (sample_nibble & 4) delta += step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
*hist1 = clamp16(sample_decoded); //no need for this actually
|
||||
*step_index += IMA_IndexTable[sample_nibble];
|
||||
if (*step_index < 0) *step_index=0;
|
||||
if (*step_index > 88) *step_index=88;
|
||||
}
|
||||
|
||||
/* update step_index before doing current sample */
|
||||
static void snds_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
|
||||
int sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
|
||||
*step_index += IMA_IndexTable[sample_nibble];
|
||||
if (*step_index < 0) *step_index=0;
|
||||
if (*step_index > 88) *step_index=88;
|
||||
|
||||
step = ADPCMTable[*step_index];
|
||||
delta = (sample_nibble & 7) * step / 4 + step / 8;
|
||||
if (sample_nibble & 8) delta = -delta;
|
||||
sample_decoded = *hist1 + delta;
|
||||
|
||||
*hist1 = clamp16(sample_decoded);
|
||||
}
|
||||
|
||||
/* algorithm by aluigi, unsure if it's a known IMA variation */
|
||||
static void otns_ima_expand_nibble(VGMSTREAMCHANNEL * stream, off_t byte_offset, int nibble_shift, int32_t * hist1, int32_t * step_index) {
|
||||
int sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = *hist1;
|
||||
step = ADPCMTable[*step_index];
|
||||
delta = 0;
|
||||
if(sample_nibble & 4) delta = step << 2;
|
||||
if(sample_nibble & 2) delta += step << 1;
|
||||
if(sample_nibble & 1) delta += step;
|
||||
delta >>= 2;
|
||||
if(sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
*hist1 = clamp16(sample_decoded);
|
||||
*step_index += IMA_IndexTable[sample_nibble];
|
||||
if (*step_index < 0) *step_index=0;
|
||||
if (*step_index > 88) *step_index=88;
|
||||
}
|
||||
|
||||
|
||||
void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
@ -79,29 +164,10 @@ void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
|
||||
}
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
off_t byte_offset = stream->offset + 4 + i/2;
|
||||
nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
//normal ima nibble expansion
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = hist1;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = step >> 3;
|
||||
if (sample_nibble & 1) delta += step >> 2;
|
||||
if (sample_nibble & 2) delta += step >> 1;
|
||||
if (sample_nibble & 4) delta += step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
step_index += IMA_IndexTable[sample_nibble];
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
int nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
ms_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -128,29 +194,10 @@ void decode_dat4_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspac
|
||||
}
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
off_t byte_offset = stream->offset + 4 + i/2;
|
||||
nibble_shift = (i&1?0:4); //high nibble first
|
||||
|
||||
//normal ima nibble expansion
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = hist1;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = step >> 3;
|
||||
if (sample_nibble & 1) delta += step >> 2;
|
||||
if (sample_nibble & 2) delta += step >> 1;
|
||||
if (sample_nibble & 4) delta += step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
step_index += IMA_IndexTable[sample_nibble];
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
int nibble_shift = (i&1?0:4); //high nibble first
|
||||
|
||||
ms_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -179,29 +226,10 @@ void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * out
|
||||
}
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
off_t byte_offset = stream->offset + 4*channel + 4*vgmstream->channels + i/8*4*vgmstream->channels + (i%8)/2;
|
||||
nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
//normal ima nibble expansion
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = hist1;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = step >> 3;
|
||||
if (sample_nibble & 1) delta += step >> 2;
|
||||
if (sample_nibble & 2) delta += step >> 1;
|
||||
if (sample_nibble & 4) delta += step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
step_index += IMA_IndexTable[sample_nibble];
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
int nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
ms_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -233,29 +261,10 @@ void decode_rad_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * ou
|
||||
}
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
off_t byte_offset = stream->offset + 4*vgmstream->channels + channel + i/2*vgmstream->channels;
|
||||
nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
//normal ima nibble expansion
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = hist1;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = step >> 3;
|
||||
if (sample_nibble & 1) delta += step >> 2;
|
||||
if (sample_nibble & 2) delta += step >> 1;
|
||||
if (sample_nibble & 4) delta += step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
step_index += IMA_IndexTable[sample_nibble];
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
int nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
ms_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -287,29 +296,10 @@ void decode_rad_ima_mono(VGMSTREAMCHANNEL * stream, sample * outbuf, int channel
|
||||
}
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
off_t byte_offset = stream->offset + 4 + i/2;
|
||||
nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
//normal ima nibble expansion
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = hist1;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = step >> 3;
|
||||
if (sample_nibble & 1) delta += step >> 2;
|
||||
if (sample_nibble & 2) delta += step >> 1;
|
||||
if (sample_nibble & 4) delta += step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
step_index += IMA_IndexTable[sample_nibble];
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
int nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
ms_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -330,7 +320,7 @@ void decode_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * o
|
||||
//internal interleave (0x20+4 size), mixed channels (4 byte per ch, mixed stereo)
|
||||
int block_samples = (vgmstream->channels==1) ?
|
||||
32 :
|
||||
32*(vgmstream->channels&2);//todo this can be zero in 4/5/8ch = SEGFAULT using %
|
||||
32*(vgmstream->channels&2);//todo this can be zero in 4/5/8ch = SEGFAULT using % below
|
||||
first_sample = first_sample % block_samples;
|
||||
|
||||
//normal header (per channel)
|
||||
@ -349,7 +339,7 @@ void decode_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * o
|
||||
}
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
int nibble_shift;
|
||||
|
||||
if(vgmstream->layout_type==layout_ea_blocked)
|
||||
offset = stream->offset + 4 + i/8*4 + (i%8)/2;
|
||||
@ -360,24 +350,7 @@ void decode_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * o
|
||||
}
|
||||
nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
//normal ima nibble expansion
|
||||
sample_nibble = (read_8bit(offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = hist1;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = step >> 3;
|
||||
if (sample_nibble & 1) delta += step >> 2;
|
||||
if (sample_nibble & 2) delta += step >> 1;
|
||||
if (sample_nibble & 4) delta += step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
step_index += IMA_IndexTable[sample_nibble];
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
|
||||
ms_ima_expand_nibble(stream, offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -410,7 +383,7 @@ void decode_int_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample
|
||||
//semi-internal interleave (0x24 size), mixed channels (4 byte per ch)?
|
||||
int block_samples = (vgmstream->channels==1) ?
|
||||
32 :
|
||||
32*(vgmstream->channels&2);//todo this can be zero in 4/5/8ch = SEGFAULT using %
|
||||
32*(vgmstream->channels&2);//todo this can be zero in 4/5/8ch = SEGFAULT using % below
|
||||
first_sample = first_sample % block_samples;
|
||||
|
||||
//normal header
|
||||
@ -424,29 +397,12 @@ void decode_int_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample
|
||||
}
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
int nibble_shift;
|
||||
|
||||
offset = stream->offset + 4 + i/8*4 + (i%8)/2;
|
||||
nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
//normal ima nibble expansion
|
||||
sample_nibble = (read_8bit(offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = hist1;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = step >> 3;
|
||||
if (sample_nibble & 1) delta += step >> 2;
|
||||
if (sample_nibble & 2) delta += step >> 1;
|
||||
if (sample_nibble & 4) delta += step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
step_index += IMA_IndexTable[sample_nibble];
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
|
||||
ms_ima_expand_nibble(stream, offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -474,29 +430,10 @@ void decode_dvi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
|
||||
//no header
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
off_t byte_offset = stream->offset + i/2;
|
||||
nibble_shift = (i&1?0:4); //high nibble first (old-style DVI)
|
||||
|
||||
//normal ima nibble expansion
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = hist1;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = step >> 3;
|
||||
if (sample_nibble & 1) delta += step >> 2;
|
||||
if (sample_nibble & 2) delta += step >> 1;
|
||||
if (sample_nibble & 4) delta += step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
step_index += IMA_IndexTable[sample_nibble&0x7]; //todo unneeded &0x7?
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
int nibble_shift = (i&1?0:4); //high nibble first (old-style DVI)
|
||||
|
||||
ms_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -521,29 +458,10 @@ void decode_eacs_ima(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing,
|
||||
vgmstream->get_high_nibble = !vgmstream->get_high_nibble;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
off_t byte_offset = stream->offset + i;
|
||||
nibble_shift = (vgmstream->get_high_nibble?0:4); //variable nibble order
|
||||
|
||||
//normal ima nibble expansion
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = hist1;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = step >> 3;
|
||||
if (sample_nibble & 1) delta += step >> 2;
|
||||
if (sample_nibble & 2) delta += step >> 1;
|
||||
if (sample_nibble & 4) delta += step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
step_index += IMA_IndexTable[sample_nibble&0x7]; //todo unneeded &0x7?
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
int nibble_shift = (vgmstream->get_high_nibble?0:4); //variable nibble order
|
||||
|
||||
ms_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -562,26 +480,10 @@ void decode_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||
//no header
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
off_t byte_offset = stream->offset + i/2;
|
||||
nibble_shift = (i&1?4:0); //low nibble order
|
||||
|
||||
//"original" ima nibble expansion
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = hist1 << 3;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = step * (sample_nibble & 7) * 2 + step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded >> 3);
|
||||
step_index += IMA_IndexTable[sample_nibble&0x7]; //todo unneeded &0x7?
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
int nibble_shift = (i&1?4:0); //low nibble order
|
||||
|
||||
ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -610,29 +512,10 @@ void decode_apple_ima4(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelsp
|
||||
}
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
off_t byte_offset = packet_offset + 2 + i/2;
|
||||
nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
//normal ima nibble expansion
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
sample_decoded = hist1;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = step >> 3;
|
||||
if (sample_nibble & 1) delta += step >> 2;
|
||||
if (sample_nibble & 2) delta += step >> 1;
|
||||
if (sample_nibble & 4) delta += step;
|
||||
if (sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
step_index += IMA_IndexTable[sample_nibble&0x7]; //todo unneeded &0x7?
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
int nibble_shift = (i&1?4:0); //low nibble first
|
||||
|
||||
ms_ima_expand_nibble_16(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -651,25 +534,10 @@ void decode_snds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspac
|
||||
//no header
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
off_t byte_offset = stream->offset + i;//one nibble per channel
|
||||
nibble_shift = (channel==0?0:4); //high nibble first, based on channel
|
||||
|
||||
//snds nibble expansion (update step_index before doing current sample)
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
|
||||
step_index += IMA_IndexTable[sample_nibble];
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
|
||||
step = ADPCMTable[step_index];
|
||||
delta = (sample_nibble & 7) * step / 4 + step / 8;
|
||||
if (sample_nibble & 8) delta = -delta;
|
||||
sample_decoded = hist1 + delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
int nibble_shift = (channel==0?0:4); //high nibble first, based on channel
|
||||
|
||||
snds_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
@ -688,33 +556,12 @@ void decode_otns_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample *
|
||||
//no header
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int nibble_shift, sample_nibble, sample_decoded, step, delta;
|
||||
|
||||
off_t byte_offset = stream->offset + (vgmstream->channels==1 ? i/2 : i); //one nibble per channel if stereo
|
||||
nibble_shift = (vgmstream->channels==1) ? //todo simplify
|
||||
int nibble_shift = (vgmstream->channels==1) ? //todo simplify
|
||||
(i&1?0:4) : //high nibble first(?)
|
||||
(channel==0?4:0); //low=ch0, high=ch1 (this is correct compared to vids)
|
||||
|
||||
//OTNS nibble expansion (algorithm by aluigi, unsure if it's a known ADPCM codec)
|
||||
sample_nibble = (read_8bit(byte_offset,stream->streamfile) >> nibble_shift)&0xf;
|
||||
|
||||
sample_decoded = hist1;
|
||||
step = ADPCMTable[step_index];
|
||||
delta = 0;
|
||||
if(sample_nibble & 4) delta = step << 2;
|
||||
if(sample_nibble & 2) delta += step << 1;
|
||||
if(sample_nibble & 1) delta += step;
|
||||
delta >>= 2;
|
||||
if(sample_nibble & 8)
|
||||
sample_decoded -= delta;
|
||||
else
|
||||
sample_decoded += delta;
|
||||
|
||||
hist1 = clamp16(sample_decoded);
|
||||
step_index += IMA_IndexTable[sample_nibble];
|
||||
if (step_index < 0) step_index=0;
|
||||
if (step_index > 88) step_index=88;
|
||||
|
||||
otns_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index);
|
||||
outbuf[sample_count] = (short)(hist1);
|
||||
}
|
||||
|
||||
|
@ -151,6 +151,7 @@ static const char* extension_list[] = {
|
||||
"matx",
|
||||
"mca",
|
||||
"mcg",
|
||||
"mds",
|
||||
"mi4",
|
||||
"mib",
|
||||
"mic",
|
||||
|
387
src/meta/genh.c
387
src/meta/genh.c
@ -1,120 +1,93 @@
|
||||
#include "../vgmstream.h"
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* GENH is an artificial "generic" header for headerless streams */
|
||||
/* known GENH types */
|
||||
typedef enum {
|
||||
PSX = 0, /* PSX ADPCM */
|
||||
XBOX = 1, /* XBOX IMA ADPCM */
|
||||
NGC_DTK = 2, /* NGC ADP/DTK ADPCM */
|
||||
PCM16BE = 3, /* 16bit big endian PCM */
|
||||
PCM16LE = 4, /* 16bit little endian PCM */
|
||||
PCM8 = 5, /* 8bit PCM */
|
||||
SDX2 = 6, /* SDX2 (3D0 games) */
|
||||
DVI_IMA = 7, /* DVI IMA ADPCM */
|
||||
MPEG = 8, /* MPEG (MP3) */
|
||||
IMA = 9, /* IMA ADPCM */
|
||||
AICA = 10, /* AICA ADPCM (dreamcast) */
|
||||
MSADPCM = 11, /* MS ADPCM (windows) */
|
||||
NGC_DSP = 12, /* NGC DSP (GC) */
|
||||
PCM8_U_int = 13, /* 8bit unsigned PCM (interleaved) */
|
||||
PSX_bf = 14, /* PSX ADPCM bad flagged */
|
||||
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 */
|
||||
VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
|
||||
int32_t channel_count;
|
||||
int32_t interleave;
|
||||
int32_t sample_rate;
|
||||
int32_t loop_start;
|
||||
int32_t loop_end;
|
||||
int32_t start_offset;
|
||||
int32_t header_size;
|
||||
int channel_count, loop_flag, sample_rate, interleave;
|
||||
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;
|
||||
|
||||
char filename[PATH_LIMIT];
|
||||
int coding;
|
||||
coding_t coding;
|
||||
genh_type type;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("genh",filename_extension(filename))) goto fail;
|
||||
if (!check_extensions(streamFile,"genh")) goto fail;
|
||||
|
||||
/* check header magic */
|
||||
if (read_32bitBE(0x0,streamFile) != 0x47454e48) goto fail;
|
||||
|
||||
/* check channel count (needed for ADP/DTK check) */
|
||||
channel_count = read_32bitLE(0x4,streamFile);
|
||||
if (channel_count < 1) goto fail;
|
||||
|
||||
/* check format */
|
||||
/* 0 = PSX ADPCM */
|
||||
/* 1 = XBOX IMA ADPCM */
|
||||
/* 2 = NGC ADP/DTK ADPCM */
|
||||
/* 3 = 16bit big endian PCM */
|
||||
/* 4 = 16bit little endian PCM */
|
||||
/* 5 = 8bit PCM */
|
||||
/* 6 = SDX2 */
|
||||
/* 7 = DVI IMA */
|
||||
/* 8 = MPEG-1 Layer III, possibly also the MPEG-2 and 2.5 extensions */
|
||||
/* 9 = IMA */
|
||||
/* 10 = AICA ADPCM */
|
||||
/* 11 = MS ADPCM */
|
||||
/* 12 = NGC DSP */
|
||||
/* 13 = 8bit unsingned PCM */
|
||||
/* 14 = PSX ADPCM (bad flagged) */
|
||||
/* 15 = Microsoft IMA (MS ADPCM) */
|
||||
/* 16 = 8-bit PCM (unsigned) */
|
||||
/* 17 = Apple Quicktime 4-bit IMA ADPCM */
|
||||
|
||||
switch (read_32bitLE(0x18,streamFile)) {
|
||||
case 0:
|
||||
coding = coding_PSX;
|
||||
break;
|
||||
case 1:
|
||||
coding = coding_XBOX;
|
||||
break;
|
||||
case 2:
|
||||
coding = coding_NGC_DTK;
|
||||
if (channel_count != 2) goto fail;
|
||||
break;
|
||||
case 3:
|
||||
coding = coding_PCM16BE;
|
||||
break;
|
||||
case 4:
|
||||
coding = coding_PCM16LE;
|
||||
break;
|
||||
case 5:
|
||||
coding = coding_PCM8;
|
||||
break;
|
||||
case 6:
|
||||
coding = coding_SDX2;
|
||||
break;
|
||||
case 7:
|
||||
coding = coding_DVI_IMA;
|
||||
break;
|
||||
type = read_32bitLE(0x18,streamFile);
|
||||
/* type to coding conversion */
|
||||
switch (type) {
|
||||
case PSX: coding = coding_PSX; break;
|
||||
case XBOX: coding = coding_XBOX; break;
|
||||
case NGC_DTK: coding = coding_NGC_DTK; break;
|
||||
case PCM16BE: coding = coding_PCM16BE; break;
|
||||
case PCM16LE: coding = coding_PCM16LE; break;
|
||||
case PCM8: coding = coding_PCM8; break;
|
||||
case SDX2: coding = coding_SDX2; break;
|
||||
case DVI_IMA: coding = coding_DVI_IMA; break;
|
||||
#ifdef VGM_USE_MPEG
|
||||
case 8:
|
||||
/* we say MPEG-1 L3 here, but later find out exactly which */
|
||||
coding = coding_MPEG1_L3;
|
||||
break;
|
||||
case MPEG: coding = coding_MPEG1_L3; break; /* we later find out exactly which */
|
||||
#endif
|
||||
case IMA: coding = coding_IMA; break;
|
||||
case AICA: coding = coding_AICA; break;
|
||||
case MSADPCM: coding = coding_MSADPCM; break;
|
||||
case NGC_DSP: coding = coding_NGC_DSP; break;
|
||||
case PCM8_U_int: coding = coding_PCM8_U_int; break;
|
||||
case PSX_bf: coding = coding_PSX_badflags; break;
|
||||
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
|
||||
case 9:
|
||||
coding = coding_IMA;
|
||||
break;
|
||||
case 10:
|
||||
coding = coding_AICA;
|
||||
break;
|
||||
case 11:
|
||||
coding = coding_MSADPCM;
|
||||
break;
|
||||
case 12:
|
||||
coding = coding_NGC_DSP;
|
||||
break;
|
||||
case 13:
|
||||
coding = coding_PCM8_U_int;
|
||||
break;
|
||||
case 14:
|
||||
coding = coding_PSX_badflags;
|
||||
break;
|
||||
case 15:
|
||||
coding = coding_MS_IMA;
|
||||
break;
|
||||
case 16:
|
||||
coding = coding_PCM8_U;
|
||||
break;
|
||||
case 17:
|
||||
coding = coding_APPLE_IMA4;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
@ -144,26 +117,34 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
/* bit 0 - split coefs (2 arrays) */
|
||||
/* bit 1 - little endian coefs */
|
||||
coef_type = read_32bitLE(0x30,streamFile);
|
||||
|
||||
/* when using split coefficients, 2nd array is at: */
|
||||
coef_splitted[0] = read_32bitLE(0x34,streamFile);
|
||||
coef_splitted[1] = read_32bitLE(0x38,streamFile);
|
||||
|
||||
//if (coding == coding_XBOX && channel_count != 2) goto fail;
|
||||
/* 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;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,(loop_start!=-1));
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital information */
|
||||
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = loop_end;
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = loop_end;
|
||||
vgmstream->loop_flag = (loop_start != -1);
|
||||
|
||||
/* codec specific */
|
||||
switch (coding) {
|
||||
case coding_PCM8_U_int:
|
||||
vgmstream->layout_type=layout_none;
|
||||
@ -178,7 +159,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
case coding_DVI_IMA:
|
||||
case coding_IMA:
|
||||
case coding_AICA:
|
||||
case coding_APPLE_IMA4:
|
||||
case coding_APPLE_IMA4:
|
||||
vgmstream->interleave_block_size = interleave;
|
||||
if (channel_count > 1)
|
||||
{
|
||||
@ -186,6 +167,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
coding = coding_SDX2_int;
|
||||
vgmstream->coding_type = coding_SDX2_int;
|
||||
}
|
||||
//todo if 0 do this too (most codecs seem to enter an infinite loop otherwise)
|
||||
if(vgmstream->interleave_block_size==0xffffffff)
|
||||
vgmstream->layout_type=layout_none;
|
||||
else {
|
||||
@ -198,6 +180,15 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
} else {
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
|
||||
/* setup adpcm */
|
||||
if (coding == coding_AICA) {
|
||||
int i;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].adpcm_step_index = 0x7f;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case coding_MS_IMA:
|
||||
vgmstream->interleave_block_size = interleave;
|
||||
@ -212,6 +203,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
case coding_NGC_DTK:
|
||||
if (channel_count != 2) goto fail;
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
case coding_NGC_DSP:
|
||||
@ -224,134 +216,115 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
} else if (dsp_interleave_type == 2) {
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
|
||||
/* get coefs */
|
||||
for (i=0;i<channel_count;i++) {
|
||||
int16_t (*read_16bit)(off_t , STREAMFILE*);
|
||||
/* bit 1 - little endian coefs */
|
||||
if ((coef_type & 2) == 0) {
|
||||
read_16bit = read_16bitBE;
|
||||
} else {
|
||||
read_16bit = read_16bitLE;
|
||||
}
|
||||
|
||||
/* bit 0 - split coefs (2 arrays) */
|
||||
if ((coef_type & 1) == 0) {
|
||||
for (j=0;j<16;j++) {
|
||||
vgmstream->ch[i].adpcm_coef[j] = read_16bit(coef[i]+j*2,streamFile);
|
||||
}
|
||||
} else {
|
||||
for (j=0;j<8;j++) {
|
||||
vgmstream->ch[i].adpcm_coef[j*2]=read_16bit(coef[i]+j*2,streamFile);
|
||||
vgmstream->ch[i].adpcm_coef[j*2+1]=read_16bit(coef_splitted[i]+j*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#ifdef VGM_USE_MPEG
|
||||
case coding_MPEG1_L3:
|
||||
vgmstream->layout_type = layout_mpeg;
|
||||
vgmstream->codec_data = init_mpeg_codec_data(streamFile, start_offset, &coding, vgmstream->channels);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
vgmstream->coding_type = coding;
|
||||
vgmstream->meta_type = meta_GENH;
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case coding_FFmpeg: {
|
||||
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||
|
||||
STREAMFILE * chstreamfile = 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;
|
||||
|
||||
for (i=0;i<channel_count;i++) {
|
||||
off_t chstart_offset = start_offset;
|
||||
|
||||
switch (coding) {
|
||||
case coding_PSX:
|
||||
case coding_PSX_badflags:
|
||||
case coding_PCM16BE:
|
||||
case coding_PCM16LE:
|
||||
case coding_SDX2:
|
||||
case coding_SDX2_int:
|
||||
case coding_DVI_IMA:
|
||||
case coding_IMA:
|
||||
case coding_PCM8:
|
||||
case coding_PCM8_U:
|
||||
case coding_PCM8_U_int:
|
||||
case coding_AICA:
|
||||
case coding_INT_DVI_IMA:
|
||||
case coding_INT_IMA:
|
||||
case coding_APPLE_IMA4:
|
||||
if (coding == coding_AICA) {
|
||||
vgmstream->ch[i].adpcm_step_index = 0x7f;
|
||||
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;
|
||||
}
|
||||
if (vgmstream->layout_type == layout_interleave) {
|
||||
if (interleave >= 512) {
|
||||
chstreamfile =
|
||||
streamFile->open(streamFile,filename,interleave);
|
||||
} else {
|
||||
if (!chstreamfile)
|
||||
chstreamfile =
|
||||
streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
chstart_offset =
|
||||
start_offset+vgmstream->interleave_block_size*i;
|
||||
} else {
|
||||
chstreamfile =
|
||||
streamFile->open(streamFile,filename,
|
||||
STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
break;
|
||||
case coding_XBOX:
|
||||
case coding_MSADPCM:
|
||||
case coding_MS_IMA:
|
||||
/* xbox's "interleave" is a lie, all channels start at same
|
||||
* offset */
|
||||
chstreamfile =
|
||||
streamFile->open(streamFile,filename,
|
||||
STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
break;
|
||||
case coding_NGC_DTK:
|
||||
if (!chstreamfile)
|
||||
chstreamfile =
|
||||
streamFile->open(streamFile,filename,32*0x400);
|
||||
break;
|
||||
case coding_NGC_DSP:
|
||||
if (!chstreamfile)
|
||||
chstreamfile =
|
||||
streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
|
||||
{
|
||||
int16_t (*read_16bit)(off_t , STREAMFILE*);
|
||||
if ((coef_type & 2) == 0) {
|
||||
read_16bit = read_16bitBE;
|
||||
} else {
|
||||
read_16bit = read_16bitLE;
|
||||
}
|
||||
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;
|
||||
|
||||
if ((coef_type & 1) == 0) {
|
||||
for (j=0;j<16;j++) {
|
||||
vgmstream->ch[i].adpcm_coef[j] = read_16bit(coef[i]+j*2,streamFile);
|
||||
}
|
||||
} else {
|
||||
for (j=0;j<8;j++) {
|
||||
vgmstream->ch[i].adpcm_coef[j*2]=read_16bit(coef[i]+j*2,streamFile);
|
||||
vgmstream->ch[i].adpcm_coef[j*2+1]=read_16bit(coef_splitted[i]+j*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
chstart_offset =start_offset+vgmstream->interleave_block_size*i;
|
||||
break;
|
||||
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;
|
||||
|
||||
#ifdef VGM_USE_MPEG
|
||||
case coding_MPEG1_L3:
|
||||
if (!chstreamfile)
|
||||
chstreamfile =
|
||||
streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
break;
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
if (!chstreamfile) goto fail;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->ch[i].streamfile = chstreamfile;
|
||||
/* force encoder delay */
|
||||
if (skip_samples_mode) {
|
||||
ffmpeg_set_skip_samples(ffmpeg_data, skip_samples);
|
||||
}
|
||||
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=chstart_offset;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef VGM_USE_MPEG
|
||||
if (coding == coding_MPEG1_L3) {
|
||||
vgmstream->codec_data = init_mpeg_codec_data(vgmstream->ch[0].streamfile, start_offset, &(vgmstream->coding_type), vgmstream->channels);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
}
|
||||
#endif
|
||||
vgmstream->coding_type = coding;
|
||||
vgmstream->meta_type = meta_GENH;
|
||||
|
||||
|
||||
if ( !vgmstream_open_stream(vgmstream,streamFile,start_offset) )
|
||||
goto fail;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2,13 +2,17 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||
static VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||
|
||||
VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile) {
|
||||
|
||||
/* check extension, case insensitive */
|
||||
if ( !check_extensions(streamFile, "hca")) return NULL;
|
||||
|
||||
return init_vgmstream_hca_offset( streamFile, 0, streamFile->get_size(streamFile) );
|
||||
}
|
||||
|
||||
VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size) {
|
||||
static VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size) {
|
||||
unsigned int ciphKey1;
|
||||
unsigned int ciphKey2;
|
||||
|
||||
|
@ -117,13 +117,11 @@ VGMSTREAM * init_vgmstream_sli_ogg(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
ffmpeg_codec_data * init_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||
ffmpeg_codec_data * init_ffmpeg_header_offset(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size);
|
||||
|
||||
void free_ffmpeg(ffmpeg_codec_data *);
|
||||
void free_ffmpeg(ffmpeg_codec_data *data);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||
|
||||
|
@ -1,99 +1,74 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* MPDS - found in Big Air Freestyle, Terminator 3 (no coeffs), etc */
|
||||
/* MPDS - found in Paradigm Entertainment GC games */
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_mpds(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
int ch1_start=-1, ch2_start=-1;
|
||||
off_t start_offset;
|
||||
int loop_flag = 0, channel_count, short_mpds;
|
||||
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("dsp",filename_extension(filename))) goto fail;
|
||||
/* .adp: Big Air Freestyle */
|
||||
/* .mds: Terminator 3 The Redemption, Mission Impossible: Operation Surma */
|
||||
if (!check_extensions(streamFile, "dsp,mds")) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x4D504453) /* "MPDS" */
|
||||
goto fail;
|
||||
/* Version byte ??? */
|
||||
if (read_32bitBE(0x04,streamFile) != 0x00010000) /* "0x10000" */
|
||||
goto fail;
|
||||
/* compare sample count with body size */
|
||||
if (((read_32bitBE(0x08,streamFile)/7*8)) != (read_32bitBE(0x0C,streamFile)))
|
||||
goto fail;
|
||||
|
||||
channel_count = read_32bitBE(0x14,streamFile);
|
||||
short_mpds = read_32bitBE(0x04,streamFile) != 0x00010000 && read_32bitBE(0x0c,streamFile) == 0x00000002; /* version byte? */
|
||||
|
||||
if (channel_count > 2)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
channel_count = short_mpds ?
|
||||
read_16bitBE(0x0a, streamFile) :
|
||||
read_32bitBE(0x14, streamFile);
|
||||
if (channel_count > 2) goto fail;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->channels = channel_count;
|
||||
|
||||
if (channel_count == 1)
|
||||
{
|
||||
vgmstream->layout_type = layout_none;
|
||||
ch1_start = 0x80;
|
||||
}
|
||||
else if (channel_count == 2)
|
||||
{
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = read_32bitBE(0x18,streamFile);
|
||||
ch1_start = 0x80;
|
||||
ch2_start = 0x80 + vgmstream->interleave_block_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = read_32bitBE(0x08,streamFile);
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = read_32bitBE(0x08,streamFile);
|
||||
}
|
||||
|
||||
vgmstream->meta_type = meta_NGC_DSP_MPDS;
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x24+i*2,streamFile);
|
||||
|
||||
if (channel_count == 2)
|
||||
{
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x4C+i*2,streamFile);
|
||||
}
|
||||
vgmstream->layout_type = channel_count == 1 ? layout_none : layout_interleave;
|
||||
|
||||
if (!short_mpds) { /* Big Air Freestyle */
|
||||
start_offset = 0x80;
|
||||
vgmstream->num_samples = read_32bitBE(0x08,streamFile);
|
||||
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
|
||||
vgmstream->interleave_block_size = channel_count==1 ? 0 : read_32bitBE(0x18,streamFile);
|
||||
|
||||
/* compare sample count with body size */
|
||||
if ((vgmstream->num_samples / 7 * 8) != (read_32bitBE(0x0C,streamFile))) goto fail;
|
||||
|
||||
dsp_read_coefs_be(vgmstream,streamFile,0x24, 0x28);
|
||||
}
|
||||
else { /* Terminator 3 The Redemption, Mission Impossible: Operation Surma */
|
||||
start_offset = 0x20;
|
||||
vgmstream->num_samples = read_32bitBE(0x04,streamFile);
|
||||
vgmstream->sample_rate = (uint16_t)read_16bitBE(0x08,streamFile);
|
||||
vgmstream->interleave_block_size = channel_count==1 ? 0 : 0x200;
|
||||
|
||||
#if 0 //todo unknown coeffs, maybe depends on stuff @ 0x10? (but looks like some kind of size)
|
||||
{
|
||||
int i,ch;
|
||||
for (ch=0; ch < vgmstream->channels; ch++) {
|
||||
for (i=0; i < 16; i++)
|
||||
vgmstream->ch[ch].adpcm_coef[i] = mpds_coefs[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* open the file for reading */
|
||||
vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[0].streamfile) goto fail;
|
||||
vgmstream->ch[0].channel_start_offset =
|
||||
vgmstream->ch[0].offset=ch1_start;
|
||||
|
||||
if (channel_count == 2)
|
||||
{
|
||||
vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[1].streamfile) goto fail;
|
||||
vgmstream->ch[1].channel_start_offset =
|
||||
vgmstream->ch[1].offset=ch2_start;
|
||||
}
|
||||
if ( !vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||
goto fail;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -54,17 +54,16 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||
int32_t loop_start, loop_end;
|
||||
|
||||
int target_stream = 1; /* N=Nth stream, 0=auto (first) */
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
int codec_id;
|
||||
int loop_flag = 0, channel_count, codec_id;
|
||||
int aux_chunk_count;
|
||||
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
||||
int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
if ( !check_extensions(streamFile, "scd") ) goto fail;
|
||||
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("scd",filename_extension(filename))) goto fail;
|
||||
|
||||
/* SEDB */
|
||||
if (read_32bitBE(0,streamFile) != 0x53454442) goto fail;
|
||||
@ -110,7 +109,7 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||
/* 0x1c: unknown (0x0) */
|
||||
headers_entries = read_16bit(tables_offset+0x04,streamFile);
|
||||
if (target_stream == 0) target_stream = 1; /* auto: default to 1 */
|
||||
if (target_stream > headers_entries) goto fail;
|
||||
if (headers_entries <= 0 || target_stream > headers_entries) goto fail;
|
||||
headers_offset = read_32bit(tables_offset+0x0c,streamFile);
|
||||
|
||||
/** header table entries (each is an uint32_t offset to stream header) **/
|
||||
@ -410,31 +409,14 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* open the file for reading */
|
||||
if (vgmstream->layout_type != layout_scd_int
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
&& vgmstream->coding_type != coding_FFmpeg
|
||||
#endif
|
||||
)
|
||||
{
|
||||
int i;
|
||||
STREAMFILE * file;
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!file) goto fail;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = file;
|
||||
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=start_offset;
|
||||
|
||||
}
|
||||
}
|
||||
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||
goto fail;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -457,7 +457,7 @@ int check_extensions(STREAMFILE *streamFile, const char * cmp_exts) {
|
||||
char filename[PATH_LIMIT];
|
||||
const char * ext = NULL;
|
||||
const char * cmp_ext = NULL;
|
||||
size_t ext_len;
|
||||
int ext_len, cmp_len;
|
||||
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
ext = filename_extension(filename);
|
||||
@ -465,11 +465,17 @@ int check_extensions(STREAMFILE *streamFile, const char * cmp_exts) {
|
||||
|
||||
cmp_ext = cmp_exts;
|
||||
do {
|
||||
if (strncasecmp(ext,cmp_ext, ext_len)==0 )
|
||||
cmp_len = strstr(cmp_ext, ",") - cmp_ext; /* find next ext; becomes negative if not found */
|
||||
if (cmp_len < 0)
|
||||
cmp_len = strlen(cmp_ext); /* total length if more not found */
|
||||
|
||||
if (strncasecmp(ext,cmp_ext, ext_len) == 0 && ext_len == cmp_len)
|
||||
return 1;
|
||||
|
||||
cmp_ext = strstr(cmp_ext, ",");
|
||||
if (cmp_ext != NULL)
|
||||
cmp_ext = cmp_ext + 1; /* skip comma */
|
||||
|
||||
} while (cmp_ext != NULL);
|
||||
|
||||
return 0;
|
||||
|
@ -2257,6 +2257,12 @@ int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inits vgmstreams' channels doing two things:
|
||||
* - sets the starting offset per channel (depending on the layout)
|
||||
* - opens its own streamfile from on a base one. One streamfile per channel may be open (to improve read/seeks).
|
||||
* Should be called in metas before returning the VGMSTREAM..
|
||||
*/
|
||||
int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset) {
|
||||
STREAMFILE * file;
|
||||
char filename[PATH_LIMIT];
|
||||
@ -2264,8 +2270,14 @@ int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t s
|
||||
int use_streamfile_per_channel = 0;
|
||||
int use_same_offset_per_channel = 0;
|
||||
|
||||
|
||||
/* stream/offsets not needed, scd manages itself */
|
||||
if (vgmstream->layout_type == layout_scd_int)
|
||||
return 1;
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
if (vgmstream->coding_type == coding_FFmpeg) /* stream not needed, FFmpeg manages itself */
|
||||
/* stream/offsets not needed, FFmpeg manages itself */
|
||||
if (vgmstream->coding_type == coding_FFmpeg)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
@ -2274,8 +2286,8 @@ int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t s
|
||||
use_streamfile_per_channel = 1;
|
||||
}
|
||||
|
||||
/* for mono or codecs like IMA (XBOX, MS IMA, MS ADPCM) where channels work with the same bytes */
|
||||
if (vgmstream->layout_type == layout_none) {
|
||||
/* for some codecs like IMA where channels work with the same bytes *///todo which ones?
|
||||
use_same_offset_per_channel = 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user