2008-07-21 07:50:28 +02:00
|
|
|
#include "../vgmstream.h"
|
|
|
|
|
|
|
|
#ifdef VGM_USE_VORBIS
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "meta.h"
|
|
|
|
#include "../util.h"
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
#define DIRSEP '\\'
|
|
|
|
#else
|
|
|
|
#define DIRSEP '/'
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* .sli is a file with loop points, associated with a similarly named .ogg */
|
|
|
|
|
|
|
|
VGMSTREAM * init_vgmstream_sli_ogg(STREAMFILE *streamFile) {
|
|
|
|
|
|
|
|
VGMSTREAM * vgmstream = NULL;
|
|
|
|
STREAMFILE * streamFileOGG = NULL;
|
2013-05-27 05:55:50 +02:00
|
|
|
char filename[PATH_LIMIT];
|
2014-03-15 06:36:23 +01:00
|
|
|
char filenameOGG[PATH_LIMIT];
|
|
|
|
char linebuffer[PATH_LIMIT];
|
2008-07-21 07:50:28 +02:00
|
|
|
off_t bytes_read;
|
|
|
|
off_t sli_offset;
|
|
|
|
int done;
|
|
|
|
int32_t loop_start = -1;
|
|
|
|
int32_t loop_length = -1;
|
2008-07-22 03:03:20 +02:00
|
|
|
int32_t loop_from = -1;
|
|
|
|
int32_t loop_to = -1;
|
2008-07-21 07:50:28 +02:00
|
|
|
|
|
|
|
/* check extension, case insensitive */
|
|
|
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
|
|
if (strcasecmp("sli",filename_extension(filename))) goto fail;
|
|
|
|
|
|
|
|
/* check for .OGG file */
|
|
|
|
strcpy(filenameOGG,filename);
|
|
|
|
/* strip off .sli */
|
|
|
|
filenameOGG[strlen(filenameOGG)-4]='\0';
|
|
|
|
|
|
|
|
streamFileOGG = streamFile->open(streamFile,filenameOGG,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
|
|
if (!streamFileOGG) {
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* let the real initer do the parsing */
|
|
|
|
vgmstream = init_vgmstream_ogg_vorbis(streamFileOGG);
|
|
|
|
if (!vgmstream) goto fail;
|
|
|
|
|
|
|
|
close_streamfile(streamFileOGG);
|
|
|
|
streamFileOGG = NULL;
|
|
|
|
|
|
|
|
sli_offset = 0;
|
|
|
|
while ((loop_start == -1 || loop_length == -1) && sli_offset < get_streamfile_size(streamFile)) {
|
|
|
|
char *endptr;
|
2008-07-22 03:03:20 +02:00
|
|
|
char *foundptr;
|
2008-07-21 07:50:28 +02:00
|
|
|
bytes_read=get_streamfile_dos_line(sizeof(linebuffer),linebuffer,sli_offset,streamFile,&done);
|
|
|
|
if (!done) goto fail;
|
|
|
|
|
|
|
|
if (!memcmp("LoopStart=",linebuffer,10) && linebuffer[10]!='\0') {
|
|
|
|
loop_start = strtol(linebuffer+10,&endptr,10);
|
|
|
|
if (*endptr != '\0') {
|
|
|
|
/* if it didn't parse cleanly */
|
|
|
|
loop_start = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!memcmp("LoopLength=",linebuffer,11) && linebuffer[11]!='\0') {
|
|
|
|
loop_length = strtol(linebuffer+11,&endptr,10);
|
|
|
|
if (*endptr != '\0') {
|
|
|
|
/* if it didn't parse cleanly */
|
|
|
|
loop_length = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-22 03:03:20 +02:00
|
|
|
/* a completely different format, also with .sli extension and can be handled similarly */
|
|
|
|
if ((foundptr=strstr(linebuffer,"To="))!=NULL && isdigit(foundptr[3])) {
|
|
|
|
loop_to = strtol(foundptr+3,&endptr,10);
|
|
|
|
if (*endptr != ';') {
|
|
|
|
loop_to = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((foundptr=strstr(linebuffer,"From="))!=NULL && isdigit(foundptr[5])) {
|
|
|
|
loop_from = strtol(foundptr+5,&endptr,10);
|
|
|
|
if (*endptr != ';') {
|
|
|
|
loop_from = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-21 07:50:28 +02:00
|
|
|
sli_offset += bytes_read;
|
|
|
|
}
|
|
|
|
|
2008-07-22 03:03:20 +02:00
|
|
|
if ((loop_start != -1 && loop_length != -1) ||
|
|
|
|
(loop_to != -1 && loop_from != -1)) {
|
2008-07-21 07:50:28 +02:00
|
|
|
/* install loops */
|
|
|
|
if (!vgmstream->loop_flag) {
|
|
|
|
vgmstream->loop_flag = 1;
|
|
|
|
vgmstream->loop_ch = calloc(vgmstream->channels,
|
|
|
|
sizeof(VGMSTREAMCHANNEL));
|
|
|
|
if (!vgmstream->loop_ch) goto fail;
|
|
|
|
}
|
|
|
|
|
2008-07-22 03:03:20 +02:00
|
|
|
if (loop_to != -1 && loop_from != -1) {
|
|
|
|
vgmstream->loop_start_sample = loop_to;
|
|
|
|
vgmstream->loop_end_sample = loop_from;
|
|
|
|
vgmstream->meta_type = meta_OGG_SLI2;
|
|
|
|
} else {
|
|
|
|
vgmstream->loop_start_sample = loop_start;
|
|
|
|
vgmstream->loop_end_sample = loop_start+loop_length;
|
|
|
|
vgmstream->meta_type = meta_OGG_SLI;
|
|
|
|
}
|
|
|
|
} else goto fail; /* if there's no loop points the .sli wasn't valid */
|
2008-07-21 07:50:28 +02:00
|
|
|
|
|
|
|
return vgmstream;
|
|
|
|
|
|
|
|
/* clean up anything we may have opened */
|
|
|
|
fail:
|
|
|
|
if (streamFileOGG) close_streamfile(streamFileOGG);
|
|
|
|
if (vgmstream) close_vgmstream(vgmstream);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|