Skip to content

Commit

Permalink
Added support for dynamically loading SMPEG library
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed May 12, 2006
1 parent 4b6fee0 commit 23ce1b1
Show file tree
Hide file tree
Showing 5 changed files with 269 additions and 28 deletions.
5 changes: 3 additions & 2 deletions configure.in
Expand Up @@ -265,8 +265,8 @@ if test x$enable_music_mp3 = xyes; then
AM_PATH_SMPEG($SMPEG_VERSION, have_smpeg=yes, have_smpeg=no)
if test x$have_smpeg = xyes; then
AC_ARG_ENABLE([music-mp3-shared],
AC_HELP_STRING([--enable-music-mp3-shared], [dynamically load MP3 support [[default=no]]]),
[], [enable_music_mp3_shared=no])
AC_HELP_STRING([--enable-music-mp3-shared], [dynamically load MP3 support [[default=yes]]]),
[], [enable_music_mp3_shared=yes])
case "$host" in
*-*-darwin*)
smpeg_lib=''
Expand All @@ -282,6 +282,7 @@ AC_HELP_STRING([--enable-music-mp3-shared], [dynamically load MP3 support [[defa
done
;;
esac
SOURCES="$SOURCES $srcdir/*_mp3.c"
EXTRA_CFLAGS="$EXTRA_CFLAGS -DMP3_MUSIC $SMPEG_CFLAGS"
if test x$enable_music_mp3_shared = xyes && test x$smpeg_lib != x; then
echo "-- dynamic libsmpeg -> $smpeg_lib"
Expand Down
180 changes: 180 additions & 0 deletions dynamic_mp3.c
@@ -0,0 +1,180 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/

#ifdef MP3_MUSIC

#include "SDL_loadso.h"

#include "dynamic_mp3.h"

smpeg_loader smpeg = {
0, NULL
};

#ifdef MP3_DYNAMIC
int Mix_InitMP3()
{
if ( smpeg.loaded == 0 ) {
smpeg.handle = SDL_LoadObject(MP3_DYNAMIC);
if ( smpeg.handle == NULL ) {
return -1;
}
smpeg.SMPEG_actualSpec =
(void (*)( SMPEG *, SDL_AudioSpec * ))
SDL_LoadFunction(smpeg.handle, "SMPEG_actualSpec");
if ( smpeg.SMPEG_actualSpec == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_delete =
(void (*)( SMPEG* ))
SDL_LoadFunction(smpeg.handle, "SMPEG_delete");
if ( smpeg.SMPEG_delete == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_enableaudio =
(void (*)( SMPEG*, int ))
SDL_LoadFunction(smpeg.handle, "SMPEG_enableaudio");
if ( smpeg.SMPEG_enableaudio == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_enablevideo =
(void (*)( SMPEG*, int ))
SDL_LoadFunction(smpeg.handle, "SMPEG_enablevideo");
if ( smpeg.SMPEG_enablevideo == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_new =
(SMPEG* (*)(const char *, SMPEG_Info*, int))
SDL_LoadFunction(smpeg.handle, "SMPEG_new");
if ( smpeg.SMPEG_new == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_new_rwops =
(SMPEG* (*)(SDL_RWops *, SMPEG_Info*, int))
SDL_LoadFunction(smpeg.handle, "SMPEG_new_rwops");
if ( smpeg.SMPEG_new_rwops == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_play =
(void (*)( SMPEG* ))
SDL_LoadFunction(smpeg.handle, "SMPEG_play");
if ( smpeg.SMPEG_play == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_playAudio =
(int (*)( SMPEG *, Uint8 *, int ))
SDL_LoadFunction(smpeg.handle, "SMPEG_playAudio");
if ( smpeg.SMPEG_playAudio == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_rewind =
(void (*)( SMPEG* ))
SDL_LoadFunction(smpeg.handle, "SMPEG_rewind");
if ( smpeg.SMPEG_rewind == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_setvolume =
(void (*)( SMPEG*, int ))
SDL_LoadFunction(smpeg.handle, "SMPEG_setvolume");
if ( smpeg.SMPEG_setvolume == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_skip =
(void (*)( SMPEG*, float ))
SDL_LoadFunction(smpeg.handle, "SMPEG_skip");
if ( smpeg.SMPEG_skip == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_status =
(SMPEGstatus (*)( SMPEG* ))
SDL_LoadFunction(smpeg.handle, "SMPEG_status");
if ( smpeg.SMPEG_status == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
smpeg.SMPEG_stop =
(void (*)( SMPEG* ))
SDL_LoadFunction(smpeg.handle, "SMPEG_stop");
if ( smpeg.SMPEG_stop == NULL ) {
SDL_UnloadObject(smpeg.handle);
return -1;
}
}
++smpeg.loaded;

return 0;
}
void Mix_QuitMP3()
{
if ( smpeg.loaded == 0 ) {
return;
}
if ( smpeg.loaded == 1 ) {
SDL_UnloadObject(smpeg.handle);
}
--smpeg.loaded;
}
#else
int Mix_InitMP3()
{
if ( smpeg.loaded == 0 ) {
smpeg.SMPEG_actualSpec = SMPEG_actualSpec;
smpeg.SMPEG_delete = SMPEG_delete;
smpeg.SMPEG_enableaudio = SMPEG_enableaudio;
smpeg.SMPEG_enablevideo = SMPEG_enablevideo;
smpeg.SMPEG_new = SMPEG_new;
smpeg.SMPEG_new_rwops = SMPEG_new_rwops;
smpeg.SMPEG_play = SMPEG_play;
smpeg.SMPEG_playAudio = SMPEG_playAudio;
smpeg.SMPEG_rewind = SMPEG_rewind;
smpeg.SMPEG_setvolume = SMPEG_setvolume;
smpeg.SMPEG_skip = SMPEG_skip;
smpeg.SMPEG_status = SMPEG_status;
smpeg.SMPEG_stop = SMPEG_stop;
}
++smpeg.loaded;

return 0;
}
void Mix_QuitMP3()
{
if ( smpeg.loaded == 0 ) {
return;
}
if ( smpeg.loaded == 1 ) {
}
--smpeg.loaded;
}
#endif /* MP3_DYNAMIC */

#endif /* MP3_MUSIC */
49 changes: 49 additions & 0 deletions dynamic_mp3.h
@@ -0,0 +1,49 @@
/*
SDL_mixer: An audio mixer library based on the SDL library
Copyright (C) 1997-2004 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
slouken@libsdl.org
*/

#ifdef MP3_MUSIC
#include "smpeg.h"

typedef struct {
int loaded;
void *handle;
void (*SMPEG_actualSpec)( SMPEG *mpeg, SDL_AudioSpec *spec );
void (*SMPEG_delete)( SMPEG* mpeg );
void (*SMPEG_enableaudio)( SMPEG* mpeg, int enable );
void (*SMPEG_enablevideo)( SMPEG* mpeg, int enable );
SMPEG* (*SMPEG_new)(const char *file, SMPEG_Info* info, int sdl_audio);
SMPEG* (*SMPEG_new_rwops)(SDL_RWops *src, SMPEG_Info* info, int sdl_audio);
void (*SMPEG_play)( SMPEG* mpeg );
int (*SMPEG_playAudio)( SMPEG *mpeg, Uint8 *stream, int len );
void (*SMPEG_rewind)( SMPEG* mpeg );
void (*SMPEG_setvolume)( SMPEG* mpeg, int volume );
void (*SMPEG_skip)( SMPEG* mpeg, float seconds );
SMPEGstatus (*SMPEG_status)( SMPEG* mpeg );
void (*SMPEG_stop)( SMPEG* mpeg );
} smpeg_loader;

extern smpeg_loader smpeg;

extern int Mix_InitMP3();
extern void Mix_QuitMP3();

#endif
2 changes: 2 additions & 0 deletions dynamic_ogg.c
Expand Up @@ -115,6 +115,8 @@ int Mix_InitOgg()
vorbis.ov_time_seek = ov_time_seek;
}
++vorbis.loaded;

return 0;
}
void Mix_QuitOgg()
{
Expand Down
61 changes: 35 additions & 26 deletions music.c
Expand Up @@ -84,7 +84,7 @@
#include "music_ogg.h"
#endif
#ifdef MP3_MUSIC
#include "smpeg.h"
#include "dynamic_mp3.h"

static SDL_AudioSpec used_mixer;
#endif
Expand Down Expand Up @@ -338,7 +338,7 @@ void music_mixer(void *udata, Uint8 *stream, int len)
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
SMPEG_playAudio(music_playing->data.mp3, stream, len);
smpeg.SMPEG_playAudio(music_playing->data.mp3, stream, len);
break;
#endif
default:
Expand Down Expand Up @@ -593,14 +593,18 @@ Mix_Music *Mix_LoadMUS(const char *file)
(ext && MIX_string_equals(ext, "MP3")) ||
(ext && MIX_string_equals(ext, "MPEG")) ||
(magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0) ) {
SMPEG_Info info;
music->type = MUS_MP3;
music->data.mp3 = SMPEG_new(file, &info, 0);
if ( !info.has_audio ) {
Mix_SetError("MPEG file does not have any audio stream.");
music->error = 1;
if ( Mix_InitMP3() == 0 ) {
SMPEG_Info info;
music->type = MUS_MP3;
music->data.mp3 = smpeg.SMPEG_new(file, &info, 0);
if ( !info.has_audio ) {
Mix_SetError("MPEG file does not have any audio stream.");
music->error = 1;
} else {
smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
}
} else {
SMPEG_actualSpec(music->data.mp3, &used_mixer);
music->error = 1;
}
} else
#endif
Expand Down Expand Up @@ -690,7 +694,8 @@ void Mix_FreeMusic(Mix_Music *music)
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
SMPEG_delete(music->data.mp3);
smpeg.SMPEG_delete(music->data.mp3);
Mix_QuitMP3();
break;
#endif
default:
Expand Down Expand Up @@ -777,9 +782,9 @@ static int music_internal_play(Mix_Music *music, double position)
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
SMPEG_enableaudio(music->data.mp3,1);
SMPEG_enablevideo(music->data.mp3,0);
SMPEG_play(music_playing->data.mp3);
smpeg.SMPEG_enableaudio(music->data.mp3,1);
smpeg.SMPEG_enablevideo(music->data.mp3,0);
smpeg.SMPEG_play(music_playing->data.mp3);
break;
#endif
default:
Expand Down Expand Up @@ -868,10 +873,10 @@ int music_internal_position(double position)
#ifdef MP3_MUSIC
case MUS_MP3:
if ( position > 0.0 ) {
SMPEG_skip(music_playing->data.mp3, (float)position);
smpeg.SMPEG_skip(music_playing->data.mp3, (float)position);
} else {
SMPEG_rewind(music_playing->data.mp3);
SMPEG_play(music_playing->data.mp3);
smpeg.SMPEG_rewind(music_playing->data.mp3);
smpeg.SMPEG_play(music_playing->data.mp3);
}
break;
#endif
Expand Down Expand Up @@ -951,7 +956,7 @@ static void music_internal_volume(int volume)
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
SMPEG_setvolume(music_playing->data.mp3,(int)(((float)volume/(float)MIX_MAX_VOLUME)*100.0));
smpeg.SMPEG_setvolume(music_playing->data.mp3,(int)(((float)volume/(float)MIX_MAX_VOLUME)*100.0));
break;
#endif
default:
Expand Down Expand Up @@ -1019,7 +1024,7 @@ static void music_internal_halt(void)
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
SMPEG_stop(music_playing->data.mp3);
smpeg.SMPEG_stop(music_playing->data.mp3);
break;
#endif
default:
Expand Down Expand Up @@ -1161,7 +1166,7 @@ static int music_internal_playing()
#endif
#ifdef MP3_MUSIC
case MUS_MP3:
if ( SMPEG_status(music_playing->data.mp3) != SMPEG_PLAYING )
if ( smpeg.SMPEG_status(music_playing->data.mp3) != SMPEG_PLAYING )
playing = 0;
break;
#endif
Expand Down Expand Up @@ -1388,14 +1393,18 @@ Mix_Music *Mix_LoadMUS_RW(SDL_RWops *rw) {
#endif
#ifdef MP3_MUSIC
if ( magic[0] == 0xFF && (magic[1] & 0xF0) == 0xF0 ) {
SMPEG_Info info;
music->type = MUS_MP3;
music->data.mp3 = SMPEG_new_rwops(rw, &info, 0);
if ( !info.has_audio ) {
Mix_SetError("MPEG file does not have any audio stream.");
music->error = 1;
if ( Mix_InitMP3() == 0 ) {
SMPEG_Info info;
music->type = MUS_MP3;
music->data.mp3 = smpeg.SMPEG_new_rwops(rw, &info, 0);
if ( !info.has_audio ) {
Mix_SetError("MPEG file does not have any audio stream.");
music->error = 1;
} else {
smpeg.SMPEG_actualSpec(music->data.mp3, &used_mixer);
}
} else {
SMPEG_actualSpec(music->data.mp3, &used_mixer);
music->error = 1;
}
} else
#endif
Expand Down

0 comments on commit 23ce1b1

Please sign in to comment.