[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