From b5028dc9c03585cdf231a37d8996a7e836932c3e Mon Sep 17 00:00:00 2001 From: Einar Pehrson Date: Wed, 14 May 2003 11:15:08 +0000 Subject: [PATCH] *** empty log message *** --- Methods of Key Classes.txt | 2 +- MooDialog.java | 112 +++++++++++++++++++++++-- MooNote.java | 15 ++-- MooNoteElement.java | 67 ++++++++++----- MooNoteProp.java | 127 ----------------------------- MooTrackTitle.java | 22 +++-- MooTrackView.java | 163 ++++++++++++++++--------------------- Moosique.java | 38 ++++----- 8 files changed, 262 insertions(+), 284 deletions(-) delete mode 100644 MooNoteProp.java diff --git a/Methods of Key Classes.txt b/Methods of Key Classes.txt index a2dd941..289943e 100644 --- a/Methods of Key Classes.txt +++ b/Methods of Key Classes.txt @@ -139,7 +139,7 @@ int getPitchBend() int getPolyPressure(int noteNumber) Obtains the pressure with which the specified key is being depressed. int getProgram() - Obtains the current program number for this channel. + Obtains the current program number for this channel. boolean getSolo() Obtains the current solo state for this channel. boolean localControl(boolean on) diff --git a/MooDialog.java b/MooDialog.java index ee95f09..9769c50 100644 --- a/MooDialog.java +++ b/MooDialog.java @@ -1,6 +1,8 @@ import javax.swing.*; import java.awt.*; +import java.awt.event.*; import javax.sound.midi.*; +import java.beans.*; /* * The add dialog that pops up if the user clicks on the add track menuitem @@ -14,7 +16,10 @@ public class MooDialog extends JDialog { private JTextField textfield; private JComboBox trackList, trackLust; private JButton okbutton, cancelbutton; - public static final int ADD_TRACK = 1, DELETE_TRACK = 2, COPY_TRACK = 3, MOVE_TRACK = 4; + public static final int ADD_TRACK = 1, + DELETE_TRACK = 2, + COPY_TRACK = 3, + MOVE_TRACK = 4; /* * Creates the add dialog @@ -148,11 +153,106 @@ public class MooDialog extends JDialog { setVisible(true); break; } - - - - - } + private MooNote note; + private JOptionPane optionPane; + private JTextField pitch; + private JTextField velocity; + private JTextField length; + + /** + * Creates a new note preference dialog. + * @param mn the note that will be graphically represented + */ + public MooDialog(MooNote mn) { + super(Moosique.getGUI(), "Note properties", false); + note = mn; + pitch = new JTextField(new Integer(note.getPitch()).toString(),3); + JPanel pitchpanel = new JPanel(); + pitchpanel.add(new Label("Pitch: ")); + pitchpanel.add(pitch); + + + velocity = new JTextField(new Integer(note.getVelocity()).toString(),3); + JPanel velocitypanel = new JPanel(); + velocitypanel.add(new Label("Velocity: ")); + velocitypanel.add(velocity); + + length = new JTextField(new Integer(note.getDuration()).toString(),5); + JPanel lengthpanel = new JPanel(); + lengthpanel.add(new Label("Length: ")); + lengthpanel.add(length); + + Object[] array = {"Set the note properties", + pitchpanel, + velocitypanel, + lengthpanel}; + + final String btnString1 = "Enter"; + final String btnString2 = "Cancel"; + Object[] options = {btnString1, btnString2}; + + optionPane = new JOptionPane(array, + JOptionPane.QUESTION_MESSAGE, + JOptionPane.YES_NO_OPTION, + null, + options, + options[0]); + setContentPane(optionPane); + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + + ActionListener intValidator = new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (e.getSource() instanceof JTextField){ + JTextField s = (JTextField)e.getSource(); + int num = Integer.parseInt(s.getText()); + if (num < 0) + num = 0; + else if (num > 127 && s != length) + num = 127; + s.setText(new Integer(num).toString()); + } + } + }; + pitch.addActionListener(intValidator); + velocity.addActionListener(intValidator); + length.addActionListener(intValidator); + + optionPane.addPropertyChangeListener(new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent e) { + String prop = e.getPropertyName(); + + if (isVisible() + && (e.getSource() == optionPane) + && (prop.equals(JOptionPane.VALUE_PROPERTY) || + prop.equals(JOptionPane.INPUT_VALUE_PROPERTY))) { + Object value = optionPane.getValue(); + + if (value == JOptionPane.UNINITIALIZED_VALUE) { + //ignore reset + return; + } + + // Reset the JOptionPane's value. + // If you don't do this, then if the user + // presses the same button next time, no + // property change event will be fired. + optionPane.setValue( + JOptionPane.UNINITIALIZED_VALUE); + + if (value.equals(btnString1)) { + note.setPitch(Integer.parseInt(pitch.getText())); + note.setVelocity(Integer.parseInt(velocity.getText())); + note.setDuration(Integer.parseInt(length.getText())); + + setVisible(false); + } else { // user closed dialog or clicked cancel + setVisible(false); + } + } + } + }); + pack(); + } } diff --git a/MooNote.java b/MooNote.java index 77ecd53..6cb9f9e 100644 --- a/MooNote.java +++ b/MooNote.java @@ -61,9 +61,8 @@ public class MooNote extends MidiEvent { public void setChannel(int channel) { try { noteOnMsg.setMessage(noteOnMsg.getCommand(), (byte)channel, noteOnMsg.getData1(), noteOnMsg.getData2()); - noteOffMsg.setMessage(noteOffMsg.getCommand(), (byte)channel, noteOffMsg.getData1(), noteOffMsg.getData2()); - } catch (Exception e) {} - //} catch (InvalidMidiDataException e) {} + if(hasNoteOffEvent()) noteOffMsg.setMessage(noteOffMsg.getCommand(), (byte)channel, noteOffMsg.getData1(), noteOffMsg.getData2()); + } catch (InvalidMidiDataException e) {} } /** @@ -73,9 +72,8 @@ public class MooNote extends MidiEvent { public void setPitch(int pitch) { try { noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), (byte)pitch, noteOnMsg.getData2()); - noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), (byte)pitch, noteOffMsg.getData2()); - } catch (Exception e) {} - //} catch (InvalidMidiDataException e) {} + if(hasNoteOffEvent()) noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), (byte)pitch, noteOffMsg.getData2()); + } catch (InvalidMidiDataException e) {} } /** @@ -85,9 +83,8 @@ public class MooNote extends MidiEvent { public void setVelocity(int vel) { try { noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), noteOnMsg.getData1(), (byte)vel); - noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), noteOffMsg.getData1(), noteOffMsg.getData2()); - } catch (Exception e) {} - //} catch (InvalidMidiDataException e) {} + if(hasNoteOffEvent()) noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), noteOffMsg.getData1(), noteOffMsg.getData2()); + } catch (InvalidMidiDataException e) {} } /** diff --git a/MooNoteElement.java b/MooNoteElement.java index 65ed0ba..d5e4d2a 100644 --- a/MooNoteElement.java +++ b/MooNoteElement.java @@ -11,6 +11,7 @@ import java.awt.event.*; public class MooNoteElement extends JPanel { + private MooTrackView mtv; private MooNote note; private int columns; private boolean selected; @@ -18,13 +19,16 @@ public class MooNoteElement extends JPanel { public static final Color bgColor = new Color(160, 218, 255); private String notePitch; private String noteVelocity; + private JPopupMenu popup; + private JMenuItem popupRemove, popupProp; /** * Creates a new note element. * @param mn the note that will be graphically represented * @param rows the number of rows that the note will occupy */ - public MooNoteElement (MooNote mn) { + public MooNoteElement (MooTrackView parent, MooNote mn) { + mtv = parent; note = mn; calculateString(); columns = mn.getDuration() / (Moosique.getSequence().getResolution() / 4); @@ -32,8 +36,21 @@ public class MooNoteElement extends JPanel { setBackground(bgColor); addMouseListener(new MAdapter()); + // Defines coordinates. pitchRect = new Rectangle(0, 0, 15, 10); veloRect = new Rectangle(20, 0, 40, 10); + + // Creates pop-up menu. + popup = new JPopupMenu(); + PopupListener pList = new PopupListener(); + popupProp = new JMenuItem("Preferences..."); + popupProp.addActionListener(pList); + popup.add(popupProp); + + popupRemove = new JMenuItem("Remove"); + popupRemove.addActionListener(pList); + popup.add(popupRemove); + } /** @@ -99,27 +116,39 @@ public class MooNoteElement extends JPanel { } class MAdapter extends MouseAdapter { - public void mouseClicked(MouseEvent e) { - if (pitchRect.contains(e.getPoint())) { - if (SwingUtilities.isRightMouseButton(e)) { - note.setPitch(note.getPitch() + 1); - } else if (SwingUtilities.isLeftMouseButton(e)) { - note.setPitch(note.getPitch() - 1); + public void mousePressed(MouseEvent e) { + if (e.isControlDown()) { + if (pitchRect.contains(e.getPoint())) { + if (SwingUtilities.isRightMouseButton(e)) { + note.setPitch(note.getPitch() + 1); + } else if (SwingUtilities.isLeftMouseButton(e)) { + note.setPitch(note.getPitch() - 1); + } + calculateString(); + } else if (veloRect.contains(e.getPoint())) { + if (SwingUtilities.isRightMouseButton(e)) { + note.setVelocity(note.getVelocity() + 1); + } else if (SwingUtilities.isLeftMouseButton(e)) { + note.setVelocity(note.getVelocity() - 1); + } + calculateString(); } - calculateString(); - } else if (veloRect.contains(e.getPoint())) { - if (SwingUtilities.isRightMouseButton(e)) { - note.setVelocity(note.getVelocity() + 1); - } else if (SwingUtilities.isLeftMouseButton(e)) { - note.setVelocity(note.getVelocity() - 1); - } - calculateString(); + e.getComponent().repaint(); + } + if (e.isPopupTrigger()) { + popup.show(e.getComponent(), e.getX(), e.getY()); } - e.getComponent().repaint(); } + } - public void mousePressed(MouseEvent e) {} - - public void mouseReleased(MouseEvent e) {} + class PopupListener implements ActionListener { + public void actionPerformed(ActionEvent e) { + Object source = e.getSource(); + if (source == popupProp) { + new MooDialog(note); + } else if (source == popupRemove) { + mtv.remove((MooNoteElement)((JComponent)e.getSource()).getParent().getParent()); + } + } } } diff --git a/MooNoteProp.java b/MooNoteProp.java deleted file mode 100644 index e1826e3..0000000 --- a/MooNoteProp.java +++ /dev/null @@ -1,127 +0,0 @@ -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import java.beans.*; - -/** - * Graphical representation of a MIDI note. - * - * @author Andersson, Andreen, Lanneskog, Pehrson - * @version 1 - */ - -public class MooNoteProp extends JDialog{ - - private MooNote note; - private JOptionPane optionPane; - private JTextField pitch; - private JTextField velocity; - private JTextField length; - - /** - * Creates a new note preference dialog. - * @param mn The note that will be graphically represented - */ - public MooNoteProp(MooNote mn) { - super((JFrame)null, true); - note = mn; - setTitle("Note properties"); - - pitch = new JTextField(new Integer(note.getPitch()).toString(),3); - JPanel pitchpanel = new JPanel(); - pitchpanel.add(new Label("Pitch: ")); - pitchpanel.add(pitch); - - - velocity = new JTextField(new Integer(note.getVelocity()).toString(),3); - JPanel velocitypanel = new JPanel(); - velocitypanel.add(new Label("Velocity: ")); - velocitypanel.add(velocity); - - length = new JTextField(new Integer(note.getDuration()).toString(),5); - JPanel lengthpanel = new JPanel(); - lengthpanel.add(new Label("Length: ")); - lengthpanel.add(length); - - Object[] array = {"Set the note properties", - pitchpanel, - velocitypanel, - lengthpanel}; - - final String btnString1 = "Enter"; - final String btnString2 = "Cancel"; - Object[] options = {btnString1, btnString2}; - - optionPane = new JOptionPane(array, - JOptionPane.QUESTION_MESSAGE, - JOptionPane.YES_NO_OPTION, - null, - options, - options[0]); - setContentPane(optionPane); - setDefaultCloseOperation(DISPOSE_ON_CLOSE); - - ActionListener intValidator = new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (e.getSource() instanceof JTextField){ - JTextField s = (JTextField)e.getSource(); - int num = Integer.parseInt(s.getText()); - if (num < 0) - num = 0; - else if (num > 127 && s != length) - num = 127; - s.setText(new Integer(num).toString()); - } - } - }; - pitch.addActionListener(intValidator); - velocity.addActionListener(intValidator); - length.addActionListener(intValidator); - - optionPane.addPropertyChangeListener(new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent e) { - String prop = e.getPropertyName(); - - if (isVisible() - && (e.getSource() == optionPane) - && (prop.equals(JOptionPane.VALUE_PROPERTY) || - prop.equals(JOptionPane.INPUT_VALUE_PROPERTY))) { - Object value = optionPane.getValue(); - - if (value == JOptionPane.UNINITIALIZED_VALUE) { - //ignore reset - return; - } - - // Reset the JOptionPane's value. - // If you don't do this, then if the user - // presses the same button next time, no - // property change event will be fired. - optionPane.setValue( - JOptionPane.UNINITIALIZED_VALUE); - - if (value.equals(btnString1)) { - note.setPitch(Integer.parseInt(pitch.getText())); - note.setVelocity(Integer.parseInt(velocity.getText())); - note.setDuration(Integer.parseInt(length.getText())); - - setVisible(false); - } else { // user closed dialog or clicked cancel - setVisible(false); - } - } - } - }); - pack(); - } - - public static void main(String[] args){ - - MooNote n = new MooNote(0,0,10,20,0,30); - MooNoteProp prop = new MooNoteProp(n); - prop.setVisible(true); - prop = new MooNoteProp(n); - prop.setVisible(true); - - } -} diff --git a/MooTrackTitle.java b/MooTrackTitle.java index 412fb24..b921926 100644 --- a/MooTrackTitle.java +++ b/MooTrackTitle.java @@ -15,7 +15,7 @@ public class MooTrackTitle extends JPanel { private MetaMessage trackNameMessage; private String trackName = ""; private ShortMessage programChangeMessage; - private int programChange = 0, channel = 0; + private int channel = 0; private JTextField title; private MooInstrumentList instruments; private JComboBox channelBox; @@ -32,21 +32,24 @@ public class MooTrackTitle extends JPanel { track = aTrack; this.trackNum = aTrackNum; - // Finds track name and program change + // Finds track name, program change and channel. MidiMessage msg; + int status; for (int i = 0; i < track.size(); i++) { msg = track.get(i).getMessage(); - if (msg.getStatus() == 255) { + status = msg.getStatus(); + if (status == MetaMessage.META) { if (((MetaMessage)msg).getType() == 3) { trackNameMessage = (MetaMessage)msg; trackName = new String(trackNameMessage.getData()); } - } else if (msg.getStatus() == 192) { + } else if (status >= 192 && status <= 207) { programChangeMessage = (ShortMessage)msg; - programChange = programChangeMessage.getData1(); + channel = status - 192; } } +/* // Finds channel number. MidiEvent event; for (int i = 0; i < track.size(); i++) { event = track.get(i); @@ -55,7 +58,7 @@ public class MooTrackTitle extends JPanel { break; } } - +*/ // Creates and places components. setLayout(new GridLayout(4,1)); setBorder(BorderFactory.createLineBorder(Color.black)); @@ -66,6 +69,10 @@ public class MooTrackTitle extends JPanel { title.addFocusListener(new TitleFocusListener()); add(title); + instruments = new MooInstrumentList(channel); + // instruments = new MooInstrumentList(channel, programChangeMessage); + add(instruments); + channelBox = new JComboBox(); channelBox.setFont(Moosique.getGUI().FONT); for (int i = 1; i <= 16; i++) @@ -73,9 +80,6 @@ public class MooTrackTitle extends JPanel { channelBox.setSelectedIndex(channel); - instruments = new MooInstrumentList(channelBox.getSelectedIndex()); - add(instruments); - channelBox.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ int chan = channelBox.getSelectedIndex(); diff --git a/MooTrackView.java b/MooTrackView.java index 129b0af..c058cc5 100644 --- a/MooTrackView.java +++ b/MooTrackView.java @@ -11,46 +11,96 @@ import java.util.*; * @version 1 */ -public class MooTrackView extends JPanel implements ActionListener { +public class MooTrackView extends JPanel { private Track track; - private NoteArea notes; private Rectangle box; private JPopupMenu popup; - private JPopupMenu notePopup; private JMenuItem menuItem; + private ArrayList rects; protected static int viewLength = 0; public static final int NOTE_HEIGHT = 10, NOTE_WIDTH = 40, VIEW_WIDTH = 200; public MooTrackView (Track track) { super(true); this.track = track; - setLayout(new BorderLayout()); - notes = new NoteArea(track); - notes.setBackground(Color.white); - notes.setBorder(BorderFactory.createLineBorder(Color.black)); + // Configures panel + setBackground(Color.white); + setBorder(BorderFactory.createLineBorder(Color.black)); + setLayout(null); + setPreferredSize(new Dimension(VIEW_WIDTH, 140 * NOTE_HEIGHT)); + + // Creates temporary variables + MidiEvent note; + MooNoteElement elem; + int extraHeight = Toolkit.getDefaultToolkit().getScreenSize().height - 150; + int x, y, height; + int beatsPerSixteenth = Moosique.getSequence().getResolution() / 4; + rects = new ArrayList(track.size() / 2); + + // Places note elements + Insets insets = getInsets(); + for (int i = 0; i < track.size(); i++) { + note = track.get(i); + if (note instanceof MooNote) { + // Adds the note element to the note area. + MooNote mn = (MooNote)note; + elem = new MooNoteElement(this, mn); + add(elem); + + // Moves the note element to the appropriate place. + x = insets.left; + y = insets.top + (int)(mn.getTick() / beatsPerSixteenth) * NOTE_HEIGHT; + height = (mn.getDuration() / beatsPerSixteenth) * NOTE_HEIGHT; + if (height == 0) height = NOTE_HEIGHT; + Rectangle r = new Rectangle(x, y, NOTE_WIDTH, height); + while(isOccupied(r)) r.translate(NOTE_WIDTH, 0); + elem.setBounds(r); + rects.add(r); + if (viewLength < (y + height)) viewLength = y + height; + } + setPreferredSize(new Dimension(VIEW_WIDTH, viewLength + extraHeight)); + } + validate(); + // Creates pop-up menu. popup = new JPopupMenu(); menuItem = new JMenuItem("Add..."); - menuItem.addActionListener(this); + // menuItem.addActionListener(); popup.add(menuItem); - notePopup = new JPopupMenu(); - menuItem = new JMenuItem("Preferences..."); - menuItem.addActionListener(this); - notePopup.add(menuItem); - -// notes.addMouseListener(new PopupListener()); - add(notes, BorderLayout.CENTER); + addMouseListener(new PopupListener()); } - public void actionPerformed(ActionEvent e) {} - public Track getTrack() { return track; } + private boolean isOccupied(Rectangle r) { + Iterator it = rects.iterator(); + while (it.hasNext()) { + if(r.intersects((Rectangle)it.next())) return true; + } + return false; + } + + public void remove(MooNoteElement elem) { + remove((Component)elem); + validate(); + } + + public void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D)g; + for (int c = 0; c < viewLength || c < getHeight(); c += NOTE_HEIGHT) { + for (int r = 0; r < (10 * NOTE_WIDTH); r += NOTE_WIDTH) { + box = new Rectangle(r, c, NOTE_WIDTH, NOTE_HEIGHT); + g2.setColor(Color.gray); + g2.draw(box); + } + } + } /** * Updates the track view. @@ -59,86 +109,11 @@ public class MooTrackView extends JPanel implements ActionListener { repaint(); } - class NoteArea extends JPanel { - public static final int NOTE_HEIGHT = 10, NOTE_WIDTH = 40, VIEW_WIDTH = 200; - private ArrayList rects; - - public NoteArea(Track track) { - // Configuring panel - super(true); - setLayout(null); - setPreferredSize(new Dimension(VIEW_WIDTH, 140 * NOTE_HEIGHT)); - - // Creating temporary variables - MidiEvent note; - MooNoteElement elem; - int x, y, height; - int beatsPerSixteenth = Moosique.getSequence().getResolution() / 4; - rects = new ArrayList(track.size() / 2); - - // Placing note elements - Insets insets = getInsets(); - for (int i = 0; i < track.size(); i++) { - note = track.get(i); - if (note instanceof MooNote) { - // Adds the note element to the note area. - MooNote mn = (MooNote)note; - elem = new MooNoteElement(mn); - add(elem); - - // Moves the note element to the appropriate place. - x = insets.left; - y = insets.top + (int)(mn.getTick() / beatsPerSixteenth) * NOTE_HEIGHT; - height = (mn.getDuration() / beatsPerSixteenth) * NOTE_HEIGHT; - if (height == 0) height = NOTE_HEIGHT; - Rectangle r = new Rectangle(x, y, NOTE_WIDTH, height); - while(isOccupied(r)) r.translate(NOTE_WIDTH, 0); - elem.setBounds(r); - rects.add(r); - if (viewLength < (y + height)) viewLength = y + height; - } - setPreferredSize(new Dimension(VIEW_WIDTH, viewLength)); - } - validate(); - } - - private boolean isOccupied(Rectangle r) { - Iterator it = rects.iterator(); - while (it.hasNext()) { - if(r.intersects((Rectangle)it.next())) return true; - } - return false; - } - - public void paintComponent(Graphics g) { - super.paintComponent(g); - Graphics2D g2 = (Graphics2D)g; - for (int c = 0; c < viewLength || c < getHeight(); c += NOTE_HEIGHT) { - for (int r = 0; r < (10 * NOTE_WIDTH); r += NOTE_WIDTH) { - box = new Rectangle(r, c, NOTE_WIDTH, NOTE_HEIGHT); - g2.setColor(Color.gray); - g2.draw(box); - } - } - } - } - class PopupListener extends MouseAdapter { public void mousePressed(MouseEvent e) { - maybeShowPopup(e); - } - - public void mouseReleased(MouseEvent e) { - maybeShowPopup(e); - } - - private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) { - if (findComponentAt(e.getX(), e.getY()) instanceof MooNoteElement) - notePopup.show(e.getComponent(), e.getX(), e.getY()); - else - popup.show(e.getComponent(), e.getX(), e.getY()); + popup.show(e.getComponent(), e.getX(), e.getY()); } } } -} +} \ No newline at end of file diff --git a/Moosique.java b/Moosique.java index df94b47..e72cdf5 100644 --- a/Moosique.java +++ b/Moosique.java @@ -274,7 +274,9 @@ public class Moosique { MidiEvent noteOn, noteOff = null, nextEvent; MidiMessage nextMsg; ShortMessage shortMsg; + ArrayList noteOns, noteOffs; for (int i = 0; i < tracks.length; i++) { + noteOns = new ArrayList(tracks.length); /* Collections.sort(track[i].events, new Comparator() { public int compare(Object o1, Object o2) { @@ -284,28 +286,26 @@ public class Moosique { */ for (int j = 0; j < tracks[i].size(); j++) { noteOn = tracks[i].get(j); - if (noteOn.getMessage() instanceof ShortMessage) { - if (((ShortMessage)noteOn.getMessage()).getCommand() == ShortMessage.NOTE_ON) { - // Finds the corresponding NoteOff event - for (int k = j + 1; k < tracks[i].size(); k++) { - nextEvent = tracks[i].get(k); - nextMsg = nextEvent.getMessage(); - if (nextMsg instanceof ShortMessage) { - shortMsg = (ShortMessage) nextMsg; - if (shortMsg.getCommand() == ShortMessage.NOTE_OFF && shortMsg.getChannel() == ((ShortMessage)noteOn.getMessage()).getChannel() && shortMsg.getData1() == ((ShortMessage)noteOn.getMessage()).getData1()) { - noteOff = nextEvent; - break; - } + if (noteOn.getMessage().getStatus() == ShortMessage.NOTE_ON) { + // Finds the corresponding NoteOff event + for (int k = j + 1; k < tracks[i].size(); k++) { + nextEvent = tracks[i].get(k); + nextMsg = nextEvent.getMessage(); + if (nextMsg instanceof ShortMessage) { + shortMsg = (ShortMessage) nextMsg; + if (shortMsg.getCommand() == ShortMessage.NOTE_OFF && shortMsg.getChannel() == ((ShortMessage)noteOn.getMessage()).getChannel() && shortMsg.getData1() == ((ShortMessage)noteOn.getMessage()).getData1()) { + noteOff = nextEvent; + break; } - } - // Replaces the NoteOn event with a MooNote, if possible with the corresponding NoteOff event - tracks[i].remove(noteOn); - if (noteOff != null) { - tracks[i].add(new MooNote(noteOn, noteOff)); - } else { - tracks[i].add(new MooNote(noteOn)); } } + // Replaces the NoteOn event with a MooNote, if possible with the corresponding NoteOff event + tracks[i].remove(noteOn); + if (noteOff != null) { + tracks[i].add(new MooNote(noteOn, noteOff)); + } else { + tracks[i].add(new MooNote(noteOn)); + } } } } -- 2.39.2