/* Load an OGG stream from the given file */ OGG_music *OGG_new(const char *file) { OGG_music *music; FILE *fp; 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; fp = fopen(file, "rb"); if ( fp == NULL ) { SDL_SetError("Couldn't open %s", file); free(music); return(NULL); } if ( ov_open(fp, &music->vf, NULL, 0) < 0 ) { SDL_SetError("Not an Ogg Vorbis audio stream"); free(music); fclose(fp); return(NULL); } } else { SDL_SetError("Out of memory"); } return(music); }
/* 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); }
/* Load an OGG stream from an SDL_RWops object */ OGG_music *OGG_new_RW(SDL_RWops *rw, int freerw) { OGG_music *music; ov_callbacks callbacks; if ( !Mix_Init(MIX_INIT_OGG) ) { if ( freerw ) { SDL_RWclose(rw); } return(NULL); } SDL_memset(&callbacks, 0, sizeof(callbacks)); callbacks.read_func = sdl_read_func; callbacks.seek_func = sdl_seek_func; callbacks.tell_func = sdl_tell_func; music = (OGG_music *)SDL_malloc(sizeof *music); if ( music ) { /* Initialize the music structure */ memset(music, 0, (sizeof *music)); music->rw = rw; music->freerw = freerw; OGG_stop(music); OGG_setvolume(music, MIX_MAX_VOLUME); music->section = -1; if ( vorbis.ov_open_callbacks(rw, &music->vf, NULL, 0, callbacks) < 0 ) { SDL_free(music); if ( freerw ) { SDL_RWclose(rw); } SDL_SetError("Not an Ogg Vorbis audio stream"); return(NULL); } } else { if ( freerw ) { SDL_RWclose(rw); } SDL_OutOfMemory(); return(NULL); } return(music); }
/* Load an OGG stream from an SDL_RWops object */ OGG_music *OGG_new_RW(SDL_RWops *src, int freesrc) { OGG_music *music; ov_callbacks callbacks; if(!Mix_Init(MIX_INIT_OGG)) return(NULL); SDL_memset(&callbacks, 0, sizeof(callbacks)); callbacks.read_func = sdl_read_func; callbacks.seek_func = sdl_seek_func; callbacks.tell_func = sdl_tell_func; music = (OGG_music *)SDL_malloc(sizeof * music); if(music) { vorbis_info *vi; vorbis_comment *ptr; int isLength = 0; int i; ogg_int64_t total; /* Initialize the music structure */ SDL_memset(music, 0, (sizeof * music)); music->src = src; music->freesrc = freesrc; OGG_stop(music); OGG_setvolume(music, MIX_MAX_VOLUME); music->section = -1; music->channels = 0; music->mus_title = NULL; music->mus_artist = NULL; music->mus_album = NULL; music->mus_copyright = NULL; MyResample_zero(&music->resample); music->loop = -1; music->loop_start = -1; music->loop_end = 0; music->loop_len = 0; if(vorbis.ov_open_callbacks(src, &music->vf, NULL, 0, callbacks) < 0) { SDL_SetError("Not an Ogg Vorbis audio stream"); SDL_free(music); return(NULL); } vi = vorbis.ov_info(&music->vf, -1); music->channels = vi->channels; /* Parse comments and extract title and loop points */ ptr = ov_comment(&music->vf, -1); for(i = 0; i < ptr->comments; i++) { int paramLen = ptr->comment_lengths[i] + 1; char *param = (char *)SDL_malloc(paramLen); char *argument = param; char *value = param; memset(param, 0, paramLen); memcpy(param, ptr->user_comments[i], ptr->comment_lengths[i]); value = strchr(param, '='); if(value == NULL) { value = param + paramLen - 1; /* set null */ } else { *(value++) = '\0'; } #ifdef __USE_ISOC99 #define A_TO_OGG64(x) (ogg_int64_t)atoll(x) #else #define A_TO_OGG64(x) (ogg_int64_t)atol(x) #endif if(strcasecmp(argument, "LOOPSTART") == 0) music->loop_start = A_TO_OGG64(value); else if(strcasecmp(argument, "LOOPLENGTH") == 0) { music->loop_len = A_TO_OGG64(value); isLength = 1; } else if(strcasecmp(argument, "LOOPEND") == 0) { isLength = 0; music->loop_end = A_TO_OGG64(value); } else if(strcasecmp(argument, "TITLE") == 0) { music->mus_title = (char *)SDL_malloc(sizeof(char) * strlen(value) + 1); strcpy(music->mus_title, value); } else if(strcasecmp(argument, "ARTIST") == 0) { music->mus_artist = (char *)SDL_malloc(sizeof(char) * strlen(value) + 1); strcpy(music->mus_artist, value); } else if(strcasecmp(argument, "ALBUM") == 0) { music->mus_album = (char *)SDL_malloc(sizeof(char) * strlen(value) + 1); strcpy(music->mus_album, value); } else if(strcasecmp(argument, "COPYRIGHT") == 0) { music->mus_copyright = (char *)SDL_malloc(sizeof(char) * strlen(value) + 1); strcpy(music->mus_copyright, value); } SDL_free(param); } #undef A_TO_OGG64 if(isLength == 1) music->loop_end = music->loop_start + music->loop_len; else music->loop_len = music->loop_end - music->loop_start; total = ov_pcm_total(&music->vf, -1); if(((music->loop_start >= 0) || (music->loop_end > 0)) && ((music->loop_start < music->loop_end) || (music->loop_end == 0)) && (music->loop_start < total) && (music->loop_end <= total)) { if(music->loop_start < 0) music->loop_start = 0; if(music->loop_end == 0) music->loop_end = total; music->loop = 1; music->loop_len_ch = music->channels; } } else { SDL_OutOfMemory(); return(NULL); } return (music); }
/* Halt playing of music */ static void music_internal_halt(void) { switch (music_playing->type) { #ifdef CMD_MUSIC case MUS_CMD: MusicCMD_Stop(music_playing->data.cmd); break; #endif #ifdef WAV_MUSIC case MUS_WAV: WAVStream_Stop(); break; #endif #ifdef MODPLUG_MUSIC case MUS_MODPLUG: modplug_stop(music_playing->data.modplug); break; #endif #ifdef MOD_MUSIC case MUS_MOD: MOD_stop(music_playing->data.module); break; #endif #ifdef MID_MUSIC case MUS_MID: #ifdef USE_NATIVE_MIDI if ( native_midi_ok ) { native_midi_stop(); goto skip; } #endif #ifdef USE_FLUIDSYNTH_MIDI if ( fluidsynth_ok ) { fluidsynth_stop(music_playing->data.fluidsynthmidi); goto skip; } #endif #ifdef USE_TIMIDITY_MIDI if ( timidity_ok ) { Timidity_Stop(); goto skip; } #endif break; #endif #ifdef OGG_MUSIC case MUS_OGG: OGG_stop(music_playing->data.ogg); break; #endif #ifdef FLAC_MUSIC case MUS_FLAC: FLAC_stop(music_playing->data.flac); break; #endif #ifdef MP3_MUSIC case MUS_MP3: smpeg.SMPEG_stop(music_playing->data.mp3); break; #endif #ifdef MP3_MAD_MUSIC case MUS_MP3_MAD: mad_stop(music_playing->data.mp3_mad); break; #endif default: /* Unknown music type?? */ return; } skip: music_playing->fading = MIX_NO_FADING; music_playing = NULL; }