-
Notifications
You must be signed in to change notification settings - Fork 12
/
addChord.qml
172 lines (150 loc) · 6.07 KB
/
addChord.qml
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import MuseScore 1.0
import QtQuick 2.0
MuseScore {
version: "1.0";
description: "This demo plugin adds new chords\n\n" +
"Comments, feedbacks, report bugs, ask for new features, contribute:\n" +
"https://github.com/rousselmanu/msc_plugins/";
menuPath: "Plugins.Chords." + qsTr("Add Chord Demo")
// ---------- remove duplicate notes from chord (notes with same pitch) --------
function rm_dup(chord){
var chord_notes=new Array();
if(chord.pitch != null){
for(var i=0; i<chord.length; i++)
chord_notes[i] = chord[i].pitch; // remove octaves
}else{
chord_notes=chord;
}
chord_notes.sort(function(a, b) { return a - b; }); //sort notes
var chord_uniq = chord_notes.filter(function(elem, index, self) {
return index == self.indexOf(elem);
}); //remove duplicates
return chord_uniq;
}
function rm_octave(chord){
var chord_notes=new Array();
if(chord.pitch != null){
for(var i=0; i<chord.length; i++)
chord_notes[i] = chord[i].pitch%12; // remove octaves
}else{
for(var i=0; i<chord.length; i++)
chord_notes[i]=chord[i]%12;
}
return chord_notes;
}
function shift_notes(chord, n){
var shifted_chord=new Array();
for(var i=0; i<chord.length; i++)
shifted_chord[i] = chord[i]+n;
return shifted_chord;
}
// create and return a new Note element with given (midi) pitch, tpc1, tpc2 and headtype
function createNote(pitch, tpc1, tpc2, head){
var note = newElement(Element.NOTE);
note.pitch = pitch;
var pitch_mod12 = pitch%12;
var pitch2tpc=[14,21,16,23,18,13,20,15,22,17,24,19]; //get tpc from pitch... yes there is a logic behind these numbers :-p
if (tpc1){
note.tpc1 = tpc1;
note.tpc2 = tpc2;
}else{
note.tpc1 = pitch2tpc[pitch_mod12];
note.tpc2 = pitch2tpc[pitch_mod12];
}
if (head) note.headType = head;
else note.headType = NoteHead.HEAD_AUTO;
console.log(" created note with tpc: ",note.tpc1," ",note.tpc2," pitch: ",note.pitch);
return note;
}
function setCursorToTime(cursor, time){
cursor.rewind(0);
while (cursor.segment) {
var current_time = cursor.tick;
if(current_time>=time){
return true;
}
cursor.next();
}
cursor.rewind(0);
return false;
}
//adds chord at current position. chord_notes is an array with pitch of notes.
function addChord(cursor, chord_notes, duration){
if(chord_notes.length==0) return -1;
if(chord_notes.length>1) chord_notes=rm_dup(chord_notes);
var cur_time=cursor.tick;
cursor.setDuration(1, duration);
cursor.addNote(chord_notes[0]); //add 1st note
var next_time=cursor.tick;
setCursorToTime(cursor, cur_time); //rewind to this note
var chord = cursor.element; //get the chord created when 1st note was inserted
for(var i=1; i<chord_notes.length; i++){
chord.add(createNote(chord_notes[i])); //add notes to the chord
}
setCursorToTime(cursor, next_time);
return 0;
}
//note to pitch
function n2p(note, octave){
var notenames=['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'];
var pitch=notenames.indexOf(note);
if(pitch==-1) return -1;
pitch+=12*(octave+1);
//console.log('pitch: '+pitch);
return pitch;
}
onRun: {
if (typeof curScore === 'undefined') {
Qt.quit();
}
var cursor = curScore.newCursor(),
startStaff,
endStaff,
endTick,
fullScore = false;
cursor.rewind(1);
if (!cursor.segment) { // no selection
fullScore = true;
startStaff = 0; // start with 1st staff
endStaff = curScore.nstaves - 1; // and end with last
} else {
startStaff = cursor.staffIdx;
cursor.rewind(2);
if (cursor.tick === 0) {
// this happens when the selection includes
// the last measure of the score.
// rewind(2) goes behind the last segment (where
// there's none) and sets tick=0
endTick = curScore.lastSegment.tick + 1;
} else {
endTick = cursor.tick;
}
endStaff = cursor.staffIdx;
}
console.log(startStaff + " - " + endStaff + " - " + endTick);
console.log('curScore.nstaves: ' + curScore.nstaves);
console.log('cursor.tick: ' + cursor.tick);
console.log('curScore.lastSegment.tick: ' + curScore.lastSegment.tick);
cursor.rewind(1); // beginning of selection
if (fullScore) { // no selection
cursor.rewind(0); // beginning of score
}
cursor.voice = 0;
cursor.staffIdx = startStaff; //staff;
//cursor.track = 0;
// ------------------ GENERATE CHORDS ----------------
addChord(cursor, [n2p('D',4)], 2); //add a D4 note
addChord(cursor, [n2p('D',4), n2p('A',4), n2p('D',5), n2p('F',5)], 4); //add a Dm chord with 2 roots
addChord(cursor, [n2p('A#',3), n2p('D',4), n2p('G',4)], 4);
addChord(cursor, [n2p('A',3), n2p('G',4), n2p('C#',5)], 4);
addChord(cursor, [n2p('D',4), n2p('D',5), n2p('F',4), n2p('A',4)], 2);
addChord(cursor, [62], 1); //other method to add note: give the pitch
addChord(cursor, [60, 65, 69, 72, 69], 8); //duplicate note is automatically removed
addChord(cursor, [60], 8);
var chord = [60, 64, 67];
addChord(cursor, shift_notes(chord,5), 8); //shift the chord by 5 semi-tones
addChord(cursor, chord, 2);
// ----------------------------------
Qt.quit();
} // end onRun
}