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;
|
data->bytes_used_in_interleave_buffer = 0;
|
||||||
|
|
||||||
for (i=0; i < data->ms_size; i++) {
|
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);
|
decode_mpeg_interleave_samples(&vgmstream->ch[0], data, data->ms[i], channels, i, vgmstream->interleave_block_size);
|
||||||
else
|
else
|
||||||
decode_mpeg_interleave_samples(&vgmstream->ch[i], data, data->ms[i], channels, i, vgmstream->interleave_block_size);
|
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 */
|
/* Manually find new frame size. Not ideal but mpg123_info.framesize is wrong sometimes */
|
||||||
if ( !mpeg_get_frame_info(streamfile, offset, &info) )
|
if ( !mpeg_get_frame_info(streamfile, offset, &info) )
|
||||||
goto fail;
|
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;
|
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) */
|
/* 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)
|
? data->interleave_value - (data->current_frame_size % data->interleave_value)
|
||||||
: 0;
|
: 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 */
|
else if (data->interleave_type == MPEG_P3D) { /* varying frames size, even though the frame header says 0x120 */
|
||||||
uint32_t header = read_32bitBE(offset,streamfile);
|
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));
|
VGM_LOG("MPEG: unknown frame size @ %lx, %x\n", offset, read_32bitBE(offset+0x120,streamfile));
|
||||||
goto fail;
|
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;
|
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 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 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 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) */
|
/* 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;
|
break;
|
||||||
|
|
||||||
case EA_CODEC2_MT5: /* MicroTalk (5:1) */
|
#ifdef VGM_USE_MPEG
|
||||||
case EA_CODEC2_LAYER2: /* MPEG Layer II, aka MP2 */
|
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 */
|
case EA_CODEC2_EALAYER3: /* MP3 variant */
|
||||||
default:
|
default:
|
||||||
VGM_LOG("EA: unknown codec2 0x%02x for platform 0x%02x\n", ea.codec2, ea.platform);
|
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;
|
int i, num_samples = 0;
|
||||||
size_t file_size = get_streamfile_size(streamFile);
|
size_t file_size = get_streamfile_size(streamFile);
|
||||||
off_t block_offset = start_offset;
|
off_t block_offset = start_offset;
|
||||||
int32_t (*read_32bit)(off_t,STREAMFILE*) =
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = ea->big_endian ? read_32bitBE : read_32bitLE;
|
||||||
ea->big_endian ? read_32bitBE : read_32bitLE;
|
|
||||||
|
|
||||||
while (block_offset < file_size) {
|
while (block_offset < file_size) {
|
||||||
uint32_t id, block_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;
|
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
|
#endif
|
||||||
|
|
||||||
#ifdef VGM_USE_MPEG
|
#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 {
|
typedef struct {
|
||||||
uint8_t *buffer; /* raw (coded) data buffer */
|
uint8_t *buffer; /* raw (coded) data buffer */
|
||||||
size_t buffer_size;
|
size_t buffer_size;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user