Last active
August 29, 2015 14:01
-
-
Save Expack3/bf17450ad15a05a48cdf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*The following method is designed to play a given line of sound samples as fast as possible. | |
This code was taken from the source code of XMOD, a simple, high-speed sound module/MIDI hybrid designed using the XACT subset utilized by the XNA game framework. | |
*/ | |
//Variables used: | |
private int currLine; //indicates the current line in a song | |
public short playbackStatus = 0; //Used to store the current playback status. 0 = stop, 1 = pause, 2 = play, 3 = loop | |
private int LPS; //used to store the current tempo, or lines per second (LPS). | |
private Cue[] cueBank; //used to store up to 4 cues, XACT's language for "instances of a loaded sound file with playback metadata", to be used for a song; can be updated as needed | |
private String[] cueNames; //used to store the names of all cues to be used for a song | |
public int[,] soundCache; //used to store all commands required to playback a song | |
private void playLine() | |
{ | |
if (currLine >= soundCache.GetLength(0)) //First, check to see if the current line number (currLine) exceeds the length of the first dimension of soundCache, the XMOD player's 2D command cache. | |
currLine = 0; //If so, reset currLine to 0. | |
for (int x = 0, y = 0; x < soundCache.GetLength(1); x = x + 2, y++) /*Next, create a FOR loop using integers x and y, initalized to 0. | |
Continue eval if x is less than the length of the second dimension of soundCache. | |
Since commands stored in soundCache are arranged in groups of two (commandNumber, commandParameter), increase x by 2 and y by 1 at the end of each eval.*/ | |
{ | |
switch (soundCache[currLine, x]) //Determine what kind of command is stored in row currLine, column x of soundCache. | |
{ | |
case -3: //-3 indicates a change in tempo (internally called LPS or Lines Per Second) | |
lps += soundCache[currLine, x + 1]; //change LPS using the command's parameter (stored in row currLine, column x +1 of soundCache) | |
break; | |
case -2: //-2 indicates the EOF (End-Of-File) of the song. | |
if (playbackStatus != 3)//Check to see if the value of playbackStatus isn't equal to 3, which would indicate the song is to be looped indefinitely | |
{ | |
stopXMOD(); //If is, tell the player to stop playback | |
} | |
else | |
loopFile(); //Otherwise, tell the player to loop the file (by setting currLine to 0) | |
return; //exit early from the current method | |
case -1: //-1 indicates no processing is to take place for the current row/column combination. | |
break; | |
default: //Otherwise, the command is referring to an instrument | |
if (cueBank[y] != null && cueBank[y].IsPlaying) //Is there an instance of a sound loaded into position x of cueBank, a fixed-size cache storing loaded audio file instances and accessible as an array, and is the currently-loaded instance playing? | |
//The latter check is important since XACT generates an exception if the program tries to stop a loaded sound file which isn't being played. | |
{ | |
cueBank[y].Stop(AudioStopOptions.AsAuthored); //If both are true, stop playing the sound immediately as intended by the instance's metadata | |
} | |
loadInstance(soundCache[currLine, x], soundCache[currLine, x + 1], y); //Load a new instance of the sound at row currLine, column x in soundCache, | |
//the matching pitch at row currLine, column x in soundCache, and y to indicate the position to store the instance in cueBank | |
audioEngine.Update(); | |
cueBank[y].Play(); //play instance y on the current line | |
break; | |
} | |
} | |
currLine++; //increment currLine by 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment