Results 1 to 5 of 5

Thread: Midi

  1. #1
    Maya is offline Member
    Join Date
    Feb 2011
    Posts
    9
    Rep Power
    0

    Default Midi

    Hi,

    I am new to MIDI and I am trying to learn it. I am following examples from java nutshell. Here is an example, and no matter what modifications I am doing to it, I get the same error. Could you please go through this example and let me know what modifications are to be performed for getting a results
    P.S: the error is Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
    at expiano.main(expiano.java:52)




    import java.io.File;
    import java.io.IOException;

    import javax.sound.midi.InvalidMidiDataException;
    import javax.sound.midi.MetaEventListener;
    import javax.sound.midi.MetaMessage;
    import javax.sound.midi.MidiEvent;
    import javax.sound.midi.MidiSystem;
    import javax.sound.midi.MidiUnavailableException;
    import javax.sound.midi.Sequence;
    import javax.sound.midi.Sequencer;
    import javax.sound.midi.ShortMessage;
    import javax.sound.midi.Synthesizer;
    import javax.sound.midi.Track;

    public class expiano {
    // These are some MIDI constants from the spec. They aren't defined
    // for us in javax.sound.midi.
    public static final int DAMPER_PEDAL = 64;

    public static final int DAMPER_ON = 127;

    public static final int DAMPER_OFF = 0;

    public static final int END_OF_TRACK = 47;

    public static void main(String[] args) throws MidiUnavailableException, InvalidMidiDataException,
    IOException {
    int instrument = 0;
    int tempo = 120;
    String filename = null;

    // Parse the options
    // -i <instrument number> default 0, a piano. Allowed values: 0-127
    // -t <beats per minute> default tempo is 120 quarter notes per minute
    // -o <filename> save to a midi file instead of playing
    int a = 0;
    while (a < args.length) {
    if (args[a].equals("-i")) {
    instrument = Integer.parseInt(args[a + 1]);
    a += 2;
    } else if (args[a].equals("-t")) {
    tempo = Integer.parseInt(args[a + 1]);
    a += 2;
    } else if (args[a].equals("-o")) {
    filename = args[a + 1];
    a += 2;
    } else
    break;
    }

    char[] notes = args[a].toCharArray();

    // 16 ticks per quarter note.
    Sequence sequence = new Sequence(Sequence.PPQ, 16);

    // Add the specified notes to the track
    addTrack(sequence, instrument, tempo, notes);

    if (filename == null) { // no filename, so play the notes
    // Set up the Sequencer and Synthesizer objects
    Sequencer sequencer = MidiSystem.getSequencer();
    sequencer.open();
    Synthesizer synthesizer = MidiSystem.getSynthesizer();
    synthesizer.open();
    sequencer.getTransmitter().setReceiver(synthesizer .getReceiver());

    // Specify the sequence to play, and the tempo to play it at
    sequencer.setSequence(sequence);
    sequencer.setTempoInBPM(tempo);

    // Let us know when it is done playing
    sequencer.addMetaEventListener(new MetaEventListener() {
    public void meta(MetaMessage m) {
    // A message of this type is automatically sent
    // when we reach the end of the track
    if (m.getType() == END_OF_TRACK)
    System.exit(0);
    }
    });
    // And start playing now.
    sequencer.start();
    } else { // A file name was specified, so save the notes
    int[] allowedTypes = MidiSystem.getMidiFileTypes(sequence);
    if (allowedTypes.length == 0) {
    System.err.println("No supported MIDI file types.");
    } else {
    MidiSystem.write(sequence, allowedTypes[0], new File(filename));
    System.exit(0);
    }
    }
    }

    static final int[] offsets = { // add these amounts to the base value
    // A B C D E F G
    -4, -2, 0, 1, 3, 5, 7 };

    /*
    * This method parses the specified char[] of notes into a Track. The musical
    * notation is the following: A-G: A named note; Add b for flat and # for
    * sharp. +: Move up one octave. Persists. -: Move down one octave. Persists.
    * /1: Notes are whole notes. Persists 'till changed /2: Half notes /4:
    * Quarter notes /n: N can also be, 8, 16, 32, 64. s: Toggle sustain pedal on
    * or off (initially off)
    * >: Louder. Persists <: Softer. Persists .: Rest. Length depends on current
    * length setting Space: Play the previous note or notes; notes not separated
    * by spaces are played at the same time
    */
    public static void addTrack(Sequence s, int instrument, int tempo, char[] notes)
    throws InvalidMidiDataException {
    Track track = s.createTrack(); // Begin with a new track

    // Set the instrument on channel 0
    ShortMessage sm = new ShortMessage();
    sm.setMessage(ShortMessage.PROGRAM_CHANGE, 0, instrument, 0);
    track.add(new MidiEvent(sm, 0));

    int n = 0; // current character in notes[] array
    int t = 0; // time in ticks for the composition

    // These values persist and apply to all notes 'till changed
    int notelength = 16; // default to quarter notes
    int velocity = 64; // default to middle volume
    int basekey = 60; // 60 is middle C. Adjusted up and down by octave
    boolean sustain = false; // is the sustain pedal depressed?
    int numnotes = 0; // How many notes in current chord?

    while (n < notes.length) {
    char c = notes[n++];

    if (c == '+')
    basekey += 12; // increase octave
    else if (c == '-')
    basekey -= 12; // decrease octave
    else if (c == '>')
    velocity += 16; // increase volume;
    else if (c == '<')
    velocity -= 16; // decrease volume;
    else if (c == '/') {
    char d = notes[n++];
    if (d == '2')
    notelength = 32; // half note
    else if (d == '4')
    notelength = 16; // quarter note
    else if (d == '8')
    notelength = 8; // eighth note
    else if (d == '3' && notes[n++] == '2')
    notelength = 2;
    else if (d == '6' && notes[n++] == '4')
    notelength = 1;
    else if (d == '1') {
    if (n < notes.length && notes[n] == '6')
    notelength = 4; // 1/16th note
    else
    notelength = 64; // whole note
    }
    } else if (c == 's') {
    sustain = !sustain;
    // Change the sustain setting for channel 0
    ShortMessage m = new ShortMessage();
    m
    .setMessage(ShortMessage.CONTROL_CHANGE, 0, DAMPER_PEDAL, sustain ? DAMPER_ON
    : DAMPER_OFF);
    track.add(new MidiEvent(m, t));
    } else if (c >= 'A' && c <= 'G') {
    int key = basekey + offsets[c - 'A'];
    if (n < notes.length) {
    if (notes[n] == 'b') { // flat
    key--;
    n++;
    } else if (notes[n] == '#') { // sharp
    key++;
    n++;
    }
    }

    addNote(track, t, notelength, key, velocity);
    numnotes++;
    } else if (c == ' ') {
    // Spaces separate groups of notes played at the same time.
    // But we ignore them unless they follow a note or notes.
    if (numnotes > 0) {
    t += notelength;
    numnotes = 0;
    }
    } else if (c == '.') {
    // Rests are like spaces in that they force any previous
    // note to be output (since they are never part of chords)
    if (numnotes > 0) {
    t += notelength;
    numnotes = 0;
    }
    // Now add additional rest time
    t += notelength;
    }
    }
    }

    // A convenience method to add a note to the track on channel 0
    public static void addNote(Track track, int startTick, int tickLength, int key, int velocity)
    throws InvalidMidiDataException {
    ShortMessage on = new ShortMessage();
    on.setMessage(ShortMessage.NOTE_ON, 0, key, velocity);
    ShortMessage off = new ShortMessage();
    off.setMessage(ShortMessage.NOTE_OFF, 0, key, velocity);
    track.add(new MidiEvent(on, startTick));
    track.add(new MidiEvent(off, startTick + tickLength));
    }
    }

  2. #2
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    It would help to know which line is line 52 in the file expiano.java. Put a try/catch around that line and then do a printStackTrace on the exception. That will help understand why the array (whichever it is) is zero length. My guess is that 'notes' is zero length.
    Last edited by toadaly; 02-22-2011 at 07:11 PM.

  3. #3
    Maya is offline Member
    Join Date
    Feb 2011
    Posts
    9
    Rep Power
    0

    Default

    import java.io.File;
    import java.io.IOException;

    import javax.sound.midi.InvalidMidiDataException;
    import javax.sound.midi.MetaEventListener;
    import javax.sound.midi.MetaMessage;
    import javax.sound.midi.MidiEvent;
    import javax.sound.midi.MidiSystem;
    import javax.sound.midi.MidiUnavailableException;
    import javax.sound.midi.Sequence;
    import javax.sound.midi.Sequencer;
    import javax.sound.midi.ShortMessage;
    import javax.sound.midi.Synthesizer;
    import javax.sound.midi.Track;

    public class expiano {
    // These are some MIDI constants from the spec. They aren't defined
    // for us in javax.sound.midi.
    public static final int DAMPER_PEDAL = 64;

    public static final int DAMPER_ON = 127;

    public static final int DAMPER_OFF = 0;

    public static final int END_OF_TRACK = 47;

    public static void main(String[] args) throws MidiUnavailableException, InvalidMidiDataException,
    IOException {
    int instrument = 0;
    int tempo = 120;
    String filename = null;

    // Parse the options
    // -i <instrument number> default 0, a piano. Allowed values: 0-127
    // -t <beats per minute> default tempo is 120 quarter notes per minute
    // -o <filename> save to a midi file instead of playing
    int a = 0;
    while (a < args.length) {
    if (args[a].equals("-i")) {
    instrument = Integer.parseInt(args[a + 1]);
    a += 2;
    } else if (args[a].equals("-t")) {
    tempo = Integer.parseInt(args[a + 1]);
    a += 2;
    } else if (args[a].equals("-o")) {
    filename = args[a + 1];
    a += 2;
    } else
    break;
    }

    char[] notes = args[a].toCharArray();------------51

    I tried using try/catch, but I got the same error

  4. #4
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    Ok. What's going on is that 'args' is a zero length array. As a result, any value of 'a' is going to result in an ArrayIndexOutOfBoundsException. The reason args is zero length is because your program is being run without any command line arguments.

    A try/catch isn't going to fix anything. What it will do is allow you to examine more details of the error, and handle it.

  5. #5
    Maya is offline Member
    Join Date
    Feb 2011
    Posts
    9
    Rep Power
    0

Similar Threads

  1. Get MIDI Song Title
    By mcindafizzy in forum New To Java
    Replies: 1
    Last Post: 01-20-2011, 12:28 AM
  2. MIDI - Music Player Help
    By bs3ac in forum New To Java
    Replies: 0
    Last Post: 08-29-2010, 01:03 AM
  3. MIDI to PCM
    By Ben Wheatley in forum Advanced Java
    Replies: 1
    Last Post: 08-05-2009, 05:58 PM
  4. midi bytes
    By willemjav in forum Advanced Java
    Replies: 77
    Last Post: 07-29-2008, 03:10 PM
  5. help with midi files
    By leonard in forum New To Java
    Replies: 1
    Last Post: 08-06-2007, 04:40 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •