Skip to content

Commit

Permalink
Song accidentals
Browse files Browse the repository at this point in the history
  • Loading branch information
espadrine committed Mar 10, 2016
1 parent 064af5b commit b56ff60
Showing 1 changed file with 28 additions and 11 deletions.
39 changes: 28 additions & 11 deletions lib/midi/song.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ var parseAbc = function(text) {
// Tokenizer states.
var tstate = {
main: function(tok, c) {
if (isNote(c)) {
if (isAccidental(c)) {
tok.startToken();
return tstate.accidental;
} if (isNote(c)) {
tok.startToken();
return tstate.letter;
} else if (c === undefined) {
return tstate.end;
Expand All @@ -81,11 +85,20 @@ var tstate = {
end: function(tok, c) {},

// A note has the following elements:
// letter [octave] [duration].
// [accidental] letter [octave] [duration].

accidental: function(tok, c) {
if (isNote(c)) {
return tstate.letter;
} else if (c === '^') {
tok.accidental++;
} else if (c === '_') {
tok.accidental--;
}
},

// We are on a letter.
letter: function(tok, c) {
tok.startToken();
tok.note = tok.char().charCodeAt(0);
if (tok.note >= 97) { // Higher-pitched (a-g instead of A-G).
tok.note -= 32; // Convert to A-G.
Expand Down Expand Up @@ -113,7 +126,7 @@ var tstate = {
var slash = (c === '/');
var number = /^[0-9]$/.test(c);
if (number || slash) {
tok.numStart = tok.i;
tok.spanStart = tok.i;
tok.char();
if (number) {
return tstate.durNum;
Expand All @@ -128,7 +141,7 @@ var tstate = {
durNum: function(tok, c) {
var number = /^[0-9]$/.test(c);
if (!number) {
var num = tok.text.slice(tok.numStart, tok.i);
var num = tok.text.slice(tok.spanStart, tok.i);
tok.durNum = +num;
if (c === '/') {
tok.char();
Expand All @@ -144,7 +157,7 @@ var tstate = {
var slash = (c === '/');
var number = /^[0-9]$/.test(c);
if (number) {
tok.numStart = tok.i;
tok.spanStart = tok.i;
tok.char();
return tstate.durDenom;
} else if (slash) {
Expand All @@ -159,7 +172,7 @@ var tstate = {
durSlashes: function(tok, c) {
var slash = (c === '/');
if (!slash) {
var slashes = tok.i - tok.numStart;
var slashes = tok.i - tok.spanStart;
tok.durDenom = (1 << slashes);
return tstate.mkNote;
}
Expand All @@ -168,15 +181,15 @@ var tstate = {
durDenom: function(tok, c) {
var number = /^[0-9]$/.test(c);
if (!number) {
var num = tok.text.slice(tok.numStart, tok.i);
var num = tok.text.slice(tok.spanStart, tok.i);
tok.durDenom = +num;
return tstate.mkNote;
}
},

mkNote: function(tok, c) {
var dur = tok.durNum / tok.durDenom;
var note = tok.note + tok.octave * 12;
var note = tok.note + tok.octave * 12 + tok.accidental;
tok.addNote(note, dur);
return tstate.main;
},
Expand All @@ -195,7 +208,8 @@ var Tokenizer = function(text) {
this.note = undefined;
this.octave = 0;
this.noteStart = 0;
this.numStart = 0;
this.spanStart = 0;
this.accidental = 0;
this.durNum = 1;
this.durDenom = 1;
this.noteDur = 0.4;
Expand All @@ -212,7 +226,8 @@ Tokenizer.prototype = {
note: undefined, // MIDI note number between A-G.
octave: 0,
noteStart: 0, // Time since the start of the song.
numStart: 0, // Position in the text string.
spanStart: 0, // Position in the text string.
accidental: 0, // Sharp / flat note change.
durNum: 1, // Note duration numerator / denominator.
durDenom: 1,
noteDur: 0.5, // Note duration.
Expand Down Expand Up @@ -254,6 +269,7 @@ Tokenizer.prototype = {
this.noteStart += dur * this.noteDur;
this.token(noteOffEvent(note, this.noteStart + this.noteOverlay));
this.octave = 0;
this.accidental = 0;
this.durNum = 1;
this.durDenom = 1;
this.noteDur = 0.4;
Expand All @@ -262,6 +278,7 @@ Tokenizer.prototype = {
};

var isNote = function(c) { return /^[a-gA-G]$/.test(c); };
var isAccidental = function(c) { return /^[\^_=]$/.test(c); };
var isSilence = function(c) { return /^[zZ]$/.test(c); };

var noteOnEvent = function(note, start) {
Expand Down

0 comments on commit b56ff60

Please sign in to comment.