[jmsl] Utility class for tiedNotes

jmsl at music.columbia.edu jmsl at music.columbia.edu
Fri Jul 18 15:36:49 EDT 2008


Hi all,

Here is a little utility class that is helpful in dealing with tied  
notes.  It also has getNextNote() and getPrevNote() methods which may  
help some people who have problems with the nulls produced by Note's  
nextNote() method.

Peter McCulloch



package com.petermcculloch.megalo.util;

import java.util.ArrayList;
import java.util.Vector;

import com.softsynth.jmsl.score.Note;

/**
  * @author peter
  *
  */
/**
  * @author peter
  *
  */
/**
  * @author peter
  *
  */
/**
  * @author peter
  *
  */
public class NoteUtil {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

	}

	/**
	 * Operates just like Note's removeInterval(note) method, except that  
it
	 * will delete root notes as well. Single notes are converted into  
rests if
	 * removed.
	 *
	 * @param note
	 * @return note
	 */
	@SuppressWarnings("unchecked")
	public static void removeInterval(Note note) {
		Note.resortChord(note);
		if (!note.isMonoNote()) {
			if (note.isInterval()) {
				Note handleNote = note.getHandle();
				handleNote.removeInterval(note);
				Note.resortChord(handleNote);
				return;
			} else {
				Vector<Note> intervals = note.getIntervals();
				Note delNote = (Note) intervals.get(0);
				note.setData(delNote.getData());
				Vector<Object> addBeans = delNote.getUserBeans();
				Vector<Object> delBeans = note.getUserBeans();
				for (Object bean : delBeans) {
					note.removeUserBean(bean);
				}
				for (Object bean : addBeans) {
					note.addUserBean(bean);
				}
				note.removeInterval((Note) intervals.get(0));
				Note.resortChord(note);
				return;
			}
		}
		note.setPitchData(0);
		return;
	}

	public static boolean safeAddInterval(Note n, double pitch) {
		Note[] chord = Note.getSortedChord(Note.getRoot(n));

		boolean inChord = true;

		for (int i = 0; i < chord.length; i++) {
			if (chord[i].getPitchData() == pitch) {
				System.out.println("Duplicate pitch!:\t" + pitch);
				return false;
			}
		}

		if (n.isMonoNote()) {
			System.out.println("Added pitch to mono note:\t" + pitch);
			n.addInterval(pitch);
		} else {
			System.out.println("Added pitch to chord:    \t" + pitch);
			Note.getRoot(n).addInterval(pitch);
		}
		Note.resortChord(n);
		return true;
	}

	/**
	 * Useful way of tying all the intervals of a note.
	 *
	 * @param n
	 * @param isTiedOut
	 */
	public static void setTiedOutAll(Note n, boolean isTiedOut) {
		Note.resortChord(n);
		if (n.isMonoNote()) {
			// System.out.println("Mono note");
			n.setTiedOut(true);
		} else {
			Note[] chord = Note.getSortedChord(Note.getRoot(n));

			for (int i = 0; i < chord.length; i++) {
				chord[i].setTiedOut(isTiedOut);
			}
		}
	}

	/**
	 * Convenience method for getNextNote. This is the strict version  
that by
	 * default will only output the nextNote if it immediately follows  
the last
	 * note.
	 *
	 * @param n
	 * @return
	 */
	public static Note getNextNote(Note n) {
		return getNextNote(n, true);
	}

	/**
	 * A reimplemented version of Note's nextNote() method. With strict  
mode, it
	 * will produce nulls if the next note does not immediately follow the
	 * preceding note. Example: A quarter note on the third beat of a 4/4  
bar.
	 * No note follows it in the bar, but the next measure has a half  
note at
	 * the beginning. Note's nextNote() method would return the halfNote.  
With
	 * useStrict, it will return a null, because the note does not  
immediately
	 * follow the first note.
	 *
	 * If useStrict is false, getNextNote() will only return a null if  
this is
	 * the last note in the staff for that track. (Note's nextNote()  
method will
	 * return a null if there is a measure of space between two notes)
	 *
	 * @param n
	 * @return
	 */
	public static Note getNextNote(Note n, boolean useStrict) {
		if (useStrict) {
			Note nextNote = n.nextNote();

			if (nextNote != null) {
				if (nextNote.getStaffIndex() != n.getStaffIndex()) {
					nextNote = null;
				} else {
					// if not in same measure...
					if (nextNote.getMeasureIndex() != n.getMeasureIndex()) {
						// if n ends before the end of the measure, then there
						// is a
						// gap
						if (n.getTrack().getEndTimeOfNote(n) < n.getScore().getMeasure(
							n.getMeasureIndex()).getTimeSig().getTotalTime()) {
							nextNote = null;
						}
					}
				}
			}
			return nextNote;
		} else {
			// Try and avoid nulls if at all possible by skipping measures to
			// the next note.
			Note nextNote = n.nextNote();

			if (nextNote == null) {
				// point to next measure
				int measureIndex = n.getMeasureIndex() + 1;
				int staffIndex = n.getStaffIndex();
				int trackIndex = n.getTrack().getTrackIndex();
				int scoreSize = n.getScore().size();

				while (measureIndex < scoreSize) {
					if  
(n.getScore().getMeasure(measureIndex).getStaff(staffIndex).getTrack(
						trackIndex).size() == 0) {
						measureIndex++;
					} else {
						nextNote =
							 
n.getScore().getMeasure(measureIndex).getStaff(staffIndex).getTrack(
								trackIndex).getNote(0);
						break;
					}
				}
			}
			return nextNote;
		}
	}

	/**
	 * Convenience method for getPrevNote. Operates in same fashion as
	 * getNextNote
	 *
	 * @param n
	 * @return Note
	 */
	public static Note getPrevNote(Note n) {
		return getPrevNote(n, true);
	}

	/**
	 * A reimplemented version of Note's prevNote() method. Operates in  
same
	 * fashion as getNextNote
	 *
	 * @param n
	 * @return Note
	 */
	public static Note getPrevNote(Note n, boolean useStrict) {
		if (useStrict) {
			Note prevNote = n.prevNote();

			if (prevNote != null) {
				if (prevNote.getStaffIndex() != n.getStaffIndex()) {
					prevNote = null;
				} else {
					// if not in same measure...
					if (prevNote.getMeasureIndex() != n.getMeasureIndex()) {
						// if n ends before the end of the measure, then there
						// is a
						// gap
						if (prevNote.getTrack().getEndTimeOfNote(prevNote) <  
prevNote.getScore()
							.getMeasure 
(prevNote.getMeasureIndex()).getTimeSig().getTotalTime()) {
							prevNote = null;
						}
					}
				}
			}
			return prevNote;
		} else {
			// Try to avoid nulls if at all possible by skipping measures to
			// the next note.
			Note prevNote = n.prevNote();

			if (prevNote == null) {
				// point to next measure
				int measureIndex = n.getMeasureIndex() - 1;
				int staffIndex = n.getStaffIndex();
				int trackIndex = n.getTrack().getTrackIndex();
				int scoreSize = n.getScore().size();

				while (measureIndex > 0) {
					if  
(n.getScore().getMeasure(measureIndex).getStaff(staffIndex).getTrack(
						trackIndex).size() == 0) {
						measureIndex--;
					} else {
						// Get the last note of the track
						prevNote =
							 
n.getScore().getMeasure(measureIndex).getStaff(staffIndex).getTrack(
								trackIndex).getNote(
								n.getScore().getMeasure(measureIndex).getStaff(staffIndex)
									.getTrack(trackIndex).size());
						break;
					}
				}
			}
			return prevNote;
		}
	}

	public static boolean containsInterval(Note n, double pitch) {
		if (n.isMonoNote()) {
			if (n.getPitchData() == pitch) {
				return true;
			} else {
				return false;
			}
		} else {
			Note[] chord = Note.getSortedChord(n);
			for (int i = 0; i < chord.length; i++) {
				if (chord[i].getPitchData() == pitch) {
					return true;
				}
			}
		}
		return false;
	}

	public static Note getInterval(Note n, double pitch) {
		if (n != null) {
			Note[] chord = Note.getSortedChord(n);
			for (int i = 0; i < chord.length; i++) {
				if (chord[i].getPitchData() == pitch) {
					return chord[i];
				}
			}
		}
		return null;
	}

	/**
	 * Gets all of the tied notes that follow the specified note. (use  
only on
	 * notes that are NOT tied in!)
	 *
	 * @param note
	 * @return
	 */
	public static ArrayList<Note> getTiedChildren(Note note) {
		ArrayList<Note> list = new ArrayList<Note>();
		list.add(note);

		double pitch = note.getPitchData();

		// Get the matching note from the next note
		Note nextNote = getInterval(getNextNote(note), pitch);

		// Add all tied members to the list
		while (true) {
			if (nextNote == null) {
				break;
			} else {
				if (nextNote.getTiedIn()) {
					list.add(nextNote);
					nextNote = getInterval(getNextNote(nextNote), pitch);
				} else {
					break;
				}
			}
		}
		return list;
	}

	/**
	 * Gets the note that ends a tie
	 *
	 * @param note
	 * @return
	 */
	public static Note getTieStart(Note note) {

		double pitch = note.getPitchData();

		// Get the matching note from the next note
		Note prevNote = getInterval(getPrevNote(note), pitch);

		// Add all tied members to the list
		while (true) {
			if (prevNote == null) {
				break;
			} else {
				if (prevNote.getTiedOut()) {
					note = prevNote;
					prevNote = getInterval(getPrevNote(note), pitch);
				} else {
					break;
				}
			}
		}
		return note;
	}

	/**
	 * Gets the note that ends a tie
	 *
	 * @param note
	 * @return
	 */
	public static Note getTieEnd(Note note) {

		double pitch = note.getPitchData();

		// Get the matching note from the next note
		Note nextNote = getInterval(getNextNote(note), pitch);

		// Add all tied members to the list
		while (true) {
			if (nextNote == null) {
				break;
			} else {
				if (nextNote.getTiedIn()) {
					note = nextNote;
					nextNote = getInterval(getNextNote(note), pitch);
				} else {
					break;
				}
			}
		}
		return note;
	}

	/**
	 * Gets all of the tied notes that precede the specified note. (use  
only on
	 * notes that are NOT tied out?)
	 *
	 * @param note
	 * @return
	 */
	public static ArrayList<Note> getTiedParent(Note note) {
		ArrayList<Note> list = new ArrayList<Note>();
		list.add(note);

		double pitch = note.getPitchData();

		// Get the matching note from the next note
		Note prevNote = getInterval(getPrevNote(note), pitch);

		// Add all tied members to the list
		while (true) {
			if (prevNote == null) {
				break;
			} else {
				if (prevNote.getTiedOut()) {
					list.add(prevNote);
					prevNote = getInterval(getNextNote(prevNote), pitch);
				} else {
					break;
				}
			}
		}
		return list;
	}

	/**
	 * For any tied in/out note, returns all of the notes that are tied  
into/out
	 * of it.
	 *
	 * @param note
	 * @return ArrayList<Note>
	 */
	public static ArrayList<Note> getTiedNotes(Note note) {
		ArrayList<Note> list = new ArrayList<Note>();

		// Add the first note in the list.
		Note nextNote = getTieStart(note);
		list.add(nextNote);

		double pitch = nextNote.getPitchData();

		// Add all tied members to the list
		while (true) {
			// Get the matching note from the next note
			nextNote = getInterval(getNextNote(nextNote), pitch);
			// If there is no next note at that interval, break out
			if (nextNote == null) {
				break;
			} else {
				// if the next note is tied in (same pitch, next element in
				// track), add it
				if (nextNote.getTiedIn()) {
					list.add(nextNote);
				} else {
					break;
				}
			}
		}
		return list;
	}

}



More information about the jmsl mailing list