mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-31 04:13:47 +01:00
make MPEG detection accessible to anyone, add MPEG support for XVAG (though it seems that the sample count is wrong)
git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@831 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
51a12c5e30
commit
617ee5cdff
@ -78,6 +78,7 @@ void decode_ws(VGMSTREAM * vgmstream, int channel, sample * outbuf, int channels
|
||||
void decode_fake_mpeg2_l2(VGMSTREAMCHANNEL * stream,
|
||||
mpeg_codec_data * data,
|
||||
sample * outbuf, int32_t samples_to_do);
|
||||
mpeg_codec_data *init_mpeg_codec_data(STREAMFILE *streamfile, off_t start_offset, long given_sample_rate, int given_channels, coding_t *coding_type);
|
||||
void decode_mpeg(VGMSTREAMCHANNEL * stream,
|
||||
mpeg_codec_data * data,
|
||||
sample * outbuf, int32_t samples_to_do, int channels);
|
||||
|
@ -85,6 +85,94 @@ void decode_fake_mpeg2_l2(VGMSTREAMCHANNEL *stream,
|
||||
}
|
||||
}
|
||||
|
||||
mpeg_codec_data *init_mpeg_codec_data(STREAMFILE *streamfile, off_t start_offset, long given_sample_rate, int given_channels, coding_t *coding_type) {
|
||||
int rc;
|
||||
off_t read_offset;
|
||||
mpeg_codec_data *data = NULL;
|
||||
|
||||
data = calloc(1,sizeof(mpeg_codec_data));
|
||||
if (!data) goto mpeg_fail;
|
||||
|
||||
data->m = mpg123_new(NULL,&rc);
|
||||
if (rc==MPG123_NOT_INITIALIZED) {
|
||||
if (mpg123_init()!=MPG123_OK) goto mpeg_fail;
|
||||
data->m = mpg123_new(NULL,&rc);
|
||||
if (rc!=MPG123_OK) goto mpeg_fail;
|
||||
} else if (rc!=MPG123_OK) {
|
||||
goto mpeg_fail;
|
||||
}
|
||||
|
||||
mpg123_param(data->m,MPG123_REMOVE_FLAGS,MPG123_GAPLESS,0.0);
|
||||
|
||||
if (mpg123_open_feed(data->m)!=MPG123_OK) {
|
||||
goto mpeg_fail;
|
||||
}
|
||||
|
||||
/* check format */
|
||||
read_offset=0;
|
||||
do {
|
||||
size_t bytes_done;
|
||||
if (read_streamfile(data->buffer, start_offset+read_offset,
|
||||
MPEG_BUFFER_SIZE,streamfile) !=
|
||||
MPEG_BUFFER_SIZE) goto mpeg_fail;
|
||||
read_offset+=1;
|
||||
rc = mpg123_decode(data->m,data->buffer,MPEG_BUFFER_SIZE,
|
||||
NULL,0,&bytes_done);
|
||||
if (rc != MPG123_OK && rc != MPG123_NEW_FORMAT &&
|
||||
rc != MPG123_NEED_MORE) goto mpeg_fail;
|
||||
} while (rc != MPG123_NEW_FORMAT);
|
||||
|
||||
{
|
||||
long rate;
|
||||
int channels,encoding;
|
||||
struct mpg123_frameinfo mi;
|
||||
rc = mpg123_getformat(data->m,&rate,&channels,&encoding);
|
||||
if (rc != MPG123_OK) goto mpeg_fail;
|
||||
//fprintf(stderr,"getformat ok, sr=%ld (%ld) ch=%d (%d) enc=%d (%d)\n",rate,given_sample_rate,channels,vgmstream->channels,encoding,MPG123_ENC_SIGNED_16);
|
||||
if ((given_sample_rate != -1 && rate != given_sample_rate) ||
|
||||
(given_channels != -1 && channels != given_channels) ||
|
||||
encoding != MPG123_ENC_SIGNED_16) goto mpeg_fail;
|
||||
mpg123_info(data->m,&mi);
|
||||
if (given_sample_rate != -1 &&
|
||||
mi.rate != given_sample_rate) goto mpeg_fail;
|
||||
|
||||
//fprintf(stderr,"mi.version=%d, mi.layer=%d\n",mi.version,mi.layer);
|
||||
|
||||
if (mi.version == MPG123_1_0 && mi.layer == 1)
|
||||
*coding_type = coding_MPEG1_L1;
|
||||
else if (mi.version == MPG123_1_0 && mi.layer == 2)
|
||||
*coding_type = coding_MPEG1_L2;
|
||||
else if (mi.version == MPG123_1_0 && mi.layer == 3)
|
||||
*coding_type = coding_MPEG1_L3;
|
||||
else if (mi.version == MPG123_2_0 && mi.layer == 1)
|
||||
*coding_type = coding_MPEG2_L1;
|
||||
else if (mi.version == MPG123_2_0 && mi.layer == 2)
|
||||
*coding_type = coding_MPEG2_L2;
|
||||
else if (mi.version == MPG123_2_0 && mi.layer == 3)
|
||||
*coding_type = coding_MPEG2_L3;
|
||||
else if (mi.version == MPG123_2_5 && mi.layer == 1)
|
||||
*coding_type = coding_MPEG25_L1;
|
||||
else if (mi.version == MPG123_2_5 && mi.layer == 2)
|
||||
*coding_type = coding_MPEG25_L2;
|
||||
else if (mi.version == MPG123_2_5 && mi.layer == 3)
|
||||
*coding_type = coding_MPEG25_L3;
|
||||
else goto mpeg_fail;
|
||||
}
|
||||
|
||||
/* reinit, to ignore the reading we've done so far */
|
||||
mpg123_open_feed(data->m);
|
||||
|
||||
return data;
|
||||
|
||||
mpeg_fail:
|
||||
fprintf(stderr, "mpeg_fail start_offset=%x\n",(unsigned int)start_offset);
|
||||
if (data) {
|
||||
mpg123_delete(data->m);
|
||||
free(data);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* decode anything mpg123 can */
|
||||
void decode_mpeg(VGMSTREAMCHANNEL *stream,
|
||||
mpeg_codec_data * data,
|
||||
|
@ -26,9 +26,6 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
|
||||
char filename[260];
|
||||
int coding;
|
||||
#ifdef VGM_USE_MPEG
|
||||
mpeg_codec_data *data = NULL;
|
||||
#endif
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
@ -325,89 +322,14 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||
|
||||
#ifdef VGM_USE_MPEG
|
||||
if (coding == coding_MPEG1_L3) {
|
||||
int rc;
|
||||
off_t read_offset;
|
||||
data = calloc(1,sizeof(mpeg_codec_data));
|
||||
if (!data) goto mpeg_fail;
|
||||
|
||||
data->m = mpg123_new(NULL,&rc);
|
||||
if (rc==MPG123_NOT_INITIALIZED) {
|
||||
if (mpg123_init()!=MPG123_OK) goto mpeg_fail;
|
||||
data->m = mpg123_new(NULL,&rc);
|
||||
if (rc!=MPG123_OK) goto mpeg_fail;
|
||||
} else if (rc!=MPG123_OK) {
|
||||
goto mpeg_fail;
|
||||
}
|
||||
|
||||
mpg123_param(data->m,MPG123_REMOVE_FLAGS,MPG123_GAPLESS,0.0);
|
||||
|
||||
if (mpg123_open_feed(data->m)!=MPG123_OK) {
|
||||
goto mpeg_fail;
|
||||
}
|
||||
|
||||
/* check format */
|
||||
read_offset=0;
|
||||
do {
|
||||
size_t bytes_done;
|
||||
if (read_streamfile(data->buffer, start_offset+read_offset,
|
||||
MPEG_BUFFER_SIZE,vgmstream->ch[0].streamfile) !=
|
||||
MPEG_BUFFER_SIZE) goto mpeg_fail;
|
||||
read_offset+=1;
|
||||
rc = mpg123_decode(data->m,data->buffer,MPEG_BUFFER_SIZE,
|
||||
NULL,0,&bytes_done);
|
||||
if (rc != MPG123_OK && rc != MPG123_NEW_FORMAT &&
|
||||
rc != MPG123_NEED_MORE) goto mpeg_fail;
|
||||
} while (rc != MPG123_NEW_FORMAT);
|
||||
|
||||
{
|
||||
long rate;
|
||||
int channels,encoding;
|
||||
struct mpg123_frameinfo mi;
|
||||
rc = mpg123_getformat(data->m,&rate,&channels,&encoding);
|
||||
if (rc != MPG123_OK) goto mpeg_fail;
|
||||
if (rate != vgmstream->sample_rate ||
|
||||
channels != vgmstream->channels ||
|
||||
encoding != MPG123_ENC_SIGNED_16) goto mpeg_fail;
|
||||
mpg123_info(data->m,&mi);
|
||||
if (mi.rate != vgmstream->sample_rate) goto mpeg_fail;
|
||||
if (mi.version == MPG123_1_0 && mi.layer == 1)
|
||||
vgmstream->coding_type = coding_MPEG1_L1;
|
||||
else if (mi.version == MPG123_1_0 && mi.layer == 2)
|
||||
vgmstream->coding_type = coding_MPEG1_L2;
|
||||
else if (mi.version == MPG123_1_0 && mi.layer == 3)
|
||||
vgmstream->coding_type = coding_MPEG1_L3;
|
||||
else if (mi.version == MPG123_2_0 && mi.layer == 1)
|
||||
vgmstream->coding_type = coding_MPEG2_L1;
|
||||
else if (mi.version == MPG123_2_0 && mi.layer == 2)
|
||||
vgmstream->coding_type = coding_MPEG2_L2;
|
||||
else if (mi.version == MPG123_2_0 && mi.layer == 3)
|
||||
vgmstream->coding_type = coding_MPEG2_L3;
|
||||
else if (mi.version == MPG123_2_5 && mi.layer == 1)
|
||||
vgmstream->coding_type = coding_MPEG25_L1;
|
||||
else if (mi.version == MPG123_2_5 && mi.layer == 2)
|
||||
vgmstream->coding_type = coding_MPEG25_L2;
|
||||
else if (mi.version == MPG123_2_5 && mi.layer == 3)
|
||||
vgmstream->coding_type = coding_MPEG25_L3;
|
||||
else goto mpeg_fail;
|
||||
}
|
||||
|
||||
/* reinit, to ignore the reading we've done so far */
|
||||
mpg123_open_feed(data->m);
|
||||
|
||||
vgmstream->codec_data = data;
|
||||
vgmstream->codec_data = init_mpeg_codec_data(vgmstream->ch[0].streamfile, start_offset, vgmstream->sample_rate, &(vgmstream->coding_type));
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
#ifdef VGM_USE_MPEG
|
||||
mpeg_fail:
|
||||
if (data) {
|
||||
mpg123_delete(data->m);
|
||||
free(data);
|
||||
}
|
||||
#endif
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* XVAG (from Ratchet & Clank Future: Quest for Booty) */
|
||||
@ -18,10 +19,15 @@ VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE *streamFile) {
|
||||
int channel_count;
|
||||
off_t readOffset = 0;
|
||||
int little_endian = 0;
|
||||
long sample_rate = 0;
|
||||
long num_samples = 0;
|
||||
|
||||
mpeg_codec_data *mpeg_data = NULL;
|
||||
coding_t mpeg_coding_type = coding_MPEG1_L3;
|
||||
|
||||
int loopStartPointsCount=0;
|
||||
int loopEndPointsCount=0;
|
||||
int mp3ID;
|
||||
uint16_t mp3ID;
|
||||
off_t loopStartPoints[0x10];
|
||||
off_t loopEndPoints[0x10];
|
||||
|
||||
@ -45,18 +51,38 @@ VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE *streamFile) {
|
||||
{
|
||||
channel_count = read_32bitLE(0x28,streamFile);
|
||||
start_offset = read_32bitLE(0x4,streamFile);
|
||||
sample_rate = read_32bitLE(0x3c,streamFile);
|
||||
num_samples = read_32bitLE(0x30,streamFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
channel_count = read_32bitBE(0x28,streamFile);
|
||||
start_offset = read_32bitBE(0x4,streamFile);
|
||||
sample_rate = read_32bitBE(0x3c,streamFile);
|
||||
num_samples = read_32bitBE(0x30,streamFile);
|
||||
}
|
||||
|
||||
readOffset=start_offset;
|
||||
|
||||
// MP3s ?
|
||||
mp3ID=read_16bitLE(0x4C,streamFile);
|
||||
if(mp3ID!=0xFFFFFBFF) {
|
||||
mp3ID=(uint16_t)read_16bitBE(0x4C,streamFile);
|
||||
if(mp3ID==0xFFFB) {
|
||||
#ifdef VGM_USE_MPEG
|
||||
long rate;
|
||||
int channels,encoding;
|
||||
|
||||
mpeg_data = init_mpeg_codec_data(streamFile, start_offset, -1, -1, &mpeg_coding_type); // -1 to not check sample rate or channels
|
||||
if (!mpeg_data) goto fail;
|
||||
|
||||
if (MPG123_OK != mpg123_getformat(mpeg_data->m,&rate,&channels,&encoding)) goto fail;
|
||||
channel_count = channels;
|
||||
sample_rate = rate;
|
||||
|
||||
#else
|
||||
// reject if no MPEG support
|
||||
goto fail;
|
||||
#endif
|
||||
} else {
|
||||
// get the loops the same way we get on .MIB
|
||||
do {
|
||||
readOffset+=(off_t)read_streamfile(testBuffer,readOffset,0x10,streamFile);
|
||||
@ -121,22 +147,21 @@ VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE *streamFile) {
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
if (little_endian) {
|
||||
vgmstream->sample_rate = read_32bitLE(0x3c,streamFile);
|
||||
vgmstream->num_samples = read_32bitLE(0x30,streamFile);
|
||||
} else {
|
||||
vgmstream->sample_rate = read_32bitBE(0x3c,streamFile);
|
||||
vgmstream->num_samples = read_32bitBE(0x30,streamFile);
|
||||
}
|
||||
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->meta_type = meta_PS3_XVAG;
|
||||
|
||||
if(mp3ID==0xFFFFFBFF) {
|
||||
// mp3s support doesn't work atm !
|
||||
if(mp3ID==0xFFFB) {
|
||||
#ifdef VGM_USE_MPEG
|
||||
/* NOTE: num_samples seems to be quite wrong for MPEG */
|
||||
vgmstream->codec_data = mpeg_data;
|
||||
vgmstream->layout_type = layout_mpeg;
|
||||
vgmstream->coding_type = coding_MPEG1_L3;
|
||||
vgmstream->coding_type = mpeg_coding_type;
|
||||
#else
|
||||
// reject if no MPEG support
|
||||
goto fail;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
@ -161,13 +186,7 @@ VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE *streamFile) {
|
||||
{
|
||||
int i;
|
||||
STREAMFILE * file;
|
||||
if(vgmstream->layout_type == layout_mpeg) {
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,MPEG_BUFFER_SIZE);
|
||||
vgmstream->ch[i].channel_start_offset= vgmstream->ch[i].offset=start_offset;
|
||||
}
|
||||
|
||||
} else {
|
||||
if(vgmstream->layout_type == layout_interleave) {
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!file) goto fail;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
@ -179,6 +198,16 @@ VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE *streamFile) {
|
||||
|
||||
}
|
||||
}
|
||||
#ifdef VGM_USE_MPEG
|
||||
else if(vgmstream->layout_type == layout_mpeg) {
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,MPEG_BUFFER_SIZE);
|
||||
vgmstream->ch[i].channel_start_offset= vgmstream->ch[i].offset=start_offset;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
else { goto fail; }
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
Loading…
x
Reference in New Issue
Block a user