/* 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); }
/* Set the music volume */ static void music_internal_volume(int volume) { switch (music_playing->type) { #ifdef CMD_MUSIC case MUS_CMD: MusicCMD_SetVolume(volume); break; #endif #ifdef WAV_MUSIC case MUS_WAV: WAVStream_SetVolume(volume); break; #endif #ifdef MODPLUG_MUSIC case MUS_MODPLUG: modplug_setvolume(music_playing->data.modplug, volume); break; #endif #ifdef MOD_MUSIC case MUS_MOD: MOD_setvolume(music_playing->data.module, volume); break; #endif #ifdef MID_MUSIC case MUS_MID: #ifdef USE_NATIVE_MIDI if ( native_midi_ok ) { native_midi_setvolume(volume); return; } #endif #ifdef USE_FLUIDSYNTH_MIDI if ( fluidsynth_ok ) { fluidsynth_setvolume(music_playing->data.fluidsynthmidi, volume); return; } #endif #ifdef USE_TIMIDITY_MIDI if ( timidity_ok ) { Timidity_SetVolume(volume); return; } #endif break; #endif #ifdef OGG_MUSIC case MUS_OGG: OGG_setvolume(music_playing->data.ogg, volume); break; #endif #ifdef FLAC_MUSIC case MUS_FLAC: FLAC_setvolume(music_playing->data.flac, volume); break; #endif #ifdef MP3_MUSIC case MUS_MP3: smpeg.SMPEG_setvolume(music_playing->data.mp3,(int)(((float)volume/(float)MIX_MAX_VOLUME)*100.0)); break; #endif #ifdef MP3_MAD_MUSIC case MUS_MP3_MAD: mad_setVolume(music_playing->data.mp3_mad, volume); break; #endif default: /* Unknown music type?? */ break; } }