-
Notifications
You must be signed in to change notification settings - Fork 5
/
chordsplitter.js
154 lines (124 loc) · 4.38 KB
/
chordsplitter.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/* Herrmutt Lobby • Chord Splitter JS 0.7 */
/* (c) Herrmutt Lobby 2012 • herrmuttlobby.com */
/* This code is distributed under a Creative Commons : Attribution, Share Alike, No-commercial Licence */
/* INPUT : list message starting with note then a note number and velocity ( note noteNbr velocity ) or "reset" message to reset the chord */
/* OUTPUT : quick series of ordered note tuples ( [index, noteNbr, velocity, nbrOfNoteInTheChord] ) */
/* MADE TO BE USED WITHIN the JS object of MAX4LIVE or MAX/MSP or in PureData with the jj object of the PDJ external (http://www.le-son666.com/software/pdj/) */
/* CONFIG (should be done with message through an inlet */
groupSend = false; // choose between pushing note once by once through the outlet, or all in a big tuple
DEBUG = false; // put in debug mode
/* CODE */
/* quick sort function */
quicksort = function( input ){
if(input.length <= 1) return input;
var pivot = input.splice(0, 1);
var less = [];
var greater = [];
var x;
for(i = 0; i < input.length; i++)
{
x = input[i];
switch(splitter.sortAlgo)
{
default:
case "sortUp":
x <= pivot[0][0] ? less.push(x) : greater.push(x);
break;
case "sortDown":
x >= pivot[0][0] ? less.push(x) : greater.push(x);
}
}
return [].concat(quicksort(less), pivot, quicksort(greater));
}
var splitter = {
groupSend : groupSend
,chord : []
,addStatus : false
,outChord : []
,sortAlgo : "sortUp" // choose an sort algorythm ( sortUp, sortDown, ...)
}
//*NOTE IN*//
//* When a note is received we check if the note is a note on or a note off and route them accordingly. *//
splitter.newNote = function(note){
if(DEBUG) post("newnote " + note);
// if note velocity different of 0 add note otherwise remove
note[1] ? this.addNote(note) : this.delNote(note);
}
//*NOTE ON*//
//* When a note on (vel not equal to 0) is received, the note is added to the buffer, then the buffer is sorted and sent to output *//
splitter.addNote = function(note){ /* add a note to the chord */
this.addStatus = true;
this.chord.push(note);
this.chord = quicksort(this.chord);
this.output42();
}
//*NOTE OFF*//
//* When a note with a velocity of 0 (note off) is received, the corresponding note on is removed from the buffer and the note off is send with the channel number of the corresponding note on, then the buffer is sent to output *//
splitter.delNote = function(note){
this.addStatus = false;
for (i = 0; i < this.chord.length; i++)
{
if(this.chord[i][0] === note[0])
{
outlet(0, [this.chord[i][3], this.chord[i][0], 0, this.chord.length-1]);
this.chord.splice(i, 1);
}
}
this.output42();
}
//*RESET*//
//* On a reset message a note off is sent to the output and the buffer is cleared. *//
splitter.reset = function()
{
for (i = 0; i< this.chord.length; i++)
{
outlet(0, [this.chord[i][3], this.chord[i][0], 0, this.chord.length-1]);
}
this.chord = [];
}
//*OUTPUT*//
//* When we need to send the whole buffer (after a note on or off) we trig this output function *//
splitter.output42 = function(){
this.outChord = []; //init the big tuple wich will be sent if we asked for
for (i = 0; i < this.chord.length; i++){
if(this.chord[i][3] != i+1 && this.chord[i][3]) // if the note channel has been shifted from previous position
{
outlet(0, [this.chord[i][3], this.chord[i][0], 0, this.chord.length-1]); // send note off
this.chord[i][2] = false;
}
this.chord[i][3] = i+1; // change the channel number
if(splitter.groupSend == false){ // send note on
if(this.chord[i][2] == false)
{
outlet(0, [this.chord[i][3], this.chord[i][0], this.chord[i][1], this.chord.length]);
this.chord[i][2] = true;
}
}
else{ //populate the big tuple
this.outChord.push([this.chord[i][3], this.chord[i][0], this.chord[i][1], this.chord.length]);
}
}
if(splitter.groupSend == true){ /* Sending the big tuple if asked for */
outlet(0, outChord);
outlet(1, this.chord.length);
}
}
/* MAIN */
inlets = 1; // number of inlets
outlets = 2; // number of outlets
function note(note, vel)
{
splitter.newNote([note, vel, false]);
}
function list(info, note, vel)
{
splitter.newNote([note, vel, false]);
}
function algo(algorythm)
{
splitter.sortAlgo = algorythm;
}
function reset()
{
splitter.reset();
}