mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-12-01 09:37:21 +01:00
Added .swag [Frantix PSP]
This commit is contained in:
parent
86ba7a6a23
commit
4e6ce8747d
@ -247,6 +247,7 @@ static const char* extension_list[] = {
|
||||
"stx",
|
||||
"svag",
|
||||
"svs",
|
||||
"swag",
|
||||
"swav",
|
||||
"swd",
|
||||
|
||||
|
21
src/header.c
21
src/header.c
@ -42,24 +42,39 @@ int header_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t star
|
||||
STREAMFILE * file;
|
||||
char filename[PATH_LIMIT];
|
||||
int ch;
|
||||
int buffer_size = STREAMFILE_DEFAULT_BUFFER_SIZE;
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
if (vgmstream->coding_type == coding_FFmpeg) /* not needed */
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
/* minor optimizations */
|
||||
if (vgmstream->layout_type == layout_interleave
|
||||
&&vgmstream->interleave_block_size > 0
|
||||
&& vgmstream->interleave_block_size > buffer_size) {
|
||||
buffer_size = vgmstream->interleave_block_size;
|
||||
}
|
||||
|
||||
if (buffer_size > 0x8000) {
|
||||
buffer_size = 0x8000;
|
||||
/* todo if interleave is big enough open one streamfile per channel so each uses it's own buffer */
|
||||
}
|
||||
|
||||
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
file = streamFile->open(streamFile,filename,buffer_size);
|
||||
if (!file) return 0;
|
||||
|
||||
for (ch=0; ch < vgmstream->channels; ch++) {
|
||||
|
||||
vgmstream->ch[ch].streamfile = file;
|
||||
|
||||
if (vgmstream->layout_type == layout_none
|
||||
#ifdef VGM_USE_MPEG
|
||||
|| vgmstream->layout_type == layout_mpeg
|
||||
|| vgmstream->layout_type == layout_mpeg //todo simplify using flag "start offset"
|
||||
#endif
|
||||
) { /* no appreciable difference for mpeg */
|
||||
/* for some codecs like IMA where channels work with the same bytes */
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
#include "../header.h"
|
||||
|
||||
|
||||
static int vag_find_loop_offsets(STREAMFILE *streamFile, off_t start_offset, off_t * loop_start, off_t * loop_end);
|
||||
@ -9,26 +10,23 @@ static int vag_find_loop_offsets(STREAMFILE *streamFile, off_t start_offset, off
|
||||
*/
|
||||
VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
|
||||
off_t loopStart = 0;
|
||||
off_t loopEnd = 0;
|
||||
off_t start_offset, loopStart = 0, loopEnd = 0;
|
||||
|
||||
uint8_t vagID;
|
||||
uint32_t version = 0;
|
||||
|
||||
size_t filesize = 0, datasize = 0;
|
||||
size_t interleave;
|
||||
off_t start_offset;
|
||||
size_t filesize = 0, datasize = 0, interleave;
|
||||
|
||||
int loop_flag=0;
|
||||
int loop_samples_found = 0;
|
||||
int loop_flag = 0, loop_samples_found = 0;
|
||||
int channel_count = 0;
|
||||
int i;
|
||||
int is_swag = 0;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("vag",filename_extension(filename))) goto fail;
|
||||
if ( !header_check_extensions(streamFile,"vag,swag") )
|
||||
goto fail;
|
||||
|
||||
/* Frantix VAGp .swag: some (not all) fields in LE + 2 VAGp in the same file (full interleave) */
|
||||
is_swag = header_check_extensions(streamFile,"swag");
|
||||
|
||||
/* check VAG Header */
|
||||
if (((read_32bitBE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700) && /* "VAG\0" */
|
||||
@ -41,6 +39,9 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||
* ex: 00000000 = v1.8 PC, 00000002 = v1.3 Mac, 00000003 = v1.6+ Mac, 00000020 = v2.0+ PC */
|
||||
version = read_32bitBE(0x04,streamFile);
|
||||
/* 0x08-0c: reserved */
|
||||
if (is_swag)
|
||||
datasize = read_32bitLE(0x0c,streamFile);
|
||||
else
|
||||
datasize = read_32bitBE(0x0c,streamFile);
|
||||
/* 0x14-20 reserved */
|
||||
/* 0x20-30: name (optional) */
|
||||
@ -66,8 +67,11 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||
break;
|
||||
case 'p': /* "VAGp" (extended) [most common, ex Ratchet & Clank] */
|
||||
|
||||
if ((version <= 0x00000004) && (datasize < filesize / 2)) {
|
||||
loop_flag=(read_32bitBE(0x14,streamFile)!=0);
|
||||
if ((version <= 0x00000004) && (datasize < filesize / 2)) { /* two VAGp in the same file */
|
||||
if (is_swag)
|
||||
loop_flag = vag_find_loop_offsets(streamFile, 0x30, &loopStart, &loopEnd);
|
||||
else
|
||||
loop_flag = read_32bitBE(0x14,streamFile) != 0;
|
||||
channel_count=2;
|
||||
}
|
||||
else if (version == 0x00020001) { /* HEVAG */
|
||||
@ -91,6 +95,9 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
if (is_swag)
|
||||
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||
else
|
||||
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
|
||||
|
||||
switch(vagID) {
|
||||
@ -121,18 +128,24 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||
|
||||
if ((version == 0x00000004) && (datasize < filesize / 2)) {
|
||||
vgmstream->channels=2;
|
||||
vgmstream->num_samples = datasize; /* todo test if datasize/16*28? */
|
||||
vgmstream->layout_type=layout_interleave;
|
||||
vgmstream->meta_type=meta_PS2_VAGs;
|
||||
|
||||
if (is_swag) {
|
||||
start_offset = 0x30;
|
||||
interleave = datasize;
|
||||
vgmstream->num_samples = datasize / 16 * 28;
|
||||
vgmstream->loop_start_sample = (loopStart-start_offset) / 16 * 28;
|
||||
vgmstream->loop_end_sample = (loopEnd-start_offset) / 16 * 28;
|
||||
loop_samples_found = 1;
|
||||
|
||||
} else {
|
||||
start_offset=0x80;
|
||||
vgmstream->num_samples = datasize; /* todo test if datasize/16*28? */
|
||||
if(loop_flag) {
|
||||
vgmstream->loop_start_sample=read_32bitBE(0x14,streamFile);
|
||||
vgmstream->loop_end_sample =read_32bitBE(0x18,streamFile);
|
||||
loop_samples_found = 1;
|
||||
}
|
||||
|
||||
start_offset=0x80;
|
||||
vgmstream->layout_type=layout_interleave;
|
||||
vgmstream->meta_type=meta_PS2_VAGs;
|
||||
|
||||
// Double VAG Header @ 0x0000 & 0x1000
|
||||
if(read_32bitBE(0,streamFile)==read_32bitBE(0x1000,streamFile)) {
|
||||
vgmstream->num_samples = datasize / 16 * 28;
|
||||
@ -140,6 +153,8 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||
start_offset=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (version == 0x40000000) { /* Guerilla VAG (little endian) */
|
||||
datasize = read_32bitLE(0x0c,streamFile);
|
||||
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||
@ -195,28 +210,14 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||
}
|
||||
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
for (i=0;i<channel_count;i++) {
|
||||
if (vgmstream->interleave_block_size > 0) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,vgmstream->interleave_block_size);
|
||||
} else {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=
|
||||
(off_t)(start_offset+vgmstream->interleave_block_size*i);
|
||||
}
|
||||
}
|
||||
/* open the file for reading */
|
||||
if ( !header_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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user