indexing description: "[ Implements a simple music player. This player can play either WAVE, MOD, MIDI, OGG or MP3. Use this player if you don't want to handle all music stuff yoursef. This player let's you play music files in a very very easy way. This class was designed for having music support in a hurry. We recommend to use it whenever you need just to play music. Note: You need to have special compiled version of SDL_mixer to be able to play MP3-files. Please check documentation for further details. Note: This is typically used to play background music, whereas EM_SOUND_PLAYER is used to play sound effects. ]" date: "$Date$" revision: "$Revision$" class EM_MUSIC_PLAYER inherit EM_SHARED_SUBSYSTEMS export {NONE} all end EM_SHARED_AUDIO_FACTORY export {NONE} all end EM_SHARED_AUDIO_EVENTS export {NONE} all end EM_AUDIO_CONSTANTS export {NONE} all end EM_TIME_SINGLETON export {NONE} all end EM_CONSTANTS export {NONE} all end EM_AUDIO_FUNCTIONS_EXTERNAL export {NONE} all end SDL_FUNCTIONS_EXTERNAL export {NONE} all end SDL_MIXER_FUNCTIONS_EXTERNAL export {NONE} all end create make_with_path,make_with_list, make_with_file,make_empty feature {NONE} -- Initialization initialize_subsystem is -- Initialize audio subsystem. do audio_subsystem.enable if audio_subsystem.is_enabled then audio_subsystem.mixer.open_default did_initialize_subsystem := True end end make_with_path (a_path: STRING; an_extension_list: DS_LINKED_LIST [STRING]; do_recursive_search: BOOLEAN; do_initialize_subsystem: BOOLEAN) is -- Make playlist from `a_path' searching for file with -- extensions in `an_extension_list'. -- -- If you want to search files also in subfolders, set -- `do_recursive_search' to True. -- -- This player may initialize the audio subsystem for you. -- Use `do_initialize_subsystem' to have it enabled by this player. require a_path_not_void: a_path /= Void do make_empty (do_initialize_subsystem) create playlist.make_with_path (a_path, an_extension_list, do_recursive_search) end make_with_list (a_list: DS_LINKED_LIST [STRING]; do_initialize_subsystem: BOOLEAN) is -- Make playlist from `a_list'. -- -- This player may initialize the audio subsystem for you. -- Use `do_initialize_subsystem' to have it enabled by this player. do make_empty (do_initialize_subsystem) create playlist.make_with_list (a_list) end make_with_file (a_filename: STRING; do_initialize_subsystem: BOOLEAN) is -- Make playlist with `a_filename'. -- -- This player may initialize the audio subsystem for you. -- Use `do_initialize_subsystem' to have it enabled by this player. require a_filename_not_void: a_filename /= Void do make_empty (do_initialize_subsystem) playlist.extend (a_filename) ensure playlist_count_is_one: playlist.count = 1 end make_empty (do_initialize_subsystem: BOOLEAN) is -- Make with an empty playlist. -- -- This player may initialize the audio subsystem for you. -- Use `do_initialize_subsystem' to have it enabled by this player. do if do_initialize_subsystem then initialize_subsystem end audio_events.music_finished_event.subscribe (agent music_finished) shuffle := False repeat := False volume := Em_max_volume create playlist.make_empty stop_pressed := False ensure playlist_count_is_zero: playlist.count = 0 end feature -- Callback events music_finished is -- Event is fired when music finishes playing. do debug ("em_audio") io.put_string ("music has finished playing") io.put_new_line end if not stop_pressed then forth end stop_pressed := False end feature -- Playback play is -- Play current playlist entry. require not_playing: not is_playing local a_filename: STRING do if shuffle then random_number.forth create a_filename.make_from_string (playlist.get_i_th ((random_number.double_item * playlist.count).truncated_to_integer + 1)) else create a_filename.make_from_string (playlist.get_i_th (1)) end audio_factory.create_music_from_file (a_filename) music_playing := audio_factory.last_music music_playing.set_volume (volume) music_playing.play (0) is_playing := True stop_pressed := False ensure is_playing: music_playing.is_playing end play_i_th (an_index: INTEGER) is -- Play track at position `an_index' in playlist. require not_playing: not is_playing index_valid: 1 <= an_index and then an_index <= playlist.count local a_filename: STRING do create a_filename.make_from_string (playlist.get_i_th (an_index)) audio_factory.create_music_from_file (a_filename) music_playing := audio_factory.last_music music_playing.set_volume (volume) music_playing.play (0) is_playing := True ensure is_playing: music_playing.is_playing end stop is -- Stop playing. do stop_pressed := True music_playing.stop is_playing := False ensure is_stopped: not music_playing.is_playing end resume is -- Resume playback. require music_set: music_playing /= Void is_paused: is_paused do music_playing.resume is_paused := False ensure is_playing: not is_paused and is_playing end pause is -- Pause playback. require music_set: music_playing /= Void is_playing: not is_paused and is_playing do music_playing.pause is_paused := True ensure is_paused: is_paused end forth is -- Go to next playlist entry and play it. local a_filename: STRING do if is_playing then music_playing.stop end is_playing := False if playlist.index = playlist.count then if repeat then if shuffle then random_number.forth create a_filename.make_from_string (playlist.get_i_th ((random_number.double_item * playlist.count).truncated_to_integer + 1)) else create a_filename.make_from_string (playlist.get_i_th (1)) end audio_factory.create_music_from_file (a_filename) music_playing := audio_factory.last_music music_playing.set_volume (volume) music_playing.play (0) is_playing := True end else if shuffle then random_number.forth create a_filename.make_from_string (playlist.get_i_th ((random_number.double_item * playlist.count).truncated_to_integer + 1)) else create a_filename.make_from_string (playlist.next) end audio_factory.create_music_from_file (a_filename) music_playing := audio_factory.last_music music_playing.set_volume (volume) music_playing.play (0) is_playing := True end end back is -- Go to previous playlist entry and play it. local a_filename: STRING do if is_playing then music_playing.stop end is_playing := False if playlist.index = 1 then if repeat then if shuffle then random_number.forth create a_filename.make_from_string (playlist.get_i_th ((random_number.double_item * playlist.count).truncated_to_integer + 1)) else create a_filename.make_from_string (playlist.get_i_th (playlist.count)) end audio_factory.create_music_from_file (a_filename) music_playing := audio_factory.last_music music_playing.set_volume (volume) music_playing.play (0) is_playing := True end else if shuffle then random_number.forth create a_filename.make_from_string (playlist.get_i_th ((random_number.double_item * playlist.count).truncated_to_integer + 1)) else create a_filename.make_from_string (playlist.back) end audio_factory.create_music_from_file (a_filename) music_playing := audio_factory.last_music music_playing.set_volume (volume) music_playing.play (0) is_playing := True end end feature -- Access shuffle: BOOLEAN -- Does playlist plays shuffled? repeat: BOOLEAN -- Does playlist repeats playback? volume: INTEGER -- Returns current volume. playlist: EM_PLAYLIST -- Playlist of this music player music_playing: EM_MUSIC -- Actually playing music -- Note: File may already be deallocated! did_initialize_subsystem: BOOLEAN -- Did this player initialize the audio subsystem? is_playing: BOOLEAN -- Is this Player playing a file? is_paused: BOOLEAN -- Is this player in paused mode? feature {NONE} -- Internal variables random_number: RANDOM -- Random number for shuffling playlist stop_pressed: BOOLEAN -- Was stop pressed? feature -- Setters set_shuffle (do_shuffle: like shuffle) is -- Set `shuffle' to `do_shuffle'. do shuffle := do_shuffle if shuffle then create random_number.set_seed (time.ticks) end ensure shuffle_assigned: shuffle = do_shuffle end set_repeat (do_repeat: like repeat) is -- Set `repeat' to `do_repeat'. do repeat := do_repeat ensure repeat_assigned: repeat = do_repeat end set_volume (a_volume: like volume) is -- Set `volume' for player to `a_volume'. do volume := a_volume if music_playing /= Void then music_playing.set_volume (a_volume) end ensure volume_assigned: volume = a_volume end invariant playlist_created: playlist /= Void end