mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-18 07:44:43 +01:00
Add MPEG to EA SCHl [Harry Potter and the Chamber of Secrets (PS2)]
This commit is contained in:
parent
d85c033c9d
commit
68071467c2
@ -373,7 +373,8 @@ static void decode_mpeg_interleave(VGMSTREAM * vgmstream, mpeg_codec_data * data
|
||||
data->bytes_used_in_interleave_buffer = 0;
|
||||
|
||||
for (i=0; i < data->ms_size; i++) {
|
||||
if (data->interleave_type == MPEG_P3D) /* P3D have a strange way to interleave so just use first offset */
|
||||
if (data->interleave_type == MPEG_P3D /* P3D have a strange way to interleave so just use first offset */
|
||||
|| data->interleave_type == MPEG_EA) /* EA MPEG is simply frame by frame normal MPEG */
|
||||
decode_mpeg_interleave_samples(&vgmstream->ch[0], data, data->ms[i], channels, i, vgmstream->interleave_block_size);
|
||||
else
|
||||
decode_mpeg_interleave_samples(&vgmstream->ch[i], data, data->ms[i], channels, i, vgmstream->interleave_block_size);
|
||||
@ -529,12 +530,6 @@ static int update_frame_sizes(mpeg_codec_data * data, STREAMFILE *streamfile, of
|
||||
/* Manually find new frame size. Not ideal but mpg123_info.framesize is wrong sometimes */
|
||||
if ( !mpeg_get_frame_info(streamfile, offset, &info) )
|
||||
goto fail;
|
||||
|
||||
/* could mess some calcs */
|
||||
VGM_ASSERT(data->sample_rate_per_frame != info.sample_rate || data->samples_per_frame != info.frame_samples,
|
||||
"MPEG: variable frame info found @ 0x%08lx", offset);
|
||||
|
||||
/* new frame */
|
||||
data->current_frame_size = info.frame_size;
|
||||
|
||||
/* get FSB padding for MPEG1/2 Layer III (MPEG1 Layer II doesn't use it, and Layer I doesn't seem to be supported) */
|
||||
@ -543,6 +538,10 @@ static int update_frame_sizes(mpeg_codec_data * data, STREAMFILE *streamfile, of
|
||||
? data->interleave_value - (data->current_frame_size % data->interleave_value)
|
||||
: 0;
|
||||
}
|
||||
|
||||
/* could mess some calcs */
|
||||
VGM_ASSERT(data->sample_rate_per_frame != info.sample_rate || data->samples_per_frame != info.frame_samples,
|
||||
"MPEG: variable frame info found @ 0x%08lx", offset);
|
||||
}
|
||||
else if (data->interleave_type == MPEG_P3D) { /* varying frames size, even though the frame header says 0x120 */
|
||||
uint32_t header = read_32bitBE(offset,streamfile);
|
||||
@ -561,7 +560,14 @@ static int update_frame_sizes(mpeg_codec_data * data, STREAMFILE *streamfile, of
|
||||
VGM_LOG("MPEG: unknown frame size @ %lx, %x\n", offset, read_32bitBE(offset+0x120,streamfile));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else if (data->interleave_type == MPEG_EA) { /* straight frame by frame */
|
||||
mpeg_frame_info info;
|
||||
|
||||
/* Manually find new frame size. Not ideal but mpg123_info.framesize is wrong sometimes */
|
||||
if ( !mpeg_get_frame_info(streamfile, offset, &info) )
|
||||
goto fail;
|
||||
data->current_frame_size = info.frame_size;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -71,6 +71,7 @@ typedef struct {
|
||||
static int parse_stream_header(STREAMFILE* streamFile, ea_header* ea, off_t begin_offset, int max_length);
|
||||
static uint32_t read_patch(STREAMFILE* streamFile, off_t* offset);
|
||||
static int get_ea_total_samples(STREAMFILE* streamFile, off_t start_offset, const ea_header* ea);
|
||||
static off_t get_ea_mpeg_start_offset(STREAMFILE* streamFile, off_t start_offset, const ea_header* ea);
|
||||
|
||||
|
||||
/* EA SCHl - from EA games (roughly 1997~2010, generated by EA Canada's sx.exe / Sound eXchange) */
|
||||
@ -170,9 +171,26 @@ VGMSTREAM * init_vgmstream_ea_schl(STREAMFILE *streamFile) {
|
||||
}
|
||||
break;
|
||||
|
||||
case EA_CODEC2_MT5: /* MicroTalk (5:1) */
|
||||
#ifdef VGM_USE_MPEG
|
||||
case EA_CODEC2_LAYER2: /* MPEG Layer II, aka MP2 */
|
||||
case EA_CODEC2_LAYER3: /* MPEG Layer III, aka MP3 */
|
||||
case EA_CODEC2_LAYER3: { /* MPEG Layer III, aka MP3 */
|
||||
mpeg_codec_data *mpeg_data = NULL;
|
||||
coding_t mpeg_coding_type;
|
||||
|
||||
off_t mpeg_start_offset = get_ea_mpeg_start_offset(streamFile, start_offset, &ea);
|
||||
if (!mpeg_start_offset) goto fail;
|
||||
|
||||
mpeg_data = init_mpeg_codec_data_interleaved(streamFile, mpeg_start_offset, &mpeg_coding_type, vgmstream->channels, MPEG_EA, 0);
|
||||
if (!mpeg_data) goto fail;
|
||||
vgmstream->codec_data = mpeg_data;
|
||||
vgmstream->coding_type = mpeg_coding_type;
|
||||
//vgmstream->layout_type = layout_mpeg;
|
||||
//mpeg_set_error_logging(mpeg_data, 0); /* should not be needed anymore with the interleave decoder */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case EA_CODEC2_MT5: /* MicroTalk (5:1) */
|
||||
case EA_CODEC2_EALAYER3: /* MP3 variant */
|
||||
default:
|
||||
VGM_LOG("EA: unknown codec2 0x%02x for platform 0x%02x\n", ea.codec2, ea.platform);
|
||||
@ -504,8 +522,7 @@ static int get_ea_total_samples(STREAMFILE* streamFile, off_t start_offset, cons
|
||||
int i, num_samples = 0;
|
||||
size_t file_size = get_streamfile_size(streamFile);
|
||||
off_t block_offset = start_offset;
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*) =
|
||||
ea->big_endian ? read_32bitBE : read_32bitLE;
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = ea->big_endian ? read_32bitBE : read_32bitLE;
|
||||
|
||||
while (block_offset < file_size) {
|
||||
uint32_t id, block_size;
|
||||
@ -559,3 +576,33 @@ static int get_ea_total_samples(STREAMFILE* streamFile, off_t start_offset, cons
|
||||
|
||||
return num_samples;
|
||||
}
|
||||
|
||||
/* find data start offset inside the first SCDl; not very elegant but oh well */
|
||||
static off_t get_ea_mpeg_start_offset(STREAMFILE* streamFile, off_t start_offset, const ea_header* ea) {
|
||||
size_t file_size = get_streamfile_size(streamFile);
|
||||
off_t block_offset = start_offset;
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = ea->big_endian ? read_32bitBE : read_32bitLE;
|
||||
|
||||
while (block_offset < file_size) {
|
||||
uint32_t id, block_size;
|
||||
|
||||
id = read_32bitBE(block_offset+0x00,streamFile);
|
||||
|
||||
block_size = read_32bitLE(block_offset+0x04,streamFile);
|
||||
if (block_size > 0xF0000000) /* size is always LE, except in early MAC apparently */
|
||||
block_size = read_32bitBE(block_offset+0x04,streamFile);
|
||||
|
||||
if (id == 0x5343446C) { /* "SCDl" data block found */
|
||||
off_t offset = read_32bit(block_offset+0x0c,streamFile); /* first channel offset is ok, MPEG channels share offsets */
|
||||
return block_offset + 0x0c + ea->channels*0x04 + offset;
|
||||
} else if (id == 0x5343436C) { /* "SCCl" data count found */
|
||||
block_offset += block_size; /* size includes header */
|
||||
continue;
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
@ -825,7 +825,7 @@ typedef struct {
|
||||
#endif
|
||||
|
||||
#ifdef VGM_USE_MPEG
|
||||
typedef enum { /*MPEG_NONE,*/ MPEG_FIXED, MPEG_FSB, MPEG_P3D } mpeg_interleave_type;
|
||||
typedef enum { /*MPEG_NONE,*/ MPEG_FIXED, MPEG_FSB, MPEG_P3D, MPEG_EA } mpeg_interleave_type;
|
||||
typedef struct {
|
||||
uint8_t *buffer; /* raw (coded) data buffer */
|
||||
size_t buffer_size;
|
||||
|
Loading…
x
Reference in New Issue
Block a user