UNPKG

10.7 kBHTMLView Raw
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="utf-8">
5 <title>JSDoc: Source: index.js</title>
6
7 <script src="scripts/prettify/prettify.js"> </script>
8 <script src="scripts/prettify/lang-css.js"> </script>
9 <!--[if lt IE 9]>
10 <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
13 <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
14</head>
15
16<body>
17
18<div id="main">
19
20 <h1 class="page-title">Source: index.js</h1>
21
22
23
24
25
26
27 <section>
28 <article>
29 <pre class="prettyprint source linenums"><code>var circleOfFifths = require('./dict/circleOfFifths.json');
30var accidental = require('./dict/accidentals.json');
31var pitches = require('./dict/pitches.json');
32var durations = require('./dict/durations.json');
33var clefs = require('./dict/clefs.json');
34
35var Parser = require('./lib/abc_parser');
36
37/**
38 * Returns the abc notation string from given input
39 * @param {object} input - The parsed input from input file
40 * @returns {string}
41 */
42function getAbcString(input) {
43 var outputData = "";
44 outputData += "X:"
45 + input.id
46 + "\n";
47 outputData += "T:"
48 + input.id
49 + "\n";
50 outputData += "M:"
51 + input.attributes.time.beats
52 + "/"
53 + input.attributes.time["beat-type"]
54 + "\n";
55 outputData += "L:"
56 + "1/"
57 + (input.attributes.divisions * input.attributes.time["beat-type"])
58 + "\n";
59 outputData += "K:"
60 + getAbcKey(input.attributes.key.fifths, input.attributes.key.mode)
61 + "\n";
62 outputData += "K:"
63 + getAbcClef(input.attributes.clef.sign)
64 + "\n";
65
66 for (var i = 0; i &lt; input.measures.length; i++) {
67 if (i % 5 === 0 &amp;&amp; i > 0) { // 5 measures per line
68 outputData += "\n";
69 outputData += "|";
70 }
71 var measure = input.measures[i];
72 if (measure.attributes.repeat.left) {
73 outputData += ":";
74 }
75
76 for (var j = 0; j &lt; measure.notes.length; j++) {
77
78 outputData += getAbcNote(measure.notes[j-1], measure.notes[j]);
79 }
80
81 if (measure.attributes.repeat.right) {
82 outputData += ":";
83 }
84 outputData += "|";
85
86 }
87
88 return outputData;
89}
90
91/**
92 * Returns the abc notation string from given input
93 * @param {object} input - The parsed input from input file
94 * @returns {string}
95 */
96function getMusicJSON(input) {
97 var outputData = {};
98 var parser = new Parser();
99 parser.parse(input);
100 var tune = parser.getTune();
101 outputData = createJsonFromLines(tune);
102 outputData.id = getJsonId(input);
103
104 return JSON.stringify(outputData);
105}
106
107/**
108 * Returns the key for abc notation from given fifths
109 * @param {number} fifths - The position inside the circle of fifths
110 * @param {string|undefined} mode - The mode (major / minor)
111 * @returns {string}
112 */
113function getAbcKey(fifths, mode) {
114 if (typeof mode === 'undefined') mode = 'major';
115 return circleOfFifths[mode][fifths];
116}
117
118/**
119 * Returns the key for abc notation from given fifths
120 * @param {string} sign - The clef sign
121 * @returns {string}
122 */
123function getAbcClef(sign) {
124 return clefs[sign];
125}
126
127/**
128 * Returns a note in abc notation from given note object (JSON)
129 * @param {object} prevNote - The previous note
130 * @param {object} curNote - The note that should be transformed to abc
131 * @returns {string}
132 */
133function getAbcNote(prevNote, curNote) {
134 var _accidental = accidental.json[curNote.pitch.accidental];
135 var _pitch = pitches.json[curNote.pitch.octave][curNote.pitch.step];
136 var _duration = curNote.duration;
137 if (typeof prevNote !== 'undefined') {
138 if (prevNote.dot) {
139 _duration = _duration * 2;
140 }
141 }
142 var _dotted = '';
143 if (curNote.dot) {
144 _dotted = '>';
145 }
146
147 // check if rest
148 if (curNote.rest) {
149 // return rest as abc
150 return "z" + _duration + _dotted;
151 } else {
152 // return note as abc
153 return _accidental + _pitch + _duration + _dotted;
154 }
155}
156
157/**
158 * Get id from abc string
159 * @param data
160 * @returns {string}
161 */
162var getJsonId = function getJSONId(data) {
163 var lines = data.split('\n');
164 for (var i = 0; i &lt; lines.length; i++) {
165 if (lines[i].indexOf('X:') > -1) {
166 return lines[i].substr(lines[i].indexOf(':') + 1, lines[i].length);
167 }
168 }
169 throw new Error('Could not determine "X:" field');
170};
171
172/**
173 * Creates json object from abc tunes object
174 * @param {object} tune - The parsed tune object
175 * @returns {object}
176 */
177var createJsonFromLines = function(tune) {
178 var ret = {
179 attributes: {
180 divisions: 1 /tune.getBeatLength(),
181 clef: {
182 line: 2
183 },
184 key: {},
185 time: {}
186 }
187 };
188 var measures = [];
189 var measureCounter = 0;
190 var barlineCounter = 0;
191
192 // parse lines
193 for (var l = 0; l &lt; tune.lines.length; l++) {
194 for (var s = 0; s &lt; tune.lines[l].staff.length; s++) {
195 var staff = tune.lines[l].staff[s];
196
197 // parse default clef, key, meter
198 if (l === 0 &amp;&amp; s === 0) {
199 ret.attributes.clef.sign = getKeyByValue(clefs, staff.clef.type);
200 ret.attributes.clef.line = staff.clef.clefPos / 2;
201 ret.attributes.key.fifths = parseInt(getKeyByValue(circleOfFifths, staff.key.root));
202 ret.attributes.time.beats = staff.meter.value[0].num;
203 ret.attributes.time['beat-type'] = staff.meter.value[0].den;
204 }
205
206 for (var v = 0; v &lt; staff.voices.length; v++) {
207 for (var t = 0; t &lt; staff.voices[v].length; t++) {
208 var token = staff.voices[v][t];
209
210 // init measure if none exists
211 if (measures[measureCounter] === undefined) {
212 measures[measureCounter] = new Measure();
213 }
214
215 switch (token.el_type) {
216 case "note":
217 measures[measureCounter].addNote(token, tune, ret.attributes.divisions, ret.attributes.time['beat-type']);
218 break;
219 case "bar":
220 if (token.type === 'bar_right_repeat') {
221 measures[measureCounter].setRepeatRight();
222 }
223 measureCounter++;
224 if (measures[measureCounter] === undefined) {
225 measures[measureCounter] = new Measure();
226 }
227 if (token.type === 'bar_left_repeat') {
228 measures[measureCounter].setRepeatLeft();
229 }
230 break;
231 }
232 }
233 }
234 }
235 }
236
237 // put measures together
238 ret.measures = [];
239 for (var i = 0; i &lt; measures.length; i++) {
240 var measure = measures[i].get();
241 if (measure.notes.length > 0) {
242 ret.measures.push(measure);
243 }
244 }
245 return ret;
246};
247
248/**
249 * Constructor for measure objects
250 */
251var Measure = function() {
252 var attributes = {
253 repeat: {
254 left: false,
255 right: false
256 }
257 };
258 var notes = [];
259
260 this.setRepeatLeft = function () {
261 attributes.repeat.left = true;
262 };
263 this.setRepeatRight = function () {
264 attributes.repeat.right = true;
265 };
266
267 this.addNote = function(note, tune, divisions, beatType) {
268 var _note = {pitch:{}};
269 var _octave = 5, _step, _alter = 0;
270 if (note.hasOwnProperty('pitches')) {
271 _octave--;
272 _step = note.pitches[0].pitch;
273 while (_step > 6) {
274 _octave++;
275 _step -= 7;
276 }
277 while (_step &lt; 0) {
278 _octave--;
279 _step +=7
280 }
281 _note.pitch.step = pitches.abc[_step];
282 _note.rest = false;
283 if (note.pitches[0].hasOwnProperty('accidental')) {
284 _alter = accidental.abc[note.pitches[0].accidental];
285 _note.pitch.accidental = note.pitches[0].accidental;
286 }
287 } else {
288 _note.pitch.step = "C";
289 _note.pitch.octave = 5;
290 _note.rest = true;
291 _note.pitch.alter = 0;
292 }
293 _note.pitch.octave = _octave;
294 _note.pitch.alter = _alter;
295
296 for (var i = 0; i &lt; durations.length; i++) {
297 if (typeof durations[i+1] !== 'undefined') {
298 if (durations[i].duration > note.duration &amp;&amp; durations[i+1].duration &lt;= note.duration) {
299 var diff = note.duration - durations[i+1].duration;
300 _note.duration = durations[i+1].duration * divisions * beatType;
301 _note.type = durations[i+1].type;
302 if (diff > 0) {
303 if ((diff / durations[i+1].duration) === 0.5) {
304 _note.dot = true;
305 } else {
306 throw new Error('Unknown duration: ' + note.duration);
307 }
308 }
309 break;
310 }
311 } else {
312 throw new Error('Unknown duration: ' + note.duration);
313 }
314 }
315
316 notes.push(_note);
317 };
318
319 this.get = function() {
320 return {
321 attributes: attributes,
322 notes: notes
323 };
324 };
325};
326
327/**
328 * Get object key by value
329 * @param {object} object - The object to search in
330 * @param {string} value - The value to search for
331 * @returns {string}
332 */
333var getKeyByValue = function(object, value) {
334 for (var key in object) {
335 if (!object.hasOwnProperty(key)) continue;
336 if (typeof object[key] === 'object') {
337 return getKeyByValue(object[key], value);
338 } else {
339 if (object[key] == value) return key;
340 }
341 }
342};
343
344/**
345 * Returns a string in abc notation from given data
346 * @param {object} data - The JSON string data that should be transformed to abc
347 * @returns {string}
348 */
349exports.convert2Abc = function(data) {
350 return getAbcString(JSON.parse(data));
351};
352
353/**
354 * Returns a string in json notation from given abc data
355 * @param {object} data - The abc string that should be transformed to json
356 * @returns {string}
357 */
358exports.convert2JSON = function(data) {
359 return getMusicJSON(data);
360};
361
362// Run jsdoc with: jsdoc index.js -d doc -R README.md
363</code></pre>
364 </article>
365 </section>
366
367
368
369
370</div>
371
372<nav>
373 <h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#convert2Abc">convert2Abc</a></li><li><a href="global.html#convert2JSON">convert2JSON</a></li><li><a href="global.html#createJsonFromLines">createJsonFromLines</a></li><li><a href="global.html#getAbcClef">getAbcClef</a></li><li><a href="global.html#getAbcKey">getAbcKey</a></li><li><a href="global.html#getAbcNote">getAbcNote</a></li><li><a href="global.html#getAbcString">getAbcString</a></li><li><a href="global.html#getJsonId">getJsonId</a></li><li><a href="global.html#getKeyByValue">getKeyByValue</a></li><li><a href="global.html#getMusicJSON">getMusicJSON</a></li><li><a href="global.html#Measure">Measure</a></li></ul>
374</nav>
375
376<br class="clear">
377
378<footer>
379 Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.4.0</a> on Sat Apr 23 2016 19:38:33 GMT+0200 (Mitteleuropäische Sommerzeit)
380</footer>
381
382<script> prettyPrint(); </script>
383<script src="scripts/linenumber.js"> </script>
384</body>
385</html>