* snd_mpg123.c: added new codec for mp3 playback using libmpg123 as

an alternative to the existing one using libmad. requires at least
  mpg123-1.12.0, i.e. api version 25.


git-svn-id: http://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@414 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
sezero 2011-02-14 20:02:52 +00:00
parent 119e534bd0
commit 81a318c09b
9 changed files with 294 additions and 13 deletions

View file

@ -19,6 +19,9 @@ USE_CODEC_WAVE=1
USE_CODEC_MP3=1
USE_CODEC_VORBIS=1
# which library to use for mp3 decoding: mad or mpg123
MP3LIB=mad
# ============================================================================
# Helper functions
# ============================================================================
@ -121,6 +124,17 @@ ifeq ($(USE_QS_CONBACK),1)
CFLAGS+= -DUSE_QS_CONBACK
endif
ifeq ($(MP3LIB),mad)
mp3_obj=snd_mp3.o
else
ifeq ($(MP3LIB),mpg123)
mp3_obj=snd_mpg123.o
else
USE_CODEC_MP3=no
mp3_obj=snd_mp3.o
endif
endif
CODECLIBS :=
ifeq ($(USE_CODEC_WAVE),1)
CFLAGS+= -DUSE_CODEC_WAVE
@ -131,7 +145,7 @@ CODECLIBS+= vorbis vorbisfile ogg
endif
ifeq ($(USE_CODEC_MP3),1)
CFLAGS+= -DUSE_CODEC_MP3
CODECLIBS+= mad
CODECLIBS+= $(MP3LIB)
endif
COMMON_LIBS:= m GL
@ -161,7 +175,7 @@ MUSIC_OBJS:= bgmusic.o \
snd_codec.o \
snd_wave.o \
snd_vorbis.o \
snd_mp3.o
$(mp3_obj)
COMOBJ_SND := snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS)
SYSOBJ_SND := snd_sdl.o
SYSOBJ_CDA := cd_sdl.o

View file

@ -18,6 +18,9 @@ USE_CODEC_WAVE=1
USE_CODEC_MP3=1
USE_CODEC_VORBIS=1
# which library to use for mp3 decoding: mad or mpg123
MP3LIB=mad
# ============================================================================
# Helper functions
# ============================================================================
@ -127,6 +130,17 @@ ifeq ($(USE_QS_CONBACK),1)
CFLAGS+= -DUSE_QS_CONBACK
endif
ifeq ($(MP3LIB),mad)
mp3_obj=snd_mp3.o
else
ifeq ($(MP3LIB),mpg123)
mp3_obj=snd_mpg123.o
else
USE_CODEC_MP3=no
mp3_obj=snd_mp3.o
endif
endif
# FIXME: The codec libs stuff are copied over from the unix makefile
# They might need adaptations for Darwin
CODECLIBS :=
@ -139,7 +153,7 @@ CODECLIBS+= -lvorbis -lvorbisfile -logg
endif
ifeq ($(USE_CODEC_MP3),1)
CFLAGS+= -DUSE_CODEC_MP3
CODECLIBS+= -lmad
CODECLIBS+= -l$(MP3LIB)
endif
COMMON_LIBS = -Wl,-framework,OpenGL
@ -170,7 +184,7 @@ MUSIC_OBJS:= bgmusic.o \
snd_codec.o \
snd_wave.o \
snd_vorbis.o \
snd_mp3.o
$(mp3_obj)
COMOBJ_SND := snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS)
SYSOBJ_SND := snd_sdl.o
SYSOBJ_CDA := cd_sdl.o

View file

@ -14,6 +14,9 @@ USE_CODEC_WAVE=1
USE_CODEC_MP3=1
USE_CODEC_VORBIS=1
# which library to use for mp3 decoding: mad or mpg123
MP3LIB=mad
# ============================================================================
# Helper functions
# ============================================================================
@ -93,6 +96,17 @@ ifeq ($(USE_QS_CONBACK),1)
CFLAGS+= -DUSE_QS_CONBACK
endif
ifeq ($(MP3LIB),mad)
mp3_obj=snd_mp3.o
else
ifeq ($(MP3LIB),mpg123)
mp3_obj=snd_mpg123.o
else
USE_CODEC_MP3=no
mp3_obj=snd_mp3.o
endif
endif
CODECLIBS :=
ifeq ($(USE_CODEC_WAVE),1)
CFLAGS+= -DUSE_CODEC_WAVE
@ -109,7 +123,7 @@ ifeq ($(USE_CODEC_MP3),1)
CFLAGS+= -DUSE_CODEC_MP3
CODEC_INC = -I../Windows/codecs/include
CODEC_LINK= -L../Windows/codecs/x86
CODECLIBS+= -lmad
CODECLIBS+= -l$(MP3LIB)
endif
CFLAGS+= $(CODEC_INC)
@ -142,7 +156,7 @@ MUSIC_OBJS:= bgmusic.o \
snd_codec.o \
snd_wave.o \
snd_vorbis.o \
snd_mp3.o
$(mp3_obj)
COMOBJ_SND := snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS)
SYSOBJ_SND := snd_sdl.o
SYSOBJ_CDA := cd_sdl.o

View file

@ -14,6 +14,9 @@ USE_CODEC_WAVE=1
USE_CODEC_MP3=1
USE_CODEC_VORBIS=1
# which library to use for mp3 decoding: mad or mpg123
MP3LIB=mad
# ============================================================================
# Helper functions
# ============================================================================
@ -93,6 +96,17 @@ ifeq ($(USE_QS_CONBACK),1)
CFLAGS+= -DUSE_QS_CONBACK
endif
ifeq ($(MP3LIB),mad)
mp3_obj=snd_mp3.o
else
ifeq ($(MP3LIB),mpg123)
mp3_obj=snd_mpg123.o
else
USE_CODEC_MP3=no
mp3_obj=snd_mp3.o
endif
endif
CODECLIBS :=
ifeq ($(USE_CODEC_WAVE),1)
CFLAGS+= -DUSE_CODEC_WAVE
@ -109,7 +123,7 @@ ifeq ($(USE_CODEC_MP3),1)
CFLAGS+= -DUSE_CODEC_MP3
CODEC_INC = -I../Windows/codecs/include
CODEC_LINK= -L../Windows/codecs/x64
CODECLIBS+= -lmad
CODECLIBS+= -l$(MP3LIB)
endif
CFLAGS+= $(CODEC_INC)
@ -142,7 +156,7 @@ MUSIC_OBJS:= bgmusic.o \
snd_codec.o \
snd_wave.o \
snd_vorbis.o \
snd_mp3.o
$(mp3_obj)
COMOBJ_SND := snd_dma.o snd_mix.o snd_mem.o $(MUSIC_OBJS)
SYSOBJ_SND := snd_sdl.o
SYSOBJ_CDA := cd_sdl.o

View file

@ -1,4 +1,4 @@
/* MP3 decoding support using libmad. */
/* MP3 decoding support using libmad or libmpg123. */
#if !defined(_SND_MP3_H_)
#define _SND_MP3_H_

225
Quake/snd_mpg123.c Normal file
View file

@ -0,0 +1,225 @@
/*
* MP3 decoding support using libmpg123, loosely based on an SDL_mixer
* plugin found at http://bubu.lv/
* See: http://bubu.lv/changeset/4/public/libs/SDL/generated/SDL_mixer
*
* Copyright (C) 2011 O.Sezer <sezero@users.sourceforge.net>
*
* 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 Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "quakedef.h"
#if defined(USE_CODEC_MP3)
#include "snd_codec.h"
#include "snd_codeci.h"
#include "snd_mp3.h"
#include <errno.h>
#include <mpg123.h>
#if !defined(MPG123_API_VERSION) || (MPG123_API_VERSION < 25)
#error minimum required libmpg123 version is 1.12.0 (api version 25)
#endif /* MPG123_API_VERSION */
/* Private data */
typedef struct _mp3_priv_t
{
int handle_newed, handle_opened;
mpg123_handle* handle;
} mp3_priv_t;
/* CALLBACK FUNCTIONS: */
/* CAREFUL: libmpg123 expects POSIX read() and lseek() behavior,
* however our FS_fread() and FS_fseek() return fread() and fseek()
* compatible values. */
static ssize_t mp3_read (void *f, void *buf, size_t size)
{
ssize_t ret = (ssize_t) FS_fread(buf, 1, size, (fshandle_t *)f);
if (ret == 0 && errno != 0)
ret = -1;
return ret;
}
static off_t mp3_seek (void *f, off_t offset, int whence)
{
if (f == NULL) return (-1);
if (FS_fseek((fshandle_t *)f, (long) offset, whence) < 0)
return (off_t)-1;
return (off_t) FS_ftell((fshandle_t *)f);
}
static qboolean S_MP3_CodecInitialize (void)
{
if (! mp3_codec.initialized)
{
if (mpg123_init() != MPG123_OK)
return false;
mp3_codec.initialized = true;
return true;
}
return true;
}
static void S_MP3_CodecShutdown (void)
{
if (mp3_codec.initialized)
{
mp3_codec.initialized = false;
mpg123_exit();
}
}
static snd_stream_t *S_MP3_CodecOpenStream (const char *filename)
{
snd_stream_t *stream;
long rate = 0;
int encoding = 0, channels = 0;
mp3_priv_t *priv = NULL;
stream = S_CodecUtilOpen(filename, &mp3_codec);
if (!stream)
return NULL;
stream->priv = Z_Malloc(sizeof(mp3_priv_t));
priv = (mp3_priv_t *) stream->priv;
priv->handle = mpg123_new(NULL, NULL);
if (priv->handle == NULL)
{
Con_Printf("Unable to allocate mpg123 handle\n");
goto _fail;
}
priv->handle_newed = 1;
if (mpg123_replace_reader_handle(priv->handle, mp3_read, mp3_seek, NULL) != MPG123_OK ||
mpg123_open_handle(priv->handle, &stream->fh) != MPG123_OK)
{
Con_Printf("Unable to open mpg123 handle\n");
goto _fail;
}
priv->handle_opened = 1;
if (mpg123_getformat(priv->handle, &rate, &channels, &encoding) != MPG123_OK)
{
Con_Printf("Unable to retrieve mpg123 format for %s\n", filename);
goto _fail;
}
switch (channels)
{
case MPG123_MONO:
stream->info.channels = 1;
break;
case MPG123_STEREO:
stream->info.channels = 2;
break;
default:
Con_Printf("Unsupported channel count in %s\n", filename);
goto _fail;
}
stream->info.rate = rate;
switch (encoding)
{
case MPG123_ENC_UNSIGNED_8:
stream->info.width = 1;
break;
case MPG123_ENC_SIGNED_8:
/* unsupported: force mpg123 to convert */
stream->info.width = 1;
encoding = MPG123_ENC_UNSIGNED_8;
break;
case MPG123_ENC_SIGNED_16:
stream->info.width = 2;
break;
case MPG123_ENC_UNSIGNED_16:
default:
/* unsupported: force mpg123 to convert */
stream->info.width = 2;
encoding = MPG123_ENC_SIGNED_16;
break;
}
if (mpg123_format_support(priv->handle, rate, encoding) == 0)
{
Con_Printf("Unsupported format for %s\n", filename);
goto _fail;
}
mpg123_format_none(priv->handle);
mpg123_format(priv->handle, rate, channels, encoding);
return stream;
_fail:
if (priv)
{
if (priv->handle_opened)
mpg123_close(priv->handle);
if (priv->handle_newed)
mpg123_delete(priv->handle);
Z_Free(stream->priv);
}
S_CodecUtilClose(&stream);
return NULL;
}
static int S_MP3_CodecReadStream (snd_stream_t *stream, int bytes, void *buffer)
{
mp3_priv_t *priv = (mp3_priv_t *) stream->priv;
size_t bytes_read = 0;
int res = mpg123_read (priv->handle, (unsigned char *)buffer, (size_t)bytes, &bytes_read);
switch (res)
{
case MPG123_DONE:
Con_DPrintf("mp3 EOF\n");
case MPG123_OK:
return (int)bytes_read;
}
return -1; /* error */
}
static void S_MP3_CodecCloseStream (snd_stream_t *stream)
{
mp3_priv_t *priv = (mp3_priv_t *) stream->priv;
mpg123_close(priv->handle);
mpg123_delete(priv->handle);
Z_Free(stream->priv);
S_CodecUtilClose(&stream);
}
static int S_MP3_CodecRewindStream (snd_stream_t *stream)
{
mp3_priv_t *priv = (mp3_priv_t *) stream->priv;
return (int) mpg123_seek(priv->handle, 0, SEEK_SET);
}
snd_codec_t mp3_codec =
{
CODECTYPE_MP3,
false,
".mp3",
S_MP3_CodecInitialize,
S_MP3_CodecShutdown,
S_MP3_CodecOpenStream,
S_MP3_CodecReadStream,
S_MP3_CodecRewindStream,
S_MP3_CodecCloseStream,
NULL
};
#endif /* USE_CODEC_MP3 */

View file

@ -113,7 +113,7 @@ Compile time options include
<LI><B>make SDL_CONFIG=</B><EM>/PATH/TO/SDL-CONFIG</EM> for unusual SDL installs</LI>
</UL>
</P>
<P>Streaming music playback requires "libmad" for MP3, and "libogg", "libvorbis" for OGG files.</P>
<P>Streaming music playback requires "libmad" or "libmpg123" for MP3, and "libogg" and "libvorbis" for OGG files.</P>
<P>HOME directory support can be enabled via the <B>Misc/homedir_0.patch</B></P>
<P>The project can also be built with Codeblocks (project files included).</P>
.

View file

@ -66,7 +66,7 @@ Compile time options include
<item><bf>make SDLNET=1</bf> to enable SDL_net (Otherwise the socket api will be used directly)
<item><bf>make SDL_CONFIG=</bf><em>/PATH/TO/SDL-CONFIG</em> for unusual SDL installs
</itemize>
<p>Streaming music playback requires "libmad" for MP3, and "libogg", "libvorbis" for OGG files.
<p>Streaming music playback requires "libmad" or "libmpg123" for MP3, and "libogg" and "libvorbis" for OGG files.
<p>HOME directory support can be enabled via the <bf>Misc/homedir_0.patch</bf>
<p>The project can also be built with Codeblocks (project files included).</p>.

View file

@ -109,8 +109,8 @@
o make SDL_CONFIG=/PATH/TO/SDL-CONFIG for unusual SDL installs
Streaming music playback requires "libmad" for MP3, and "libogg",
"libvorbis" for OGG files.
Streaming music playback requires "libmad" or "libmpg123" for MP3, and
"libogg" and "libvorbis" for OGG files.
HOME directory support can be enabled via the Misc/homedir_0.patch