
Description

Default support for music in TGE is fairly minimal, to say the least.  It consists of playing, stopping, looping, and volume control.  while this suffices for most sounds in a game, it just doesn't cut it for music.  In the past game programmers using TGE were forced to manually implement features commonly used for playing music in games, such as fading, transitioning between songs, randomly playing songs, etc.

VMPlayer (Virtual Music Player) changes all of that.  Simply put, it's a script resource that adds some advanced music playing capabilities to the Torque Game Engine. To be more precise, think of it as a media player with no GUI, that's made specifically for playing music in your TGE games.

Note that this resource supports both TGE 1.4 and TGE 1.3.


Installation Instructions

1) Add the VMPlayer.cs file to your game directory and include it in your game.

2) While VMPlayer is written entirely in script it does require a small modification to TGE to fix a bug, as well that you have installed a previous resource I wrote to allow pausing and seeking of audio.  I hope for GarageGames to add both of these changes to the HEAD which would remove any required modification to TGE, but in the meantime:

You can install the required resource here: http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=9385

The bug that needs to be fixed is in vorbisStreamSource.cc/vorbisStreamSource.h.  Simply replace those files with the two version included in the source and recompile Torque.


Features

Common Music Player Functions - VMPlayer includes the commonly used features you would expect from any music player, such as play, pause, stop, rewind, fastforward, skip tracks, etc.

Playlists - Create multiple playlists and add as many songs as you like to each playlist.  Playlists are perfect for grouping similar songs together, whether they are grouped based on game level/map, grouped by the mood of the songs, or any other grouping you can imagine.  For instance, an RPG could load and play an "eerie" playlist when the player enters a dungeon and an "upbeat" playlist when the user enters a town.

Random - Randomly play tracks in your playlist.  A great way to mix things up.

Repeat - Repeat the same song infinately or repeat entire playlists.

Fading - Automatically fade songs in when they start and fade them out as they end.  No more abrupt music stoppages that make a game sound unprofessional.

Cross Fading - Cross fading allows you to smoothly transition from one song to another by fading out the current song while simultaneously fading in the next song.  This is perfect for those games where you want the background music to dynamically change based when what is currently happening in your game.

Play Only User Defined Segments of Songs - This handy feature allows you to optionally specify a starting and ending time for each song in your playlist.  This allows you to only play a small segment of a song rather than the entire song.  It's also useful to remove that extra 5 seconds of white noise at the end some songs.

Synchronize Your Game with Your Music - Ever notice how background music in movies perfectly match events in the movie?  VMPlayer gives the programmer this same ability by automatically calling user specified functions at user defined points in a song.  This could allow you to flash a bolt of lightning in front of the player exactly when your background music hits its cresendo, or spawn a monster directly behind the player when your music is especially scary.

Let the Player Control the Music - Imagine being able to enable players of your FPS game to modify and create their OWN playlists and play their OWN music in your game while they play.  VMPlayer is built with all the features you need to do this, including saving/reading of custom playlists to/from disk.  All you need to do is develop the user interface for the user!

Easy to Use - Despite all the features of VMPlayer, it's actually very easy to use.  In fact, it's faster to add new songs to your game and play them using VMPlayer than it is to do so using TGE without VMPlayer.  It's literally as simple as placing the new song file in your data directory and calling VMPlayer.PlaySong(filename).  No need to ever create AudioProfiles or AudioDescriptions, as VMPlayer handles that for you behind the scenes.

The feature list of VMPlayer is even longer than this, but the features listed above cover all the major features.  For a complete listing of everything possible in VMPlayer, review the function list below.


Playlist Functions

bool SavePlaylistsToDisk(filename) - Saves all playlists, tracks, track info, and events in VMPlayer to the specified file.  If successful true is returned, otherwise false.

bool OpenPlaylistsFromDisk(filename) - Reads a previously saved playlists, tracks, track info, and events from the specified file.  If successful true is returned, otherwise false.

number AddPlaylist(playlistname [, song1, song2, song3, song4, song5, song6, song7, song8, song9, song10, song11, song12, song13, song14, song15, song16]) - Adds a new playlist to VMPlayer, with the options of adding 16 songs to that playlist.  If successful the index of the new playlist is returned, otherwise 0.

bool RemovePlaylist(playlistname) - Removes the specified playlists from VMPlayer.  This will also remove all tracks and events associated with that playlist.  If a matching playlist is found and removed true is returned, otherwise false.

void RemoveAllPlaylists() - Removes all playlists from VMPlayer.  This will, as a result, also remove all tracks and events.

bool LoadPlaylist(playlistname) - Loads the specified playlist so it can now be played.  If the specified playlist does not exist then false is returned, otherwise true.

void UnloadPlaylist(playlistname) - Unloads the currently loaded playlist, if any.  This will stop any songs currently playing in that playlist.

bool IsPlaylistLoaded() - Returns true if a playlist is currently loaded, otherwise false.

string GetCurrentPlaylistName() - Returns the name of the currently loaded playlist.  If no playlist is loaded then it returns an empty string.

number GetPlaylistCount() - Returns the number of added playlists.

string GetPlaylistName(index) - Returns the name of the specified playlist index.  If the specified playlist index is invalid an empty string is returned.

number AddSongToPlaylist(playlistname, song [, title, artist, start_pos, end_pos]) - Adds a new track to the specified playlist.  Optional parameters allow you to specify a title and artist, as well as to specify starting and ending positions (in seconds) for the track to play.  If the specified playlist does not exist 0 is returned, otherwise the new track number for the song.


Track/Song Functions

bool RemoveTrack(playlistname, tracknumber) - Removes the specified track from the specified playlist.  This will also remove events associated with that track.  If a matching playlist and track is found and removed true is returned, otherwise false.

bool RemoveAllTracks(playlistname) - Removes all tracks from the specified playlist.  This will also remove all events associated with these tracks.  If a matching playlist is not found false is returned, otherwise true.

number GetTrackCount(playlistname) - Returns the number of tracks in the specified playlist.  If no matching playlist is found -1 is returned.

number GetCurrentTrackNumber() - Returns the track number of the currently selected track.  If no playlist is loaded then 0 is returned.  A song does not have to be playing for a track to be selected.

bool SetCurrentTrackNumber(tracknumber) - Selects the specified track number.  If a song is currently playing the song is stopped.  This function does not automatically play the selected track.  If the specified track number is not found false is returned, otherwise true.

string GetTrackFilename(playlistname, tracknumber) - Returns the filename of the specified track number in the specified playlist.  If no matching playlist is found or the track number is invalid an empty string is returned.

string GetTrackTitle(playlistname, tracknumber) - Returns the song title of the specified track number in the specified playlist.  If no matching playlist is found or the track number is invalid an empty string is returned.

bool SetTrackTitle(playlistname, tracknumber, title) - Changes the song title of the specified track number in the specified playlist.  If no matching playlist is found or the track number is invalid false is returned, otherwise true.

string GetTrackArtist(playlistname, tracknumber) - Returns the song artist of the specified track number in the specified playlist.  If no matching playlist is found, or the track number is invalid an empty string is returned.

bool SetTrackArtist(playlistname, tracknumber, artist) - Changes the song title of the specified track number in the specified playlist.  If no matching playlist is found or the track number is invalid false is returned, otherwise true.

float GetTrackStartPosition(playlistname, tracknumber) - Returns the position (in seconds) to start the song for the specified track number in the specified playlist.  If no starting position was ever set on the specified track, then 0 is returned, which means the song will start at the very beginning of the song.  If no matching playlist is found, or the track number is invalid -1 is returned.

bool SetTrackStartPosition(playlistname, tracknumber, start_pos) - Sets the position (in seconds) to start the song for the specified track number in the specified playlist.  Note that the starting position cannot be higher than the ending position in the song.  If no matching playlist is found or the track number is invalid false is returned, otherwise true.

float GetTrackEndPosition(playlistname, tracknumber) - Returns the position (in seconds) to end the song for the specified track number in the specified playlist.  If no ending position was ever set on the specified track, then end of the song is returned, which means the song will play till the very end of the song.  If no matching playlist is found, or the track number is invalid -1 is returned.

bool SetTrackEndPosition(playlistname, tracknumber, end_pos) - Sets the position (in seconds) to end the song for the specified track number in the specified playlist.  Note that the ending position cannot be lower than the starting position in the song.  If no matching playlist is found or the track number is invalid false is returned, otherwise true.

number GetTrackDuration(playlistname, tracknumber) - Returns the duration (in seconds) of the song for the specified track number in the specified playlist.  If no matching playlist is found, or the track number is invalid -1 is returned.

string GetSongFilename() - Returns the filename of the currently playing song.  If no song is playing an empty string is returned.

string GetSongTitle() - Returns the song title of the currently playing song.  If no song is playing an empty string is returned.

bool SetSongTitle(title) - Changes the song title of the currently playing song.  If no song is playing false is returned, otherwise true.

string GetSongArtist() - Returns the song artist of the currently playing song.  If no song is playing an empty string is returned.

bool SetSongArtist(artist) - Changes the song artist of the currently playing song.  If no song is playing false is returned, otherwise true.

float GetSongStartPosition() - Returns the position (in seconds) to start the song for the currently playing song.  If no starting position was ever set on the song, then 0 is returned, which means the song will start at the very beginning of the song.  If no song is playing -1 is returned.

bool SetSongStartPosition(start_pos) - Sets the position (in seconds) to start the song for the currently playing song.  Note that the starting position cannot be higher than the ending position in the song.  If song is playing false is returned, otherwise true.

float GetSongEndPosition() - Returns the position (in seconds) to end the song for the currently playing song.  If no ending position was ever set on the song, then position at the very end of the song is returned.  If song is playing -1 is returned.

bool SetTrackEndPosition(end_pos) - Sets the position (in seconds) to end the song for the currently playing song.  Note that the ending position cannot be lower than the startng position in the song.  If no song is playing false is returned, otherwise true.

number GetSongDuration() - Returns the duration (in seconds) of the song for the currently playing song.  If no song is playing -1 is returned.


Event Functions

bool AddEventToTrack(playlistname, tracknumber, eventfunc, position) - Adds an event function to the specified track in the specified playlist.  This event is fired whenever the specified position in the track is played.  Only one event function can be added to the same position in the track.  If no matching playlist is found or the track number is invalid false is returned, otherwise true.  Note that the position specified is absolute, and not relative to the starting position of the song.

bool RemoveEventFromTrack(playlistname, tracknumber, position) - Removes an event from the specified position in the specified track in the specified playlist.  If no matching playlist is found, the track number is invalid, or the position does not have an event added false is returned, otherwise true.  Note that the position specified is absolute, and not relative to the starting position of the song.

bool RemoveAllEventsFromTrack(playlistname, tracknumber) - Removes all events from the specified position in the specified track in the specified playlist.  If no matching playlist is found or the track number is invalid false is returned, otherwise true.

bool AddEventToSong(eventfunc, position) - Adds an event function to the currently playing song. This event is fired whenever the specified position in the track is played.  Only one event function can be added to the same position in the same song.  If no song is playing false is returned, otherwise true.  Note that the position specified is absolute, and not relative to the starting position of the song.

bool RemoveEventFromSong(position) -  Removes an event from the currently playing song.  If no song is playing or the position does not have an event added false is returned, otherwise true.  Note that the position specified is absolute, and not relative to the starting position of the song.

bool RemoveAllEventsFromSong() - Removes all events from the currently playing song.  If no song is playing false is returned, otherwise true.


Option Functions

void SetAudioChannels(primary, secondary) -  Sets the audio channels for VMPlayer to use when playing music.  VMPlayer requires the dedicated use of two channels for fading/crossfading and this function allows you to specify the two channels to use.  By default the channels used are 7 and 8.

void SetVolume(volume) - Sets the music volume.  Valid volume values range from 0.0 to 1.0.

float GetVolume() - Returns the intended music volume.  Note that this NOT return a lower volume level when a song is fading, but rather the normal music volume when playing songs.

float GetNextTrackDelay() - Returns the specified number of seconds to delay between track changes.  This setting is ignored when fade or cross fade is enabled.

float SetNextTrackDelay(seconds) - Sets a specified number of seconds to delay track changes.  This setting is ignored when fade or cross fade is enabled.

void EnableFade(true/false) - Enables or disables fading of music.  Enabling fading will cause all songs to start playing with the volume set to 0.0 and gradually increase until the normal music volume is reached, and will also cause all songs that stop to gradually decrease their volume level to 0.0 before actually stopping the song.  When enabled, fading IS used between track changes.

bool IsFadeEnabled() - Returns true if fading is enabled, otherwise false.

void EnableCrossFade(true/false) - Enables or disables cross fading of music.  Enabling cross fading will cause all songs which are interupted to play another song to start fading out the old song while simultaneously fading in the new song.  Note that if a song is manually stopped before attempting to play a new song cross fading does not occur.  When enabled, cross fading IS used to transition between track changes.

bool IsCrossFadeEnabled() - Returns true if cross fading is enabled, otherwise false.

void SetFadeDuration(seconds) - Sets how long a song fade or cross fade lasts, in seconds.

float GetFadeDuration() - Returns the number of seconds a song fade or cross fade lasts.

void EnableRandom(true/false) - Enables or disables the random selection of tracks in playlists.

bool IsRandomEnabled() - Returns true if random is enabled, otherwise false.

void EnableRepeat(true/false) - Enables or disables the repeating of songs or playlists.

bool IsRepeatEnabled() - Returns true if repeat is enabled, otherwise false.


Playing Functions

bool IsPlaying() - Returns true if VMPlayer is currently playing a song, otherwise false.

bool PlaySong() - Loads and plays the specified song.  If a playlist was previously loaded it will be unloaded.  If the song was successfully played true is returned, otherwise false.

bool PlayTrack(tracknumber) - Plays the specified track in a playlist.  If no playlist has been loaded, or if the track is invalid then false is returned, otherwise true.

bool Play() - Plays all songs in the current playlist starting with the currently selected track.  If no playlist has been loaded, or if no tracks have been added to the playlist then false is returned, otherwise true.

bool IsPaused() - Returns true if the VMPlayer was playing a song but is currently paused, otherwise false.

void Pause() - Pauses the currently playing song.

void Unpause() - Unpauses a currently paused song.

void Stop() - Stops the currently playing song.  Note that if fading is turned on the song will not immediately stop, but instead the volume will fade to nothing and then the song will stop.  If you call Stop() and immediately call Play() when fading is enabled, then the first song will fade out completely before the second song starts to fade in.


Traversing Functions

float GetSongPosition() - Returns the current position of the currently playing song, in seconds.  If no song is currently playing it returns -1.  Note that the position returned is relative to the starting position of the song.

bool SetSongPosition(seconds) - Sets the current position of the currently playing song, in seconds.  If no song is currently playing it returns false, otherwise true.  Note that the specified position should be relative to the starting position of the song.

bool JumpBackward(seconds) - Jumps backward in the currently playing song from its current position by the specified number of seconds.  If no song is currently playing it returns false, otherwise true.

bool JumpForward(seconds) - Jumps forward in the currently playing song from its current position by the specified number of seconds.  If no song is currently playing it returns false, otherwise true.

bool SkipBackward() - Skips back to the beginning of a song, or if already at the beginning and a playlist is loaded and the currently playing song is not the first track then it will skip to the previous track.  If no song is currently playing it returns false, otherwise true.

bool SkipForward() - Skips forward to the end of the song, or if a playlist is loaded and the currently playing song is not the last track then it will skip to the next track.  If no song is currently playing it returns false, otherwise true.


Using VMPlayer

Below is an example of using VMPlayer to simply play a song:

$VMPlayer = new ScriptObject(VMPlayer);
...
$VMPlayer.PlaySong("~/data/music/song1.ogg");


Below is an example of setting up and playing playlists in random order:

$VMPlayer = new ScriptObject(VMPlayer);
...
$VMPlayer.AddPlaylist("playlist1", "~/data/music/song1.ogg", "~/data/music/song2.ogg", ~/data/music/song3.ogg");
$VMPlayer.AddPlaylist("playlist2", "~/data/music/song4.ogg", "~/data/music/song5.ogg");

$VMPlayer.LoadPlaylist("playlist1");
$VMPlayer.EnableRandom(true);
$VMPlayer.Play();


Below is an example of using VMPlayer for event callbacks:

function TestEvent()
{
   echo("Event Fired");
}

$VMPlayer = new ScriptObject(VMPlayer);
...
$VMPlayer.AddPlaylist("playlist1", "~/data/music/song1.ogg", "~/data/music/song2.ogg",  ~/data/music/song3.ogg");
$VMPlayer.AddEventToTrack("playlist1", 1, TestEvent, 23.5); // Fire TestEvent at 23.5 seconds into track 1
$VMPlayer.LoadPlaylist("playlist1");

$VMPlayer.Play();


Updates

03/09/2006 - Modified my Add Pausing and Seeking of Audio resource to include functionality needed for VMPlayer to work in TGE 1.3.

03/16/2006 - Fixed issue with repeat not working when playing songs via PlaySong (Repeat worked fine with playlists).

03/16/2006 - Fixed issue with repeat not working when playing songs via PlaySong (Repeat worked fine with playlists).

04/19/2006 - Fixed small memory leak issue - Thanks CSUMB (#0010)!


Enjoy!