package roombacomm; import java.util.*; import java.util.regex.*; /** * */ public class RTTTLParser { public static HashMap noteToNum; static { noteToNum = new HashMap(); noteToNum.put("c", new Integer(0) ); noteToNum.put("c#", new Integer(1) ); noteToNum.put("d", new Integer(2) ); noteToNum.put("d#", new Integer(3) ); noteToNum.put("e", new Integer(4) ); noteToNum.put("f", new Integer(5) ); noteToNum.put("f#", new Integer(6) ); noteToNum.put("g", new Integer(7) ); noteToNum.put("g#", new Integer(8) ); noteToNum.put("a", new Integer(9) ); noteToNum.put("a#", new Integer(10) ); noteToNum.put("b", new Integer(11) ); noteToNum.put("h", new Integer(7) ); } public static void main(String[] args) { if( args.length == 0 ) { System.out.println( "usage: roombacomm.RTTTLParser "); System.exit(0); } String rtttl = args[0]; ArrayList notelist = parse( rtttl ); for( int i=0; i< notelist.size(); i++ ) { System.out.println("notelist["+i+"]="+notelist.get(i)); } } public static ArrayList parse(String rtttl) { System.out.println("parsing: "+rtttl); String rtttl_working = rtttl.toLowerCase(); String parts[] = rtttl_working.split(":"); String name = parts[0]; String defaults[] = parts[1].split("[,=]"); String notes[] = parts[2].split(","); // global defaults int bpm = 63; int octave = 6; int duration = 4; ArrayList notelist = new ArrayList(); for( int i=0; i < defaults.length; i++ ) { //System.out.println("defaults["+i+"]="+defaults[i]); if( defaults[i].equals("b") ) try { bpm = Integer.parseInt(defaults[i+1]); } catch(Exception e) {} else if( defaults[i].equals("o") ) try { octave = Integer.parseInt(defaults[i+1]); } catch(Exception e) {} else if( defaults[i].equals("d") ) try { duration = Integer.parseInt(defaults[i+1]); } catch(Exception e) {} } System.out.println("bpm:"+bpm+",octave:"+octave+",duration:"+duration); for( int i=0; i < notes.length; i++ ) { Matcher m =Pattern.compile("(\\d+)*(.+?)(\\d)*(\\.)*").matcher(notes[i]); m.find(); // group(1) == duration (optional) // group(2) == note (required) // group(3) == scale (optional) // group(4) == triplet (optional) int dur = duration; int oct = octave; if( m.group(1) != null ) try { dur = Integer.parseInt( m.group(1) ); } catch(Exception e) {} if( m.group(4) != null && m.group(4).equals(".") ) dur += dur/2; if( m.group(3) != null ) try { oct = Integer.parseInt( m.group(3) ); } catch(Exception e) {} if( m.group(2) != null ) { int notenum; if( m.group(2).equals("p") ) { notenum = 0; } else { Integer nn = (Integer) noteToNum.get( m.group(2) ); notenum = nn.intValue(); notenum = notenum + 12*oct; } dur = bpmToMillis(bpm) / dur; notelist.add( new Note( notenum, dur ) ); } } return notelist; } public static int bpmToMillis( int bpm ) { return (60 * 1000 ) / bpm; } }