package jmsltestsuite; import java.util.Vector; import com.softsynth.jmsl.JMSL; import com.softsynth.jmsl.JMSLRandom; import com.softsynth.jmsl.MusicShape; import com.softsynth.jmsl.score.Note; import com.softsynth.jmsl.score.NoteFactory; import com.softsynth.jmsl.score.Score; import com.softsynth.jmsl.score.ScoreFrame; import com.softsynth.jmsl.score.Staff; import com.softsynth.jmsl.score.Tempo; import com.softsynth.jmsl.score.transcribe.BeatDivisionSchemeList; import com.softsynth.jmsl.score.transcribe.ElementMissedException; import com.softsynth.jmsl.score.transcribe.SearchPathListExpansionException; import com.softsynth.jmsl.score.transcribe.TempoTimeSignatureHolder; import com.softsynth.jmsl.score.transcribe.Transcriber; import com.softsynth.jmsl.score.transcribe.TranscriberListener; import com.softsynth.jmsl.util.TimeSignature; /** * TranscriberListener gets a callback for every note added to a Score during the transcription * process. You can make decisions about this Note and access it, adding text, sccents, marks, * dynamics, etc * * * JMSL's com.softsynth.jmsl.score.transcribe package enables the transcription of arbitrary * MusicShape data into common music notation. * * This test uses Note setText() and TranscriberListener to add algorithmically generated lyrics to * a transcription It sets marks on Note depending on its note index * * @author Nick Didkovsky, (c) 2002 Nick Didkovsky, All Rights reserved. * */ public class TestTranscribe8 implements TranscriberListener { /** simplified solfeggio scale syllables, using ascending syllables only */ String[] solfeggio = { "do", "di", "re", "ri", "mi", "fa", "fi", "sol", "si", "la", "li", "ti" }; /** * Notify listener when a Note is added to score by the transcriber. Use this to do special * things to the Note, like set a dynamic, or transpose it if it is out of range of a particular * instrument, etc * * Notice that setting text on an interval, while supported by JMSL/Score causes problems when * exported to MusicXML and imported into Finale. So instead of setting text on an interval, * retrieve the chord's root and append interval's text to the root's text */ public void noteAdded(Score score, Note note) { if (note.isRest()) { return; } int scaleStep = ((int) note.getPitchData()) % 12; if (!note.isInterval()) { note.setText(solfeggio[scaleStep]); setLyricTextLevel(note); } else { Note chordHandle = note.getHandle(); String rootText = chordHandle.getText(); chordHandle.setText(rootText + " (" + solfeggio[scaleStep] + ")"); setLyricTextLevel(chordHandle); } if (JMSLRandom.choose() < 0.3) { note.setMark(Note.MARK_ACCENT); } } /** * Notify listener of note events that will spill over into the next measure, ie notes that are * found within the current time window but will round up to beat 1 of the following measure. * Note: musicShape could be null if there was no spillover! */ public void notifyCarriedOverMusicShape(Score score, int currentMeasureNumber, MusicShape musicShape) { // Don't care to do anything with this info } /** Set the Y offset of the text of the note to a constant level below the staff */ static void setLyricTextLevel(Note note) { int offset = 30; if (note.getLevel() >= NoteFactory.LEVEL_OF_MIDDLE_C) { offset = (note.getLevel() - NoteFactory.LEVEL_OF_MIDDLE_C + 8) * Staff.SPACE_INTERVAL / 2; } note.setTextOffsetY(offset); } public static void main(String args[]) { JMSL.clock.setAdvance(0.1); Transcriber.setFillBeatWithNote(true); BeatDivisionSchemeList.defaultSetup(); System.out.println("number of beat division schemes under consideration: " + BeatDivisionSchemeList.size()); MusicShape source = new MusicShape(4); source.add(0, 74, 0.5, 0.25); for (int i = 0; i < 24; i++) { source.add(i * 0.5, 60 + i, 0.5, 0.25); } // 1 staff, let score dimensions auto adjust to number of staves and your screen Score score = new Score(1); score.addMeasure(); Transcriber transcriber = new Transcriber(); transcriber.setScore(score); transcriber.setSourceMusicShape(source); Vector tsVector = new Vector(); tsVector.addElement(new TempoTimeSignatureHolder(new Tempo(60), new TimeSignature(4, 4))); transcriber.setTempoTimeSignatures(tsVector); transcriber.addTranscriberListener(new TestTranscribe8()); try { score.setCurrentStaffNumber(0); transcriber.transcribe(); } catch (ElementMissedException e) { e.printStackTrace(); System.out.println("ERROR: " + e); System.exit(0); } catch (SearchPathListExpansionException e) { e.printStackTrace(); System.out.println("ERROR: " + e); System.exit(0); } final ScoreFrame f = new ScoreFrame(); f.addScore(score); f.loadPrefs(); f.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent e) { f.quit(); } }); //f.pack(); f.setVisible(true); } }