/* * Created on Jan 17, 2011 by Nick * */ package jmsltestsuite; import com.softsynth.jmsl.JMSLRandom; import com.softsynth.jmsl.MusicShape; /** * test: all note ons with noteoffs * * no noteoffs at all * * some noteons have noteoffs * * some noteoffs with no matching noteon * * @author Nick Didkovsky, (c) 2005 Nick Didkovsky, nick@didkovsky.com * */ public class TestNoteOffHoldAlgorithm { // MusicShape s; private int lookAheadForNoteOff(MusicShape s, int elementIndex) { if (elementIndex == s.size() - 1) { // System.out.println("Can't locate noteoff for last element of MusicShape"); return -1; } int noteOffIndex = -1; for (int i = elementIndex; i < s.size(); i++) { if (s.get(i, 1) == s.get(elementIndex, 1) && s.get(i, 2) == 0) { noteOffIndex = i; break; } } return noteOffIndex; } private void calculateHoldTimesFromNoteOffs(MusicShape s) { for (int i = 0; i < s.size(); i++) { if (s.get(i, 2) != 0) { int noteOffIndex = lookAheadForNoteOff(s, i); // System.out.println("Note on at index " + i + ", noteoff at " + noteOffIndex); if (noteOffIndex != -1) { double hold = s.get(noteOffIndex, 0) - s.get(i, 0); s.set(hold, i, 3); } else { // System.out.println("NoteOff not found for element " + i); } } } } private void trimNoteOffs(MusicShape s) { boolean noteOffFound = true; while (noteOffFound) { noteOffFound = false; for (int i = 0; i < s.size(); i++) { if (s.get(i, 2) == 0) { s.remove(i); noteOffFound = true; break; } } } } /** * some noteons do not have noteoffs. Change their hold time to the duration since previous * event */ private void handleOrphans(MusicShape s) { for (int i = 0; i < s.size() - 1; i++) { // System.out.println("Checking if " + i + "/" + s.size() + " is orphan"); if (s.get(i, 3) == -1) { double hold = s.get(i + 1, 0) - s.get(i, 0); s.set(hold, i, 3); } } if ((s.get(s.size() - 1, 3) == -1)) { s.set(1.0, s.size() - 1, 3); } } /** * @param s */ public void calculateHoldTimes(MusicShape s) { calculateHoldTimesFromNoteOffs(s); trimNoteOffs(s); handleOrphans(s); } MusicShape test1() { MusicShape s = new MusicShape(5); double currentTime = JMSLRandom.choose(4.0); for (int i = 0; i < 10; i++) { double[] data = new double[5]; data[0] = currentTime; data[1] = 60 + i; data[2] = 0.5; data[3] = -1; // hold data[4] = 0; s.add(data); double offTime = currentTime + JMSLRandom.choose(5.0); data = new double[5]; data[0] = offTime; data[1] = 60 + i; data[2] = 0; // amp=0 is noteoff data[3] = -1; // hold data[4] = 0; s.add(data); currentTime += JMSLRandom.choose(2.0); } s.sort(); return s; } MusicShape test2() { MusicShape s = new MusicShape(5); double currentTime = JMSLRandom.choose(4.0); for (int i = 0; i < 10; i++) { double[] data = new double[5]; data[0] = currentTime; data[1] = 60 + i; data[2] = 0.5; data[3] = -1; // hold data[4] = 0; s.add(data); currentTime += JMSLRandom.choose(2.0); } s.sort(); return s; } MusicShape test3() { MusicShape s = new MusicShape(5); double currentTime = JMSLRandom.choose(4.0); for (int i = 0; i < 10; i++) { double[] data = new double[5]; data[0] = currentTime; data[1] = 60 + i; data[2] = 0.5; data[3] = -1; // hold data[4] = 0; s.add(data); if (JMSLRandom.choose() < 0.2) { double offTime = currentTime + JMSLRandom.choose(5.0); data = new double[5]; data[0] = offTime; data[1] = 60 + i; data[2] = 0; // amp=0 is noteoff data[3] = -1; // hold data[4] = 0; s.add(data); } currentTime += JMSLRandom.choose(2.0); } s.sort(); return s; } MusicShape test4() { MusicShape s = new MusicShape(5); s.add(0., 0., 60., 0.); s.add(0.5, 1., 65., 70.); s.add(2, 1., 66., 70.); s.add(2.3333, 1., 70., 70.); s.add(2.6666, 1., 69., 70.); return s; } public static void main(String[] args) { TestNoteOffHoldAlgorithm test = new TestNoteOffHoldAlgorithm(); System.out.println("TEST 1"); MusicShape s = test.test1(); test.calculateHoldTimes(s); s.print(); System.out.println("\n\n"); System.out.println("TEST 2"); s = test.test2(); test.calculateHoldTimes(s); s.print(); System.out.println("\n\n"); System.out.println("TEST 3"); s = test.test3(); test.calculateHoldTimes(s); s.print(); System.out.println("\n\n"); } }