int Mix_EachSoundFont(int (*function)(const char*, void*), void *data) { char *context, *path, *paths; const char* cpaths = Mix_GetSoundFonts(); if (!cpaths) { Mix_SetError("No SoundFonts have been requested"); return 0; } if (!(paths = SDL_strdup(cpaths))) { Mix_SetError("Insufficient memory to iterate over SoundFonts"); return 0; } #if defined(__MINGW32__) || defined(__MINGW64__) for (path = strtok(paths, ";"); path; path = strtok(NULL, ";")) { #elif defined(_WIN32) for (path = strtok_s(paths, ";", &context); path; path = strtok_s(NULL, ";", &context)) { #else for (path = strtok_r(paths, ":;", &context); path; path = strtok_r(NULL, ":;", &context)) { #endif if (!function(path, data)) { SDL_free(paths); return 0; } } SDL_free(paths); return 1; }
int Mix_SetLoopStart(int which, int loop_start) { int old_loop_start; int position; if ((which >= 0) && (which < num_channels)) { Mix_SetError("Invalid channel specified"); return(-1); } if ((mix_channel[which].playing == 0) && (mix_channel[which].looping == 0)) { Mix_SetError("Channel not playing"); return(-1); } SDL_LockAudio(); old_loop_start = mix_channel[which].loop_start; if (loop_start >= 0) { position = milliseconds_to_bytes(loop_start); if (((Uint32) position) < mix_channel[which].sound->chunk->alen) { mix_channel[which].loop_start = position; } else { Mix_SetError("Position out of range!"); } } SDL_UnlockAudio(); return bytes_to_milliseconds(old_loop_start); }
/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */ static int _Mix_remove_effect(int channel, effect_info **e, Mix_EffectFunc_t f) { effect_info *cur; effect_info *prev = NULL; effect_info *next = NULL; if (!e) { Mix_SetError("Internal error"); return(0); } for (cur = *e; cur != NULL; cur = cur->next) { if (cur->callback == f) { next = cur->next; if (cur->done_callback != NULL) { cur->done_callback(channel, cur->udata); } SDL_free(cur); if (prev == NULL) { /* removing first item of list? */ *e = next; } else { prev->next = next; } return(1); } prev = cur; } Mix_SetError("No such effect registered"); return(0); }
static int fluidsynth_loadsong_RW_internal(FluidSynthMidiSong *song, void *data) { off_t offset; size_t size; char *buffer; SDL_RWops *rw = (SDL_RWops*) data; offset = SDL_RWtell(rw); SDL_RWseek(rw, 0, RW_SEEK_END); size = SDL_RWtell(rw) - offset; SDL_RWseek(rw, offset, RW_SEEK_SET); if ((buffer = (char*) SDL_malloc(size))) { if(SDL_RWread(rw, buffer, size, 1) == 1) { if (fluidsynth.fluid_player_add_mem(song->player, buffer, size) == FLUID_OK) { return 1; } else { Mix_SetError("FluidSynth failed to load in-memory song"); } } else { Mix_SetError("Failed to read in-memory song"); } SDL_free(buffer); } else { Mix_SetError("Insufficient memory for song"); } return 0; }
int Mix_SetPlayPosition(int which, int position) { int old_position; int new_position; if ((which >= 0) && (which < num_channels)) { Mix_SetError("Invalid channel specified"); return(-1); } if ((mix_channel[which].playing == 0) && (mix_channel[which].looping == 0)) { Mix_SetError("Channel not playing"); return(-1); } SDL_LockAudio(); old_position = mix_channel[which].sound->chunk->alen - mix_channel[which].playing; if (position >= 0) { new_position = milliseconds_to_bytes(position); if (((Uint32) new_position) < mix_channel[which].sound->chunk->alen) { mix_channel[which].playing = (mix_channel[which].sound->chunk->alen - new_position); } else { Mix_SetError("Position out of range!"); } } SDL_UnlockAudio(); return bytes_to_milliseconds(old_position); }
int Mix_Init(int flags) { int result = 0; if (flags & MIX_INIT_FLUIDSYNTH) { #ifdef USE_FLUIDSYNTH_MIDI if ((initialized & MIX_INIT_FLUIDSYNTH) || Mix_InitFluidSynth() == 0) { result |= MIX_INIT_FLUIDSYNTH; } #else Mix_SetError("Mixer not built with FluidSynth support"); #endif } if (flags & MIX_INIT_FLAC) { #ifdef FLAC_MUSIC if ((initialized & MIX_INIT_FLAC) || Mix_InitFLAC() == 0) { result |= MIX_INIT_FLAC; } #else Mix_SetError("Mixer not built with FLAC support"); #endif } if (flags & MIX_INIT_MOD) { #ifdef MOD_MUSIC if ((initialized & MIX_INIT_MOD) || Mix_InitMOD() == 0) { result |= MIX_INIT_MOD; } #else Mix_SetError("Mixer not built with MOD support"); #endif } if (flags & MIX_INIT_MP3) { #ifdef MP3_MUSIC if ((initialized & MIX_INIT_MP3) || Mix_InitMP3() == 0) { result |= MIX_INIT_MP3; } #else Mix_SetError("Mixer not built with MP3 support"); #endif } if (flags & MIX_INIT_OGG) { #ifdef OGG_MUSIC if ((initialized & MIX_INIT_OGG) || Mix_InitOgg() == 0) { result |= MIX_INIT_OGG; } #else Mix_SetError("Mixer not built with Ogg Vorbis support"); #endif } initialized |= result; return (result); }
SDL_bool _Mix_ValidateChunk(Mix_Chunk *chunk) { /* Don't play null pointers :-) */ if ( chunk == NULL ) { Mix_SetError("Tried to play a NULL chunk"); return(SDL_FALSE); } if ( !checkchunkintegral(chunk)) { Mix_SetError("Tried to play a chunk with a bad frame"); return(SDL_FALSE); } return(SDL_TRUE); }
/* Play an audio chunk on a specific channel. If the specified channel is -1, play on the first free channel. 'ticks' is the number of milliseconds at most to play the sample, or -1 if there is no limit. Returns which channel was used to play the sound. */ int Mix_PlayChannelTimed(int which, Mix_Chunk *chunk, int loops, int ticks) { int i; /* Don't play null pointers :-) */ if ( chunk == NULL ) { Mix_SetError("Tried to play a NULL chunk"); return(-1); } if ( !checkchunkintegral(chunk)) { Mix_SetError("Tried to play a chunk with a bad frame"); return(-1); } /* Lock the mixer while modifying the playing channels */ SDL_LockAudio(); { /* If which is -1, play on the first free channel */ if ( which == -1 ) { for ( i=reserved_channels; i<num_channels; ++i ) { if ( mix_channel[i].playing <= 0 ) break; } if ( i == num_channels ) { Mix_SetError("No free channels available"); which = -1; } else { which = i; } } /* Queue up the audio data for this channel */ if ( which >= 0 && which < num_channels ) { Uint32 sdl_ticks = SDL_GetTicks(); if (Mix_Playing(which)) _Mix_channel_done_playing(which); mix_channel[which].samples = chunk->abuf; mix_channel[which].playing = chunk->alen; mix_channel[which].looping = loops; mix_channel[which].chunk = chunk; mix_channel[which].paused = 0; mix_channel[which].fading = MIX_NO_FADING; mix_channel[which].start_time = sdl_ticks; mix_channel[which].expire = (ticks>0) ? (sdl_ticks + ticks) : 0; } } SDL_UnlockAudio(); /* Return the channel on which the sound is being played */ return(which); }
int Mix_InitModPlug() { if ( modplug.loaded == 0 ) { #ifdef __MACOSX__ extern ModPlugFile* ModPlug_Load(const void* data, int size) __attribute__((weak_import)); if ( ModPlug_Load == NULL ) { /* Missing weakly linked framework */ Mix_SetError("Missing modplug.framework"); return -1; } #endif // __MACOSX__ modplug.ModPlug_Load = ModPlug_Load; modplug.ModPlug_Unload = ModPlug_Unload; modplug.ModPlug_Read = ModPlug_Read; modplug.ModPlug_Seek = ModPlug_Seek; modplug.ModPlug_GetSettings = ModPlug_GetSettings; modplug.ModPlug_SetSettings = ModPlug_SetSettings; modplug.ModPlug_SetMasterVolume = ModPlug_SetMasterVolume; } ++modplug.loaded; return 0; }
int Mix_InitFLAC() { if ( flac.loaded == 0 ) { #ifdef __MACOSX__ extern FLAC__StreamDecoder *FLAC__stream_decoder_new(void) __attribute__((weak_import)); if ( FLAC__stream_decoder_new == NULL ) { /* Missing weakly linked framework */ Mix_SetError("Missing FLAC.framework"); return -1; } #endif /* __MACOSX__ */ flac.FLAC__stream_decoder_new = FLAC__stream_decoder_new; flac.FLAC__stream_decoder_delete = FLAC__stream_decoder_delete; flac.FLAC__stream_decoder_init_stream = FLAC__stream_decoder_init_stream; flac.FLAC__stream_decoder_finish = FLAC__stream_decoder_finish; flac.FLAC__stream_decoder_flush = FLAC__stream_decoder_flush; flac.FLAC__stream_decoder_process_single = FLAC__stream_decoder_process_single; flac.FLAC__stream_decoder_process_until_end_of_metadata = FLAC__stream_decoder_process_until_end_of_metadata; flac.FLAC__stream_decoder_process_until_end_of_stream = FLAC__stream_decoder_process_until_end_of_stream; flac.FLAC__stream_decoder_seek_absolute = FLAC__stream_decoder_seek_absolute; flac.FLAC__stream_decoder_get_state = FLAC__stream_decoder_get_state; } ++flac.loaded; return 0; }
int Mix_InitMP3() { if ( smpeg.loaded == 0 ) { #ifdef __MACOSX__ extern SMPEG* SMPEG_new_rwops(SDL_RWops*, SMPEG_Info*, int, int) __attribute__((weak_import)); if ( SMPEG_new_rwops == NULL ) { /* Missing weakly linked framework */ Mix_SetError("Missing smpeg2.framework"); return -1; } #endif /* __MACOSX__ */ smpeg.SMPEG_actualSpec = SMPEG_actualSpec; smpeg.SMPEG_delete = SMPEG_delete; smpeg.SMPEG_enableaudio = SMPEG_enableaudio; smpeg.SMPEG_enablevideo = SMPEG_enablevideo; 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; }
/* Play some of a stream previously started with GME_play() */ int GME_playAudio(struct MUSIC_GME *music, Uint8 *stream, int len) { if(music==NULL) return 1; if(music->game_emu==NULL) return 1; if(music->playing==-1) return 1; if( len<0 ) return 0; int srgArraySize = len/music->cvt.len_ratio; short buf[srgArraySize]; int srcLen = (int)((double)(len/2)/music->cvt.len_ratio); char *err = (char*)gme_play( music->game_emu, srcLen, buf ); if( err != NULL) { Mix_SetError("GAME-EMU: %s", err); return 0; } int dest_len = srcLen*2; if( music->cvt.needed ) { music->cvt.len = dest_len; music->cvt.buf = (Uint8*)buf; SDL_ConvertAudio(&music->cvt); dest_len = music->cvt.len_cvt; } if ( music->volume == MIX_MAX_VOLUME ) { SDL_memcpy(stream, (Uint8*)buf, dest_len); } else { SDL_MixAudioFormat(stream, (Uint8*)buf, mixer.format, dest_len, music->volume); } return len-dest_len; }
/* Start playback of a given music stream */ void MusicCMD_Start(MusicCMD *music) { music->pid = fork(); switch(music->pid) { /* Failed fork() system call */ case -1: Mix_SetError("fork() failed"); return; /* Child process - executes here */ case 0: { char command[PATH_MAX]; char **argv; /* Execute the command */ strcpy(command, music->cmd); argv = parse_args(command, music->file); if ( argv != NULL ) { execvp(argv[0], argv); } /* exec() failed */ perror(argv[0]); _exit(-1); } break; /* Parent process - executes here */ default: break; } return; }
int Mix_SetMusicPosition(double position) { int retval; SDL_LockAudio(); if ( music_playing ) { retval = music_internal_position(position); if ( retval < 0 ) { Mix_SetError("Position not implemented for music type"); } } else { Mix_SetError("Music isn't playing"); retval = -1; } SDL_UnlockAudio(); return(retval); }
/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */ static int _Mix_register_effect(effect_info **e, Mix_EffectFunc_t f, Mix_EffectDone_t d, void *arg) { effect_info *new_e; if (!e) { Mix_SetError("Internal error"); return(0); } if (f == NULL) { Mix_SetError("NULL effect callback"); return(0); } new_e = SDL_malloc(sizeof (effect_info)); if (new_e == NULL) { Mix_SetError("Out of memory"); return(0); } new_e->callback = f; new_e->done_callback = d; new_e->udata = arg; new_e->next = NULL; /* add new effect to end of linked list... */ if (*e == NULL) { *e = new_e; } else { effect_info *cur = *e; while (1) { if (cur->next == NULL) { cur->next = new_e; break; } cur = cur->next; } } return(1); }
static FluidSynthMidiSong *fluidsynth_loadsong_common(int (*function)(FluidSynthMidiSong*, void*), void *data) { FluidSynthMidiSong *song; fluid_settings_t *settings = NULL; if (!Mix_Init(MIX_INIT_FLUIDSYNTH)) { return NULL; } if ((song = SDL_malloc(sizeof(FluidSynthMidiSong)))) { SDL_memset(song, 0, sizeof(FluidSynthMidiSong)); if (SDL_BuildAudioCVT(&song->convert, AUDIO_S16, 2, freq, format, channels, freq) >= 0) { if ((settings = fluidsynth.new_fluid_settings())) { fluidsynth.fluid_settings_setnum(settings, "synth.sample-rate", (double) freq); if ((song->synth = fluidsynth.new_fluid_synth(settings))) { if (Mix_EachSoundFont(fluidsynth_load_soundfont, (void*) song->synth)) { if ((song->player = fluidsynth.new_fluid_player(song->synth))) { if (function(song, data)) return song; fluidsynth.delete_fluid_player(song->player); } else { Mix_SetError("Failed to create FluidSynth player"); } } fluidsynth.delete_fluid_synth(song->synth); } else { Mix_SetError("Failed to create FluidSynth synthesizer"); } fluidsynth.delete_fluid_settings(settings); } else { Mix_SetError("Failed to create FluidSynth settings"); } } else { Mix_SetError("Failed to set up audio conversion"); } SDL_free(song); } else { Mix_SetError("Insufficient memory for song"); } return NULL; }
int fluidsynth_loadsong_internal(FluidSynthMidiSong *song, void *data) { const char* path = (const char*) data; if (fluidsynth.fluid_player_add(song->player, path) == FLUID_OK) { return 1; } else { Mix_SetError("FluidSynth failed to load %s", path); return 0; } }
int _Mix_SetupChunk(int which, Mix_Chunk* chunk, int loops, int ticks, int fade_in, int loop_start) { int loop_start_bytes; /* Lock the mixer while modifying the playing channels */ SDL_LockAudio(); { /* If which is -1, play on the first free channel */ if ( which == -1 ) { which = get_available_channel(); if ( which == -1 ) { Mix_SetError("No free channels available"); which = -1; } } loop_start_bytes = milliseconds_to_bytes(loop_start); if (((Uint32) loop_start_bytes) >= chunk->alen) { loop_start_bytes = 0; } /* Queue up the audio data for this channel */ if ( which >= 0 && which < num_channels ) { Uint32 sdl_ticks = SDL_GetTicks(); if (Mix_Playing(which)) _Mix_channel_done_playing(which); if (mix_channel[which].is_music) { mix_channel[which].music = NULL; mix_channel[which].sound = (Mix_Sound *) malloc(sizeof(Mix_Sound)); mix_channel[which].is_music = SDL_FALSE; } mix_channel[which].sound->samples = chunk->abuf + loop_start_bytes; mix_channel[which].playing = chunk->alen - loop_start_bytes; mix_channel[which].looping = loops; mix_channel[which].loop_start = loop_start_bytes; mix_channel[which].sound->chunk = chunk; mix_channel[which].paused = 0; mix_channel[which].expire = (ticks>0) ? (sdl_ticks + ticks) : 0; if (fade_in){ mix_channel[which].fading = MIX_FADING_IN; mix_channel[which].sound->fade_volume = mix_channel[which].volume; mix_channel[which].fade_volume_reset = mix_channel[which].volume; mix_channel[which].volume = 0; mix_channel[which].sound->fade_length = (Uint32)fade_in; mix_channel[which].sound->start_time = mix_channel[which].sound->ticks_fade = sdl_ticks; } else { mix_channel[which].fading = MIX_NO_FADING; mix_channel[which].sound->start_time = sdl_ticks; } } } SDL_UnlockAudio(); return(which); }
int fluidsynth_check_soundfont(const char *path, void *data) { FILE *file = fopen(path, "r"); if (file) { fclose(file); return 1; } else { Mix_SetError("Failed to access the SoundFont %s", path); return 0; } }
int Mix_SetLoops(int which, int loops) { int old_loops; if ((which >= 0) && (which < num_channels)) { Mix_SetError("Invalid channel specified"); return(-1); } if ((mix_channel[which].playing == 0) && (mix_channel[which].looping == 0)) { Mix_SetError("Channel not playing"); return(-1); } SDL_LockAudio(); old_loops = mix_channel[which].looping; mix_channel[which].looping = loops; SDL_UnlockAudio(); return old_loops; }
int fluidsynth_playsome(FluidSynthMidiSong *song, void *dest, int dest_len) { int result = -1; int frames = dest_len / channels / ((format & 0xFF) / 8); int src_len = frames * 4; /* 16-bit stereo */ void *src = dest; if (dest_len < src_len) { if (!(src = malloc(src_len))) { Mix_SetError("Insufficient memory for audio conversion"); return result; } } if (fluidsynth.fluid_synth_write_s16(song->synth, frames, src, 0, 2, src, 1, 2) != FLUID_OK) { Mix_SetError("Error generating FluidSynth audio"); goto finish; } song->convert.buf = src; song->convert.len = src_len; if (SDL_ConvertAudio(&song->convert) < 0) { Mix_SetError("Error during audio conversion"); goto finish; } if (src != dest) memcpy(dest, src, dest_len); result = 0; finish: if (src != dest) free(src); return result; }
/* Load a Game Music Emulators stream from an SDL_RWops object */ struct MUSIC_GME *GME_new_RW(struct SDL_RWops *src, int freesrc, int trackNum) { struct MUSIC_GME *gmeMusic; gmeMusic = GME_LoadSongRW(src, trackNum); if (!gmeMusic) { Mix_SetError("GAME-EMU: Can't load file"); return NULL; } if ( freesrc ) { SDL_RWclose(src); } return gmeMusic; }
int Mix_InitMOD() { if ( mikmod.loaded == 0 ) { #ifdef __MACOSX__ extern void Player_Start(MODULE*) __attribute__((weak_import)); if ( Player_Start == NULL ) { /* Missing weakly linked framework */ Mix_SetError("Missing mikmod.framework"); return -1; } #endif // __MACOSX__ mikmod.MikMod_Exit = MikMod_Exit; mikmod.MikMod_InfoDriver = MikMod_InfoDriver; mikmod.MikMod_InfoLoader = MikMod_InfoLoader; mikmod.MikMod_Init = MikMod_Init; mikmod.MikMod_RegisterAllLoaders = MikMod_RegisterAllLoaders; mikmod.MikMod_RegisterDriver = MikMod_RegisterDriver; mikmod.MikMod_errno = &MikMod_errno; mikmod.MikMod_strerror = MikMod_strerror; #if LIBMIKMOD_VERSION < ((3<<16)|(2<<8)) mikmod.MikMod_free = free; #else mikmod.MikMod_free = MikMod_free; #endif mikmod.Player_Active = Player_Active; mikmod.Player_Free = Player_Free; mikmod.Player_LoadGeneric = Player_LoadGeneric; mikmod.Player_SetPosition = Player_SetPosition; mikmod.Player_SetVolume = Player_SetVolume; mikmod.Player_Start = Player_Start; mikmod.Player_Stop = Player_Stop; mikmod.VC_WriteBytes = VC_WriteBytes; mikmod.drv_nos = &drv_nos; mikmod.md_device = &md_device; mikmod.md_mixfreq = &md_mixfreq; mikmod.md_mode = &md_mode; mikmod.md_musicvolume = &md_musicvolume; mikmod.md_pansep = &md_pansep; mikmod.md_reverb = &md_reverb; mikmod.md_sndfxvolume = &md_sndfxvolume; mikmod.md_volume = &md_volume; } ++mikmod.loaded; return 0; }
/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */ int _Mix_UnregisterAllEffects_locked(int channel) { effect_info **e = NULL; if (channel == MIX_CHANNEL_POST) { e = &posteffects; } else { if ((channel < 0) || (channel >= num_channels)) { Mix_SetError("Invalid channel number"); return(0); } e = &mix_channel[channel].effects; } return _Mix_remove_all_effects(channel, e); }
/* MUS_MOD can't be auto-detected. If no other format was detected, MOD is * assumed and MUS_MOD will be returned, meaning that the format might not * actually be MOD-based. * * Returns MUS_NONE in case of errors. */ static Mix_MusicType detect_music_type(SDL_RWops *rw) { Uint8 magic[5]; Uint8 moremagic[9]; int start = SDL_RWtell(rw); if (SDL_RWread(rw, magic, 1, 4) != 4 || SDL_RWread(rw, moremagic, 1, 8) != 8 ) { Mix_SetError("Couldn't read from RWops"); return MUS_NONE; } SDL_RWseek(rw, start, RW_SEEK_SET); magic[4]='\0'; moremagic[8] = '\0'; /* WAVE files have the magic four bytes "RIFF" AIFF files have the magic 12 bytes "FORM" XXXX "AIFF" */ if (((strcmp((char *)magic, "RIFF") == 0) && (strcmp((char *)(moremagic+4), "WAVE") == 0)) || (strcmp((char *)magic, "FORM") == 0)) { return MUS_WAV; } /* Ogg Vorbis files have the magic four bytes "OggS" */ if (strcmp((char *)magic, "OggS") == 0) { return MUS_OGG; } /* FLAC files have the magic four bytes "fLaC" */ if (strcmp((char *)magic, "fLaC") == 0) { return MUS_FLAC; } /* MIDI files have the magic four bytes "MThd" */ if (strcmp((char *)magic, "MThd") == 0) { return MUS_MID; } if (detect_mp3(magic)) { return MUS_MP3; } /* Assume MOD format. * * Apparently there is no way to check if the file is really a MOD, * or there are too many formats supported by MikMod/ModPlug, or * MikMod/ModPlug does this check by itself. */ return MUS_MOD; }
int Mix_Init(int flags) { int result = 0; if (flags & MIX_INIT_OGG) { #ifdef OGG_MUSIC if ((initialized & MIX_INIT_OGG) || Mix_InitOgg() == 0) { result |= MIX_INIT_OGG; } #else Mix_SetError("Mixer not built with Ogg Vorbis support"); #endif } initialized |= result; return (result); }
/* MAKE SURE you hold the audio lock (SDL_LockAudio()) before calling this! */ int _Mix_RegisterEffect_locked(int channel, Mix_EffectFunc_t f, Mix_EffectDone_t d, void *arg) { effect_info **e = NULL; if (channel == MIX_CHANNEL_POST) { e = &posteffects; } else { if ((channel < 0) || (channel >= num_channels)) { Mix_SetError("Invalid channel number"); return(0); } e = &mix_channel[channel].effects; } return _Mix_register_effect(e, f, d, arg); }
int Mix_SetSoundFonts(const char *paths) { #ifdef MID_MUSIC if (soundfont_paths) { SDL_free(soundfont_paths); soundfont_paths = NULL; } if (paths) { if (!(soundfont_paths = SDL_strdup(paths))) { Mix_SetError("Insufficient memory to set SoundFonts"); return 0; } } #endif return 1; }
/* Load a music stream from the given file */ MusicCMD *MusicCMD_LoadSong(const char *cmd, const char *file) { MusicCMD *music; /* Allocate and fill the music structure */ music = (MusicCMD *)malloc(sizeof *music); if ( music == NULL ) { Mix_SetError("Out of memory"); return(NULL); } strncpy(music->file, file, (sizeof music->file)-1); music->file[(sizeof music->file)-1] = '\0'; strncpy(music->cmd, cmd, (sizeof music->cmd)-1); music->cmd[(sizeof music->cmd)-1] = '\0'; music->pid = 0; /* We're done */ return(music); }
int Mix_FadeInMusicPos(Mix_Music *music, int loops, int ms, double position) { int retval; if ( ms_per_step == 0 ) { SDL_SetError("Audio device hasn't been opened"); return(-1); } /* Don't play null pointers :-) */ if ( music == NULL ) { Mix_SetError("music parameter was NULL"); return(-1); } /* Setup the data */ if ( ms ) { music->fading = MIX_FADING_IN; } else { music->fading = MIX_NO_FADING; } music->fade_step = 0; music->fade_steps = ms/ms_per_step; /* Play the puppy */ SDL_LockAudio(); /* If the current music is fading out, wait for the fade to complete */ while ( music_playing && (music_playing->fading == MIX_FADING_OUT) ) { SDL_UnlockAudio(); SDL_Delay(100); SDL_LockAudio(); } music_active = 1; if (loops == 1) { /* Loop is the number of times to play the audio */ loops = 0; } music_loops = loops; retval = music_internal_play(music, position); SDL_UnlockAudio(); return(retval); }