mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-12 09:03:10 +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,
|
void decode_fake_mpeg2_l2(VGMSTREAMCHANNEL * stream,
|
||||||
mpeg_codec_data * data,
|
mpeg_codec_data * data,
|
||||||
sample * outbuf, int32_t samples_to_do);
|
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,
|
void decode_mpeg(VGMSTREAMCHANNEL * stream,
|
||||||
mpeg_codec_data * data,
|
mpeg_codec_data * data,
|
||||||
sample * outbuf, int32_t samples_to_do, int channels);
|
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 */
|
/* decode anything mpg123 can */
|
||||||
void decode_mpeg(VGMSTREAMCHANNEL *stream,
|
void decode_mpeg(VGMSTREAMCHANNEL *stream,
|
||||||
mpeg_codec_data * data,
|
mpeg_codec_data * data,
|
||||||
|
@ -26,9 +26,6 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
char filename[260];
|
char filename[260];
|
||||||
int coding;
|
int coding;
|
||||||
#ifdef VGM_USE_MPEG
|
|
||||||
mpeg_codec_data *data = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -325,89 +322,14 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
#ifdef VGM_USE_MPEG
|
#ifdef VGM_USE_MPEG
|
||||||
if (coding == coding_MPEG1_L3) {
|
if (coding == coding_MPEG1_L3) {
|
||||||
int rc;
|
vgmstream->codec_data = init_mpeg_codec_data(vgmstream->ch[0].streamfile, start_offset, vgmstream->sample_rate, &(vgmstream->coding_type));
|
||||||
off_t read_offset;
|
if (!vgmstream->codec_data) goto fail;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
/* clean up anything we may have opened */
|
||||||
#ifdef VGM_USE_MPEG
|
|
||||||
mpeg_fail:
|
|
||||||
if (data) {
|
|
||||||
mpg123_delete(data->m);
|
|
||||||
free(data);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
|
#include "../coding/coding.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
|
||||||
/* XVAG (from Ratchet & Clank Future: Quest for Booty) */
|
/* XVAG (from Ratchet & Clank Future: Quest for Booty) */
|
||||||
@ -18,10 +19,15 @@ VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE *streamFile) {
|
|||||||
int channel_count;
|
int channel_count;
|
||||||
off_t readOffset = 0;
|
off_t readOffset = 0;
|
||||||
int little_endian = 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 loopStartPointsCount=0;
|
||||||
int loopEndPointsCount=0;
|
int loopEndPointsCount=0;
|
||||||
int mp3ID;
|
uint16_t mp3ID;
|
||||||
off_t loopStartPoints[0x10];
|
off_t loopStartPoints[0x10];
|
||||||
off_t loopEndPoints[0x10];
|
off_t loopEndPoints[0x10];
|
||||||
|
|
||||||
@ -45,18 +51,38 @@ VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE *streamFile) {
|
|||||||
{
|
{
|
||||||
channel_count = read_32bitLE(0x28,streamFile);
|
channel_count = read_32bitLE(0x28,streamFile);
|
||||||
start_offset = read_32bitLE(0x4,streamFile);
|
start_offset = read_32bitLE(0x4,streamFile);
|
||||||
|
sample_rate = read_32bitLE(0x3c,streamFile);
|
||||||
|
num_samples = read_32bitLE(0x30,streamFile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
channel_count = read_32bitBE(0x28,streamFile);
|
channel_count = read_32bitBE(0x28,streamFile);
|
||||||
start_offset = read_32bitBE(0x4,streamFile);
|
start_offset = read_32bitBE(0x4,streamFile);
|
||||||
|
sample_rate = read_32bitBE(0x3c,streamFile);
|
||||||
|
num_samples = read_32bitBE(0x30,streamFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
readOffset=start_offset;
|
readOffset=start_offset;
|
||||||
|
|
||||||
// MP3s ?
|
// MP3s ?
|
||||||
mp3ID=read_16bitLE(0x4C,streamFile);
|
mp3ID=(uint16_t)read_16bitBE(0x4C,streamFile);
|
||||||
if(mp3ID!=0xFFFFFBFF) {
|
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
|
// get the loops the same way we get on .MIB
|
||||||
do {
|
do {
|
||||||
readOffset+=(off_t)read_streamfile(testBuffer,readOffset,0x10,streamFile);
|
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);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
vgmstream->sample_rate = sample_rate;
|
||||||
if (little_endian) {
|
vgmstream->num_samples = num_samples;
|
||||||
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->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
vgmstream->meta_type = meta_PS3_XVAG;
|
vgmstream->meta_type = meta_PS3_XVAG;
|
||||||
|
|
||||||
if(mp3ID==0xFFFFFBFF) {
|
if(mp3ID==0xFFFB) {
|
||||||
// mp3s support doesn't work atm !
|
#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->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 {
|
else {
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
@ -161,13 +186,7 @@ VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE *streamFile) {
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
STREAMFILE * file;
|
STREAMFILE * file;
|
||||||
if(vgmstream->layout_type == layout_mpeg) {
|
if(vgmstream->layout_type == layout_interleave) {
|
||||||
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 {
|
|
||||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||||
if (!file) goto fail;
|
if (!file) goto fail;
|
||||||
for (i=0;i<channel_count;i++) {
|
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;
|
return vgmstream;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user