JFugue User's Guide

Get JFugue at http://www.jfugue.org.
See what's new in JFugue 2.0 in the appendix.

Printing suggestion: If you want to print this guide, it is recommended that you print in Landscape mode. The wider pages will allow all of the values in the Appendix to fit on the page properly.

Table of Contents

Welcome to JFugue

JFugue is a Java API for Music Programming. With JFugue, you can program music quickly and easily, and without knowing MIDI.

JFugue differs from other Java music API's in two significant ways. First, to program music in JFugue, you send strings that specify notes, instrument changes, controller messages, and other musical data. These strings are quick to create and easy to understand: for example, to play a C, you say play("C");. Other API's use objects to represent each note in a musical score, which makes music programming extremely tedious. Or, they require low-level manipulation of MIDI events.

Second, JFugue lets you create "patterns" of music that can be manipulated, recombined, and transformed, allowing you to play and experiment with musical statements in new and interesting ways. Want to reverse your music, or change all of the notes by three intervals? All it takes it one method call.

JFugue is particular geared towards developers who need to create music during runtime. You can't play music that has already been recorded, because you don't know yet what the music is going to be! Applications include algorithmic or evolutionary music, music editors, and jazz improvisers.

You can use JFugue to play music while your application is running, or you can save music into MIDI files.

JFugue is 100% Java based. It uses the javax.sound.midi package to generate music.

Basics of JFugue

First, make sure you have the Java2 Standard Environment (J2SE) version 1.3 or later. You need at least version 1.3, because that's the version that has the javax.sound.midi packages.

You may want to see if additional MIDI sound banks are available for your Java installation. Installing additional sound banks may give you richer instrument sounds.

Next, you need the JFugue package, jfugue.jar, which you can download here. Remember where you put jfugue.jar; wherever it is, we'll call that directory %JFUGUE_DIR%.

Now you're ready to create your first music application! Let's walk through a quick program, so you can be sure you have everything set up correctly. Then we'll get into more details about programming JFugue.

Create a new file called MyMusicApp.java and enter this program:

		import org.jfugue.*;

		public class MyMusicApp
		{
			public static void main(String[] args)
			{
				Player player = new Player();
				Pattern pattern = new Pattern("C D E F G A B");
				player.play(pattern);
				System.exit(0);
			}
		}
		

Save the file and compile it, making sure jfugue.jar is in your classpath:

javac -classpath %JFUGUE_DIR%\jfugue.jar MyMusicApp.java

And run it...

java -classpath %JFUGUE_DIR%\jfugue.jar MyMusicApp

Turn up your speakers -- your first JFugue application should be singing to you! Wasn't that easy?

(You might be wondering why it's necessary to put System.exit(0); at the end of the program. It turns out that the Java MIDI classes open a bunch of threads, but they're not all closed properly when the song is done playing. This prevents the program from ending on its own, but it does not otherwise affect the execution of the program.)

Introducing the Music String

The Music String is used to specify the notes, instrument changes, and other data required to play music. Along with Patterns, it is one of the two features of JFugue that make it unique, easy to use, and ideal for creating and experimenting with music.

The Music String is a string of characters, where each group of characters represents a musical command. It does not matter to the parser if you use upper or lowercase characters, but the following style guidelines are recommended to help keep your Music Strings readable:

  1. Use capital lettes for commands and notes
  2. Use lowercase characters for durations
  3. Used mixed-case for instrument and drum names

What commands are available?

Here is a list of the types of commands available in a Music String.

  1. Notes, Chords, and Rests: Specify a note or chord to play, and its duration. You may also indicate velocity for a note.
  2. Tempo: Specify the speed of the song.
  3. Voice: Indicate the voice (also known as the channel or track) in which notes are to be played.
  4. Instrument Change: Change the instrument, or patch, that is being used to play the notes.
  5. Controller Messages: Set any of the MIDI controller events, including portamento, balance, and much more.
  6. Variables: Define a value for use by the other commands.

Notes, Chords, and Rests

A note command begins with the note name or chord root, or the rest character: A, B, C, D, E, F, G, or R; or, with a numeric representation of the note, which is explained below. The following paragraphs describe additional details you can specify for a note.

Notes

You can indicate that a note is sharp or flat by using the # and b characters, respectively.

In addition to specifying a note using the note letter, there are two other ways to specify a note. One is to use the note value, which is a numerical value that indicates the note. MIDI has 128 notes, numbered 0 through 127. Note 60 is Middle-C. To specify a note value, enclose the value in square brackets; for example, [60].

The second way is to use a percussion name. In MIDI, the tenth voice (Voice 9, the voices begin with 0) is reserved for percussion sounds. There are a bunch of different percussion sounds you can play in that voice, and you can indicate them by giving the percussion name in brackets. For example, [Hi_Bongo]. Appendix: Percussion Sounds shows the names of the available percussion sounds.

We'll talk about chords a bit later.

Octave

MIDI is capable of playing notes than span 10 octaves. This diagram shows the more common octaves.

To indicate an octave, use the numbers 0 through 9 (remember, counting in MIDI starts at 0, so 0 through 9 is 10 octaves). For example, here's an A note in the 6th octave: A6.

If you don't specify the octave, the default is Octave 5, which includes Middle-C (so, Middle-C can be represented by both C and C5).

Duration

The Duration tells for how long to play the note. The following values are allowed. If you don't enter a duration, the default is a quarter note.

  1. w - whole duration
  2. h - half duration
  3. q - quarter duration
  4. i - eighth duration
  5. s - sixteenth duration
  6. t - thirty-second duration
  7. x - sixty-fourth duration
  8. n - 1/128th duration
You can specify a dotted duration by following the duration character with a period ('.'). The duration of a dotted note is the original duration, plus half the duration.

You can append durations to get a larger duration. For example, qh. would be a quarter note plus a dotted half note; wwww is four whole notes.

In addition to specifying a duration with a letter, you may also specify the duration as a decimal fraction. A quarter note would be 0.25, an eighth note would be 0.125, and so on. To represent a number as a decimal fraction, use the / character, followed by the fraction. For example, the following is an A note, 4th octave, half duration: A4/0.5.

Let's look at some examples. Here's a C5 half note: C5h. Can you think how to indicate a F-sharp, 4th octave, quarter note? The answer is F#4q, or F#4/0.25 if you're using decimal fractions.

Chords

Once you've specified the root of a chord, you can give its structure. All notes in a chord are played using the same instrument, in the same voice.

Here are the chord structures that are recognized by JFugue:

  1. maj - Major
  2. min - Minor
  3. maj7 - Major 7th
  4. min7 - Minor 7th
  5. dim - Diminished
  6. aug - Augmented
  7. aug7 - Augmented 7th
  8. sus - Sustained
  9. add9 - Add 9

The chord indicator goes directly after the root, and before the octave or duration. For example, a C-major, 5th octave, quarter note would be Cmaj5q. How would you specify a D-minor chord, 3rd octave, whole note? The answer is Dmin3w.

Special Note for Chords in the 7th Octave: If you want to play a major, minor, or augmented chord in the 7th octave, use note value instead of actual notes. For example, instead of Cmaj7 to indicate a C-major chord in the 7th octave, use [84]maj. 84 is the note number for C7. You can understand how the parser would easily be confused between Cmaj7 meaning "C-major chord in the 7th octave" and "C-major-7th chord". In fact, if you did say Cmaj7, you would get a major seventh chord, with C5 as the root (using the default value for the octave). Incidentally, Cmaj75 would give you the same thing.

Velocity

You can indicate how hard a note is struck, and how quickly the note is released.

To indicate how hard a note is struck, set the attack velocity using the a indicator, followed by a value from 0 to 127. To indicate how quickly a note is released, set the decay velocity using the d indicator, followed by a value from 0 to 127.

The default attack velocity and decay velocity for each note is 64. Incidentally, this is a standard default value for MIDI devices that do not support velocity.

Here's an example: C5qa120d30. This represents a Middle C, quarter duration, that is struck very strongly (120), and is released softly (30).

Combining Notes

There are two special characters that you may use to combine notes. The plus (+) character can be used to play multiple notes in at the same time (in harmony). The underscore (_) character can be used to play notes in order (in melody) when the melody is being played with a harmony. The scenarios below illustrate this.

Here are C, E, and G played in a melody. The music string to represent this piece of music is C5q E5q G5q. Nothing new here.
You can play more than one note at the same time using the same voice. To do this, connect notes with the plus (+) characer. For example, C5q+E5q+G5q will play the C, E, and G notes, quarter duration, at the same time. In this particular case, you could also represent this harmony as a chord, since these notes make up a C-major chord: Cmaj5q
You can also play multiple notes at the same time with mixed durations. Use the underscore (_) character to indicate notes that should be played in sequence, while the sequence plays in parallel with other notes. For example, this set of notes would be played by the command C5h+E5q_G5q.

Sample Note commands

Note commands are very useful, and as you write music for JFugue, you will find that they become easy to understand. Initially, they might seem a little intimidating. Here are some examples, which descriptions that may help you understand them better.

  1. A - Play an A note, fifth octave (default), quarter duration (default).
  2. Rw - A whole-duration rest.
  3. Cmaj3w - Play a C-major chord, octave 3, whole duration.
  4. [77]h - Play note #77 (equal to a F, 6th octave - remember note #60 is Middle-C), half duration.
  5. [Cowbell]qi - This note is intended for Voice 9, the percussion channel. It plays a cowbell sound for a quarter plus eighth duration. If you played this note in a voice other than Voice 9, you'd get Note #56, since the code for a cowbell is 56 (see the list of percussion sounds for more info). That would be A#, 4th octave.
  6. D4q+F4q+A4q - Plays the notes D, F, and A together; this would play the same notes as Dmin4q.
  7. C5w+E5h_G5h+Dmaj3w - Plays a C note, fifth octave, whole duration; at the same time, plays an E, fifth octave, half duration, followed by a G, fifth octave, half duration; at the same time, plays a D-major chord, third octave, whole duration. Be aware that a better way to play this might be to play the notes in one voice and the chord in another voice; for example, V0 C5W+E5h_G5h V1 Dmaj3w or V0 C5w V1 E5h G5h V2 Dmaj3w.

Tempo

You should specify the tempo of your song - how fast or slow the song should be played. The tempo value represents "Pulses Per Quarter", or PPQ, which is how many "pulses", or clock cycles, to give a quarter note. A smaller value will result in a faster song, and a larger number will result in a slower song. A good value to start with is 120; this is also the default if you do not specfy a tempo.

You only have to specify the tempo once in your music string, even if you are using multiple voices. Different voices cannot have different tempos. Also, it does not matter where you specify the tempo in your Music String, although it is recommended that you place it at the very beginning of a song.

The command is a T, followed by a number from 0 to infinity. For example: T120.

Voice

The Voice command tells JFugue to play the following notes in the given MIDI voice (also known as a channel). You can think of a voice as a musical track. Voices give you the ability to play multiple melodies at the same time. If you're programming piano music, you can use one voice for the treble clef, and a second voice for the bass clef. If you're creating a symphonic piece, you could give each instrument its own track.

The command is a V, followed by a number from 0 to 15. For example: V5

There are 16 voices, numbered 0 through 15. The tenth voice (or channel) is special -- it is the channel that plays the rhythym instruments. Notes played in this voice sound like drums, cymbals, woodblocks, and other percussion instruments. Since we're counting from 0, the tenth voice is Voice 9. When playing notes on Voice 9, you can use percussion names to represent the percussion instruments; see the Note command for details on this.

Instrument Change

The Instrument Change command tells JFugue to play the following notes with the given MIDI instrument number or name.

The command is an I, followed by either a number from 0 to 127, or the name of an instrument enclosed in brackets:

		I9
		I[Guitar]
		

Instrument changes (also known as patch changes) are specific to the voice in which the change takes place. In the following example, the notes A and B will be played with the Piano, and C and D with the Flute:


		V0 I[Piano] A V1 I[Flute] C V0 B V1 D
		

Appendix: Instrument Names contains pre-set names for instruments. You may also create your own names for instruments using the Variable command.

Controller Messages

The MIDI specification defines about 100 controller events, which are used to specify a wide variety of settings that control the sound of the music. These include foot pedals, left-to-right balance, portamento (notes sliding into each other), tremulo, and lots more. For a complete list, refer to a MIDI specification document.

The Controller command, X, tells JFugue to set the given controller:

		Xcontroller_number=value
		X37=18
		X[Chorus_Level]=64
		

If you're familiar with MIDI Controllers, you know that there 14 controllers that have both "coarse" and "fine" settings. These controllers essentially have 16 bits of data, instead of the typical 8 bits (one byte) for most of the others. There are two ways that you can specify coarse and fine settings.

The first way is quite uninspired:

		X[Foot_Pedal_Coarse]=10
		X[Foot_Pedal_Fine]=65
		

Surely, JFugue can be smarter than this. Indeed it is: For any of those 14 controller events that have coarse and fine components, you can specify both values at the same time:

		X[Foot_Pedal]=1345
		

There you have it. Want to set the volume to 10200, out of a possible 16383? There's no need to figure out what the high byte and low byte of 10200 are. Just use X[Volume]=10200.

The numeric value of the word VOLUME is equal to a 16-bit number, using the value for VOLUME_COARSE as the high byte, and the value for VOLUME_FINE as the low byte.

Some controller events have two settings: ON and OFF. Normally, ON means 127 and OFF means 0. JFugue has defined two constants, ON and OFF, that you can use instead of the numbers: X[Local_Keyboard]=ON. JFugue has also defined DEFAULT, which is set to 64.

Defining Constants

When you're programming music, your main task is to make beautiful sounds - not to be inundated with random and meaningless numbers. You should be able to set the VOLUME and use the FLUTE, without having to remember that VOLUME is 935 and FLUTE is 73.

The command to set a constant is as follows:

		$WORD=DEFINITION
		

Here's an example: $ELEC_GRAND=2. Of course, JFugue has already defined ELECTRIC_GRAND to be 2. But maybe you'd like to use a shorter name, or maybe you have a more memorable name for this instrument, like simply ELEC.

JFugue defines a bunch of constants - around 360! - for things like instrument names, percussion instruments, and controller events. Creating these defintions is the job of the JFugueDefinitions class.

Words that are defined with the Constants command are put into the JFugue Dictionary, ready to be looked up whenever you refer to them.

Constants are also useful in cases where you have settings that you may want to change some day. Suppose you want to play some music with your favorite instrument, the piano. You could definine FAV_INST to be 0, and then you can say I[Fav_Inst] when you want to use it. But if your favorite instrument ever changes, all you have to change in your music string is the definition of FAV_INST; you do not have to change every place where you refer to your favorite instrument.

You can use a constant anyplace where a number would be expected, with the exception of the Octave value (but that's okay, because you can just specify the note itself, with the octave, as a single number), and if you're using a constant for a duration, you have to use decimal duration values (and preceed the duration with a slash, /).

You should place the constant word in square brackets, but depending on the circumstance, the parser will probably still understand the word if you don't use the brackets.

Introducing Patterns

A pattern is a collection of notes that comprise a musical statement. A pattern can represent an entire song, individual parts of a song, or snippets of frequently used music. Patterns may be created from other patterns, and the music in a pattern may be transformed in interesting and creative ways.

Patterns as parts of a song

Patterns may be used to represent parts of a song. Suppose you're writing a standard rock or pop song. You might break your song into the following parts:

Many of these parts share similarities. For example, the chorus will probably be the same throughout the song. The verses will have the same music, even if the words are different. The outro is probably a repetition of the chorus as it fades away.

To program this in JFugue, you can create the sections of music as patterns:

        Pattern intro = new Pattern("music string");
        Pattern verse = new Pattern("music string");
        Pattern chorus = new Pattern("music string");
        Pattern breakdown = new Pattern("music string");
        Pattern outro = new Pattern("music string");
		
Then, you can create the song using those sections. We'll even create a verseAndChorus pattern, since that is repeated three times:
        Pattern verseAndChorus = new Pattern();
        verseAndChorus.add(verse);
        verseAndChorus.add(chorus);

        Pattern song = new Pattern();
        song.add(intro);
        song.add(verseAndChorus,2);  // This adds verseAndChorus twice
        song.add(breakdown);
        song.add(verseAndChorus);
        song.add(outro);
		

You can play the entire song by saying player.play(song);. You may also play the individual sections outside of the song itself: player.play(breakdown);.

Pattern Factories

If you're creating a song that needs a drum track, wouldn't it be cool if you could just make a method call that would instantly give you a Rock rhythm, or an 8-Beat rhythm, or even a Swing rhythm? With JFugue, you can!

A pattern factory gives you a pattern that you can use in your own songs. You can also write your own pattern factories - and if you create your own and place them on the Web, let me know so I can link to you so others around the world can use your rhythms.

A pattern factory call looks like this:


		RockPatternFactory rpf = new RockPatternFactory();
		Pattern rhythm = rpf.getPattern(0);
		
That's it!

RockPatternFactory is supplied with JFugue, and can be found in the org.jfugue.demo package.

Some factories also provide different parts of the same rhythm. For example, RockPatternFactory has a fill-in pattern that can be accessed with getPattern(2);. You could hear all of the different patterns a PatternFactory can produce by calling the pattern factory's getDemo method:


		Player player = new Player();
		RockPatternFactory rpf = new RockPatternFactory();
		Pattern demo = rpf.getDemo();
		player.play(demo);
		
The demo will play all of the different patterns that the factory can produce, added together in one pattern that is returned from getDemo().

Information on writing your own pattern factory is provided below.

Pattern Transformers

One of the coolest things about patterns of music is that you can apply a transformation on them, and get different music based on the same musical base.

What are some things you might want to do to transform a pattern? There are many; here are a few ideas:

The list of potential transformations is limitless, which is why you're able to create your own pattern transformers.

The JFugue package comes with a few pattern transformers. They're all named XxxxPatternTransformer, where Xxxx indicated what they do - for example, IntervalPatternTransformer changes the intervals between notes, DurationPatternTransformer changes the duration of notes, and ReversePatternTransformer reverses a pattern.

Before using a pattern transformer, you have to know what variables they expect. For example, the IntervalPatternTransformer needs to know by how many steps to change the intervals between notes. This information can be found in the comments of the pattern transformer code, or in documentation that accompanies the transformer. There is also a method, getVariables(), that you can call on a transformer. If you print that output, you'll see what is required:


IntervalPatternTransformer ipt = new IntervalPatternTransformer();
String output = ipt.getVariables();
System.out.println(output);
		
If you're writing a music editing program and you want to use pattern transformers, you can use the getVariables() method to get a list of the variables required, which you may then present in your user interface. The output from getVariables() should be easy to parse.

To set a pattern transformer variable, use the setVariable() method. This method takes two arguments. The first is a String representing the name of the variable. You can type the actual string, but to keep with programming best practices, it's best to use the constants provided by the class to represent the string. For example, IntervalPatternTransformer defines a static constant, INTERVAL, which contains the string "Interval". If you mis-type the word INTERVAL when referring to the constant, you'll get a compile-time error that you can fix immediately. But if you happen to mistype the string "Interval", the program will compile cleanly, although it won't work as you expect.


Player player = new Player();
Pattern pattern = new Pattern("music string");
IntervalPatternTransformer ipt = new IntervalPatternTransformer();
ipt.setVariable(IntervalPatternTransformer.INTERVAL, 2);
Pattern transformedPattern = ipt.transform(pattern);
player.play(transformedPattern);
		

Information on writing your own pattern transformer is provided below.

Pattern Tools

Patterns are a great way to manage sections of a musical statement. As you're using patterns, you may realize the need to perform some calculation on a pattern. How long does this pattern play? What is the last voice that was used in this pattern? How many A notes are there in this pattern?

Pattern tools are used to perform calculations across a pattern. Like pattern transformers, they are parser listeners, and they work by parsing the pattern, and performing their calcuations when the parser makes callbacks to the event methods (for example, voiceEvent(Voice voice)).

There is one pattern tools that ships with JFugue. DurationPatternTool lets you know how long a pattern plays. You can use DurationPatternTool as an example for your own tools.

To use a pattern tool, first instantiate the tool, then call its execute method. The execute method takes a pattern as its parameter, and returns an object with the result. You can also get the result of a pattern tool calculation that has already been performed by calling getResult(). Here's an example:


Pattern pattern = new Pattern("music string");
DurationPatternTool dpt = new DurationPatternTool();
System.out.println("Duration of pattern is " + dpt.execute(pattern));
		

Information on writing your own pattern transformer is provided below.

Writing Your Own Pattern Factory

Writing your own Pattern Factory is easy. Simply create a new class that extends PatternFactory, and fill in the getPattern(int whichPattern) and getDemo() methods.

getPattern(int) should return a pattern, and you can return different patterns based on the value passed in. If you're creating an 8-Beat rhythm, for example, you might want to make a 0 return the base rhythm, a 1 return a slightly different base rhythm, a 2 return a breakdown, a 3 return an intro, and a 4 return an outro. Your code might look like this:


public Pattern getPattern(int whichPattern)
{
Pattern pattern = new Pattern();

switch(whichPattern) {
	default,
	case 0 : pattern.setMusicString("notes for base rhythm");
			 break;
	case 1 : pattern.setMusicString("notes for alternate base rhythm");
			 break;
	case 2 : pattern.setMusicString("notes for breakdown");
			 break;
	case 3 : pattern.setMusicString("notes for intro");
			 break;
	case 4 : pattern.setMusicString("notes for outro");
			 break;
}

return pattern;
}
		

You also have to flesh out the getNumberOfPatterns() method. This method returns an integer that indicates how many patterns your factory can produce. Remember to start counting at 0 -- so if your Pattern Factory produces 5 patterns, they should be numbered 0 through 4 in your getPattern() method.

The PatternFactory class automatically creates a demo for your Factory. This is composed of a number of beeps that indicate which pattern will be played (pattern 0 gets no beeps), followed by the pattern. The demo uses getNumberOfPatterns() to determine how many patterns the factory can produce. Use the getDemo() method to get a PatternFactory's demo.

Writing Your Own Pattern Transformer

A PatternTransformer can do some powerful things with your patterns. The ability to modify musical patterns is a unique feature that only JFugue delivers.

To begin, create a new class that extends PatternTransformer. PatternTransformer implements ParserListener. When the Parser object translates musical patterns from strings to data that is more easily understood by the computer, it sends events to ParserListeners.

Your Pattern Transformer will also listen for parsed events. Your transformer can then do interesting things with these events.

The first thing to do is to override the ParserListener methods. There are seven of them, but you don't have to override all of them. Each is implemented in PatternTransformer itself; in there, the method simply adds the event to the return pattern. If you extend PatternTransformer but do not override any of the event methods, you will get a pattern transformer that simply returns the same pattern that went in. These are the seven event methods:


public void voiceEvent(Voice voice)
public void tempoEvent(Tempo tempo)
public void instrumentEvent(Instrument instrument)
public void controllerEvent(Controller controller)
public void noteEvent(Note note)
public void sequentialNoteEvent(Note note)
public void parallelNoteEvent(Note note)
		

If you're creating a Transformer that will modify note values, make sure that all three note methods perform the transformation. For more information on parser listening, see this section.

Add all of your changes to the returnPattern variable. returnPattern is defined by PatternTransformer.java, and it is the pattern that holds the transformed pattern.

Here is an example of a transformer that will always convert all flute instrument changes into saxophones:


public void instrumentEvent(Instrument instrument)
{
	// The Flute is Instrument 73
	// The Soprano_Sax is Instrument 64
	if (instrument.getInstrumentNumber() == 73) {
		instrument.setInstrumentNumber(64);
	}

	returnPattern.addElement(instrument);
}

When you're dealing with Note event, you will always handle both the note itself and its duration as values, not as letters. So, even though you may say C5q to play an C-note, 5th octave, quarter duration, in your noteEvent methods, you'll be dealing with [60]/0.25. This makes it very easy to modify note values and durations, since all you have to do is a little math - you don't have to interpret letters.

Here's an example, straight from DurationPatternTransformer. It changes the duration of notes based on a factor passed in as a variable. For brevity, only the important event callback methods are shown.


public void noteEvent(Note note)
{
	double durationValue = note.getTotalDurationNumber();
	durationValue *= ((Double)getVariable(FACTOR)).doubleValue();
	note.setTotalDurationNumber(durationValue);

	returnPattern.addElement(note);
}

public void sequentialNoteEvent(Note note)
{
	// same stuff as in noteEvent
}

public void parallelNoteEvent(Note note)
{
	// same stuff as in noteEvent
}

In addition to the event callback methods, you have to override getDescription(), which should return a String giving a quick description of what this transformer does.

Next, you have to indicate to the user what variables are required by the transformer. For example, the IntervalPatternTransformer requires that the user tell the transformer by how many intervals to transform a pattern.

To do this, extend the getVariables() method, and return a String that contains the needed information.

There is a format to the getVariables() string that must be followed for consistency. Notice the use of quotes and slashes.

'variable name'/type/description/default
If you need to return multiple Strings, end each String with a \n, the newline character.

Also, be sure to add your strings to the JavaDoc for the getVariables() method as well, so users can learn what your code needs from its documentation.

Here's an example, straight from IntervalPatternTransformer:


/**
 * Returns a string declaring what variables IntervalPatternTransformer
 * can use to perform the transformation.
 * <p>
 * IntervalPatternTransformer requires the following:<br>
 *   <i>'interval'</i> - Integer - Number of intervals by
 *   which to change each note, can be positive or negative.
 *   Default is 1.
 * </p>
 */
public String getVariables()
{
	String returnString = "'interval'/int/Number of intervals "+
						  "by which to change each note, can "+
						  "be positive or negative/1";

	return returnString;
}

Finally, one last thing to do is to create a constructor for your class that defines the default values for your variables. This is important because otherwise, people (including yourself!) who are using your transformer and forget to set the variables will find that their program crashes at runtime.

When you're declaring your own constructor, make sure to call the parent constructor first by using super(). Here's an example from IntervalPatternTransformer:


public IntervalPatternTransformer()
{
	super();
	putVariable(INTERVAL,new Integer(1));
}
		

You're done! When someone wants to use your Transformer, they will have to set the variables that you declared to be important, and then they can call YourPatternTransformer.transform(pattern) to get their transformed pattern!

A quick review of the steps:

  1. 1. Override any of the seven event callback methods
  2. 2. Create a getDescription method that returns a string
  3. 3. Create a getVariables method that returns a string that follows the standard format metioned above
  4. 4. Make sure your constructor initializes the variables used by the transformer

Writing Your Own Pattern Tool

It's pretty easy to make your own Tool to perform a calculation on a given pattern. Like the Pattern Transformer, a Pattern Tool is a ParserListener, so you may override any of the following methods:


public void voiceEvent(Voice voice)
public void tempoEvent(Tempo tempo)
public void instrumentEvent(Instrument instrument)
public void controllerEvent(Controller controller)
public void noteEvent(Note note)
public void sequentialNoteEvent(Note note)
public void parallelNoteEvent(Note note)
		

In addition, like the Pattern Transformer, you have to override getDescription(), which should return a String giving a quick description of what this tool does.

You must create a reset() method. This method simply sets the counters and variables in your tool to their initial states. It is called whenever the tool is executed. By requiring reset(), users can create a PatternTool object once, then re-use it on multiple patterns:


Pattern pattern1 = new Pattern("music string 1");
Pattern pattern2 = new Pattern("music string 2");
DurationPatternTool dpt = new DurationPatternTool();
System.out.println("Duration of pattern 1 is " + dpt.execute(pattern1));

// If execute() didn't call reset(), then the next line might give a bad
// result, because its variables still have calculations from the first
// time it was used
System.out.println("Duration of pattern 2 is " + dpt.execute(pattern2));
		

Finally, you must create a getResult() method. This method returns the answer that the Pattern Tool is meant to calculate. It is called at the end of execute(), and it may also be called as often as you wish to get the result from the calculation, without actually perfoming the entire calculation again:


Pattern pattern = new Pattern("music string");
DurationPatternTool dpt = new DurationPatternTool();
System.out.println("Duration of pattern is " + dpt.execute(pattern));
System.out.println("That value again is " + dpt.getResult());
System.out.println("One more time, without running the calculation: " + dpt.getResult());
        

Parsing and Rendering

When you send a music string to JFugue, the tokens in the string are parsed, or intepreted. These interpreted tokens then go to the renderer, which turns events into MIDI musical events.

Listening to the Parser

When a token is parsed, the parser sends callback events to all parser listeners. You can listen to these events to find out what the parser is interpreting. To listen to events from the parser, your class needs to implement ParserListener and add itself to the parser's list of parser listeners with the addActionListener method.

The Renderer is one example of a parser listener. As each token is parsed, the Renderer gets an event, which it uses to add MIDI evnts to the music sequence.

There are seven callback methods:


public void voiceEvent(Voice voice)
public void tempoEvent(Tempo tempo)
public void instrumentEvent(Instrument instrument)
public void controllerEvent(Controller controller)
public void noteEvent(Note note)
public void sequentialNoteEvent(Note note)
public void parallelNoteEvent(Note note)
		

Notice that there are three different methods for notes: noteEvent, sequentialNoteEvent, and parallelNoteEvent. The method noteEvent is fired when a single note comes through, such as A5q. The method sequentialNoteEvent is fired when the underscore character is used to connect notes, as in A5q_C4q. The method parallelNoteEvent is fired when the plus character is used to connect notes, or when a chord is played, as in A5q+C5q or Cminq.

Idea: a Sheet Music Renderer

The Renderer class takes parser events and turns them into music. Similarly, you could create a SheetmusicRenderer class that would take parser events and turn them into graphics.

Adding new tokens to the Music String

If you find the need to add new tokens to the music string, here's what to do.

In Parser.java, find the bit switch statement, and add an entry for your new token. Make sure your token begins with a character that isn't already used.

Create a new method that will actually do the parsing. You can model this method after something like parseInstrumentElement.

The ultimate result of your parsing method should call a new event callback that you will add to ParserListener.java. For completeness, you should also update ParserListenerAdapter.java and PatternTransformer.java, which both implement ParserListener.

If you'd like to watch the parser as it goes about parsing, turn on tracing: Parser.setTracing(Parser.TRACING_ON);. You can also print new tracing output with the trace method.

Working with MIDI

When you play a pattern of music through JFugue, everything you specified in the Music String is parsed and turned into MIDI events. It is these MIDI events that you hear when you play a song.

Saving your music in MIDI files

You can save the output of your program as a MIDI file. All of the MIDI files available on these pages were created with JFugue programs, the outputs of which were saved to MIDI.

Saving your song as a MIDI file is very easy to do: player.save("filename");. You have to throw a try/catch block around the save method, just in case there's a problem writing the file. Here's a more complete example:


   Player player = new Player();
   Pattern pattern = new Pattern("music string");
   try {
	   player.save(pattern,"filename");
   } catch (Exception e) {
	   e.printStackTrace();
   }
		

You cannot load MIDI data into a Player, because the Player always generates a fresh new sequence based on the Patterns that it is asked to play.

Getting the MIDI sequence

If you ever feel the need to get the MIDI sequence after JFugue has rendered it, you can do it using player.getSequencer();. The Player does not have a setSequencer() method because it always creates a new Sequencer object to play music specified by Patterns.

Sample Programs

One of the best ways to learn something new is to see it in action. The following samples are complete programs that show how to use JFugue.

Example 1: A Simple Song

In this simple song, you'll be introduced to the Music String, which is how music data is represented in JFugue. The Pattern is split across multiple lines so it's easier to read.

import com.innix.jfugue.Player;
import com.innix.jfugue.Pattern;

public class Example1
{
public static void main(String[] args)
{
	Player player = new Player();
	Pattern pattern = new Pattern("T160 I[Cello] "+
		 "G3q G3q G3q Eb3q Bb3i G3q Eb3q Bb3i G3h");
	player.play(song);
}
}
		

Example 2: "Frere Jacques"

In this example, we'll use patterns to easily replicate identical pieces of music. In the sheet music below, you'll notice that there are eight measures, but measures 1 and 2 are duplicates of each other, as are measures 3 and 4, 5 and 6, and 7 and 8. Instead of re-typing the duplicate measures, we can just add that pattern to the song twice.

import com.innix.jfugue.Player;
import com.innix.jfugue.Pattern;

public class FrereJacques
{
public static void main(String[] args)
{
	Player player = new Player();

	// "Frere Jacques"
	Pattern pattern1 = new Pattern("C5q D5q E5q C5q");

	// "Dormez-vous?"
	Pattern pattern2 = new Pattern("E5q F5q G5h");

	// "Sonnez les matines"
	Pattern pattern3 = new Pattern("G5i A5i G5i F5i E5q C5q");

	// "Ding ding dong"
	Pattern pattern4 = new Pattern("C5q G4q C5h");

	// Put it all together
	Pattern song = new Pattern();
	song.add(pattern1);
	song.add(pattern1);
	song.add(pattern2);
	song.add(pattern2);
	song.add(pattern3);
	song.add(pattern3);
	song.add(pattern4);
	song.add(pattern4);

	// Play the song!
	player.play(song);
}
}
		

Example 3: "Frere Jacques" as a round

The previous example showed how to use patterns to replicate similar pieces of music. In this example, we'll turn the whole song into a pattern, so we can replicate the entire song. With this technique, we can create a round.

Notice how in this example, we're adding sections of songs together in a single pattern, as we did in Example 2. In Example 2 the patterns are played in order, but in Example 3 the patterns will be played at the same time. To do this, we add each pattern in a different voice with the V0, V1, and V2 Music String commands. All voices are played simultaneously. The Rw Rw Music String represents two whole-note rests, which are used to stagger the simultaneous patterns so they each start two measures apart.

This example requires the code from Example 2. Replace the "Play the song!" and "player.play(song)" lines in Example 2 with the following program segment.

Click here to listen to the song this program generates: FrereJacques.mid

	Pattern doubleMeasureRest = new Pattern("Rw Rw");

	// Create the first voice
	Pattern round1 = new Pattern("V0 ");
	round1.add(song);

	// Create the second voice
	Pattern round2 = new Pattern("V1 ");
	round2.add(doubleMeasureRest);
	round2.add(song);

	// Create the third voice
	Pattern round3 = new Pattern("V2 ");
	round3.add(doubleMeasureRest);
	round3.add(doubleMeasureRest);
	round3.add(song);

	// Put the voices together
	Pattern roundSong = new Pattern();
	roundSong.add(round1);
	roundSong.add(round2);
	roundSong.add(round3);

	// Play the song!
	player.play(roundSong);
		

Appendix

What's New in JFugue 2.0

JFugue 1.0 introduced the world to JFugue, and gave music programmers an easy way to create music using music strings and patterns, and saving files as MIDI.

JFugue 2.0 improves on the first version, and it introduces the following new features:

Upgrading to JFugue 2.0

If you have used JFugue 1.0 and you want to use JFugue 2.0, you should know the following things:

Instrument names

The following words come pre-defined in the JFugue parser. You can use any of these values to specify an instrument. For example, to play music using the clavinet, you can say I[Clavinet]


PIANO                    0
ACOUSTIC_GRAND           0
BRIGHT_ACOUSTIC          1
ELECTRIC_GRAND           2
HONKEY_TONK              3
ELECTRIC_PIANO           4
ELECTRIC_PIANO_1         4
ELECTRIC_PIANO_2         5
HARPISCHORD              6
CLAVINET                 7
CELESTA                  8
GLOCKENSPIEL             9

MUSIC_BOX                10
VIBRAPHONE               11
MARIMBA                  12
XYLOPHONE                13
TUBULAR_BELLS            14
DULCIMER                 15
DRAWBAR_ORGAN            16
PERCUSSIVE_ORGAN         17
ROCK_ORGAN               18
CHURCH_ORGAN             19

REED_ORGAN               20
ACCORIDAN                21
HARMONICA                22
TANGO_ACCORDIAN          23
GUITAR                   24
NYLON_STRING_GUITAR      24
STEEL_STRING_GUITAR      25
ELECTRIC_JAZZ_GUITAR     26
ELECTRIC_CLEAN_GUITAR    27
ELECTRIC_MUTED_GUITAR    28
OVERDRIVEN_GUITAR        29

DISTORTION_GUITAR        30
GUITAR_HARMONICS         31
ACOUSTIC_BASS            32
ELECTRIC_BASS_FINGER     33
ELECTRIC_BASS_PICK       34
FRETLESS_BASS            35
SLAP_BASS_1              36
SLAP_BASS_2              37
SYNTH_BASS_1             38
SYNTH_BASS_2             39

VIOLIN                   40
VIOLA                    41
CELLO                    42
CONTRABASS               43
TREMOLO_STRINGS          44
PIZZICATO_STRINGS        45
ORCHESTRAL_STRINGS       46
TIMPANI                  47
STRING_ENSEMBLE_1        48
STRING_ENSEMBLE_2        49

SYNTHSTRINGS_1           50
SYNTHSTRINGS_2           51
CHOIR_AAHS               52
VOICE_OOHS               53
SYNTH_VOICE              54
ORCHESTRA_HIT            55
TRUMPET                  56
TROMBONE                 57
TUBA                     58
MUTED_TRUMPET            59

FRENCH_HORN              60
BRASS_SECTION            61
SYNTHBRASS_1             62
SYNTHBRASS_2             63
SOPRANO_SAX              64
ALTO_SAX                 65
TENOR_SAX                66
BARITONE_SAX             67
OBOE                     68
ENGLISH_HORN             69

BASSOON                  70
CLARINET                 71
PICCOLO                  72
FLUTE                    73
RECORDER                 74
PAN_FLUTE                75
BLOWN_BOTTLE             76
SKAKUHACHI               77
WHISTLE                  78
OCARINA                  79

LEAD_SQUARE              80
SQUARE                   80
LEAD_SAWTOOTH            81
SAWTOOTH                 81
LEAD_CALLIOPE            82
CALLIOPE                 82
LEAD_CHIFF               83
CHIFF                    83
LEAD_CHARANG             84
CHARANG                  84
LEAD_VOICE               85
VOICE                    85
LEAD_FIFTHS              86
FIFTHS                   86
LEAD_BASSLEAD            87
BASSLEAD                 87
PAD_NEW_AGE              88
NEW_AGE                  88
PAD_WARM                 89
WARM                     89

PAD_POLYSYNTH            90
POLYSYNTH                90
PAD_CHOIR                91
CHOIR                    91
PAD_BOWED                92
BOWED                    92
PAD_METALLIC             93
METALLIC                 93
PAD_HALO                 94
HALO                     94
PAD_SWEEP                95
SWEEP                    95
FX_RAIN                  96
RAIN                     96
FX_SOUNDTRACK            97
SOUNDTRACK               97
FX_CRYSTAL               98
CRYSTAL                  98
FX_ATMOSPHERE            99
ATMOSPHERE               99

FX_BRIGHTNESS            100
BRIGHTNESS               100
FX_GOBLINS               101
GOBLINS                  101
FX_ECHOES                102
ECHOES                   102
FX_SCI-FI                103
SCI-FI                   103
SITAR                    104
BANJO                    105
SHAMISEN                 106
KOTO                     107
KALIMBA                  108
BAGPIPE                  109

FIDDLE                   110
SHANAI                   111
TINKLE_BELL              112
AGOGO                    113
STEEL_DRUMS              114
WOODBLOCK                115
TAIKO_DRUM               116
MELODIC_TOM              117
SYNTH_DRUM               118
REVERSE_CYMBAL           119

GUITAR_FRET_NOISE        120
BREATH_NOISE             121
SEASHORE                 122
BIRD_TWEET               123
TELEPHONE_RING           124
HELICOPTER               125
APPLAUSE                 126
GUNSHOT                  127

Percussion names

Voice 9 is a special channel that plays percussion sounds instead of musical notes. You can use these percussion sound names in place of a note value when playing music on Voice 9. For example: V9 [Bass_Drum]q would play a bass drum for a quarter duration.

You can play more than one percussion sound at the same time by adding them together, just like you were playing multiple notes at the same time. This example will play a hand clap and a cymbal crash at the same time: V9 [Hand_Clap]q+[Crash_Cymbal_1]q


ACOUSTIC_BASS_DRUM     35
BASS_DRUM              36
SIDE_STICK             37
ACOUSTIC_SNARE         38
HAND_CLAP              39

ELECTRIC_SNARE         40
LOW_FLOOR_TOM          41
CLOSED_HI_HAT          42
HIGH_FLOOR_TOM         43
PEDAL_HI_HAT           44
LOW_TOM                45
OPEN_HI_HAT            46
LOW_MID_TOM            47
HI_MID_TOM             48
CRASH_CYMBAL_1         49

HIGH_TOM               50
RIDE_CYMBAL_1          51
CHINESE_CYMBAL         52
RIDE_BELL              53
TAMBOURINE             54
SPLASH_CYMBAL          55
COWBELL                56
CRASH_CYMBAL_2         57
VIBRASLAP              58
RIDE_CYMBAL_2          59

HI_BONGO               60
LOW_BONGO              61
MUTE_HI_CONGA          62
OPEN_HI_CONGA          63
LOW_CONGA              64
HIGH_TIMBALE           65
LOW_TIMBALE            66
HIGH_AGOGO             67
LOW_AGOGO              68
CABASA                 69

MARACAS                70
SHORT_WHISTLE          71
LONG_WHISTLE           72
SHORT_GUIRO            73
LONG_GUIRO             74
CLAVES                 75
HI_WOOD_BLOCK          76
LOW_WOOD_BLOCK         77
MUTE_CUICA             78
OPEN_CUICA             79

MUTE_TRIANGLE          80
OPEN_TRIANGLE          81

Controller names

The MIDI specification defines a number of controllers that modify how music sounds. You can use any of these controller names with the Controller command. For example, to set the hold pedal, you can say X[Hold_Pedal]=127.

Some of these controller events come in coarse/fine pairs. You can set these controllers separately, or together using the combined controller names.


BANK_SELECT_COARSE          0
MOD_WHEEL_COARSE            1
BREATH_COARSE               2
FOOT_PEDAL_COARSE           4
PORTAMENTO_TIME_COARSE      5
DATA_ENTRY_COARSE           6
VOLUME_COARSE               7
BALANCE_COARSE              8
PAN_POSITION_COARSE         10
EXPRESSION                  11
EFFECT_CONTROL_1_COARSE     12
EFFECT_CONTROL_2_COARSE     13

SLIDER_1                    16
SLIDER_2                    17
SLIDER_3                    18
SLIDER_4                    19

BANK_SELECT_FINE            32
MOD_WHEEL_FINE              33
BREATH_FINE                 34
FOOT_PEDAL_FINE             36
PORTAMENTO_TIME_FINE        37
DATA_ENTRY_FINE             38
VOLUME_FINE                 39
BALANCE_FINE                40
PAN_POSITION_FINE           42
EXPRESSION                  43
EFFECT_CONTROL_1_FINE       44
EFFECT_CONTROL_2_FINE       45

HOLD_PEDAL                  64
HOLD                        64
PORTAMENTO                  65
SUSTENUTO_PEDAL             66
SUSTENUTO                   66
SOFT_PEDAL                  67
SOFT                        67
LEGATO_PEDAL                68
LEGATO                      68
HOLD_2_PEDAL                69
HOLD_2                      69

SOUND_VARIATION             70
VARIATION                   70
SOUND_TIMBRE                71
TIMBRE                      71
SOUND_RELEASE_TIME          72
RELEASE_TIME                72
SOUND_ATTACK_TIME           73
ATTACK_TIME                 73
SOUND_BRIGHTNESS            74
BRIGHTNESS                  74
SOUND_CONTROL_6             75
CONTROL_6                   75
SOUND_CONTROL_7             76
CONTROL_7                   76
SOUND_CONTROL_8             77
CONTROL_8                   77
SOUND_CONTROL_9             78
CONTROL_9                   78
SOUND_CONTROL_10            79
CONTROL_10                  79

GENERAL_PURPOSE_BUTTON_1    80
GENERAL_BUTTON_1            80
BUTTON_1                    80
GENERAL_PURPOSE_BUTTON_2    81
GENERAL_BUTTON_2            81
BUTTON_2                    81
GENERAL_PURPOSE_BUTTON_3    82
GENERAL_BUTTON_3            82
BUTTON_3                    82
GENERAL_PURPOSE_BUTTON_4    83
GENERAL_BUTTON_4            83
BUTTON_4                    83

EFFECTS_LEVEL               91
EFFECTS                     91
TREMULO_LEVEL               92
TREMULO                     92
CHORUS_LEVEL                93
CHORUS                      93
CELESTE_LEVEL               94
CELESTE                     94
PHASER_LEVEL                95
PHASER                      95

DATA_BUTTON_INCREMENT       96
DATA_BUTTON_INC             96
BUTTON_INC                  96
DATA_BUTTON_DECREMENT       97
DATA_BUTTON_DEC             97
BUTTON_DEC                  97

NON_REGISTERED_COARSE       98
NON_REGISTERED_FINE         99
REGISTERED_COARSE           100
REGISTERED_FINE             101

ALL_SOUND_OFF               120
ALL_CONTROLLERS_OFF         121
LOCAL_KEYBOARD              122
ALL_NOTES_OFF               123
OMNI_MODE_OFF               124
OMNI_OFF                    124
OMNI_MODE_ON                125
OMNI_ON                     125
MONO_OPERATION              126
MONO                        126
POLY_OPERATION              127
POLY                        127

Events in the MIDI specification take bytes as a value, but some controllers can have a wider range of settings than is available in a byte. These controllers have a coarse and a fine setting.

However, when you want to set something like VOLUME, you shouldn't have to decompose the volume you want to set into a high byte and a low byte, and then set two controllers. With JFugue's Combined Controllers, you can simply say X[Volume]=nnnn, where nnnn is some value between 0 and 214-1, or 16383. JFugue will figure out how much to set the coarse and fine controllers on its own (and, it will ultimately generate two separate Controller events - but you don't have to worry about that unless you're interacting directly with the parser).


BANK_SELECT                16383
MOD_WHEEL                  161
BREATH                     290
FOOT_PEDAL                 548
PORTAMENTO_TIME            677
DATA_ENTRY                 806
VOLUME                     935
BALANCE                    1064
PAN_POSITION               1322
EXPRESSION                 1451
EFFECT_CONTROL_1           1580
EFFECT_CONTROL_2           1709
NON_REGISTERED             12770
REGISTERED                 13028

Other predefined constants

JFugue defines the following constants for your convenience. You can use them as values for setting controllers, as in X[Hold_Pedal]=ON.


ON                         127
OFF                        0
DEFAULT                    64