StaticKit: A Drum Kit as a Static Class
This class creates a simple
drum rhythm. Its purpose is mainly to show how a program can
be written with several static methods in the one class.
This allows some complexity to be moved out of the main()
method when code length gets a bit long. The notion of
things being 'static' in Java can take a few attempts to
fully understand, and hopefully this tutorial will provide
one more step along the way.
A thing in Java which is
declared to be static belongs only to the class it is in and
cannot be instantiated (no copies of it can be made). Thus,
if you only require (or want) one copy of a variable or
method it can be declared static - perhaps think of it as
always in one place. In this example there are static
methods which can be called without instantiating
them.
This is what the result sounds
like:
Click here to view source ..
Let's have a closer
look.
import jm.JMC;
import jm.music.data.*;
import jm.midi.*;
import jm.music.tools.*;
import jm.util.*;
/**
* An example which generates a drum kit pattern
* and writes to a MIDI file called StaticKit.mid
* This version uses static methods in the one class.
* @author Andrew Brown
*/
public final class StaticKit implements JMC{
public static void main(String[] args){
Score pattern1 = new Score("Static class example");
Part drums = new Part("Drums",0, 9); // 9 = MIDI channel 10
Phrase phrBD = new Phrase();
Phrase phrSD = new Phrase();
Phrase phrHH = new Phrase();
CPhrase phrEnd = new CPhrase();
|
The class starts in the normal
way by importing, class declaration, and creating the main()
method. The main method itself is always static, that is
because we don't want more than one main() method, that
would make no sense,the program can only start in one place.
we next instantiate the jMusic Score, Part, Phrase, and
CPhrase classes. In this section we lastly communicate with
the user.
//calling static methods below
phrBD = KickPattern();
phrSD = SnarePattern();
phrHH = HatsPattern();
phrEnd = EndPattern();
|
In this section of the class
each of the phrase generation methods are called. Because we
are calling them directly within the class, rather than
calling them from an instance of the class, each of these
methods needs to be static, as we will see below that they
are.
// loop the drum pattern
int loopNum = 7;
phrBD.loop(loopNum);
phrSD.loop(loopNum);
phrHH.loop(loopNum);
// add phrases to the instrument (part)
drums.addPhrase(phrBD);
drums.addPhrase(phrSD);
drums.addPhrase(phrHH);
drums.addCPhrase(phrEnd);
// add the drum part to a score.
pattern1.addPart(drums);
// write the score to a MIDIfile
Write.midi(pattern1, "StaticKit.mid");
}
|
The rest of the main()
method proceeds in a standard fashion. The drum phrases are
looped then packed into a jMusic score structure for export
as a MIDI file.
private static Phrase KickPattern() {
// make bass drum
Phrase phrase = new Phrase(0.0);
for(int i=0;i<4;i++){
Note note = new Note(36, C);
phrase.addNote(note);
Note rest = new Note(REST, C);
phrase.addNote(rest);
}
return phrase;
}
|
The next method in this
class is the KickPattern() method. This method is declared
static so we can call it directly from the same class
without having to put it in another class and instantiate
that class, blah, blah, blah... The only other feature to
look out for is that when the Phrase is declared in this
method it is given a start time of 0.0, the phrase declared
above had none because we knew it would be overwritten with
this phrase.
Each of the snarePattern and
hihatPattern methods look very similar to this one, so we
won't show them here.
private static CPhrase EndPattern() {
// make crash ending
CPhrase cphrase = new CPhrase();
int[] pitchArray1a = {36,49}; // kick and crash cymbal
cphrase.addChord(pitchArray1a, SB);
return cphrase;
}
|
The EndPattern() method is
different in two ways. Firstly, it uses a CPhrase rather
than a Phrase so that we can conveniently have have two
drums sounding together. Secondly, the CPhrase is declared
with no startTime argument. This means that when it is added
to the Part it will be placed at the end of the other
phrases. This is also convenient because it allows us to
make the earlier patterns of any length or have any number
of loops and the CPhrase will always be placed at the
end.
|