Skip to content

Commit

Permalink
Added supporting Time Value Syntax #2
Browse files Browse the repository at this point in the history
  • Loading branch information
mohayonao committed Oct 22, 2013
1 parent 58e86bb commit 68119f4
Show file tree
Hide file tree
Showing 3 changed files with 276 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/cc/client/compiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ define(function(require, exports, module) {
} catch(e) {}
})();

var timevalue = require("../common/timevalue").calc;

// CoffeeScript tags
// IDENTIFIER
// NUMBER
Expand Down Expand Up @@ -206,6 +208,23 @@ define(function(require, exports, module) {
return tokens.length - 1;
};

var replaceTimeValue = function(tokens) {
var i = tokens.length - 1;
while (0 <= i) {
var token = tokens[i];
if (token[TAG] === "STRING" && token[VALUE].charAt(0) === "\"") {
var time = timevalue(token[VALUE].substr(1, token[VALUE].length-2));
if (typeof time === "number") {
token[TAG] = "NUMBER";
token[VALUE] = time.toString();
}
}
i -= 1;
}
// dumpTokens(tokens);
return tokens;
};

var replacePi = function(tokens) {
var i = tokens.length - 1;
while (0 <= i) {
Expand Down Expand Up @@ -494,6 +513,7 @@ define(function(require, exports, module) {
var code = items[0];
var data = items[1];
var tokens = CoffeeScript.tokens(code);
tokens = replaceTimeValue(tokens);
tokens = replacePi(tokens);
tokens = replaceUnaryOp(tokens);
tokens = replacePrecedence(tokens);
Expand Down Expand Up @@ -555,6 +575,7 @@ define(function(require, exports, module) {
splitCodeAndData: splitCodeAndData,
findOperandHead : findOperandHead,
findOperandTail : findOperandTail,
replaceTimeValue : replaceTimeValue,
replacePi : replacePi,
replacePrecedence : replacePrecedence,
replaceUnaryOp : replaceUnaryOp,
Expand Down
142 changes: 142 additions & 0 deletions src/cc/common/timevalue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
define(function(require, exports, module) {
"use strict";

var cc = require("../cc");

var calc = function(str) {
var result = null;
var freq;
if (str.charAt(0) === "~") {
freq = true;
str = str.substr(1);
}
do {
result = hz(str);
if (result !== null) {
break;
}
result = time(str);
if (result !== null) {
break;
}
result = hhmmss(str);
if (result !== null) {
break;
}
result = samples(str);
if (result !== null) {
break;
}
result = note(str);
if (result !== null) {
break;
}
result = beat(str);
if (result !== null) {
break;
}
result = ticks(str);
} while (false);

if (result !== null) {
if (!freq) {
return result;
}
if (result !== 0) {
return 1 / result;
}
}
return str;
};

var hz = function(str) {
var m = /^(\d+(?:\.\d+)?)hz$/i.exec(str);
if (m) {
return +m[1] === 0 ? 0 : 1 / +m[1];
}
return null;
};
var time = function(str) {
var m = /^(\d+(?:\.\d+)?)(min|sec|m)s?$/i.exec(str);
if (m) {
switch (m[2]) {
case "min": return +(m[1]||0) * 60;
case "sec": return +(m[1]||0);
case "m" : return +(m[1]||0) / 1000;
}
}
return null;
};

var hhmmss = function(str) {
var m = /^(?:([1-9][0-9]*):)?([0-5]?[0-9]):([0-5][0-9])(?:\.(\d{1,3}))?$/.exec(str);
if (m) {
var x = 0;
x += (m[1]|0) * 3600;
x += (m[2]|0) * 60;
x += (m[3]|0);
x += (((m[4]||"")+"00").substr(0, 3)|0) / 1000;
return x;
}
return null;
};

var samples = function(str) {
var m = /^(\d+)samples(?:\/(\d+)hz)?$/i.exec(str);
if (m) {
return m[1] / ((m[2]|0) || cc.sampleRate);
}
return null;
};

var calcNote = function(bpm, len, dot) {
var x = (60 / bpm) * (4 / len);
x *= [1, 1.5, 1.75, 1.875][dot] || 1;
return x;
};
var note = function(str) {
var m = /^bpm([1-9]\d+(?:\.\d+)?)\s*l([1-9]\d*)(\.*)$/i.exec(str);
if (m) {
return calcNote(+m[1], +m[2], m[3].length);
}
return null;
};

var calcBeat = function(bpm, measure, beat, ticks) {
var x = (measure * 4 + beat) * 480 + ticks;
return (60 / bpm) * (x / 480);
};
var beat = function(str) {
var m = /^bpm([1-9]\d+(?:\.\d+)?)\s*(\d+)\.(\d+).(\d{1,3})$/i.exec(str);
if (m) {
return calcBeat(+m[1], +m[2], +m[3], +m[4]);
}
return null;
};

var calcTicks = function(bpm, ticks) {
return 60 / bpm * ticks / 480;
};
var ticks = function(str) {
var m = /^bpm([1-9]\d+(?:\.\d+)?)\s*(\d+)ticks$/i.exec(str);
if (m) {
return calcTicks(+m[1], +m[2]);
}
return null;
};

module.exports = {
hz : hz,
time : time,
hhmmss : hhmmss,
samples: samples,
note : note,
beat : beat,
ticks : ticks,
calcNote : calcNote,
calcBeat : calcBeat,
calcTicks: calcTicks,
calc: calc,
};

});
113 changes: 113 additions & 0 deletions src/cc/common/timevalue_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
define(function(require, exports, module) {
"use strict";

var assert = require("chai").assert;
var cc = require("../cc");
var timevalue = require("./timevalue");

var calcNote = timevalue.calcNote;
var calcBeat = timevalue.calcBeat;
var calcTicks = timevalue.calcTicks;

describe("timevlaue.js", function() {
before(function() {
cc.sampleRate = 44100;
});
it("hz", function() {
assert.equal(timevalue.hz("50hz") , 1/50);
assert.equal(timevalue.hz("50.5hz"), 1/50.5);
assert.isNull(timevalue.hz("hz"));
});
it("ms", function() {
assert.equal(timevalue.time("50ms") , 50/1000);
assert.equal(timevalue.time("50.5m"), 50.5/1000);
assert.isNull(timevalue.time("ms"));
});
it("sec", function() {
assert.equal(timevalue.time("50sec") , 50);
assert.equal(timevalue.time("50.5secs"), 50.5);
assert.isNull(timevalue.time("sec"));
});
it("min", function() {
assert.equal(timevalue.time("50min") , 50 * 60);
assert.equal(timevalue.time("50.5mins"), 50.5 * 60);
assert.isNull(timevalue.time("min"));
});
it("hhmmss", function() {
assert.equal(timevalue.hhmmss("1:00"), 60);
assert.equal(timevalue.hhmmss("1:02.3" ), 62.3);
assert.equal(timevalue.hhmmss("1:02.345"), 62.345);
assert.equal(timevalue.hhmmss("1:02:03"), 3723);
assert.isNull(timevalue.hhmmss("65:43"));
assert.isNull(timevalue.hhmmss("1.234"));
});
it("samples", function() {
assert.equal(timevalue.samples("1000samples"), 1000 / cc.sampleRate);
assert.equal(timevalue.samples("1000samples/8000hz"), 1000 / 8000);
assert.isNull(timevalue.samples("samples"));
});
it("note", function() {
assert.equal(timevalue.note("bpm140 l8"), calcNote(140, 8, 0));
assert.equal(timevalue.note("bpm100 l16.."), calcNote(100, 16, 2));
assert.equal(timevalue.note("bpm100.5 L16"), calcNote(100.5, 16, 0));
assert.isNull(timevalue.note("bpm100.5"));
});
it("beat", function() {
assert.equal(timevalue.beat("bpm140 1.0.0") , calcBeat(140, 1, 0, 0));
assert.equal(timevalue.beat("bpm150.5 0.2.240"), calcBeat(150.5, 0, 2, 240));
assert.isNull(timevalue.beat("bpm150.5"));
});
it("ticks", function() {
assert.equal(timevalue.ticks("bpm120 480ticks"), calcTicks(120, 480));
assert.equal(timevalue.ticks("bpm150.5 120ticks"), calcTicks(150.5, 120));
assert.isNull(timevalue.ticks("bpm150.5"));
});
it("timevalue", function() {
assert.equal(timevalue.calc("50hz") , 1/50);
assert.equal(timevalue.calc("50.5hz") , 1/50.5);
assert.equal(timevalue.calc("50ms") , 50/1000);
assert.equal(timevalue.calc("50.5m") , 50.5/1000);
assert.equal(timevalue.calc("50sec") , 50);
assert.equal(timevalue.calc("50.5secs"), 50.5);
assert.equal(timevalue.calc("50min") , 50 * 60);
assert.equal(timevalue.calc("50.5mins"), 50.5 * 60);
assert.equal(timevalue.calc("1:00") , 60);
assert.equal(timevalue.calc("1:02.3" ), 62.3);
assert.equal(timevalue.calc("1:02.345"), 62.345);
assert.equal(timevalue.calc("1:02:03") , 3723);
assert.equal(timevalue.calc("1000samples") , 1000 / cc.sampleRate);
assert.equal(timevalue.calc("1000samples/8000hz"), 1000 / 8000);
assert.equal(timevalue.calc("bpm140 l8") , calcNote(140, 8, 0));
assert.equal(timevalue.calc("bpm100 l16.."), calcNote(100, 16, 2));
assert.equal(timevalue.calc("bpm100.5 L16"), calcNote(100.5, 16, 0));
assert.equal(timevalue.calc("bpm140 1.0.0") , calcBeat(140, 1, 0, 0));
assert.equal(timevalue.calc("bpm150.5 0.2.240"), calcBeat(150.5, 0, 2, 240));
assert.equal(timevalue.calc("bpm120 480ticks") , calcTicks(120, 480));
assert.equal(timevalue.calc("bpm150.5 120ticks"), calcTicks(150.5, 120));
});
it("freqvalue", function() {
assert.equal(timevalue.calc("~50hz") , 1/(1/50));
assert.equal(timevalue.calc("~50.5hz") , 1/(1/50.5));
assert.equal(timevalue.calc("~50ms") , 1/(50/1000));
assert.equal(timevalue.calc("~50.5m") , 1/(50.5/1000));
assert.equal(timevalue.calc("~50sec") , 1/50);
assert.equal(timevalue.calc("~50.5secs"), 1/(50.5));
assert.equal(timevalue.calc("~50min") , 1/(50 * 60));
assert.equal(timevalue.calc("~50.5mins"), 1/(50.5 * 60));
assert.equal(timevalue.calc("~1:00") , 1/60);
assert.equal(timevalue.calc("~1:02.3" ), 1/62.3);
assert.equal(timevalue.calc("~1:02.345"), 1/62.345);
assert.equal(timevalue.calc("~1:02:03") , 1/3723);
assert.equal(timevalue.calc("~1000samples"), 1/(1000 / cc.sampleRate));
assert.equal(timevalue.calc("~1000samples/8000hz"), 1/(1000 / 8000));
assert.equal(timevalue.calc("~bpm140 l8") , 1/calcNote(140, 8, 0));
assert.equal(timevalue.calc("~bpm100 l16.."), 1/calcNote(100, 16, 2));
assert.equal(timevalue.calc("~bpm100.5 L16"), 1/calcNote(100.5, 16, 0));
assert.equal(timevalue.calc("~bpm140 1.0.0") , 1/calcBeat(140, 1, 0, 0));
assert.equal(timevalue.calc("~bpm150.5 0.2.240"), 1/calcBeat(150.5, 0, 2, 240));
assert.equal(timevalue.calc("~bpm120 480ticks") , 1/calcTicks(120, 480));
assert.equal(timevalue.calc("~bpm150.5 120ticks"), 1/calcTicks(150.5, 120));
});
});

});

0 comments on commit 68119f4

Please sign in to comment.