fix music playback
parent
999eb4a37a
commit
722fd7791f
|
@ -3,7 +3,7 @@ cmake_policy(SET CMP0046 NEW)
|
||||||
cmake_policy(SET CMP0063 NEW)
|
cmake_policy(SET CMP0063 NEW)
|
||||||
cmake_policy(SET CMP0071 NEW)
|
cmake_policy(SET CMP0071 NEW)
|
||||||
|
|
||||||
project(agw-quake C)
|
project(spingle C)
|
||||||
|
|
||||||
include(CheckCSourceCompiles)
|
include(CheckCSourceCompiles)
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ find_package(SDL2 REQUIRED)
|
||||||
|
|
||||||
find_package(PkgConfig)
|
find_package(PkgConfig)
|
||||||
|
|
||||||
if(PkgConfig_FOUND)
|
if(PKG_CONFIG_FOUND)
|
||||||
pkg_check_modules(FLAC IMPORTED_TARGET flac>=1.3.3)
|
pkg_check_modules(FLAC IMPORTED_TARGET flac>=1.3.3)
|
||||||
pkg_check_modules(Vorbis IMPORTED_TARGET vorbis>=1.3.6
|
pkg_check_modules(Vorbis IMPORTED_TARGET vorbis>=1.3.6
|
||||||
vorbisfile>=1.3.6
|
vorbisfile>=1.3.6
|
||||||
|
@ -135,8 +135,8 @@ set(srcs
|
||||||
source/snd_dma.c
|
source/snd_dma.c
|
||||||
source/snd_flac.c
|
source/snd_flac.c
|
||||||
source/snd_mem.c
|
source/snd_mem.c
|
||||||
source/snd_mikmod.c
|
|
||||||
source/snd_mix.c
|
source/snd_mix.c
|
||||||
|
source/snd_mod.c
|
||||||
source/snd_opus.c
|
source/snd_opus.c
|
||||||
source/snd_umx.c
|
source/snd_umx.c
|
||||||
source/snd_vorbis.c
|
source/snd_vorbis.c
|
||||||
|
@ -199,12 +199,15 @@ set(defs "")
|
||||||
list(APPEND srcs ${srcs_sdl})
|
list(APPEND srcs ${srcs_sdl})
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
|
set(USE_WINSOCK_2 TRUE CACHE BOOL "Use WinSock2 for networking")
|
||||||
list(APPEND srcs ${srcs_windows})
|
list(APPEND srcs ${srcs_windows})
|
||||||
list(APPEND libs winmm)
|
list(APPEND libs winmm)
|
||||||
# TODO
|
if(USE_WINSOCK_2)
|
||||||
# list(APPEND libs wsock32)
|
|
||||||
list(APPEND libs ws2_32)
|
list(APPEND libs ws2_32)
|
||||||
list(APPEND defs -D_USE_WINSOCK2)
|
list(APPEND defs _USE_WINSOCK2)
|
||||||
|
else()
|
||||||
|
list(APPEND libs wsock32)
|
||||||
|
endif()
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
list(APPEND srcs ${srcs_unix} ${srcs_linux})
|
list(APPEND srcs ${srcs_unix} ${srcs_linux})
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||||
|
@ -213,24 +216,23 @@ else()
|
||||||
message(FATAL_ERROR "platform not supported")
|
message(FATAL_ERROR "platform not supported")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(quake WIN32 ${srcs})
|
if(HAVE_COMPUTED_GOTO)
|
||||||
|
list(APPEND defs HAVE_COMPUTED_GOTO=1)
|
||||||
|
endif()
|
||||||
|
|
||||||
function(agw_checked_library define library)
|
macro(agw_checked_library define library)
|
||||||
if(PkgConfig_FOUND AND ${library}_FOUND)
|
if(${library}_FOUND)
|
||||||
list(APPEND defs -D${define}=1)
|
list(APPEND defs ${define}=1)
|
||||||
list(APPEND libs PkgConfig::${library})
|
list(APPEND libs PkgConfig::${library})
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endmacro()
|
||||||
|
|
||||||
agw_checked_library(USE_CODEC_FLAC FLAC)
|
agw_checked_library(USE_CODEC_FLAC FLAC)
|
||||||
agw_checked_library(USE_CODEC_VORBIS Vorbis)
|
agw_checked_library(USE_CODEC_VORBIS Vorbis)
|
||||||
agw_checked_library(USE_CODEC_OPUS Opus)
|
agw_checked_library(USE_CODEC_OPUS Opus)
|
||||||
agw_checked_library(USE_CODEC_MikMod MikMod)
|
agw_checked_library(USE_CODEC_MOD MikMod)
|
||||||
|
|
||||||
if(HAVE_COMPUTED_GOTO)
|
|
||||||
list(APPEND defs -DHAVE_COMPUTED_GOTO=1)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
add_executable(quake WIN32 ${srcs})
|
||||||
target_compile_options(quake PUBLIC
|
target_compile_options(quake PUBLIC
|
||||||
$<$<C_COMPILER_ID:AppleClang,Clang,GNU>:
|
$<$<C_COMPILER_ID:AppleClang,Clang,GNU>:
|
||||||
-Wall -Wextra -Werror -Wno-missing-field-initializers>
|
-Wall -Wextra -Werror -Wno-missing-field-initializers>
|
||||||
|
@ -239,5 +241,5 @@ target_compile_options(quake PUBLIC
|
||||||
$<$<C_COMPILER_ID:MSVC>: /W4>)
|
$<$<C_COMPILER_ID:MSVC>: /W4>)
|
||||||
target_include_directories(quake SYSTEM PUBLIC ${SDL2_INCLUDE_DIRS})
|
target_include_directories(quake SYSTEM PUBLIC ${SDL2_INCLUDE_DIRS})
|
||||||
target_include_directories(quake PUBLIC source)
|
target_include_directories(quake PUBLIC source)
|
||||||
target_link_libraries(quake ${libs})
|
|
||||||
target_compile_definitions(quake PUBLIC ${defs})
|
target_compile_definitions(quake PUBLIC ${defs})
|
||||||
|
target_link_libraries(quake ${libs})
|
||||||
|
|
163
source/bgmusic.c
163
source/bgmusic.c
|
@ -35,44 +35,33 @@ cvar_t bgm_extmusic = {"bgm_extmusic", "1", CVAR_ARCHIVE};
|
||||||
static bool no_extmusic = false;
|
static bool no_extmusic = false;
|
||||||
static float old_volume = -1.0f;
|
static float old_volume = -1.0f;
|
||||||
|
|
||||||
typedef enum
|
|
||||||
{
|
|
||||||
BGM_NONE = -1,
|
|
||||||
BGM_MIDIDRV = 1,
|
|
||||||
BGM_STREAMER
|
|
||||||
} bgm_player_t;
|
|
||||||
|
|
||||||
typedef struct music_handler_s
|
typedef struct music_handler_s
|
||||||
{
|
{
|
||||||
uint32_t type; /* 1U << n (see snd_codec.h) */
|
uint32_t type;
|
||||||
bgm_player_t player; /* Enumerated bgm player type */
|
const char *ext;
|
||||||
int32_t is_available; /* -1 means not present */
|
|
||||||
const char *ext; /* Expected file extension */
|
|
||||||
const char *dir; /* Where to look for music file */
|
|
||||||
struct music_handler_s *next;
|
|
||||||
} music_handler_t;
|
} music_handler_t;
|
||||||
|
|
||||||
static music_handler_t wanted_handlers[] =
|
static music_handler_t music_handlers[] =
|
||||||
{
|
{
|
||||||
{ CODECTYPE_VORBIS, BGM_STREAMER, -1, "ogg", MUSIC_DIRNAME, NULL },
|
#if USE_CODEC_FLAC
|
||||||
{ CODECTYPE_OPUS, BGM_STREAMER, -1, "opus", MUSIC_DIRNAME, NULL },
|
{ CODECTYPE_FLAC, "flac" },
|
||||||
{ CODECTYPE_MP3, BGM_STREAMER, -1, "mp3", MUSIC_DIRNAME, NULL },
|
#endif
|
||||||
{ CODECTYPE_FLAC, BGM_STREAMER, -1, "flac", MUSIC_DIRNAME, NULL },
|
#if USE_CODEC_OPUS
|
||||||
{ CODECTYPE_WAV, BGM_STREAMER, -1, "wav", MUSIC_DIRNAME, NULL },
|
{ CODECTYPE_OPUS, "opus" },
|
||||||
{ CODECTYPE_MOD, BGM_STREAMER, -1, "it", MUSIC_DIRNAME, NULL },
|
#endif
|
||||||
{ CODECTYPE_MOD, BGM_STREAMER, -1, "s3m", MUSIC_DIRNAME, NULL },
|
#if USE_CODEC_VORBIS
|
||||||
{ CODECTYPE_MOD, BGM_STREAMER, -1, "xm", MUSIC_DIRNAME, NULL },
|
{ CODECTYPE_VORBIS, "ogg" },
|
||||||
{ CODECTYPE_MOD, BGM_STREAMER, -1, "mod", MUSIC_DIRNAME, NULL },
|
#endif
|
||||||
{ CODECTYPE_UMX, BGM_STREAMER, -1, "umx", MUSIC_DIRNAME, NULL },
|
#if USE_CODEC_MOD
|
||||||
{ CODECTYPE_NONE, BGM_NONE, -1, NULL, NULL, NULL }
|
{ CODECTYPE_MOD, "it" },
|
||||||
|
{ CODECTYPE_MOD, "s3m" },
|
||||||
|
{ CODECTYPE_MOD, "xm" },
|
||||||
|
{ CODECTYPE_MOD, "mod" },
|
||||||
|
{ CODECTYPE_UMX, "umx" },
|
||||||
|
#endif
|
||||||
|
{ CODECTYPE_NONE, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
static music_handler_t *music_handlers = NULL;
|
|
||||||
|
|
||||||
#define ANY_CODECTYPE 0xFFFFFFFF
|
|
||||||
#define CDRIP_TYPES (CODECTYPE_VORBIS | CODECTYPE_MP3 | CODECTYPE_FLAC | CODECTYPE_WAV | CODECTYPE_OPUS)
|
|
||||||
#define CDRIPTYPE(x) (((x) & CDRIP_TYPES) != 0)
|
|
||||||
|
|
||||||
static snd_stream_t *bgmstream = NULL;
|
static snd_stream_t *bgmstream = NULL;
|
||||||
|
|
||||||
static void BGM_Play_f(void)
|
static void BGM_Play_f(void)
|
||||||
|
@ -123,11 +112,8 @@ static void BGM_Stop_f(void)
|
||||||
BGM_Stop();
|
BGM_Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BGM_Init(void)
|
void BGM_Init(void)
|
||||||
{
|
{
|
||||||
music_handler_t *handlers = NULL;
|
|
||||||
int32_t i;
|
|
||||||
|
|
||||||
Cvar_RegisterVariable(&bgm_extmusic);
|
Cvar_RegisterVariable(&bgm_extmusic);
|
||||||
Cmd_AddCommand("music", BGM_Play_f);
|
Cmd_AddCommand("music", BGM_Play_f);
|
||||||
Cmd_AddCommand("music_pause", BGM_Pause_f);
|
Cmd_AddCommand("music_pause", BGM_Pause_f);
|
||||||
|
@ -140,37 +126,7 @@ bool BGM_Init(void)
|
||||||
|
|
||||||
bgm_loop = true;
|
bgm_loop = true;
|
||||||
|
|
||||||
for(i = 0; wanted_handlers[i].type != CODECTYPE_NONE; i++)
|
CDAudio_Init();
|
||||||
{
|
|
||||||
switch(wanted_handlers[i].player)
|
|
||||||
{
|
|
||||||
case BGM_MIDIDRV:
|
|
||||||
/* not supported */
|
|
||||||
break;
|
|
||||||
case BGM_STREAMER:
|
|
||||||
wanted_handlers[i].is_available =
|
|
||||||
S_CodecIsAvailable(wanted_handlers[i].type);
|
|
||||||
break;
|
|
||||||
case BGM_NONE:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(wanted_handlers[i].is_available != -1)
|
|
||||||
{
|
|
||||||
if(handlers)
|
|
||||||
{
|
|
||||||
handlers->next = &wanted_handlers[i];
|
|
||||||
handlers = handlers->next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
music_handlers = &wanted_handlers[i];
|
|
||||||
handlers = music_handlers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return CDAudio_Init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BGM_Shutdown(void)
|
void BGM_Shutdown(void)
|
||||||
|
@ -178,7 +134,6 @@ void BGM_Shutdown(void)
|
||||||
BGM_Stop();
|
BGM_Stop();
|
||||||
/* sever our connections to
|
/* sever our connections to
|
||||||
* midi_drv and snd_codec */
|
* midi_drv and snd_codec */
|
||||||
music_handlers = NULL;
|
|
||||||
CDAudio_Shutdown();
|
CDAudio_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,36 +142,14 @@ static void BGM_Play_noext(const char *filename, uint32_t allowed_types)
|
||||||
char tmp[MAX_QPATH];
|
char tmp[MAX_QPATH];
|
||||||
music_handler_t *handler;
|
music_handler_t *handler;
|
||||||
|
|
||||||
handler = music_handlers;
|
for(handler = music_handlers; handler->type != CODECTYPE_NONE; handler++)
|
||||||
while(handler)
|
|
||||||
{
|
{
|
||||||
if(!(handler->type & allowed_types))
|
if(!(handler->type & allowed_types))
|
||||||
{
|
|
||||||
handler = handler->next;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
q_snprintf(tmp, sizeof(tmp), "%s/%s.%s", MUSIC_DIRNAME, filename, handler->ext);
|
||||||
if(!handler->is_available)
|
|
||||||
{
|
|
||||||
handler = handler->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
q_snprintf(tmp, sizeof(tmp), "%s/%s.%s",
|
|
||||||
handler->dir, filename, handler->ext);
|
|
||||||
switch(handler->player)
|
|
||||||
{
|
|
||||||
case BGM_MIDIDRV:
|
|
||||||
/* not supported */
|
|
||||||
break;
|
|
||||||
case BGM_STREAMER:
|
|
||||||
bgmstream = S_CodecOpenStreamType(tmp, handler->type);
|
bgmstream = S_CodecOpenStreamType(tmp, handler->type);
|
||||||
if(bgmstream)
|
if(bgmstream)
|
||||||
return; /* success */
|
return;
|
||||||
break;
|
|
||||||
case BGM_NONE:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
handler = handler->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Con_Printf("Couldn't handle music file %s\n", filename);
|
Con_Printf("Couldn't handle music file %s\n", filename);
|
||||||
|
@ -230,9 +163,6 @@ void BGM_Play(const char *filename)
|
||||||
|
|
||||||
BGM_Stop();
|
BGM_Stop();
|
||||||
|
|
||||||
if(music_handlers == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!filename || !*filename)
|
if(!filename || !*filename)
|
||||||
{
|
{
|
||||||
Con_DPrintf("null music file name\n");
|
Con_DPrintf("null music file name\n");
|
||||||
|
@ -246,34 +176,20 @@ void BGM_Play(const char *filename)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
handler = music_handlers;
|
for(handler = music_handlers; handler->type != CODECTYPE_NONE; handler++)
|
||||||
while(handler)
|
|
||||||
{
|
{
|
||||||
if(handler->is_available &&
|
if(!q_strcasecmp(ext, handler->ext))
|
||||||
!q_strcasecmp(ext, handler->ext))
|
|
||||||
break;
|
break;
|
||||||
handler = handler->next;
|
|
||||||
}
|
}
|
||||||
if(!handler)
|
if(handler->type == CODECTYPE_NONE)
|
||||||
{
|
{
|
||||||
Con_Printf("Unhandled extension for %s\n", filename);
|
Con_Printf("Unhandled extension for %s\n", filename);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
q_snprintf(tmp, sizeof(tmp), "%s/%s", handler->dir, filename);
|
q_snprintf(tmp, sizeof(tmp), "%s/%s", MUSIC_DIRNAME, filename);
|
||||||
switch(handler->player)
|
|
||||||
{
|
|
||||||
case BGM_MIDIDRV:
|
|
||||||
/* not supported */
|
|
||||||
break;
|
|
||||||
case BGM_STREAMER:
|
|
||||||
bgmstream = S_CodecOpenStreamType(tmp, handler->type);
|
bgmstream = S_CodecOpenStreamType(tmp, handler->type);
|
||||||
if(bgmstream)
|
if(bgmstream)
|
||||||
return; /* success */
|
return; /* success */
|
||||||
break;
|
|
||||||
case BGM_NONE:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Con_Printf("Couldn't handle music file %s\n", filename);
|
Con_Printf("Couldn't handle music file %s\n", filename);
|
||||||
}
|
}
|
||||||
|
@ -296,41 +212,32 @@ void BGM_PlayCDTrack(byte track, bool looping)
|
||||||
if(CDAudio_Play(track, looping) == 0)
|
if(CDAudio_Play(track, looping) == 0)
|
||||||
return; /* success */
|
return; /* success */
|
||||||
|
|
||||||
if(music_handlers == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(no_extmusic || !bgm_extmusic.value)
|
if(no_extmusic || !bgm_extmusic.value)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
prev_id = 0;
|
prev_id = 0;
|
||||||
type = 0;
|
type = 0;
|
||||||
ext = NULL;
|
ext = NULL;
|
||||||
handler = music_handlers;
|
for(handler = music_handlers; handler->type != CODECTYPE_NONE; handler++)
|
||||||
while(handler)
|
|
||||||
{
|
{
|
||||||
if(! handler->is_available)
|
|
||||||
goto next;
|
|
||||||
if(!CDRIPTYPE(handler->type))
|
if(!CDRIPTYPE(handler->type))
|
||||||
goto next;
|
continue;
|
||||||
q_snprintf(tmp, sizeof(tmp), "%s/track%02" PRIi32 ".%s",
|
printf("%s\n", handler->ext);
|
||||||
MUSIC_DIRNAME, (int32_t)track, handler->ext);
|
q_snprintf(tmp, sizeof(tmp), "%s/track%02i.%s", MUSIC_DIRNAME, track, handler->ext);
|
||||||
if(!COM_FileExists(tmp, &path_id))
|
if(!COM_FileExists(tmp, &path_id))
|
||||||
goto next;
|
continue;
|
||||||
if(path_id > prev_id)
|
if(path_id > prev_id)
|
||||||
{
|
{
|
||||||
prev_id = path_id;
|
prev_id = path_id;
|
||||||
type = handler->type;
|
type = handler->type;
|
||||||
ext = handler->ext;
|
ext = handler->ext;
|
||||||
}
|
}
|
||||||
next:
|
|
||||||
handler = handler->next;
|
|
||||||
}
|
}
|
||||||
if(ext == NULL)
|
if(ext == NULL)
|
||||||
Con_Printf("Couldn't find a cdrip for track %" PRIi32 "\n", (int32_t)track);
|
Con_Printf("Couldn't find a cdrip for track %" PRIi32 "\n", (int32_t)track);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
q_snprintf(tmp, sizeof(tmp), "%s/track%02" PRIi32 ".%s",
|
q_snprintf(tmp, sizeof(tmp), "%s/track%02i.%s", MUSIC_DIRNAME, track, ext);
|
||||||
MUSIC_DIRNAME, (int32_t)track, ext);
|
|
||||||
bgmstream = S_CodecOpenStreamType(tmp, type);
|
bgmstream = S_CodecOpenStreamType(tmp, type);
|
||||||
if(! bgmstream)
|
if(! bgmstream)
|
||||||
Con_Printf("Couldn't handle music file %s\n", tmp);
|
Con_Printf("Couldn't handle music file %s\n", tmp);
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
extern bool bgm_loop;
|
extern bool bgm_loop;
|
||||||
extern cvar_t bgm_extmusic;
|
extern cvar_t bgm_extmusic;
|
||||||
|
|
||||||
bool BGM_Init(void);
|
void BGM_Init(void);
|
||||||
void BGM_Shutdown(void);
|
void BGM_Shutdown(void);
|
||||||
|
|
||||||
void BGM_Play(const char *filename);
|
void BGM_Play(const char *filename);
|
||||||
|
|
|
@ -27,18 +27,11 @@
|
||||||
#include "snd_codec.h"
|
#include "snd_codec.h"
|
||||||
#include "snd_codeci.h"
|
#include "snd_codeci.h"
|
||||||
|
|
||||||
static snd_codec_t *codecs;
|
static snd_codec_t *codecs[] = {
|
||||||
|
#define snd_codec__xmac(x, y) &x##_codec,
|
||||||
/*
|
#include "snd_codec.h"
|
||||||
=================
|
NULL
|
||||||
S_CodecRegister
|
};
|
||||||
=================
|
|
||||||
*/
|
|
||||||
static void S_CodecRegister(snd_codec_t *codec)
|
|
||||||
{
|
|
||||||
codec->next = codecs;
|
|
||||||
codecs = codec;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
|
@ -47,35 +40,11 @@ S_CodecInit
|
||||||
*/
|
*/
|
||||||
void S_CodecInit(void)
|
void S_CodecInit(void)
|
||||||
{
|
{
|
||||||
snd_codec_t *codec;
|
snd_codec_t **codec;
|
||||||
codecs = NULL;
|
|
||||||
|
|
||||||
/* Register in the inverse order
|
for(codec = codecs; *codec; codec++)
|
||||||
* of codec choice preference: */
|
|
||||||
extern snd_codec_t umx_codec;
|
|
||||||
S_CodecRegister(&umx_codec);
|
|
||||||
#if defined(USE_CODEC_MIKMOD)
|
|
||||||
extern snd_codec_t mikmod_codec;
|
|
||||||
S_CodecRegister(&mikmod_codec);
|
|
||||||
#endif
|
|
||||||
#if defined(USE_CODEC_FLAC)
|
|
||||||
extern snd_codec_t flac_codec;
|
|
||||||
S_CodecRegister(&flac_codec);
|
|
||||||
#endif
|
|
||||||
#if defined(USE_CODEC_OPUS)
|
|
||||||
extern snd_codec_t opus_codec;
|
|
||||||
S_CodecRegister(&opus_codec);
|
|
||||||
#endif
|
|
||||||
#if defined(USE_CODEC_VORBIS)
|
|
||||||
extern snd_codec_t vorbis_codec;
|
|
||||||
S_CodecRegister(&vorbis_codec);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
codec = codecs;
|
|
||||||
while(codec)
|
|
||||||
{
|
{
|
||||||
codec->initialize();
|
(*codec)->initialize();
|
||||||
codec = codec->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,13 +55,11 @@ S_CodecShutdown
|
||||||
*/
|
*/
|
||||||
void S_CodecShutdown(void)
|
void S_CodecShutdown(void)
|
||||||
{
|
{
|
||||||
snd_codec_t *codec = codecs;
|
snd_codec_t **codec;
|
||||||
while(codec)
|
for(codec = codecs; *codec; codec++)
|
||||||
{
|
{
|
||||||
codec->shutdown();
|
(*codec)->shutdown();
|
||||||
codec = codec->next;
|
|
||||||
}
|
}
|
||||||
codecs = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -102,7 +69,7 @@ S_CodecOpenStream
|
||||||
*/
|
*/
|
||||||
snd_stream_t *S_CodecOpenStreamType(const char *filename, uint32_t type)
|
snd_stream_t *S_CodecOpenStreamType(const char *filename, uint32_t type)
|
||||||
{
|
{
|
||||||
snd_codec_t *codec;
|
snd_codec_t **codec;
|
||||||
snd_stream_t *stream;
|
snd_stream_t *stream;
|
||||||
|
|
||||||
if(type == CODECTYPE_NONE)
|
if(type == CODECTYPE_NONE)
|
||||||
|
@ -111,31 +78,30 @@ snd_stream_t *S_CodecOpenStreamType(const char *filename, uint32_t type)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
codec = codecs;
|
for(codec = codecs; *codec; codec++)
|
||||||
while(codec)
|
|
||||||
{
|
{
|
||||||
if(type == codec->type)
|
if((*codec)->type == type)
|
||||||
break;
|
break;
|
||||||
codec = codec->next;
|
|
||||||
}
|
}
|
||||||
if(!codec)
|
if(!*codec)
|
||||||
{
|
{
|
||||||
Con_Printf("Unknown type for %s\n", filename);
|
Con_Printf("Unknown type for %s\n", filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
stream = S_CodecUtilOpen(filename, codec);
|
stream = S_CodecUtilOpen(filename, *codec);
|
||||||
if(stream)
|
if(stream)
|
||||||
{
|
{
|
||||||
if(codec->codec_open(stream))
|
if((*codec)->codec_open(stream))
|
||||||
stream->status = STREAM_PLAY;
|
stream->status = STREAM_PLAY;
|
||||||
else S_CodecUtilClose(&stream);
|
else
|
||||||
|
S_CodecUtilClose(&stream);
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_stream_t *S_CodecOpenStreamExt(const char *filename)
|
snd_stream_t *S_CodecOpenStreamExt(const char *filename)
|
||||||
{
|
{
|
||||||
snd_codec_t *codec;
|
snd_codec_t **codec;
|
||||||
snd_stream_t *stream;
|
snd_stream_t *stream;
|
||||||
const char *ext;
|
const char *ext;
|
||||||
|
|
||||||
|
@ -146,31 +112,30 @@ snd_stream_t *S_CodecOpenStreamExt(const char *filename)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
codec = codecs;
|
for(codec = codecs; *codec; codec++)
|
||||||
while(codec)
|
|
||||||
{
|
{
|
||||||
if(!q_strcasecmp(ext, codec->ext))
|
if(!q_strcasecmp(ext, (*codec)->ext))
|
||||||
break;
|
break;
|
||||||
codec = codec->next;
|
|
||||||
}
|
}
|
||||||
if(!codec)
|
if(!*codec)
|
||||||
{
|
{
|
||||||
Con_Printf("Unknown extension for %s\n", filename);
|
Con_Printf("Unknown extension for %s\n", filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
stream = S_CodecUtilOpen(filename, codec);
|
stream = S_CodecUtilOpen(filename, *codec);
|
||||||
if(stream)
|
if(stream)
|
||||||
{
|
{
|
||||||
if(codec->codec_open(stream))
|
if((*codec)->codec_open(stream))
|
||||||
stream->status = STREAM_PLAY;
|
stream->status = STREAM_PLAY;
|
||||||
else S_CodecUtilClose(&stream);
|
else
|
||||||
|
S_CodecUtilClose(&stream);
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_stream_t *S_CodecOpenStreamAny(const char *filename)
|
snd_stream_t *S_CodecOpenStreamAny(const char *filename)
|
||||||
{
|
{
|
||||||
snd_codec_t *codec;
|
snd_codec_t **codec;
|
||||||
snd_stream_t *stream;
|
snd_stream_t *stream;
|
||||||
const char *ext;
|
const char *ext;
|
||||||
|
|
||||||
|
@ -179,45 +144,42 @@ snd_stream_t *S_CodecOpenStreamAny(const char *filename)
|
||||||
{
|
{
|
||||||
char tmp[MAX_QPATH];
|
char tmp[MAX_QPATH];
|
||||||
|
|
||||||
codec = codecs;
|
for(codec = codecs; *codec; codec++)
|
||||||
while(codec)
|
|
||||||
{
|
{
|
||||||
q_snprintf(tmp, sizeof(tmp), "%s.%s", filename, codec->ext);
|
q_snprintf(tmp, sizeof(tmp), "%s.%s", filename, (*codec)->ext);
|
||||||
stream = S_CodecUtilOpen(tmp, codec);
|
stream = S_CodecUtilOpen(tmp, *codec);
|
||||||
if(stream)
|
if(stream)
|
||||||
{
|
{
|
||||||
if(codec->codec_open(stream))
|
if((*codec)->codec_open(stream))
|
||||||
{
|
{
|
||||||
stream->status = STREAM_PLAY;
|
stream->status = STREAM_PLAY;
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
S_CodecUtilClose(&stream);
|
S_CodecUtilClose(&stream);
|
||||||
}
|
}
|
||||||
codec = codec->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else /* use the name as is */
|
else /* use the name as is */
|
||||||
{
|
{
|
||||||
codec = codecs;
|
for(codec = codecs; *codec; codec++)
|
||||||
while(codec)
|
|
||||||
{
|
{
|
||||||
if(!q_strcasecmp(ext, codec->ext))
|
if(!q_strcasecmp(ext, (*codec)->ext))
|
||||||
break;
|
break;
|
||||||
codec = codec->next;
|
|
||||||
}
|
}
|
||||||
if(!codec)
|
if(!*codec)
|
||||||
{
|
{
|
||||||
Con_Printf("Unknown extension for %s\n", filename);
|
Con_Printf("Unknown extension for %s\n", filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
stream = S_CodecUtilOpen(filename, codec);
|
stream = S_CodecUtilOpen(filename, *codec);
|
||||||
if(stream)
|
if(stream)
|
||||||
{
|
{
|
||||||
if(codec->codec_open(stream))
|
if((*codec)->codec_open(stream))
|
||||||
stream->status = STREAM_PLAY;
|
stream->status = STREAM_PLAY;
|
||||||
else S_CodecUtilClose(&stream);
|
else
|
||||||
|
S_CodecUtilClose(&stream);
|
||||||
}
|
}
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
@ -225,17 +187,17 @@ snd_stream_t *S_CodecOpenStreamAny(const char *filename)
|
||||||
|
|
||||||
bool S_CodecForwardStream(snd_stream_t *stream, uint32_t type)
|
bool S_CodecForwardStream(snd_stream_t *stream, uint32_t type)
|
||||||
{
|
{
|
||||||
snd_codec_t *codec = codecs;
|
snd_codec_t **codec;
|
||||||
|
|
||||||
while(codec)
|
for(codec = codecs; *codec; codec++)
|
||||||
{
|
{
|
||||||
if(type == codec->type)
|
if((*codec)->type == type)
|
||||||
break;
|
break;
|
||||||
codec = codec->next;
|
|
||||||
}
|
}
|
||||||
if(!codec) return false;
|
if(!*codec)
|
||||||
stream->codec = codec;
|
return false;
|
||||||
return codec->codec_open(stream);
|
stream->codec = *codec;
|
||||||
|
return (*codec)->codec_open(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_CodecCloseStream(snd_stream_t *stream)
|
void S_CodecCloseStream(snd_stream_t *stream)
|
||||||
|
@ -292,15 +254,3 @@ void S_CodecUtilClose(snd_stream_t **stream)
|
||||||
*stream = NULL;
|
*stream = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t S_CodecIsAvailable(uint32_t type)
|
|
||||||
{
|
|
||||||
snd_codec_t *codec = codecs;
|
|
||||||
while(codec)
|
|
||||||
{
|
|
||||||
if(type == codec->type)
|
|
||||||
return codec->initialized;
|
|
||||||
codec = codec->next;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,25 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef spingle__snd_codec_h
|
#if defined(snd_codec__xmac)
|
||||||
|
|
||||||
|
#if USE_CODEC_FLAC
|
||||||
|
snd_codec__xmac(flac, FLAC)
|
||||||
|
#endif
|
||||||
|
#if USE_CODEC_OPUS
|
||||||
|
snd_codec__xmac(opus, OPUS)
|
||||||
|
#endif
|
||||||
|
#if USE_CODEC_VORBIS
|
||||||
|
snd_codec__xmac(vorbis, VORBIS)
|
||||||
|
#endif
|
||||||
|
#if USE_CODEC_MOD
|
||||||
|
snd_codec__xmac(mikmod, MOD)
|
||||||
|
snd_codec__xmac(umx, UMX)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef snd_codec__xmac
|
||||||
|
|
||||||
|
#elif !defined(spingle__snd_codec_h)
|
||||||
#define spingle__snd_codec_h
|
#define spingle__snd_codec_h
|
||||||
|
|
||||||
typedef struct snd_info_s
|
typedef struct snd_info_s
|
||||||
|
@ -83,22 +101,30 @@ int32_t S_CodecRewindStream(snd_stream_t *stream);
|
||||||
snd_stream_t *S_CodecUtilOpen(const char *filename, snd_codec_t *codec);
|
snd_stream_t *S_CodecUtilOpen(const char *filename, snd_codec_t *codec);
|
||||||
void S_CodecUtilClose(snd_stream_t **stream);
|
void S_CodecUtilClose(snd_stream_t **stream);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CODECTYPE_NONE,
|
||||||
|
#define snd_codec__xmac(x, y) CODECTYPE_##y##_BIT,
|
||||||
|
#include "snd_codec.h"
|
||||||
|
#define snd_codec__xmac(x, y) CODECTYPE_##y = 1 << CODECTYPE_##y##_BIT,
|
||||||
|
#include "snd_codec.h"
|
||||||
|
ANY_CODECTYPE = 0xFFFFFFFF,
|
||||||
|
CDRIP_TYPES =
|
||||||
|
#if USE_CODEC_VORBIS
|
||||||
|
CODECTYPE_VORBIS |
|
||||||
|
#endif
|
||||||
|
#if USE_CODEC_OPUS
|
||||||
|
CODECTYPE_OPUS |
|
||||||
|
#endif
|
||||||
|
#if USE_CODEC_FLAC
|
||||||
|
CODECTYPE_FLAC |
|
||||||
|
#endif
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
#define CODECTYPE_NONE 0
|
#define CDRIPTYPE(x) (((x) & CDRIP_TYPES) != 0)
|
||||||
#define CODECTYPE_MID (1U << 0)
|
|
||||||
#define CODECTYPE_MOD (1U << 1)
|
|
||||||
#define CODECTYPE_FLAC (1U << 2)
|
|
||||||
#define CODECTYPE_WAV (1U << 3)
|
|
||||||
#define CODECTYPE_MP3 (1U << 4)
|
|
||||||
#define CODECTYPE_VORBIS (1U << 5)
|
|
||||||
#define CODECTYPE_OPUS (1U << 6)
|
|
||||||
#define CODECTYPE_UMX (1U << 7)
|
|
||||||
|
|
||||||
#define CODECTYPE_WAVE CODECTYPE_WAV
|
#define snd_codec__xmac(x, y) extern snd_codec_t x##_codec;
|
||||||
#define CODECTYPE_MIDI CODECTYPE_MID
|
#include "snd_codec.h"
|
||||||
|
|
||||||
int32_t S_CodecIsAvailable(uint32_t type);
|
|
||||||
/* return 1 if available, 0 if codec failed init
|
|
||||||
* or -1 if no such codec is present. */
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -45,7 +45,6 @@ struct snd_codec_s
|
||||||
CODEC_READ codec_read;
|
CODEC_READ codec_read;
|
||||||
CODEC_REWIND codec_rewind;
|
CODEC_REWIND codec_rewind;
|
||||||
CODEC_CLOSE codec_close;
|
CODEC_CLOSE codec_close;
|
||||||
snd_codec_t *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool S_CodecForwardStream(snd_stream_t *stream, uint32_t type);
|
bool S_CodecForwardStream(snd_stream_t *stream, uint32_t type);
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#include "q_defs.h"
|
#include "q_defs.h"
|
||||||
|
|
||||||
#if defined(USE_CODEC_FLAC)
|
#if USE_CODEC_FLAC
|
||||||
#include "snd_codec.h"
|
#include "snd_codec.h"
|
||||||
#include "snd_codeci.h"
|
#include "snd_codeci.h"
|
||||||
|
|
||||||
|
@ -399,7 +399,6 @@ snd_codec_t flac_codec =
|
||||||
S_FLAC_CodecReadStream,
|
S_FLAC_CodecReadStream,
|
||||||
S_FLAC_CodecRewindStream,
|
S_FLAC_CodecRewindStream,
|
||||||
S_FLAC_CodecCloseStream,
|
S_FLAC_CodecCloseStream,
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* USE_CODEC_FLAC */
|
#endif /* USE_CODEC_FLAC */
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "q_defs.h"
|
#include "q_defs.h"
|
||||||
|
|
||||||
#if defined(USE_CODEC_MIKMOD)
|
#if USE_CODEC_MOD
|
||||||
#include "snd_codec.h"
|
#include "snd_codec.h"
|
||||||
#include "snd_codeci.h"
|
#include "snd_codeci.h"
|
||||||
#include <mikmod.h>
|
#include <mikmod.h>
|
||||||
|
@ -167,6 +167,7 @@ static bool S_MIKMOD_CodecOpenStream(snd_stream_t *stream)
|
||||||
|
|
||||||
static int32_t S_MIKMOD_CodecReadStream(snd_stream_t *stream, int32_t bytes, void *buffer)
|
static int32_t S_MIKMOD_CodecReadStream(snd_stream_t *stream, int32_t bytes, void *buffer)
|
||||||
{
|
{
|
||||||
|
(void)stream;
|
||||||
if(!Player_Active())
|
if(!Player_Active())
|
||||||
return 0;
|
return 0;
|
||||||
return (int32_t) VC_WriteBytes((SBYTE *)buffer, bytes);
|
return (int32_t) VC_WriteBytes((SBYTE *)buffer, bytes);
|
||||||
|
@ -182,6 +183,7 @@ static void S_MIKMOD_CodecCloseStream(snd_stream_t *stream)
|
||||||
|
|
||||||
static int32_t S_MIKMOD_CodecRewindStream(snd_stream_t *stream)
|
static int32_t S_MIKMOD_CodecRewindStream(snd_stream_t *stream)
|
||||||
{
|
{
|
||||||
|
(void)stream;
|
||||||
Player_SetPosition(0);
|
Player_SetPosition(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -197,8 +199,7 @@ snd_codec_t mikmod_codec =
|
||||||
S_MIKMOD_CodecReadStream,
|
S_MIKMOD_CodecReadStream,
|
||||||
S_MIKMOD_CodecRewindStream,
|
S_MIKMOD_CodecRewindStream,
|
||||||
S_MIKMOD_CodecCloseStream,
|
S_MIKMOD_CodecCloseStream,
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* USE_CODEC_MIKMOD */
|
#endif /* USE_CODEC_MOD */
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "q_defs.h"
|
#include "q_defs.h"
|
||||||
|
|
||||||
#if defined(USE_CODEC_OPUS)
|
#if USE_CODEC_OPUS
|
||||||
#include "snd_codec.h"
|
#include "snd_codec.h"
|
||||||
#include "snd_codeci.h"
|
#include "snd_codeci.h"
|
||||||
|
|
||||||
|
@ -201,7 +201,6 @@ snd_codec_t opus_codec =
|
||||||
S_OPUS_CodecReadStream,
|
S_OPUS_CodecReadStream,
|
||||||
S_OPUS_CodecRewindStream,
|
S_OPUS_CodecRewindStream,
|
||||||
S_OPUS_CodecCloseStream,
|
S_OPUS_CodecCloseStream,
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* USE_CODEC_OPUS */
|
#endif /* USE_CODEC_OPUS */
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include "q_defs.h"
|
#include "q_defs.h"
|
||||||
|
|
||||||
|
#if USE_CODEC_MOD
|
||||||
#include "snd_codec.h"
|
#include "snd_codec.h"
|
||||||
#include "snd_codeci.h"
|
#include "snd_codeci.h"
|
||||||
|
|
||||||
|
@ -387,9 +388,8 @@ static bool S_UMX_CodecOpenStream(snd_stream_t *stream)
|
||||||
case UMUSIC_MOD:
|
case UMUSIC_MOD:
|
||||||
return S_CodecForwardStream(stream, CODECTYPE_MOD);
|
return S_CodecForwardStream(stream, CODECTYPE_MOD);
|
||||||
case UMUSIC_WAV:
|
case UMUSIC_WAV:
|
||||||
return S_CodecForwardStream(stream, CODECTYPE_WAV);
|
|
||||||
case UMUSIC_MP2:
|
case UMUSIC_MP2:
|
||||||
return S_CodecForwardStream(stream, CODECTYPE_MP3);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -423,6 +423,7 @@ snd_codec_t umx_codec =
|
||||||
S_UMX_CodecReadStream,
|
S_UMX_CodecReadStream,
|
||||||
S_UMX_CodecRewindStream,
|
S_UMX_CodecRewindStream,
|
||||||
S_UMX_CodecCloseStream,
|
S_UMX_CodecCloseStream,
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif /* USE_CODEC_MOD */
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
#include "q_defs.h"
|
#include "q_defs.h"
|
||||||
|
|
||||||
#if defined(USE_CODEC_VORBIS)
|
#if USE_CODEC_VORBIS
|
||||||
#include "snd_codec.h"
|
#include "snd_codec.h"
|
||||||
#include "snd_codeci.h"
|
#include "snd_codeci.h"
|
||||||
|
|
||||||
|
@ -199,7 +199,6 @@ snd_codec_t vorbis_codec =
|
||||||
S_VORBIS_CodecReadStream,
|
S_VORBIS_CodecReadStream,
|
||||||
S_VORBIS_CodecRewindStream,
|
S_VORBIS_CodecRewindStream,
|
||||||
S_VORBIS_CodecCloseStream,
|
S_VORBIS_CodecCloseStream,
|
||||||
NULL
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* USE_CODEC_VORBIS */
|
#endif /* USE_CODEC_VORBIS */
|
||||||
|
|
Loading…
Reference in New Issue