SDL_mixer, loading of OGG music from RWops

Hi

This small patch makes SDL_mixer able to load OGG music from RWops
objects. Enjoy. :slight_smile:

// Martin
-------------- next part --------------
— sdl-mixer1.2-orig/music.c 2004-08-13 14:42:57.000000000 +0300
+++ sdl-mixer1.2-1.2.5/music.c 2004-08-13 14:28:27.000000000 +0300
@@ -1132,19 +1132,21 @@
#ifdef USE_RWOPS

Mix_Music *Mix_LoadMUS_RW(SDL_RWops *rw) {

  • /Uint8 magic[5]; Apparently there is no way to check if the file is really a MOD,/
  •  /*		    or there are too many formats supported by MikMod or MikMod does */
    
  •  /*		    this check by itself. If someone implements other formats (e.g. MP3) */
    
  •  /*		    the check can be uncommented */
    
  • Uint8 magic[5]; /Apparently there is no way to check if the file is really a MOD,/
  • /* or there are too many formats supported by MikMod or MikMod does */
  • /* this check by itself. If someone implements other formats (e.g. MP3) */
  • /* the check can be uncommented */
    Mix_Music *music;
  • int start;
  •  /* Just skip the check */
    
    /* Figure out what kind of file this is */
  • /*if (SDL_RWread(rw,magic,1,4)!=4) {
  • start = SDL_RWtell(rw);
  • if (SDL_RWread(rw,magic,1,4)!=4) {
    Mix_SetError(“Couldn’t read from RWops”);
    return NULL;
    }
  • magic[4]=’\0’;*/
  • SDL_RWseek(rw, start, SEEK_SET);

  • magic[4]=’\0’;

    /* Allocate memory for the music structure */
    music=(Mix_Music *)malloc(sizeof(Mix_Music));
    @@ -1154,6 +1156,16 @@
    }
    music->error = 0;

+#ifdef OGG_MUSIC

  • /* Ogg Vorbis files have the magic four bytes “OggS” */
  • if ( strcmp((char *)magic, “OggS”) == 0 ) {
  •   music->type = MUS_OGG;
    
  •   music->data.ogg = OGG_new_RW(rw);
    
  •   if ( music->data.ogg == NULL ) {
    
  •   	music->error = 1;
    
  •   }
    
  • } else
    +#endif
    #ifdef MOD_MUSIC
    if (1) {
    music->type=MUS_MOD;
    — sdl-mixer1.2-orig/music_ogg.c 2004-08-13 14:42:57.000000000 +0300
    +++ sdl-mixer1.2-1.2.5/music_ogg.c 2004-08-18 12:53:35.000000000 +0300
    @@ -83,6 +83,58 @@
    return(music);
    }+
    +static size_t sdl_read_func(void *ptr, size_t size, size_t nmemb, void *datasource)
    +{
  • return SDL_RWread((SDL_RWops*)datasource, ptr, size, nmemb);
    +}

+static int sdl_seek_func(void *datasource, ogg_int64_t offset, int whence)
+{

  • return SDL_RWseek((SDL_RWops*)datasource, (int)offset, whence);
    +}

+static int sdl_close_func(void *datasource)
+{

  • return SDL_RWclose((SDL_RWops*)datasource);
    +}

+static long sdl_tell_func(void *datasource)
+{

  • return SDL_RWtell((SDL_RWops*)datasource);
    +}

+/* Load an OGG stream from an SDL_RWops object */
+OGG_music *OGG_new_RW(SDL_RWops *rw)
+{

  • OGG_music *music;
  • ov_callbacks callbacks;
  • callbacks.read_func = sdl_read_func;
  • callbacks.seek_func = sdl_seek_func;
  • callbacks.close_func = sdl_close_func;
  • callbacks.tell_func = sdl_tell_func;
  • music = (OGG_music *)malloc(sizeof *music);
  • if ( music ) {
  •   /* Initialize the music structure */
    
  •   memset(music, 0, (sizeof *music));
    
  •   OGG_stop(music);
    
  •   OGG_setvolume(music, MIX_MAX_VOLUME);
    
  •   music->section = -1;
    
  •   if ( ov_open_callbacks(rw, &music->vf, NULL, 0, callbacks) < 0 ) {
    
  •   	SDL_SetError("Not an Ogg Vorbis audio stream");
    
  •   	free(music);
    
  •   	SDL_RWclose(rw);
    
  •   	return(NULL);
    
  •   }
    
  • } else {
  •   SDL_SetError("Out of memory");
    
  • }
  • return(music);
    +}

/* Start playback of a given OGG stream */
void OGG_play(OGG_music music)
{
— sdl-mixer1.2-orig/music_ogg.h 2004-08-13 14:42:57.000000000 +0300
+++ sdl-mixer1.2-1.2.5/music_ogg.h 2004-08-13 14:05:33.000000000 +0300
@@ -49,6 +49,9 @@
/
Load an OGG stream from the given file */
extern OGG_music *OGG_new(const char *file);

+/* Load an OGG stream from an SDL_RWops object */
+extern OGG_music *OGG_new_RW(SDL_RWops rw);
+
/
Start playback of a given OGG stream */
extern void OGG_play(OGG_music *music);

Hi

This small patch makes SDL_mixer able to load OGG music from RWops
objects. Enjoy. :slight_smile:

Thanks! This patch is in CVS.

See ya,
-Sam Lantinga, Software Engineer, Blizzard Entertainment