+/*
+====================
+OGG_FreeSfx
+====================
+*/
+static void OGG_FreeSfx (void *sfxfetcherdata)
+{
+ ogg_stream_persfx_t* per_sfx = (ogg_stream_persfx_t *)sfxfetcherdata;
+
+ // Free the Ogg Vorbis file
+ Mem_Free(per_sfx->file);
+
+ // Free the stream structure
+ Mem_Free(per_sfx);
+}
+
+
+/*
+====================
+OGG_GetFormat
+====================
+*/
+static const snd_format_t* OGG_GetFormat (sfx_t* sfx)
+{
+ ogg_stream_persfx_t* per_sfx = (ogg_stream_persfx_t *)sfx->fetcher_data;
+ return &per_sfx->format;
+}
+
+static const snd_fetcher_t ogg_fetcher = { OGG_FetchSound, OGG_FetchEnd, OGG_FreeSfx, OGG_GetFormat };
+
+static void OGG_DecodeTags(vorbis_comment *vc, unsigned int *start, unsigned int *length, double samplesfactor, unsigned int numsamples, double *peak, double *gaindb)
+{
+ const char *startcomment = NULL, *lengthcomment = NULL, *endcomment = NULL, *thiscomment = NULL;
+
+ *start = numsamples;
+ *length = numsamples;
+ *peak = 0.0;
+ *gaindb = 0.0;
+
+ if(!vc)
+ return;
+
+ thiscomment = qvorbis_comment_query(vc, "REPLAYGAIN_TRACK_PEAK", 0);
+ if(thiscomment)
+ *peak = atof(thiscomment);
+ thiscomment = qvorbis_comment_query(vc, "REPLAYGAIN_TRACK_GAIN", 0);
+ if(thiscomment)
+ *gaindb = atof(thiscomment);
+
+ startcomment = qvorbis_comment_query(vc, "LOOP_START", 0); // DarkPlaces, and some Japanese app
+ if(startcomment)
+ {
+ endcomment = qvorbis_comment_query(vc, "LOOP_END", 0);
+ if(!endcomment)
+ lengthcomment = qvorbis_comment_query(vc, "LOOP_LENGTH", 0);
+ }
+ else
+ {
+ startcomment = qvorbis_comment_query(vc, "LOOPSTART", 0); // RPG Maker VX
+ if(startcomment)
+ {
+ lengthcomment = qvorbis_comment_query(vc, "LOOPLENGTH", 0);
+ if(!lengthcomment)
+ endcomment = qvorbis_comment_query(vc, "LOOPEND", 0);
+ }
+ else
+ {
+ startcomment = qvorbis_comment_query(vc, "LOOPPOINT", 0); // Sonic Robo Blast 2
+ }
+ }
+
+ if(startcomment)
+ {
+ *start = (unsigned int) bound(0, atof(startcomment) * samplesfactor, numsamples);
+ if(endcomment)
+ *length = (unsigned int) bound(0, atof(endcomment) * samplesfactor, numsamples);
+ else if(lengthcomment)
+ *length = (unsigned int) bound(0, *start + atof(lengthcomment) * samplesfactor, numsamples);
+ }
+}