2009-10-03 16:08:34 +00:00
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or (at
|
|
|
|
* your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
*
|
|
|
|
* See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
2010-07-13 18:19:42 +00:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
|
|
|
* USA.
|
2010-06-19 17:04:32 +00:00
|
|
|
*
|
|
|
|
* =======================================================================
|
|
|
|
*
|
|
|
|
* This file implements an interface to libvorbis for decoding
|
2010-07-13 18:19:42 +00:00
|
|
|
* OGG/Vorbis files. Strongly spoken this file isn't part of the sound
|
|
|
|
* system but part of the main client. It justs converts Vorbis streams
|
2013-04-21 09:27:31 +00:00
|
|
|
* into normal, raw Wave stream which are injected into the backends as
|
|
|
|
* if they were normal "raw" samples. At this moment only background
|
|
|
|
* music playback and in theory .cin movie file playback is supported.
|
2010-06-19 17:04:32 +00:00
|
|
|
*
|
|
|
|
* =======================================================================
|
|
|
|
*/
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-04-25 08:24:38 +00:00
|
|
|
#ifdef OGG
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
#define OV_EXCLUDE_STATIC_CALLBACKS
|
|
|
|
|
2014-06-13 11:07:56 +00:00
|
|
|
#ifndef _WIN32
|
2009-10-03 16:08:34 +00:00
|
|
|
#include <sys/time.h>
|
2014-06-13 11:07:56 +00:00
|
|
|
#endif
|
2009-10-03 16:08:34 +00:00
|
|
|
#include <errno.h>
|
|
|
|
#include <vorbis/vorbisfile.h>
|
|
|
|
|
|
|
|
#include "../header/client.h"
|
2010-06-19 19:10:31 +00:00
|
|
|
#include "header/local.h"
|
2010-06-19 19:04:39 +00:00
|
|
|
#include "header/vorbis.h"
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
qboolean ogg_first_init = true; /* First initialization flag. */
|
|
|
|
qboolean ogg_started = false; /* Initialization flag. */
|
|
|
|
int ogg_bigendian = 0;
|
|
|
|
byte *ogg_buffer; /* File buffer. */
|
|
|
|
char **ogg_filelist; /* List of Ogg Vorbis files. */
|
|
|
|
char ovBuf[4096]; /* Buffer for sound. */
|
|
|
|
int ogg_curfile; /* Index of currently played file. */
|
|
|
|
int ogg_numfiles; /* Number of Ogg Vorbis files. */
|
|
|
|
int ovSection; /* Position in Ogg Vorbis file. */
|
|
|
|
ogg_status_t ogg_status; /* Status indicator. */
|
|
|
|
cvar_t *ogg_autoplay; /* Play this song when started. */
|
|
|
|
cvar_t *ogg_check; /* Check Ogg files or not. */
|
|
|
|
cvar_t *ogg_playlist; /* Playlist. */
|
|
|
|
cvar_t *ogg_sequence; /* Sequence play indicator. */
|
|
|
|
cvar_t *ogg_volume; /* Music volume. */
|
2015-10-14 11:03:06 +00:00
|
|
|
cvar_t *ogg_ignoretrack0; /* Toggle track 0 playing */
|
2012-06-06 09:13:07 +00:00
|
|
|
OggVorbis_File ovFile; /* Ogg Vorbis file. */
|
|
|
|
vorbis_info *ogg_info; /* Ogg Vorbis file information */
|
2013-04-21 09:27:31 +00:00
|
|
|
int ogg_numbufs; /* Number of buffers for OpenAL */
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Initialize the Ogg Vorbis subsystem.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Init(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
cvar_t *cv; /* Cvar pointer. */
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_started)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
return;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("Starting Ogg Vorbis.\n");
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Skip initialization if disabled. */
|
2013-05-08 18:06:53 +00:00
|
|
|
cv = Cvar_Get("ogg_enable", "1", CVAR_ARCHIVE);
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (cv->value != 1)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("Ogg Vorbis not initializing.\n");
|
2009-10-03 16:08:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-11-30 10:28:20 +00:00
|
|
|
if (bigendien == true)
|
|
|
|
{
|
|
|
|
ogg_bigendian = 1;
|
|
|
|
}
|
|
|
|
|
2009-10-03 16:08:34 +00:00
|
|
|
/* Cvars. */
|
2012-06-06 09:13:07 +00:00
|
|
|
ogg_autoplay = Cvar_Get("ogg_autoplay", "?", CVAR_ARCHIVE);
|
|
|
|
ogg_check = Cvar_Get("ogg_check", "0", CVAR_ARCHIVE);
|
|
|
|
ogg_playlist = Cvar_Get("ogg_playlist", "playlist", CVAR_ARCHIVE);
|
|
|
|
ogg_sequence = Cvar_Get("ogg_sequence", "loop", CVAR_ARCHIVE);
|
|
|
|
ogg_volume = Cvar_Get("ogg_volume", "0.7", CVAR_ARCHIVE);
|
2015-10-14 11:03:06 +00:00
|
|
|
ogg_ignoretrack0 = Cvar_Get("ogg_ignoretrack0", "0", CVAR_ARCHIVE);
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Console commands. */
|
2012-06-06 09:13:07 +00:00
|
|
|
Cmd_AddCommand("ogg_list", OGG_ListCmd);
|
|
|
|
Cmd_AddCommand("ogg_pause", OGG_PauseCmd);
|
|
|
|
Cmd_AddCommand("ogg_play", OGG_PlayCmd);
|
|
|
|
Cmd_AddCommand("ogg_reinit", OGG_Reinit);
|
|
|
|
Cmd_AddCommand("ogg_resume", OGG_ResumeCmd);
|
|
|
|
Cmd_AddCommand("ogg_seek", OGG_SeekCmd);
|
|
|
|
Cmd_AddCommand("ogg_status", OGG_StatusCmd);
|
|
|
|
Cmd_AddCommand("ogg_stop", OGG_Stop);
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Build list of files. */
|
|
|
|
ogg_numfiles = 0;
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_playlist->string[0] != '\0')
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_LoadPlaylist(ogg_playlist->string);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_numfiles == 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
OGG_LoadFileList();
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Check if we have Ogg Vorbis files. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_numfiles <= 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("No Ogg Vorbis files found.\n");
|
2010-10-14 06:23:35 +00:00
|
|
|
ogg_started = true; /* For OGG_Shutdown(). */
|
2009-10-03 16:08:34 +00:00
|
|
|
OGG_Shutdown();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize variables. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_first_init)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
ogg_buffer = NULL;
|
|
|
|
ogg_curfile = -1;
|
2010-11-30 10:28:20 +00:00
|
|
|
ogg_info = NULL;
|
2009-10-03 16:08:34 +00:00
|
|
|
ogg_status = STOP;
|
|
|
|
ogg_first_init = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
ogg_started = true;
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("%d Ogg Vorbis files found.\n", ogg_numfiles);
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Autoplay support. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_autoplay->string[0] != '\0')
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_ParseCmd(ogg_autoplay->string);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Shutdown the Ogg Vorbis subsystem.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Shutdown(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (!ogg_started)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
return;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("Shutting down Ogg Vorbis.\n");
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
OGG_Stop();
|
|
|
|
|
|
|
|
/* Free the list of files. */
|
2012-06-06 09:13:07 +00:00
|
|
|
FS_FreeList(ogg_filelist, ogg_numfiles + 1);
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Remove console commands. */
|
2012-06-06 09:13:07 +00:00
|
|
|
Cmd_RemoveCommand("ogg_list");
|
|
|
|
Cmd_RemoveCommand("ogg_pause");
|
|
|
|
Cmd_RemoveCommand("ogg_play");
|
|
|
|
Cmd_RemoveCommand("ogg_reinit");
|
|
|
|
Cmd_RemoveCommand("ogg_resume");
|
|
|
|
Cmd_RemoveCommand("ogg_seek");
|
|
|
|
Cmd_RemoveCommand("ogg_status");
|
|
|
|
Cmd_RemoveCommand("ogg_stop");
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
ogg_started = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Reinitialize the Ogg Vorbis subsystem.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Reinit(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
OGG_Shutdown();
|
|
|
|
OGG_Init();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Check if the file is a valid Ogg Vorbis file.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
qboolean
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Check(char *name)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
|
|
|
qboolean res; /* Return value. */
|
2012-06-06 09:13:07 +00:00
|
|
|
byte *buffer; /* File buffer. */
|
2010-10-14 06:23:35 +00:00
|
|
|
int size; /* File size. */
|
|
|
|
OggVorbis_File ovf; /* Ogg Vorbis file. */
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_check->value == 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
return true;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
res = false;
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if ((size = FS_LoadFile(name, (void **)&buffer)) > 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ov_test(NULL, &ovf, (char *)buffer, size) == 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
res = true;
|
2012-06-06 09:13:07 +00:00
|
|
|
ov_clear(&ovf);
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
FS_FreeFile(buffer);
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
return res;
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Change position in the file.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Seek(ogg_seek_t type, double offset)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2010-06-19 17:04:32 +00:00
|
|
|
double pos; /* Position in file (in seconds). */
|
|
|
|
double total; /* Length of file (in seconds). */
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Check if the file is seekable. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ov_seekable(&ovFile) == 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("OGG_Seek: file is not seekable.\n");
|
2009-10-03 16:08:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get file information. */
|
2012-06-06 09:13:07 +00:00
|
|
|
pos = ov_time_tell(&ovFile);
|
|
|
|
total = ov_time_total(&ovFile, -1);
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
switch (type)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2010-06-19 17:04:32 +00:00
|
|
|
case ABS:
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if ((offset >= 0) && (offset <= total))
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ov_time_seek(&ovFile, offset) != 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("OGG_Seek: could not seek.\n");
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
else
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("%0.2f -> %0.2f of %0.2f.\n", pos, offset, total);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("OGG_Seek: invalid offset.\n");
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
case REL:
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if ((pos + offset >= 0) && (pos + offset <= total))
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ov_time_seek(&ovFile, pos + offset) != 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("OGG_Seek: could not seek.\n");
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
else
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("%0.2f -> %0.2f of %0.2f.\n",
|
|
|
|
pos, pos + offset, total);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("OGG_Seek: invalid offset.\n");
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
break;
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Load list of Ogg Vorbis files in "music".
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_LoadFileList(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
char **list; /* List of .ogg files. */
|
|
|
|
int i; /* Loop counter. */
|
|
|
|
int j; /* Real position in list. */
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Get file list. */
|
2012-06-06 09:13:07 +00:00
|
|
|
list = FS_ListFiles2(va("%s/*.ogg", OGG_DIR),
|
|
|
|
&ogg_numfiles, 0, SFF_SUBDIR | SFF_HIDDEN |
|
|
|
|
SFF_SYSTEM);
|
2009-10-03 16:08:34 +00:00
|
|
|
ogg_numfiles--;
|
|
|
|
|
|
|
|
/* Check if there are posible Ogg files. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if (list == NULL)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
return;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Allocate list of files. */
|
2012-06-06 09:13:07 +00:00
|
|
|
ogg_filelist = malloc(sizeof(char *) * ogg_numfiles);
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Add valid Ogg Vorbis file to the list. */
|
2012-06-06 09:13:07 +00:00
|
|
|
for (i = 0, j = 0; i < ogg_numfiles; i++)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (!OGG_Check(list[i]))
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
free(list[i]);
|
2009-10-03 16:08:34 +00:00
|
|
|
continue;
|
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
ogg_filelist[j++] = list[i];
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Free the file list. */
|
2012-06-06 09:13:07 +00:00
|
|
|
free(list);
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
/* Adjust the list size (remove
|
|
|
|
space for invalid music files). */
|
2009-10-03 16:08:34 +00:00
|
|
|
ogg_numfiles = j;
|
2012-06-06 09:13:07 +00:00
|
|
|
ogg_filelist = realloc(ogg_filelist, sizeof(char *) * ogg_numfiles);
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Load playlist.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_LoadPlaylist(char *playlist)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
byte *buffer; /* Buffer to read the file. */
|
|
|
|
char *ptr; /* Pointer for parsing the file. */
|
|
|
|
int i; /* Loop counter. */
|
2010-10-14 06:23:35 +00:00
|
|
|
int size; /* Length of buffer and strings. */
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Open playlist. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if ((size = FS_LoadFile(va("%s/%s.lst", OGG_DIR,
|
|
|
|
ogg_playlist->string), (void **)&buffer)) < 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("OGG_LoadPlaylist: could not open playlist: %s.\n",
|
|
|
|
strerror(errno));
|
2009-10-03 16:08:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Count the files in playlist. */
|
2012-06-06 09:13:07 +00:00
|
|
|
for (ptr = strtok((char *)buffer, "\n");
|
|
|
|
ptr != NULL;
|
|
|
|
ptr = strtok(NULL, "\n"))
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if ((byte *)ptr != buffer)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
ptr[-1] = '\n';
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (OGG_Check(va("%s/%s", OGG_DIR, ptr)))
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
ogg_numfiles++;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Allocate file list. */
|
2012-06-06 09:13:07 +00:00
|
|
|
ogg_filelist = malloc(sizeof(char *) * ogg_numfiles);
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
i = 0;
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
for (ptr = strtok((char *)buffer, "\n");
|
|
|
|
ptr != NULL;
|
|
|
|
ptr = strtok(NULL, "\n"))
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (OGG_Check(va("%s/%s", OGG_DIR, ptr)))
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
ogg_filelist[i++] = strdup(va("%s/%s", OGG_DIR, ptr));
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Free file buffer. */
|
2012-06-06 09:13:07 +00:00
|
|
|
FS_FreeFile(buffer);
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Play Ogg Vorbis file (with absolute or relative index).
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
qboolean
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Open(ogg_seek_t type, int offset)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2010-11-30 10:28:20 +00:00
|
|
|
int size; /* File size. */
|
2012-06-06 09:13:07 +00:00
|
|
|
int pos = -1; /* Absolute position. */
|
2010-10-14 06:23:35 +00:00
|
|
|
int res; /* Error indicator. */
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
switch (type)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2010-06-19 17:04:32 +00:00
|
|
|
case ABS:
|
|
|
|
|
|
|
|
/* Absolute index. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if ((offset < 0) || (offset >= ogg_numfiles))
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("OGG_Open: %d out of range.\n", offset + 1);
|
|
|
|
return false;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-06-19 17:04:32 +00:00
|
|
|
pos = offset;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
case REL:
|
|
|
|
|
|
|
|
/* Simulate a loopback. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if ((ogg_curfile == -1) && (offset < 0))
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2010-06-19 17:04:32 +00:00
|
|
|
offset++;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
while (ogg_curfile + offset < 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2010-06-19 17:04:32 +00:00
|
|
|
offset += ogg_numfiles;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
while (ogg_curfile + offset >= ogg_numfiles)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2010-06-19 17:04:32 +00:00
|
|
|
offset -= ogg_numfiles;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
pos = ogg_curfile + offset;
|
|
|
|
break;
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check running music. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_status == PLAY)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_curfile == pos)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
return true;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2009-10-03 16:08:34 +00:00
|
|
|
else
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
OGG_Stop();
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Find file. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if ((size = FS_LoadFile(ogg_filelist[pos], (void **)&ogg_buffer)) == -1)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("OGG_Open: could not open %d (%s): %s.\n",
|
|
|
|
pos, ogg_filelist[pos], strerror(errno));
|
|
|
|
return false;
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Open ogg vorbis file. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if ((res = ov_open(NULL, &ovFile, (char *)ogg_buffer, size)) < 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("OGG_Open: '%s' is not a valid Ogg Vorbis file (error %i).\n",
|
|
|
|
ogg_filelist[pos], res); FS_FreeFile(ogg_buffer);
|
2010-11-30 10:28:20 +00:00
|
|
|
ogg_buffer = NULL;
|
2012-06-06 09:13:07 +00:00
|
|
|
return false;
|
2010-11-30 10:28:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ogg_info = ov_info(&ovFile, 0);
|
2012-06-06 09:13:07 +00:00
|
|
|
|
2010-11-30 10:28:20 +00:00
|
|
|
if (!ogg_info)
|
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("OGG_Open: Unable to get stream information for %s.\n",
|
|
|
|
ogg_filelist[pos]);
|
|
|
|
ov_clear(&ovFile);
|
|
|
|
FS_FreeFile(ogg_buffer);
|
2010-11-30 10:28:20 +00:00
|
|
|
ogg_buffer = NULL;
|
2012-06-06 09:13:07 +00:00
|
|
|
return false;
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Play file. */
|
|
|
|
ovSection = 0;
|
|
|
|
ogg_curfile = pos;
|
|
|
|
ogg_status = PLAY;
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
return true;
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Play Ogg Vorbis file (with name only).
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
qboolean
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_OpenName(char *filename)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
char *name; /* File name. */
|
|
|
|
int i; /* Loop counter. */
|
2010-10-14 06:23:35 +00:00
|
|
|
|
2015-10-14 11:03:06 +00:00
|
|
|
/* If the track name is '00', and ogg_ignoretrack0 is set to 0, stop playback */
|
|
|
|
if ((!strncmp(filename, "00", sizeof(char) * 3)) && ogg_ignoretrack0->value == 0)
|
2010-11-27 10:45:09 +00:00
|
|
|
{
|
|
|
|
OGG_PauseCmd();
|
2012-06-06 09:13:07 +00:00
|
|
|
return false;
|
2010-11-27 10:45:09 +00:00
|
|
|
}
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
name = va("%s/%s.ogg", OGG_DIR, filename);
|
2010-10-14 06:23:35 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
for (i = 0; i < ogg_numfiles; i++)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (strcmp(name, ogg_filelist[i]) == 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
break;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (i < ogg_numfiles)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
return OGG_Open(ABS, i);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2010-10-14 06:23:35 +00:00
|
|
|
else
|
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("OGG_OpenName: '%s' not in the list.\n", filename);
|
|
|
|
return false;
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Play a portion of the currently opened file.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
int
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Read(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
int res; /* Number of bytes read. */
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Read and resample. */
|
2012-06-06 09:13:07 +00:00
|
|
|
res = ov_read(&ovFile, ovBuf, sizeof(ovBuf),
|
|
|
|
ogg_bigendian, OGG_SAMPLEWIDTH, 1,
|
|
|
|
&ovSection);
|
|
|
|
S_RawSamples(res / (OGG_SAMPLEWIDTH * ogg_info->channels),
|
|
|
|
ogg_info->rate, OGG_SAMPLEWIDTH, ogg_info->channels,
|
|
|
|
(byte *)ovBuf, ogg_volume->value);
|
2009-10-03 16:08:34 +00:00
|
|
|
|
|
|
|
/* Check for end of file. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if (res == 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
OGG_Stop();
|
|
|
|
OGG_Sequence();
|
|
|
|
}
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
return res;
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Play files in sequence.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Sequence(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (strcmp(ogg_sequence->string, "next") == 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Open(REL, 1);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
else if (strcmp(ogg_sequence->string, "prev") == 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Open(REL, -1);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
else if (strcmp(ogg_sequence->string, "random") == 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Open(ABS, randk() % ogg_numfiles);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
else if (strcmp(ogg_sequence->string, "loop") == 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Open(REL, 0);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
else if (strcmp(ogg_sequence->string, "none") != 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("Invalid value of ogg_sequence: %s\n", ogg_sequence->string);
|
|
|
|
Cvar_Set("ogg_sequence", "none");
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Stop playing the current file.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Stop(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_status == STOP)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
return;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-04-27 14:06:08 +00:00
|
|
|
#ifdef USE_OPENAL
|
2012-06-06 09:13:07 +00:00
|
|
|
if (sound_started == SS_OAL)
|
|
|
|
{
|
2012-05-17 12:47:05 +00:00
|
|
|
AL_UnqueueRawSamples();
|
|
|
|
}
|
2012-04-27 14:06:08 +00:00
|
|
|
#endif
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
ov_clear(&ovFile);
|
2009-10-03 16:08:34 +00:00
|
|
|
ogg_status = STOP;
|
2010-11-30 10:28:20 +00:00
|
|
|
ogg_info = NULL;
|
2012-04-23 07:59:39 +00:00
|
|
|
ogg_numbufs = 0;
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_buffer != NULL)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
FS_FreeFile(ogg_buffer);
|
2009-10-03 16:08:34 +00:00
|
|
|
ogg_buffer = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Stream music.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Stream(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (!ogg_started)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
return;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_status == PLAY)
|
2012-04-22 17:50:15 +00:00
|
|
|
{
|
2012-04-22 17:59:03 +00:00
|
|
|
#ifdef USE_OPENAL
|
2012-06-06 09:13:07 +00:00
|
|
|
if (sound_started == SS_OAL)
|
2012-04-22 17:50:15 +00:00
|
|
|
{
|
2012-04-23 07:59:39 +00:00
|
|
|
/* Calculate the number of buffers used
|
|
|
|
for storing decoded OGG/Vorbis data.
|
|
|
|
We take the number of active buffers
|
|
|
|
at startup (at this point most of the
|
|
|
|
samples should be precached and loaded
|
2012-04-27 14:06:08 +00:00
|
|
|
into buffers) and add 64. Empircal
|
2012-04-23 07:59:39 +00:00
|
|
|
testing showed, that at most times
|
2012-04-27 14:06:08 +00:00
|
|
|
at least 52 buffers remain available
|
|
|
|
for OGG/Vorbis, enough for about 3
|
2012-04-29 13:57:33 +00:00
|
|
|
seconds playback. The music won't
|
|
|
|
stutter as long as the framerate
|
2012-04-27 14:06:08 +00:00
|
|
|
stayes over 1 FPS. */
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_numbufs == 0)
|
2012-04-23 07:59:39 +00:00
|
|
|
{
|
2012-04-27 14:06:08 +00:00
|
|
|
ogg_numbufs = active_buffers + 64;
|
2012-04-23 07:59:39 +00:00
|
|
|
}
|
|
|
|
|
2012-04-22 17:59:03 +00:00
|
|
|
/* active_buffers are all active OpenAL buffers,
|
2012-04-23 07:59:39 +00:00
|
|
|
buffering normal sfx _and_ ogg/vorbis samples. */
|
2012-06-06 09:13:07 +00:00
|
|
|
while (active_buffers <= ogg_numbufs)
|
2012-04-22 17:59:03 +00:00
|
|
|
{
|
|
|
|
OGG_Read();
|
|
|
|
}
|
2012-06-06 09:13:07 +00:00
|
|
|
}
|
|
|
|
else /* using SDL */
|
2012-04-22 17:50:15 +00:00
|
|
|
#endif
|
2012-06-06 09:13:07 +00:00
|
|
|
{
|
2013-04-21 09:27:31 +00:00
|
|
|
if (sound_started == SS_SDL)
|
2012-04-22 17:59:03 +00:00
|
|
|
{
|
2013-04-21 09:27:31 +00:00
|
|
|
/* Read that number samples into the buffer, that
|
|
|
|
were played since the last call to this function.
|
|
|
|
This keeps the buffer at all times at an "optimal"
|
|
|
|
fill level. */
|
|
|
|
while (paintedtime + MAX_RAW_SAMPLES - 2048 > s_rawend)
|
|
|
|
{
|
|
|
|
OGG_Read();
|
|
|
|
}
|
2012-04-22 17:59:03 +00:00
|
|
|
}
|
2012-06-06 09:13:07 +00:00
|
|
|
} /* using SDL */
|
2012-04-23 07:59:39 +00:00
|
|
|
} /* ogg_status == PLAY */
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* List Ogg Vorbis files.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_ListCmd(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
int i;
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
for (i = 0; i < ogg_numfiles; i++)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("%d %s\n", i + 1, ogg_filelist[i]);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("%d Ogg Vorbis files.\n", ogg_numfiles);
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Parse play controls.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_ParseCmd(char *arg)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2010-06-19 17:04:32 +00:00
|
|
|
int n;
|
2010-01-28 21:11:46 +00:00
|
|
|
cvar_t *ogg_enable;
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2013-05-08 18:06:53 +00:00
|
|
|
ogg_enable = Cvar_Get("ogg_enable", "1", CVAR_ARCHIVE);
|
2010-10-14 06:23:35 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
switch (arg[0])
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2010-06-19 17:04:32 +00:00
|
|
|
case '#':
|
2012-06-06 09:13:07 +00:00
|
|
|
n = (int)strtol(arg + 1, (char **)NULL, 10) - 1;
|
|
|
|
OGG_Open(ABS, n);
|
2010-06-19 17:04:32 +00:00
|
|
|
break;
|
|
|
|
case '?':
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Open(ABS, randk() % ogg_numfiles);
|
2010-06-19 17:04:32 +00:00
|
|
|
break;
|
|
|
|
case '>':
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (strlen(arg) > 1)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Open(REL, (int)strtol(arg + 1, (char **)NULL, 10));
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
else
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Open(REL, 1);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
case '<':
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (strlen(arg) > 1)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Open(REL, -(int)strtol(arg + 1, (char **)NULL, 10));
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
else
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Open(REL, -1);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_enable->value != 0)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_OpenName(arg);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
break;
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Pause current song.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_PauseCmd(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_status == PLAY)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
ogg_status = PAUSE;
|
2012-04-23 07:59:39 +00:00
|
|
|
ogg_numbufs = 0;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2017-04-23 19:55:27 +00:00
|
|
|
|
2017-05-13 14:51:39 +00:00
|
|
|
#ifdef USE_OPENAL
|
2017-10-20 21:11:48 +00:00
|
|
|
if (sound_started == SS_OAL)
|
|
|
|
{
|
|
|
|
AL_UnqueueRawSamples();
|
|
|
|
}
|
2017-05-13 14:51:39 +00:00
|
|
|
#endif
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Play control.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_PlayCmd(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (Cmd_Argc() < 2)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("Usage: ogg_play {filename | #n | ? | >n | <n}\n");
|
2009-10-03 16:08:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_ParseCmd(Cmd_Argv(1));
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Resume current song.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_ResumeCmd(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_status == PAUSE)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
ogg_status = PLAY;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Change position in the file being played.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_SeekCmd(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_status != STOP)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
return;
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2009-10-03 16:08:34 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (Cmd_Argc() < 2)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("Usage: ogg_seek {n | <n | >n}\n");
|
2009-10-03 16:08:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
switch (Cmd_Argv(1)[0])
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2009-10-03 16:08:34 +00:00
|
|
|
case '>':
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Seek(REL, strtod(Cmd_Argv(1) + 1, (char **)NULL));
|
2009-10-03 16:08:34 +00:00
|
|
|
break;
|
|
|
|
case '<':
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Seek(REL, -strtod(Cmd_Argv(1) + 1, (char **)NULL));
|
2009-10-03 16:08:34 +00:00
|
|
|
break;
|
|
|
|
default:
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_Seek(ABS, strtod(Cmd_Argv(1), (char **)NULL));
|
2009-10-03 16:08:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-06-19 17:04:32 +00:00
|
|
|
* Display status.
|
|
|
|
*/
|
2010-10-14 06:23:35 +00:00
|
|
|
void
|
2012-06-06 09:13:07 +00:00
|
|
|
OGG_StatusCmd(void)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
switch (ogg_status)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2010-06-19 17:04:32 +00:00
|
|
|
case PLAY:
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("Playing file %d (%s) at %0.2f seconds.\n",
|
|
|
|
ogg_curfile + 1, ogg_filelist[ogg_curfile],
|
|
|
|
ov_time_tell(&ovFile));
|
2010-06-19 17:04:32 +00:00
|
|
|
break;
|
|
|
|
case PAUSE:
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("Paused file %d (%s) at %0.2f seconds.\n",
|
|
|
|
ogg_curfile + 1, ogg_filelist[ogg_curfile],
|
|
|
|
ov_time_tell(&ovFile));
|
2010-06-19 17:04:32 +00:00
|
|
|
break;
|
|
|
|
case STOP:
|
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
if (ogg_curfile == -1)
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("Stopped.\n");
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
else
|
2010-10-14 06:23:35 +00:00
|
|
|
{
|
2012-06-06 09:13:07 +00:00
|
|
|
Com_Printf("Stopped file %d (%s).\n",
|
|
|
|
ogg_curfile + 1, ogg_filelist[ogg_curfile]);
|
2010-10-14 06:23:35 +00:00
|
|
|
}
|
2010-06-19 17:04:32 +00:00
|
|
|
|
|
|
|
break;
|
2009-10-03 16:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
2010-07-13 18:19:42 +00:00
|
|
|
|
2012-06-06 09:13:07 +00:00
|
|
|
#endif /* OGG */
|
|
|
|
|