Skip to content

Commit

Permalink
v0.1.8: allow arbitrary beat lengths, add line number to parser errors
Browse files Browse the repository at this point in the history
  • Loading branch information
ddj231 committed Jan 4, 2021
1 parent 30ba67a commit 6bb4381
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 54 deletions.
41 changes: 20 additions & 21 deletions HandelExport.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,22 +94,17 @@ const Handel = (function(){
}

secondsFromBPM(beats){
let valueToBeat = {
'4n': 1,
'2n': 2,
'2n.': 3,
'1m': 4,
}
return valueToBeat[beats]/(this.bpm / 60);
return beats/(this.bpm / 60);
}

configurePart(playEvents){
for(let playEvent of playEvents){
this.playEvents.push(playEvent);
let length = this.secondsFromBPM(playEvent.numBeats);
if(playEvent.notes){
this.part.add({notes: playEvent.notes, time: this.currentTime, length: playEvent.length});
this.part.add({notes: playEvent.notes, time: this.currentTime, length: length});
}
this.currentTime += this.secondsFromBPM(playEvent.length);
this.currentTime += length;
}
}

Expand All @@ -120,20 +115,17 @@ const Handel = (function(){
}

play(){
//Tone.Transport.bpm.value = this.bpm;
console.log(this.bpm);
this.configureLoop(this.loopTimes);
//Tone.Transport.bpm.rampTo(this.bpm, 0.05);
this.part.start(0.1);
//Tone.Transport.start();
}

}

class PlayEvent {
constructor(notes, length){
constructor(notes, length, numBeats){
this.length = length;
this.notes = notes
this.notes = notes;
this.numBeats = numBeats;
}
}

Expand Down Expand Up @@ -305,7 +297,10 @@ const Handel = (function(){

if(result !== ""){
if(result in RESERVED_KEYWORDS){
return RESERVED_KEYWORDS[result];
let token = RESERVED_KEYWORDS[result];
token.lineno = this.lineno
return token;
//return RESERVED_KEYWORDS[result];
}
return new Token(ID, result, this.lineno);
}
Expand Down Expand Up @@ -377,6 +372,10 @@ const Handel = (function(){
this.advance();
current = Number.parseInt(this.currentChar);
}
if(this.currentChar === 'b'){
this.advance();
return new Token(BEAT, digit, this.lineno);
}
return new Token(DIGIT, Number.parseInt(digit), this.lineno);
}
}
Expand Down Expand Up @@ -540,16 +539,16 @@ const Handel = (function(){
this.currentToken = this.lexer.getNextToken();
}

error(lineno){
throw new Error(`error parsing input at line ${lineno}`);
error(){
throw new Error(`error parsing input at line ${this.currentToken.lineno}`);
}

eat(type){
if(this.currentToken.type === type){
this.currentToken = this.lexer.getNextToken();
}
else{
this.error(this.currentToken.lineno);
this.error();
}
}

Expand Down Expand Up @@ -1070,10 +1069,10 @@ const Handel = (function(){

visitFor(node){
if(node.right){
return new PlayEvent(this.visitNoteList(node.left), this.beatToValue[node.right.value]);
return new PlayEvent(this.visitNoteList(node.left), this.beatToValue[node.right.value], node.right.value);
}
else{
return new PlayEvent(null, this.beatToValue[node.left.value]);
return new PlayEvent(null, this.beatToValue[node.left.value], node.left.value);
}
}

Expand Down
25 changes: 16 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,15 @@ This function is also globally available.

## Getting started

Handel programs are contained within the **start** and **finish** keywords. Below is a complete Handel program (and the shortest syntactically correct program):
Handel programs are contained within the **start** and **finish** keywords. Below is a complete Handel program:

```
start
play E4 for 1b
finish
```

The program above does nothing. But it's a start!
The program above only plays 1 note. But it's a start!

<br/>

Expand All @@ -96,11 +97,10 @@ finish

Note the syntax above. A **play** command begins with the **play** keyword, then a note or chord (a list of notes separated by commas) follows.

Lastly play commands need a duration. The play command above ends with 'for 1b'. This states how long the particular note or notelist (chord) should be held. Currently the available beat lenghts are 1b, 2b, 3b, and 4b.
Lastly play commands need a duration. The play commands above end with 'for 1b'. This states how long the particular note or notelist (chord) should be held.

Phew! We're getting somewhere.


<br/>

## Let's rest
Expand Down Expand Up @@ -141,15 +141,17 @@ D#6, E#6, G3 for 1b

*no promises that the above chord sounds pleasing to the ear :p*

**Durations** are the keyword **for** followed by a beat length.
**Durations** are the keyword **for** followed by a beat.

A **beat** is any whole number followed by the letter 'b'

Here are all available durations:
All together, here some example durations:

```
for 1b
for 2b
for 3b
for 4b
for 16b
for 32b
```

Finally variables!
Expand Down Expand Up @@ -324,7 +326,12 @@ C4, Eb4, G#3

<br/>

**Beat**: A number of beats. Only 4 possible (1b, 2b, 3b, and 4b).
**Beat**: A number of beats. A whole number followed by the character 'b'.
*Examples*
```
1b
20b
```

<br/>

Expand Down
32 changes: 9 additions & 23 deletions example.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,16 @@
function clicked(){
RunHandel(`
start
chunk gerand
play E4, G4, B4 for 1b
rest for 1b
play D3, G4, C4, E4 for 1b
rest for 1b
play E3, G#4, B4, Eb4 for 1b
rest for 1b
chunk arb
play E3, G3, B3 for 10b
rest for 4b
play D3, F3, A3 for 10b
rest for 4b
play F3, A3, C3 for 10b
rest for 4b
play E3, G3, B3 for 10b
endchunk
chunk backbeat
rest for 1b
rest for 1b
play E1 for 1b
endchunk
chunk hats
rest for 1b
play E1 for 1b
rest for 1b
endchunk
run gerand with bpm 120, sound piano, loop for 50
run hats with bpm 240, sound hihat, loop for 100
run backbeat with bpm 240, sound kick, loop for 100
run arb with bpm 200, sound piano
finish
`)
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "handel-pl",
"version": "0.1.7",
"version": "0.1.8",
"description": "",
"main": "HandelExport.js",
"scripts": {
Expand Down

0 comments on commit 6bb4381

Please sign in to comment.