audio MIDI Music Algorithms Interfaces Programming Acoustics Context
> Audio > Musical Data > Melody and Accompaniment    
 
   

Melody and Accompaniment

This tutorial will look at a file which uses two different synthesis instruments.
One for a stochastic melody and the other for an chordal accompaniment.

This is what the result of this tutorial file can sound like:

Click here to view the source file..

Let's have a closer look:
/**
* An example of simple audio rendering of a non-trivial jMusic score
* @author Andrew R. Brown
*/

 
import jm.JMC;
import jm.music.data.*;
import jm.util.*;
import jm.audio.*;
 
public class MelodyAndAccomp implements JMC{
//----------------
// Class Attributes
//----------------

private Score s = new Score("AU demo");
private Part p1 = new Part("Melody", 0);
private Part p2 = new Part("Chords", 1);
private int sampleRate = 8000;
private Instrument[] insts = {new SineInst(sampleRate),
new TriangleInst(sampleRate)};
private int bars = 4; //measures in American
//---------------------
// required main method
//---------------------

private static void main(String[] args) {
new MelodyAndAccomp();
}


In this tutorial we define two instruments, the triangleInst and SineInst
 This is because we are going to use a different sound for each of the two parts (SineInst for the melody and TriangleInst for the chords).
 When we declare these, we store them in an Instrument array called insts.
 This will be used later.

Note also that the Part constructors are different - they do not specify a channel.
 This is because we are not using MIDI in this program (if we were using both MIDI as well as audio we could leave them in there. Infact,
even if we aren't using MIDI at all, there's not difference in the output if you specify a channel - it's irrelevant!).
 The instrument numbers for these parts are relative to the insts array - the SineInst being instrument 0, and the TriangleInst being instrument 1.
 We tell the audio render to use this array to define the instruments later (when we actually 'render' ut, of course - see the last section of this tutorial).

	//------------------
// Constructor
//------------------

public MelodyAndAccomp() {
makeMelody();
makeChords();
completeScore();
renderAudio();
}
The constructor is extremely simple - it simply runs the following methods in the appropriate order.
	//-------------------
// Methods
//-------------------


// Create the stochastic melodic phrase

private void makeMelody() {
Phrase phr = new Phrase();
int temp, newPitch; //variable to store random number
int[] mode = {0,2,4,5,7,9,11,12}; //major scale degrees
int prevPitch = 60; //start on middle C

// create a melody of 25 randomly pitched quavers
// within C major

for(short i=0;i<bars*8-3;){
// generate a random number up to two octaves
// (or so) above middle C

temp = (int)(Math.random()*14 - 7);
// smooth the melodic contour
newPitch = prevPitch + temp;
// check that it is a note in the mode
// (C major in this case)

for (short j=0; j< mode.length; j++) {
if ( newPitch%12 == mode[j]) {
// if it is then add it to the
// phrase and move to the next
// note in the phrase

if(i == bars*8-4) {
Note n = new Note(newPitch, M,
(int)(Math.random()*50+60));
phr.addNote(n);
} else {
Note n = new Note(newPitch, Q,
(int)(Math.random()*50+60));
phr.addNote(n);
}
prevPitch = newPitch;
i++;
}
}
}
// add the phrase to part 1
p1.addPhrase(phr);
}

//make the chordal accompaniment
private void makeChords() {
// create a CPhrase
CPhrase cp = new CPhrase(0.0);
// Choose one of three minum chords at random, 5 times
for(short i=0;i<bars*2;i++) {
int x = (int)(Math.random()*3);
System.out.println("chord var x is " + x);
if (x==0) {
int[] pitchArray = {c3,e3,g3};
cp.addChord(pitchArray, SQ);
cp.addChord(pitchArray, Q);
cp.addChord(pitchArray, C);
cp.addChord(pitchArray, SQ);
} else if (x==1) {
int[] pitchArray = {d3,f3,a3};
cp.addChord(pitchArray, M);
} else {
int[] pitchArray = {b2,d3,g3};
cp.addChord(pitchArray, C);
cp.addChord(pitchArray, C);
}
}
// add the phrase to part 2
p2.addCPhrase(cp);
}

// combine parts into a score
private void completeScore() {
s.addPart(p1);
s.addPart(p2);
} size="+1" face="Courier">
The above methods should be relatively easy to understand, and are fairly well commented.
  After running these methods we will have a completed score....

//save as an au audio file
private void renderAudio() {
Write.au(s, "Melody_and_Accomp.au", insts);
}
}

 ...which we can then send to Write.au(), specifying that it should use the Instruments in inststo render the appropriate sounds.  
This successfully gives us an .au file of our piece!  Simple!

 

jMusic Australia Council Queensland University of Technology Sitemap Contact Home Home http://www.qut.com http://explodingart.com/jmusic http://www.ozco.gov.au

Digital Instrument making Home