Band Machine
Band machine is an algorithmic
band. A kind of Band in a Java Box. It produces rhythm
section jMusic scores for Drum Kit, Bass, and Piano. You can
choose which parts paly, the style if music generated, the
length of the score, and wheather or not to have a fade in
or fade out. Band Machine will do the rest (like it or
not!). If you don't like it - edit it.
Band Machine appears like this
when run:
This demo is a good example of
the FadeIn and FadeOut jm music methods. Andrew T wrote them
for this program.
This program was written by
Andrew Troedson.
Here are the source files - all
classes are required.
Click here to view source -
BandMachine.java
Click here to view source -
BandMachineGUI.java
Click here to view source -
BassMachine.java
Click here to view source -
DrumMachine.java
Click here to view source -
PianoMachine.java
Click here to view source -
ChordProgression.java
Click here to view source -
ProbabilityTest.java
Click here to view source -
PhraseTools.java
Click here to view source -
CPhraseTools.java
To hear the result play the
MIDI file below.
Andrew Troedson's
comments:
Band Machine is a composition
engine which draws on a series of other tools to generate
music using a mixture of algorithmic and combinational
processes. It also allows for the user to define a number of
settings which have an important effect on the
outcome.
Technicalities
Utilizing the jMusic structure,
Band Machine incorporates several different tools whose
relationships are shown in Figure 3.1 below:
The main class,
BandMachine.java, draws upon the ChordProgression class to
establish the root and tonality of the next chord, and then
uses this information to transpose the phrases which it
receives from the Piano, Bass and Drum Machines as
appropriate. The class BandMachineGUI.java provides a GUI
interface for the BandMachine tool which allows for easy
selection of a variety of settings, and it is actually this
class that should be run.
The ChordProgression tool
selects the next chord in a progression based on the root
and the tonality (i.e. whether it is major or minor) of the
previous chord. It is based on a probability table which
gives the probability of any major or minor chord occurring
after the specified chord. The different chord styles (ROCK,
SWING and JAZZ) are simply representative of different
probability table settings. The ChordProgression class uses
the ProbabilityTest tool to make all its probability-based
decisions.
The Piano, Bass and Drum
Machines each produce phrases (or CPhrases) of the
particular instrument that they represent. The PianoMachine
and BassMachine do this in a combinational manner as each
have a list of both major and minor phrases which they
choose from as appropriate (i.e. as fits the selected style
for that instrument). The DrumMachine produces its phrases
algorithmically &endash; again by using a series of
probability-based rules.
The default name of the
generated MIDI file is "bandmachine.mid", although this can
be easily changed using the BandMachineGUI interface.
Observations
One thing that was especially
noticeable with the ChordProgression tool was that the best
results were achieved when the rules were set to restrict
the possible chords to only about 8 of the 24 possible
options. Any more than this and the resulting chord
progressions became somewhat unstable as the root (or key)
became confused. This again is logical as most pieces of
music are based around only a small number of chords
-especially rock music that is most commonly based on four
chord riffs which repeat for the duration of a song.
Another important point can be
made about the decision to treat the PianoMachine and
BassMachine combinatorially. Although (as was pointed out in
the use of this technique in Mozart's Dice Game) using this
method tends to restrict the possibilities of the final
composition, it is the easiest way to ensure that the result
sounds "correct". Also, because of the algorithmic nature of
both the chord progressions produced by the ChordProgression
tool, and the drum phrases created by the DrumMachine, the
repetitive nature of the combinatorial PianoMachine and
BassMachine phrases tends to be somewhat hidden. This is
further helped by the option to select different styles for
each instrument, and the ability to "mix and match" these
styles.
As with the wordMusic tool,
further development of BandMachine is definitely feasible.
Enhancements could be made both within and above the
existing structure such as: the creation of a wider variety
of instruments and styles; the taking into account of voice
leading; the enabling of individual instrument machines to
interact with each other; and the conversion of the
PianoMachine and BassMachine so that they generate phrases
algorithmically rather than combinatorially. These are all
possibilities, and each would provide various challenges in
their implementation. However, this basic model demonstrates
some of the possibilities and issues that can arise from
both the combinatorial and the algorithmic methods of
generating music.
Take a look at the GUI.
The code:
Let's have a closer
look.
/* --------------------
* BANDMACHINE - a class that creates a piece of music
* using the DrumMachine, BassMachine and PianoMachine,
* as well as the ChordProgression class
* @author Andrew Troedson
* ---------------------
*/
import jm.music.data.*;
import jm.JMC;
import jm.midi.SMF;
public final class BandMachine implements JMC{
public static void compose(int pieceLength,
double fadeInLength,
double fadeOutLength,
String progressionStyle,
boolean pianoPart,
String pianoStyle,
boolean bassPart,
String bassStyle,
boolean drumsPart,
String drumsStyle,
String[] firstChord,
String[] lastChord,
String fileName){
System.out.println("BAND MACHINE STATS:");
System.out.println("Piece length: " + pieceLength);
System.out.println("fade in over " + fadeInLength + " bars");
System.out.println("fade out over " + fadeOutLength + " bars");
System.out.println(progressionStyle + " style chord progression");
if (pianoPart) {System.out.println(pianoStyle + " piano part");}
if (bassPart) {System.out.println(bassStyle + " bass part");}
if (drumsPart) {System.out.println(drumsStyle + " drum part");}
System.out.println("First chord: " + firstChord[0] + " " + firstChord[1]);
System.out.println("Last chord: " + lastChord[0] + " " + lastChord[1]);
System.out.println("Output file: " + fileName);
//Create the data objects we want to use
Score score = new Score("MainScore");
//Parts can have a name, channel, and instrument.
Part piano = new Part("Piano", 0, PIANO);
Part bass = new Part("Bass", 1, BASS);
Part drums = new Part("Drums",9);
int progressionLength = pieceLength;
//set the root and tonality of the first bar
int root = Integer.parseInt(firstChord[0]);
String tonality = firstChord[1];
for (int j=0; j<progressionLength; j++){
//don't get a new chord for the first bar
if (j>0) {
String[] nextChord = ChordProgression.nextChord(root, tonality, progressionStyle);
root = Integer.parseInt(nextChord[0]);
tonality = nextChord[1];
}
//set the last chord
if (j == progressionLength - 1) {
root = Integer.parseInt(lastChord[0]);
tonality = lastChord[1];
}
System.out.println(root + " " + tonality);
if (pianoPart) {
CPhrase nextBar = PianoMachine.getBar(tonality, pianoStyle);
nextBar.setStartTime((float)(j*4));
nextBar.transpose(root);
piano.addCPhrase(nextBar);
}
if (bassPart) {
Phrase nextBassBar = BassMachine.getBar(tonality, bassStyle);
nextBassBar.setStartTime((float)(j*4));
nextBassBar.transpose(root);
bass.addPhrase(nextBassBar);
}
if (drumsPart) {
CPhrase nextDrumBar = DrumMachine.getBar(drumsStyle);
nextDrumBar.setStartTime((float)(j*4));
drums.addCPhrase(nextDrumBar);
}
}
//add part (instrument) to the score
score.addPart(piano);
score.addPart(bass);
score.addPart(drums);
score.fadeIn(fadeInLength);
score.fadeOut(fadeOutLength);
//OK now we test SMF write and read
Write.midi(score, filename);
}
}
|
This is the main
BandMachine class which is called by the BandMachineGUI
class. The class above coordinates all the individual
algorithmic generators - DrumMachine, Piano Machine, and
BassMachine. There is not room in this tutorial to show all
the code, check it out for yourself from the links
above.
|