-
Notifications
You must be signed in to change notification settings - Fork 0
/
browserIndex.js
113 lines (96 loc) · 3.53 KB
/
browserIndex.js
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
"use strict";
let getBPM = () => Tone.Transport.bpm.value;
function pianoRollToToneEvents(pianoRoll){
let notes = pianoRoll.notes;
let bpm = getBPM();
let toneEvents = Object.values(notes).map(noteInfo => {
let note = noteInfo.info;
return {
time: note.position,
pitch: noteInfo.label.text(),
dur: note.duration,
}
});
toneEvents.sort((a, b) => a.time-b.time);
toneEvents = toneEvents.filter(e => e.time+e.dur > pianoRoll.cursorPosition);
toneEvents.forEach(e => {
if(e.time < pianoRoll.cursorPosition) {
e.dur = e.dur - (pianoRoll.cursorPosition-e.time);
e.time = 0;
} else {
e.time -= pianoRoll.cursorPosition;
}
});
toneEvents = toneEvents.map((note, i) => {
return {
time: note.time * 60 / bpm,
pitch: note.pitch,
dur: note.dur * 60 / bpm,
info: {
numNotes: toneEvents.length,
ind: i
}
}
});
return toneEvents;
}
//TODO: maybe move part and playing-flag variables to inside toneclass?
let playCursorLoop;
let pianoRollIsPlaying = false;
let playingPart;
function playPianoRoll(pianoRoll){
let toneEvents = pianoRollToToneEvents(pianoRoll);
let playTime = toneEvents.slice(-1)[0].time + toneEvents.slice(-1)[0].dur;
let playStartPos = pianoRoll.cursorPosition * pianoRoll.quarterNoteWidth;
let playScreenDist = playTime * getBPM() / 60 * pianoRoll.quarterNoteWidth;
pianoRoll.playCursorElement.opacity(1);
playCursorLoop = animitter(function(deltaTime, elapsedTime, frameCount){
if(elapsedTime/1000 >= playTime){
pianoRoll.playCursorElement.opacity(0);
this.complete();
console.log("finished playing", elapsedTime/1000, playTime);
}
let playFrac = elapsedTime/1000/playTime;
pianoRoll.playCursorElement.x(playStartPos + playFrac*playScreenDist);
}).start();
playingPart = new Tone.Part((time, value) => {
console.log('part note', time, value);
pianoRoll.playHandler(value.pitch, value.dur) //and velocity once that's in the piano roll
if(value.info.numNotes == value.info.ind+1) pianoRollIsPlaying = false;
}, toneEvents).start();
pianoRollIsPlaying = true;
}
function stopPianoRoll(pianoRoll){
if(playingPart){
playCursorLoop.complete()
pianoRoll.playCursorElement.opacity(0);
pianoRollIsPlaying = false;
playingPart.stop();
playingPart.dispose();
}
}
let pianoRoll;
let synth = new Tone.PolySynth(8).toMaster();
StartAudioContext(Tone.context, 'body', () => {
Tone.Transport.start();
});
SVG.on(document, 'DOMContentLoaded', function() {
let playHandler = function(pitch, duration='16n'){
//if duration is "on" then just do noteOn, if its "off" just do note off
let pitchString = typeof pitch === 'string' ? pitch : this.midiPitchToPitchString(pitch);
synth.triggerAttackRelease(pitchString, duration);
}
let onOffHanlder = function(pitch, onOff){
let pitchString = typeof pitch === 'string' ? pitch : this.midiPitchToPitchString(pitch);
if(onOff == 'on'){
synth.triggerAttack(pitchString);
} else {
synth.triggerRelease(pitchString);
}
}
pianoRoll = new PianoRoll("drawing", playHandler, onOffHanlder);
});
/*
WORKING BUG LOG
- X prefix means good workaround found, but the "common sense" approach still fails and idk why
*/