Java MIDI sequencer

G

gerrymcc

Hello, I've got the following program, which is working fine as far as
it goes. I've included a pile of System.out.println() lines to help
me understand what is going on, and am confused by some of the output.
As far as I understand it, a Sequence has a length measured in
'ticks', and so does a Sequencer (I can't see why a Sequencer should).
Since the Sequence is what gets actually played, and is loaded into
the Sequencer, why does the Sequencer have a completely different tick
length from the Sequence? Also, it doesn't seem to be possible to
start the Sequencer at any point other than the start, even though
there is a method for moving to an arbitrary point?? I'm guessing
that it's important to understand these bits because it seems that if
I start() playback, the program should be able to know when it has
completed playing the Sequence, and stop() the Sequencer.
By the way, are there any good books on music programming, the most
widely used language for it, etc. It's kinda fun when it starts to
work :)

Thanks very much for any help,
Gerard



//import javax.swing.*;

//import javax.swing.event.*;
import javax.sound.midi.*;
import java.util.Vector;

//import java.io.IOException;


public class myPlayback{

static Sequencer sequencer;
static Sequence sequence;
static Synthesizer synthesizer;
static Instrument instruments[];
// static ChannelData channels[];

static final int NOTEON = 144;
static final int NOTEOFF = 128;


static Track track, track2;
static NoteSpecies2 [][] duplicate = new NoteSpecies2[3][2];
static NoteSpecies2 [] CF = new NoteSpecies2[3];


public static void main( String [] args){

try {
if (synthesizer == null) {
if ((synthesizer = MidiSystem.getSynthesizer()) ==
null) {
System.out.println("getSynthesizer() failed!");
return;
}
}
synthesizer.open();
sequencer = MidiSystem.getSequencer();
sequence = new Sequence(Sequence.PPQ, 10);
} catch (Exception ex) { ex.printStackTrace(); return; }

Soundbank sb = synthesizer.getDefaultSoundbank();
if (sb != null) {
instruments =
synthesizer.getDefaultSoundbank().getInstruments();
synthesizer.loadInstrument(instruments[0]);
}
MidiChannel midiChannels[] = synthesizer.getChannels();
// channels = new ChannelData[midiChannels.length];
// for (int i = 0; i < channels.length; i++)
// channels = new ChannelData(midiChannels, i);


NoteSpecies2 aNote = new NoteSpecies2();
aNote.setKey(0); aNote.setDuration(1.0);
duplicate[0][0] = aNote;

aNote = new NoteSpecies2();
aNote.setKey(-1); aNote.setDuration(1.0);
duplicate[0][1] = aNote;

aNote = new NoteSpecies2();
aNote.setKey(0); aNote.setDuration(0.5);
duplicate[1][0] = aNote;

aNote = new NoteSpecies2();
aNote.setKey(1); aNote.setDuration(0.5); aNote.setAcc(3);
duplicate[1][1] = aNote;

aNote = new NoteSpecies2();
aNote.setKey(0); aNote.setDuration(1.0);
duplicate[2][0] = aNote;

aNote = new NoteSpecies2();
aNote.setKey(-2); aNote.setDuration(2.0);
CF[0] = aNote;

aNote = new NoteSpecies2();
aNote.setKey(-2); aNote.setDuration(2.0);
CF[1] = aNote;


try {
sequence = new Sequence(Sequence.PPQ, 10);
} catch (Exception ex) { ex.printStackTrace(); }

track = sequence.createTrack();
track2 = sequence.createTrack();

makeSequence();
System.out.println( "track: " + track.toString());
System.out.println(" track size: " + track.size());
System.out.println(" track length in ticks: " + track.ticks());

System.out.println( "sequence resolution: " +
sequence.getResolution());
System.out.println( "sequence TickLength: " +
sequence.getTickLength());


try {
sequencer.open();
sequencer.setSequence(sequence);
} catch (Exception ex) { ex.printStackTrace(); }

System.out.println("sequencer: " + sequencer.toString());
System.out.println("tempo: " + sequencer.getTempoInBPM());
System.out.println("sequencerLength: " + sequencer.getTickLength());
System.out.println("sequencerPos before start: " +
sequencer.getTickPosition());

sequencer.start();
/*
while(sequencer.getTickPosition() < sequencer.getTickLength()){
if( sequencer.getTickPosition()%40 == 0)
System.out.println("next bar");
}
if(sequencer.getTickPosition() == sequencer.getTickLength())
System.out.println("finished");
*/

}


public static void createAnEvent(int type, int channel, int
keyNum, long timeInCrotchets, int t) {
ShortMessage message = new ShortMessage();
if( t==1){
try {
long tick = timeInCrotchets *
sequence.getResolution();
//For channel messages, the upper four bits of the
status byte
//are specified by a command value and the lower
four bits are
//specified by a MIDI channel number.
//e.g.(NOTEON+channel 1, keyNumber, velocity)
message.setMessage(type+channel, keyNum, 96);
System.out.println( "ShortMessage: " +
message.toString());
System.out.println(" message length: " +
message.getLength());
MidiEvent event = new MidiEvent(message, tick);
System.out.println(" event: " + event.toString());
System.out.println(" event's getTick(time): " +
event.getTick());
track.add(event);
} catch (Exception ex) { ex.printStackTrace(); }
}
else if( t ==2){
try {
long tick = timeInCrotchets * sequence.getResolution();
message.setMessage(type+channel, keyNum, 96);
System.out.println( "ShortMessage: " +
message.toString());
System.out.println(" message length: " +
message.getLength());
MidiEvent event = new MidiEvent(message, tick);
System.out.println(" event: " + event.toString());
System.out.println(" event's getTick(time): " +
event.getTick());
track2.add(event);
} catch (Exception ex) { ex.printStackTrace(); }
}
}

public static void makeSequence(){
//double tempo = 120.0;
long newTime = 0L, time = 0L;
int noteNum = 0;
long barTime = 4; // 4 crotchets per bar
//long barTime = (long) (4 * (60.0/tempo) * 1000); if we need to know
length in milliseconds
NoteSpecies2 aNote;

// create a sequence out of the student part
for( int i=0; i<duplicate.length; i++)
for( int j=0; j<duplicate.length; j++){
if( duplicate[j] != null){
aNote = duplicate[j];
System.out.println( "key: " + aNote.getKey());
System.out.println( "time: " + time);
noteNum = convertNoteNum( aNote);
createAnEvent( NOTEON, 0, noteNum, time, 1);
newTime = time + (long)(aNote.getDuration() * barTime);
createAnEvent( NOTEOFF, 0, noteNum, newTime, 1);
time = newTime;
}
}
//create a sequence from the given part
time = 0L;
newTime = 0L;
for( int i=0; i<CF.length; i++){
if( CF != null){
aNote = CF;
noteNum = convertNoteNum( aNote);
createAnEvent( NOTEON, 1, noteNum, time, 2);
newTime = time + (long) (aNote.getDuration() * barTime);
createAnEvent( NOTEOFF, 1, noteNum, newTime, 2);
time = newTime;
}
}

}


public static int convertNoteNum( NoteSpecies2 aNote){
int num;
num = aNote.getKey();
switch( num)
{
case -2: num = 55; break;
case -1: num = 57; break;
case 0: num = 59; break;
case 1: num = 60; break;
//etc
}
if( aNote.getAcc() == 1) num--;
if( aNote.getAcc() == 3) num++;
return num;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Java matrix problem 3
Java 1
Implementing Many Stacks in the Same Program 1
Java MIDI message problem 0
Help capturing MIDI stream to file ... 1
midi file parser 1
midi file toolkit 0
Midi-Sound in Java 1.5? 2

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top