summaryrefslogtreecommitdiff
path: root/roombacomm-client/src/com/hackingroomba/roombacomm/RTTTLParser.java
blob: 9759b933e461f92b0518fba8c62359185c2d0957 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112



package com.hackingroomba.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 <rttlstring>");
            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;
    }
}