abcjs 6.0.0-beta.8 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (204) hide show
  1. package/.github/workflows/tests.yml +29 -0
  2. package/CODE_OF_CONDUCT.md +76 -0
  3. package/CONTRIBUTING.md +1 -0
  4. package/LICENSE.md +1 -1
  5. package/README.md +92 -3
  6. package/RELEASE.md +959 -1
  7. package/abcjs-audio.css +14 -5
  8. package/dist/.gitignore +1 -2
  9. package/dist/abcjs-basic-min.js +3 -0
  10. package/dist/abcjs-basic-min.js.LICENSE +23 -0
  11. package/dist/abcjs-basic.js +28232 -0
  12. package/dist/abcjs-basic.js.map +1 -0
  13. package/dist/abcjs-plugin-min.js +3 -0
  14. package/dist/abcjs-plugin-min.js.LICENSE +23 -0
  15. package/dist/report-basic.html +37 -0
  16. package/dist/report-before-glyph-compress.html +37 -0
  17. package/dist/report-brown-ts-target-es5.html +37 -0
  18. package/dist/report-dev-orig-no-babel.html +37 -0
  19. package/dist/report-synth.html +37 -0
  20. package/docker-build.sh +1 -0
  21. package/glyphs.json +1 -0
  22. package/index.js +27 -2
  23. package/{static-wrappers/license.js → license.js} +1 -1
  24. package/package.json +26 -29
  25. package/{src/plugin/abc_plugin.js → plugin.js} +31 -19
  26. package/src/api/abc_animation.js +1 -17
  27. package/src/api/abc_tablatures.js +144 -0
  28. package/src/api/abc_timing_callbacks.js +239 -116
  29. package/src/api/abc_tunebook.js +18 -67
  30. package/src/api/abc_tunebook_svg.js +38 -46
  31. package/src/data/abc_tune.js +232 -972
  32. package/src/data/deline-tune.js +199 -0
  33. package/src/edit/abc_editarea.js +112 -0
  34. package/src/edit/abc_editor.js +95 -221
  35. package/src/midi/abc_midi_create.js +48 -50
  36. package/src/parse/abc_common.js +0 -14
  37. package/src/parse/abc_parse.js +167 -1321
  38. package/src/parse/abc_parse_book.js +62 -0
  39. package/src/parse/abc_parse_directive.js +164 -41
  40. package/src/parse/abc_parse_header.js +116 -145
  41. package/src/parse/abc_parse_key_voice.js +26 -20
  42. package/src/parse/abc_parse_music.js +1337 -0
  43. package/src/parse/abc_tokenizer.js +21 -15
  44. package/src/parse/abc_transpose.js +3 -15
  45. package/src/parse/tune-builder.js +896 -0
  46. package/src/parse/wrap_lines.js +205 -453
  47. package/src/synth/abc_midi_flattener.js +1292 -0
  48. package/src/{midi → synth}/abc_midi_renderer.js +44 -17
  49. package/src/synth/abc_midi_sequencer.js +648 -0
  50. package/src/synth/active-audio-context.js +3 -14
  51. package/src/synth/cents-to-factor.js +10 -0
  52. package/src/synth/create-note-map.js +21 -32
  53. package/src/synth/create-synth-control.js +20 -103
  54. package/src/synth/create-synth.js +185 -77
  55. package/src/synth/download-buffer.js +7 -21
  56. package/src/synth/get-midi-file.js +13 -20
  57. package/src/synth/images/{loading.svg → loading.svg.js} +4 -0
  58. package/src/synth/images/loop.svg.js +65 -0
  59. package/src/synth/images/pause.svg.js +10 -0
  60. package/src/synth/images/play.svg.js +9 -0
  61. package/src/synth/images/{reset.svg → reset.svg.js} +5 -1
  62. package/src/synth/instrument-index-to-name.js +1 -16
  63. package/src/synth/load-note.js +37 -76
  64. package/src/synth/pitch-to-note-name.js +0 -15
  65. package/src/synth/pitches-to-perc.js +64 -0
  66. package/src/synth/place-note.js +78 -68
  67. package/src/synth/play-event.js +17 -18
  68. package/src/synth/register-audio-context.js +11 -23
  69. package/src/synth/sounds-cache.js +0 -15
  70. package/src/synth/supports-audio.js +9 -23
  71. package/src/synth/synth-controller.js +80 -49
  72. package/src/synth/synth-sequence.js +20 -34
  73. package/src/tablatures/instruments/guitar/guitar-fonts.js +19 -0
  74. package/src/tablatures/instruments/guitar/guitar-patterns.js +23 -0
  75. package/src/tablatures/instruments/guitar/tab-guitar.js +50 -0
  76. package/src/tablatures/instruments/string-patterns.js +277 -0
  77. package/src/tablatures/instruments/string-tablature.js +56 -0
  78. package/src/tablatures/instruments/tab-note.js +282 -0
  79. package/src/tablatures/instruments/tab-notes.js +41 -0
  80. package/src/tablatures/instruments/violin/tab-violin.js +47 -0
  81. package/src/tablatures/instruments/violin/violin-fonts.js +19 -0
  82. package/src/tablatures/instruments/violin/violin-patterns.js +23 -0
  83. package/src/tablatures/tab-absolute-elements.js +310 -0
  84. package/src/tablatures/tab-common.js +29 -0
  85. package/src/tablatures/tab-renderer.js +243 -0
  86. package/src/tablatures/transposer.js +110 -0
  87. package/src/test/abc_midi_lint.js +5 -22
  88. package/src/test/abc_midi_sequencer_lint.js +11 -14
  89. package/src/test/abc_parser_lint.js +136 -32
  90. package/src/test/abc_vertical_lint.js +94 -32
  91. package/src/test/rendering-lint.js +38 -5
  92. package/src/write/abc_absolute_element.js +112 -120
  93. package/src/write/abc_abstract_engraver.js +102 -253
  94. package/src/write/abc_beam_element.js +30 -290
  95. package/src/write/abc_brace_element.js +12 -121
  96. package/src/write/abc_create_clef.js +21 -32
  97. package/src/write/abc_create_key_signature.js +8 -26
  98. package/src/write/abc_create_note_head.js +107 -0
  99. package/src/write/abc_create_time_signature.js +2 -21
  100. package/src/write/abc_crescendo_element.js +3 -50
  101. package/src/write/abc_decoration.js +7 -30
  102. package/src/write/abc_dynamic_decoration.js +3 -37
  103. package/src/write/abc_ending_element.js +1 -57
  104. package/src/write/abc_engraver_controller.js +111 -234
  105. package/src/write/abc_glyphs.js +8 -18
  106. package/src/write/abc_relative_element.js +57 -97
  107. package/src/write/abc_renderer.js +10 -832
  108. package/src/write/abc_spacing.js +0 -15
  109. package/src/write/abc_staff_group_element.js +14 -349
  110. package/src/write/abc_tempo_element.js +9 -117
  111. package/src/write/abc_tie_element.js +5 -68
  112. package/src/write/abc_triplet_element.js +6 -124
  113. package/src/write/abc_voice_element.js +7 -222
  114. package/src/write/add-chord.js +103 -0
  115. package/src/write/add-text-if.js +33 -0
  116. package/src/write/bottom-text.js +79 -0
  117. package/src/write/calcHeight.js +17 -0
  118. package/src/write/classes.js +100 -0
  119. package/src/write/draw/absolute.js +68 -0
  120. package/src/write/draw/beam.js +56 -0
  121. package/src/write/draw/brace.js +106 -0
  122. package/src/write/draw/crescendo.js +38 -0
  123. package/src/write/draw/debug-box.js +8 -0
  124. package/src/write/draw/draw.js +56 -0
  125. package/src/write/draw/dynamics.js +20 -0
  126. package/src/write/draw/ending.js +46 -0
  127. package/src/write/draw/group-elements.js +66 -0
  128. package/src/write/draw/horizontal-line.js +25 -0
  129. package/src/write/draw/non-music.js +50 -0
  130. package/src/write/draw/print-line.js +24 -0
  131. package/src/write/draw/print-path.js +7 -0
  132. package/src/write/draw/print-stem.js +30 -0
  133. package/src/write/draw/print-symbol.js +59 -0
  134. package/src/write/draw/print-vertical-line.js +18 -0
  135. package/src/write/draw/relative.js +77 -0
  136. package/src/write/draw/round-number.js +5 -0
  137. package/src/write/draw/selectables.js +59 -0
  138. package/src/write/draw/separator.js +16 -0
  139. package/src/write/draw/set-paper-size.js +45 -0
  140. package/src/write/{sprintf.js → draw/sprintf.js} +0 -0
  141. package/src/write/draw/staff-group.js +226 -0
  142. package/src/write/draw/staff-line.js +9 -0
  143. package/src/write/draw/staff.js +33 -0
  144. package/src/write/draw/tab-line.js +40 -0
  145. package/src/write/draw/tempo.js +45 -0
  146. package/src/write/draw/text.js +71 -0
  147. package/src/write/draw/tie.js +97 -0
  148. package/src/write/draw/triplet.js +46 -0
  149. package/src/write/draw/voice.js +102 -0
  150. package/src/write/format-jazz-chord.js +15 -0
  151. package/src/write/free-text.js +41 -0
  152. package/src/write/get-font-and-attr.js +37 -0
  153. package/src/write/get-text-size.js +56 -0
  154. package/src/write/highlight.js +11 -0
  155. package/src/write/layout/VoiceElements.js +121 -0
  156. package/src/write/layout/beam.js +213 -0
  157. package/src/write/layout/get-left-edge-of-staff.js +56 -0
  158. package/src/write/layout/getBarYAt.js +6 -0
  159. package/src/write/layout/layout.js +94 -0
  160. package/src/write/layout/setUpperAndLowerElements.js +232 -0
  161. package/src/write/layout/staffGroup.js +146 -0
  162. package/src/write/layout/triplet.js +75 -0
  163. package/src/write/layout/voice.js +137 -0
  164. package/src/write/selection.js +188 -70
  165. package/src/write/separator.js +10 -0
  166. package/src/write/set-class.js +21 -0
  167. package/src/write/subtitle.js +12 -0
  168. package/src/write/svg.js +95 -43
  169. package/src/write/top-text.js +54 -0
  170. package/src/write/unhighlight.js +11 -0
  171. package/temp.txt +15256 -0
  172. package/test.js +27 -64
  173. package/types/index.d.ts +1095 -0
  174. package/version.js +1 -1
  175. package/.babelrc +0 -5
  176. package/.eslintrc +0 -3
  177. package/.gitmodules +0 -3
  178. package/abcjs-midi.css +0 -166
  179. package/build-utils/loadPresets.js +0 -14
  180. package/build-utils/presets/webpack.analyze.js +0 -6
  181. package/build-utils/presets/webpack.optimize.js +0 -30
  182. package/build-utils/webpack.development.js +0 -14
  183. package/build-utils/webpack.production.js +0 -35
  184. package/deploy-docs.sh +0 -25
  185. package/docs/README.md +0 -33
  186. package/fix-versions.sh +0 -23
  187. package/mei.js +0 -43
  188. package/midi.js +0 -62
  189. package/src/api/abc_tunebook_midi.js +0 -116
  190. package/src/midi/abc_midi_controls.js +0 -701
  191. package/src/midi/abc_midi_flattener.js +0 -1119
  192. package/src/midi/abc_midi_js_preparer.js +0 -243
  193. package/src/midi/abc_midi_sequencer.js +0 -401
  194. package/src/midi/abc_midi_ui_generator.js +0 -86
  195. package/src/plugin/abc_plugin_midi.js +0 -220
  196. package/src/synth/images/loop.svg +0 -61
  197. package/src/synth/images/pause.svg +0 -6
  198. package/src/synth/images/play.svg +0 -5
  199. package/src/transform/abc2abc_write.js +0 -395
  200. package/static-wrappers/basic.js +0 -2
  201. package/static-wrappers/midi.js +0 -2
  202. package/static-wrappers/plugin-midi.js +0 -6
  203. package/static-wrappers/plugin.js +0 -6
  204. package/webpack.config.js +0 -29
@@ -1,26 +1,12 @@
1
- // Copyright (C) 2019-2020 Paul Rosen (paul at paulrosen dot net)
2
- //
3
- // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
- // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
5
- // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
6
- // to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
- //
8
- // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
- //
10
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
11
- // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
13
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
-
16
1
  var downloadBuffer = function(buffer) {
17
2
  return window.URL.createObjectURL(bufferToWave(buffer.audioBuffers));
18
3
  };
19
4
 
20
5
  // Convert an AudioBuffer to a Blob using WAVE representation
21
6
  function bufferToWave(audioBuffers) {
22
- var numOfChan = audioBuffers.length;
23
- var length = audioBuffers[0].length * numOfChan * 2 + 44;
7
+ var audioBuffer = audioBuffers[0];
8
+ var numOfChan = audioBuffer.numberOfChannels;
9
+ var length = audioBuffer.length * numOfChan * 2 + 44;
24
10
  var buffer = new ArrayBuffer(length);
25
11
  var view = new DataView(buffer);
26
12
  var channels = [];
@@ -38,8 +24,8 @@ function bufferToWave(audioBuffers) {
38
24
  setUint32(16); // length = 16
39
25
  setUint16(1); // PCM (uncompressed)
40
26
  setUint16(numOfChan);
41
- setUint32(audioBuffers[0].sampleRate);
42
- setUint32(audioBuffers[0].sampleRate * 2 * numOfChan); // avg. bytes/sec
27
+ setUint32(audioBuffer.sampleRate);
28
+ setUint32(audioBuffer.sampleRate * 2 * numOfChan); // avg. bytes/sec
43
29
  setUint16(numOfChan * 2); // block-align
44
30
  setUint16(16); // 16-bit (hardcoded in this demo)
45
31
 
@@ -47,8 +33,8 @@ function bufferToWave(audioBuffers) {
47
33
  setUint32(length - pos - 4); // chunk length
48
34
 
49
35
  // write interleaved data
50
- for(i = 0; i < audioBuffers.length; i++)
51
- channels.push(audioBuffers[i].getChannelData(0));
36
+ for(i = 0; i < numOfChan; i++)
37
+ channels.push(audioBuffer.getChannelData(i));
52
38
 
53
39
  while(pos < length) {
54
40
  for(i = 0; i < channels.length; i++) { // interleave channels
@@ -1,22 +1,7 @@
1
- // Copyright (C) 2019-2020 Paul Rosen (paul at paulrosen dot net)
2
- //
3
- // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
- // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
5
- // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
6
- // to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
- //
8
- // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
- //
10
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
11
- // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
13
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
-
16
1
  var tunebook = require('../api/abc_tunebook');
17
2
  var midiCreate = require('../midi/abc_midi_create');
18
3
 
19
- var getMidiFile = function(abcString, options) {
4
+ var getMidiFile = function(source, options) {
20
5
  var params = {};
21
6
  if (options) {
22
7
  for (var key in options) {
@@ -27,7 +12,7 @@ var getMidiFile = function(abcString, options) {
27
12
  }
28
13
  params.generateInline = false;
29
14
 
30
- function callback(div, tune, index, abcString) {
15
+ function callback(div, tune, index) {
31
16
  var downloadMidi = midiCreate(tune, params);
32
17
  switch (params.midiOutputType) {
33
18
  case "encoded":
@@ -48,12 +33,19 @@ var getMidiFile = function(abcString, options) {
48
33
  default:
49
34
  return generateMidiDownloadLink(tune, params, downloadMidi, index);
50
35
  }
51
- return downloadMidi;
52
36
  }
53
37
 
54
- return tunebook.renderEngine(callback, "*", abcString, params);
38
+ if (typeof source === "string")
39
+ return tunebook.renderEngine(callback, "*", source, params);
40
+ else
41
+ return callback(null, source, 0);
55
42
  };
56
43
 
44
+ function isFunction(functionToCheck) {
45
+ var getType = {};
46
+ return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
47
+ }
48
+
57
49
  var generateMidiDownloadLink = function(tune, midiParams, midi, index) {
58
50
  var divClasses = ['abcjs-download-midi', 'abcjs-midi-' + index]
59
51
  if (midiParams.downloadClass)
@@ -70,7 +62,8 @@ var generateMidiDownloadLink = function(tune, midiParams, midi, index) {
70
62
  else
71
63
  label = "Download MIDI for \"" + title + "\"";
72
64
  title = title.toLowerCase().replace(/'/g, '').replace(/\W/g, '_').replace(/__/g, '_');
73
- html += '<a download="' + title + '.midi" href="' + midi + '">' + label + '</a>';
65
+ var filename = (midiParams.fileName) ? midiParams.fileName : title + '.midi';
66
+ html += '<a download="' + filename + '" href="' + midi + '">' + label + '</a>';
74
67
  if (midiParams.postTextDownload)
75
68
  html += midiParams.postTextDownload;
76
69
  return html + "</div>";
@@ -1,3 +1,7 @@
1
+ var svg = `
1
2
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" class="abcjs-loading-svg">
2
3
  <circle cx="50" cy="50" fill="none" stroke-width="20" r="35" stroke-dasharray="160 55"></circle>
3
4
  </svg>
5
+ `
6
+
7
+ module.exports = svg
@@ -0,0 +1,65 @@
1
+ var svg = `
2
+ <svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 700" preserveAspectRatio="xMidYMid meet">
3
+ <g transform="translate(0,700) scale(0.1,-0.1)" >
4
+ <path d="M3111 6981 c-20 -37 -90 -55 -364 -96 -120 -18 -190 -33 -244 -55
5
+ -42 -17 -124 -42 -182 -56 -78 -18 -119 -34 -157 -60 -28 -19 -86 -46 -128
6
+ -60 -43 -13 -107 -42 -144 -64 -37 -23 -84 -46 -106 -52 -21 -7 -56 -29 -79
7
+ -50 -22 -22 -61 -50 -86 -63 -26 -13 -67 -40 -91 -60 -24 -20 -65 -47 -90 -60
8
+ -25 -13 -53 -31 -61 -41 -8 -9 -32 -30 -54 -46 -75 -54 -486 -460 -512 -507
9
+ -15 -25 -48 -69 -75 -98 -26 -28 -48 -57 -48 -63 0 -6 -18 -29 -39 -53 -21
10
+ -23 -56 -71 -77 -107 -20 -36 -50 -80 -65 -97 -16 -18 -33 -52 -40 -75 -12
11
+ -47 -47 -115 -84 -166 -13 -18 -30 -56 -38 -83 -8 -27 -34 -80 -56 -118 -33
12
+ -53 -46 -91 -62 -167 -12 -63 -34 -127 -59 -179 -42 -84 -60 -166 -60 -270 0
13
+ -90 26 -122 125 -154 54 -17 96 -19 430 -20 305 -1 381 2 430 14 82 22 140 51
14
+ 153 78 6 12 22 47 37 77 14 30 38 77 54 103 15 27 34 73 40 103 7 30 28 78 48
15
+ 107 19 28 44 74 55 101 10 28 34 67 53 87 18 20 49 61 68 90 19 30 44 63 57
16
+ 74 13 11 36 40 52 65 59 94 232 270 306 313 20 11 57 37 82 58 25 20 70 52
17
+ 100 72 30 19 66 47 79 61 13 14 49 35 80 46 30 12 80 37 111 56 31 19 95 45
18
+ 143 58 48 12 110 37 139 55 63 40 127 55 323 76 83 9 208 28 279 41 156 29
19
+ 165 29 330 4 453 -71 514 -84 606 -130 31 -16 83 -36 116 -45 32 -9 84 -34
20
+ 115 -56 31 -21 82 -48 113 -60 32 -11 72 -33 89 -48 18 -16 59 -45 92 -65 33
21
+ -21 74 -51 90 -66 17 -15 49 -40 73 -54 52 -32 65 -61 50 -113 -8 -31 -61 -90
22
+ -277 -308 -300 -303 -361 -382 -369 -481 -2 -29 0 -66 6 -81 13 -40 88 -138
23
+ 115 -151 12 -6 54 -26 92 -44 l70 -33 945 -2 c520 -1 975 2 1012 7 64 8 191
24
+ 50 231 76 11 7 33 34 50 60 22 34 42 51 65 58 l32 9 0 1101 0 1102 -32 9 c-21
25
+ 7 -44 26 -64 55 -60 84 -77 97 -140 110 -44 9 -76 10 -127 2 -59 -9 -77 -17
26
+ -134 -62 -37 -28 -172 -155 -301 -281 -129 -127 -249 -237 -267 -245 -25 -10
27
+ -41 -11 -71 -2 -58 15 -112 45 -124 69 -6 11 -35 35 -64 54 -28 18 -58 41 -66
28
+ 50 -8 9 -41 35 -75 58 -33 22 -77 56 -99 75 -21 18 -64 46 -95 61 -31 14 -73
29
+ 39 -93 55 -20 15 -70 40 -110 55 -40 15 -97 44 -127 64 -29 21 -78 44 -107 53
30
+ -30 8 -77 31 -105 51 -42 28 -73 39 -173 60 -68 14 -154 39 -196 58 -95 43
31
+ -131 51 -343 76 -209 24 -242 32 -279 70 l-30 29 -328 0 c-312 0 -330 -1 -339
32
+ -19z"></path>
33
+ <path d="M254 2875 c-89 -16 -107 -26 -145 -78 -32 -44 -62 -66 -91 -67 -17 0
34
+ -18 -61 -18 -1140 l0 -1140 24 0 c16 0 41 -17 72 -50 40 -42 61 -55 117 -72
35
+ l69 -21 82 23 c44 12 96 30 114 39 18 9 148 132 290 272 141 141 267 261 279
36
+ 268 51 26 86 14 176 -61 32 -26 62 -48 66 -48 5 0 36 -25 70 -55 34 -30 74
37
+ -61 89 -69 15 -8 37 -28 50 -45 12 -17 50 -45 84 -62 34 -17 78 -44 98 -60 19
38
+ -16 61 -37 93 -48 32 -11 81 -37 107 -56 27 -20 76 -45 109 -56 33 -12 75 -31
39
+ 93 -44 62 -45 93 -58 191 -82 54 -12 130 -37 168 -54 68 -29 180 -58 226 -59
40
+ 62 0 183 -64 183 -96 0 -12 88 -14 639 -14 l639 0 12 30 c18 44 76 66 233 89
41
+ 89 14 160 30 200 47 34 15 106 42 159 60 54 18 112 44 130 57 47 35 85 52 146
42
+ 67 29 7 76 28 105 48 29 20 77 48 107 63 30 15 66 39 80 54 14 15 50 40 81 56
43
+ 31 15 78 46 104 69 26 22 61 46 79 54 17 7 43 26 56 42 14 16 41 41 60 56 64
44
+ 48 380 362 408 405 15 23 40 51 55 63 15 12 36 38 46 58 11 21 37 57 58 82 22
45
+ 25 49 62 62 83 13 20 38 56 57 78 19 23 50 74 69 113 19 39 46 86 59 104 14
46
+ 18 34 62 46 98 12 36 32 77 45 92 31 38 60 97 80 167 9 33 26 76 37 95 29 50
47
+ 47 103 68 206 10 52 32 117 51 155 29 56 33 74 34 140 0 94 -10 108 -101 138
48
+ -61 20 -83 21 -463 21 -226 0 -421 -4 -451 -10 -63 -12 -86 -30 -110 -85 -10
49
+ -22 -33 -63 -52 -92 -21 -31 -42 -80 -53 -123 -11 -44 -32 -93 -56 -128 -20
50
+ -32 -47 -83 -59 -115 -12 -32 -37 -77 -56 -100 -19 -23 -50 -65 -69 -94 -19
51
+ -29 -44 -57 -54 -63 -11 -5 -29 -27 -42 -47 -52 -85 -234 -277 -300 -315 -25
52
+ -15 -53 -38 -62 -51 -9 -14 -42 -39 -74 -57 -32 -18 -75 -48 -95 -66 -21 -18
53
+ -59 -44 -85 -58 -26 -13 -72 -40 -100 -59 -35 -24 -78 -41 -128 -52 -47 -11
54
+ -99 -31 -139 -56 -69 -42 -94 -49 -391 -110 -245 -51 -425 -66 -595 -50 -168
55
+ 16 -230 27 -330 61 -47 16 -123 35 -170 44 -98 17 -123 25 -172 58 -20 14 -71
56
+ 37 -114 53 -44 15 -95 40 -115 56 -20 16 -70 42 -110 59 -40 16 -88 45 -108
57
+ 63 -20 19 -55 46 -78 61 -24 14 -49 35 -55 47 -7 11 -34 33 -60 49 -50 31 -65
58
+ 61 -53 102 4 13 130 147 281 298 236 238 277 283 299 335 15 32 35 71 46 86
59
+ 12 18 19 44 19 76 0 42 -8 63 -53 138 -92 151 11 139 -1207 141 -798 2 -1030
60
+ 0 -1086 -11z"></path>
61
+ </g>
62
+ </svg>
63
+ `
64
+
65
+ module.exports = svg
@@ -0,0 +1,10 @@
1
+ var svg = `
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25" class="abcjs-pause-svg">
3
+ <g>
4
+ <rect width="8.23" height="25"/>
5
+ <rect width="8.23" height="25" x="17"/>
6
+ </g>
7
+ </svg>
8
+ `
9
+
10
+ module.exports = svg
@@ -0,0 +1,9 @@
1
+ var svg = `
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25" class="abcjs-play-svg">
3
+ <g>
4
+ <polygon points="4 0 23 12.5 4 25"/>
5
+ </g>
6
+ </svg>
7
+ `
8
+
9
+ module.exports = svg
@@ -1,6 +1,10 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 25 25">
1
+ var svg = `
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 25 25">
2
3
  <g>
3
4
  <polygon points="5 12.5 24 0 24 25"/>
4
5
  <rect width="3" height="25" x="0" y="0"/>
5
6
  </g>
6
7
  </svg>
8
+ `
9
+
10
+ module.exports = svg
@@ -1,18 +1,3 @@
1
- // Copyright (C) 2019-2020 Paul Rosen (paul at paulrosen dot net)
2
- //
3
- // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
- // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
5
- // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
6
- // to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
- //
8
- // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
- //
10
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
11
- // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
13
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
-
16
1
  var instrumentIndexToName = [
17
2
  "acoustic_grand_piano",
18
3
  "bright_acoustic_piano",
@@ -111,7 +96,7 @@ var instrumentIndexToName = [
111
96
  "lead_5_charang",
112
97
  "lead_6_voice",
113
98
  "lead_7_fifths",
114
- "lead_8_bass__lead",
99
+ "lead_8_bass_lead",
115
100
 
116
101
  "pad_1_new_age",
117
102
  "pad_2_warm",
@@ -1,83 +1,44 @@
1
- // Copyright (C) 2019-2020 Paul Rosen (paul at paulrosen dot net)
2
- //
3
- // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
- // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
5
- // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
6
- // to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
- //
8
- // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
- //
10
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
11
- // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
13
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
-
16
1
  // Load one mp3 file for one note.
17
2
  // url = the base url for the soundfont
18
3
  // instrument = the instrument name (e.g. "acoustic_grand_piano")
19
4
  // name = the pitch name (e.g. "A3")
20
- var soundsCache = require('./sounds-cache');
21
-
22
- var getNote = function(url, instrument, name, audioContext) {
23
- return new Promise(function (resolve, reject) {
24
- if (!soundsCache[instrument])
25
- soundsCache[instrument] = {};
26
- var instrumentCache = soundsCache[instrument];
27
-
28
- if (instrumentCache[name] === 'error') {
29
- return resolve({instrument: instrument, name: name, status: "error", message: "Unable to load sound font" + ' ' + url + ' ' + instrument + ' ' + name });
30
- }
31
- if (instrumentCache[name] === 'pending') {
32
- return resolve({instrument: instrument, name: name, status: "pending"});
33
- }
34
- if (instrumentCache[name]) {
35
- return resolve({instrument: instrument, name: name, status: "cached"});
36
- }
37
-
38
- // if (this.debugCallback)
39
- // this.debugCallback(`Loading sound: ${instrument} ${name}`);
40
- instrumentCache[name] = "pending"; // This can be called in parallel, so don't call it a second time before the first one has loaded.
41
- var xhr = new XMLHttpRequest();
42
- xhr.open('GET', url+instrument+'-mp3/'+name+'.mp3', true);
43
- xhr.responseType = 'arraybuffer';
44
-
45
- var self = this;
46
- function onSuccess(audioBuffer) {
47
- instrumentCache[name] = audioBuffer;
48
- // if (self.debugCallback)
49
- // self.debugCallback(`Sound loaded: ${instrument} ${name} ${url}`);
50
- resolve({instrument: instrument, name: name, status: "loaded"});
51
- }
52
-
53
- function onFailure(error) {
54
- error = "Can't decode sound. " + url + ' ' + instrument + ' ' + name + error;
55
- if (self.debugCallback)
56
- self.debugCallback(error);
57
- console.log(error);
58
- return resolve({instrument: instrument, name: name, status: "error", message: error });
59
- }
60
-
61
- xhr.onload = function (e) {
62
- if (this.status === 200) {
63
- audioContext.decodeAudioData(this.response, onSuccess, onFailure);
64
- } else {
65
- instrumentCache[name] = "error"; // To keep this from trying to load repeatedly.
66
- var cantLoadMp3 = "Onload error loading sound: " + name + " " + url + " " + e.currentTarget.status + " " + e.currentTarget.statusText;
67
- if (self.debugCallback)
68
- self.debugCallback(cantLoadMp3);
69
- return resolve({instrument: instrument, name: name, status: "error", message: cantLoadMp3 });
70
- }
71
- };
72
- xhr.addEventListener("error", function () {
73
- instrumentCache[name] = "error"; // To keep this from trying to load repeatedly.
74
- var cantLoadMp3 = "Error in loading sound: " + " " + url;
75
- if (self.debugCallback)
76
- self.debugCallback(cantLoadMp3);
77
- return resolve({instrument: instrument, name: name, status: "error", message: cantLoadMp3 });
78
- }, false);
79
- xhr.send();
80
- });
5
+ var soundsCache = require("./sounds-cache");
6
+
7
+ var getNote = function (url, instrument, name, audioContext) {
8
+ if (!soundsCache[instrument]) soundsCache[instrument] = {};
9
+ var instrumentCache = soundsCache[instrument];
10
+
11
+ if (!instrumentCache[name])
12
+ instrumentCache[name] = new Promise(function (resolve, reject) {
13
+ var xhr = new XMLHttpRequest();
14
+ let noteUrl = url + instrument + "-mp3/" + name + ".mp3";
15
+ xhr.open("GET", noteUrl, true);
16
+ xhr.responseType = "arraybuffer";
17
+ xhr.onload = function () {
18
+ if (xhr.status !== 200) {
19
+ reject(Error("Can't load sound at " + noteUrl));
20
+ return
21
+ }
22
+ var noteDecoded = function(audioBuffer) {
23
+ resolve({instrument: instrument, name: name, status: "loaded", audioBuffer: audioBuffer})
24
+ }
25
+ var maybePromise = audioContext.decodeAudioData(xhr.response, noteDecoded, function () {
26
+ reject(Error("Can't decode sound at " + noteUrl));
27
+ });
28
+ // In older browsers `BaseAudioContext.decodeAudio()` did not return a promise
29
+ if (maybePromise && typeof maybePromise.catch === "function") maybePromise.catch(reject);
30
+ };
31
+ xhr.onerror = function () {
32
+ reject(Error("Can't load sound at " + noteUrl));
33
+ };
34
+ xhr.send();
35
+ })
36
+ .catch(err => {
37
+ console.error("Didn't load note", instrument, name, ":", err.message);
38
+ throw err;
39
+ });
40
+
41
+ return instrumentCache[name];
81
42
  };
82
43
 
83
44
  module.exports = getNote;
@@ -1,18 +1,3 @@
1
- // Copyright (C) 2019-2020 Paul Rosen (paul at paulrosen dot net)
2
- //
3
- // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
- // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
5
- // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
6
- // to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
- //
8
- // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
- //
10
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
11
- // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
13
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
-
16
1
  var pitchToNoteName = {
17
2
  21: 'A0',
18
3
  22: 'Bb0',
@@ -0,0 +1,64 @@
1
+ var pitchMap = {
2
+ f0: "_C",
3
+ n0: "=C",
4
+ s0: "^C",
5
+ x0: "C",
6
+ f1: "_D",
7
+ n1: "=D",
8
+ s1: "^D",
9
+ x1: "D",
10
+ f2: "_E",
11
+ n2: "=E",
12
+ s2: "^E",
13
+ x2: "E",
14
+ f3: "_F",
15
+ n3: "=F",
16
+ s3: "^F",
17
+ x3: "F",
18
+ f4: "_G",
19
+ n4: "=G",
20
+ s4: "^G",
21
+ x4: "G",
22
+ f5: "_A",
23
+ n5: "=A",
24
+ s5: "^A",
25
+ x5: "A",
26
+ f6: "_B",
27
+ n6: "=B",
28
+ s6: "^B",
29
+ x6: "B",
30
+ f7: "_c",
31
+ n7: "=c",
32
+ s7: "^c",
33
+ x7: "c",
34
+ f8: "_d",
35
+ n8: "=d",
36
+ s8: "^d",
37
+ x8: "d",
38
+ f9: "_e",
39
+ n9: "=e",
40
+ s9: "^e",
41
+ x9: "e",
42
+ f10: "_f",
43
+ n10: "=f",
44
+ s10: "^f",
45
+ x10: "f",
46
+ f11: "_g",
47
+ n11: "=g",
48
+ s11: "^g",
49
+ x11: "g",
50
+ f12: "_a",
51
+ n12: "=a",
52
+ s12: "^a",
53
+ x12: "a",
54
+ f13: "_b",
55
+ n13: "=b",
56
+ s13: "^b",
57
+ x13: "b",
58
+ }
59
+
60
+ function pitchesToPerc(pitchObj) {
61
+ var pitch = (pitchObj.accidental ? pitchObj.accidental[0] : 'x') + pitchObj.verticalPos;
62
+ return pitchMap[pitch];
63
+ }
64
+ module.exports = pitchesToPerc;
@@ -1,84 +1,94 @@
1
- // Copyright (C) 2019-2020 Paul Rosen (paul at paulrosen dot net)
2
- //
3
- // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4
- // documentation files (the "Software"), to deal in the Software without restriction, including without limitation
5
- // the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
6
- // to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
- //
8
- // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
- //
10
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
11
- // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
12
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
13
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
-
16
1
  var soundsCache = require('./sounds-cache');
17
2
  var pitchToNoteName = require('./pitch-to-note-name');
3
+ var centsToFactor = require("./cents-to-factor");
18
4
 
19
- var OfflineAC = window.OfflineAudioContext ||
20
- window.webkitOfflineAudioContext;
5
+ function placeNote(outputAudioBuffer, sampleRate, sound, startArray, volumeMultiplier, ofsMs, fadeTimeSec, noteEndSec) {
6
+ // sound contains { instrument, pitch, volume, len, pan, tempoMultiplier
7
+ // len is in whole notes. Multiply by tempoMultiplier to get seconds.
8
+ // ofsMs is an offset to subtract from the note to line up programs that have different length onsets.
9
+ var OfflineAC = window.OfflineAudioContext ||
10
+ window.webkitOfflineAudioContext;
21
11
 
22
- function placeNote(outputAudioBuffer, sampleRate, sound, startArray) {
23
12
  var len = sound.len * sound.tempoMultiplier;
24
- var offlineCtx = new OfflineAC(2,Math.floor((len+0.5)*sampleRate*2),sampleRate);
25
- var noteName = pitchToNoteName[sound.pitch+60];
26
- var noteBuffer = soundsCache[sound.instrument][noteName];
27
- if (noteBuffer === "error") { // If the note isn't available, just leave a blank spot
28
- console.log("Didn't load note: " + sound.instrument + " " + noteName);
29
- return;
13
+ if (ofsMs)
14
+ len +=ofsMs/1000;
15
+ len -= noteEndSec;
16
+ if (len < 0)
17
+ len = 0.005; // Have some small audible length no matter how short the note is.
18
+ var offlineCtx = new OfflineAC(2,Math.floor((len+fadeTimeSec)*sampleRate),sampleRate);
19
+ var noteName = pitchToNoteName[sound.pitch];
20
+ var noteBufferPromise = soundsCache[sound.instrument][noteName];
21
+
22
+ if (!noteBufferPromise) {
23
+ // if the note isn't present then just skip it - it will leave a blank spot in the audio.
24
+ return Promise.resolve();
30
25
  }
31
26
 
32
- // create audio buffer
33
- var source = offlineCtx.createBufferSource();
34
- source.buffer = noteBuffer;
27
+ return noteBufferPromise
28
+ .then(function (response) {
29
+ // create audio buffer
30
+ var source = offlineCtx.createBufferSource();
31
+ source.buffer = response.audioBuffer;
35
32
 
36
- // add gain
37
- // volume can be between 1 to 127. This translation to gain is just trial and error.
38
- // The smaller the first number, the more dynamic range between the quietest to loudest.
39
- // The larger the second number, the louder it will be in general.
40
- var volume = (sound.volume / 96) * 3.0;
41
- source.gainNode = offlineCtx.createGain();
33
+ // add gain
34
+ // volume can be between 1 to 127. This translation to gain is just trial and error.
35
+ // The smaller the first number, the more dynamic range between the quietest to loudest.
36
+ // The larger the second number, the louder it will be in general.
37
+ var volume = (sound.volume / 96) * volumeMultiplier;
38
+ source.gainNode = offlineCtx.createGain();
42
39
 
43
- // add pan if supported and present
44
- if (sound.pan && offlineCtx.createStereoPanner) {
45
- source.panNode = offlineCtx.createStereoPanner();
46
- source.panNode.pan.setValueAtTime(sound.pan, 0);
47
- }
48
- source.gainNode.gain.value = volume; // Math.min(2, Math.max(0, volume));
49
- source.gainNode.gain.linearRampToValueAtTime(source.gainNode.gain.value, len);
50
- source.gainNode.gain.linearRampToValueAtTime(0.0, len + 0.3);
40
+ // add pan if supported and present
41
+ if (sound.pan && offlineCtx.createStereoPanner) {
42
+ source.panNode = offlineCtx.createStereoPanner();
43
+ source.panNode.pan.setValueAtTime(sound.pan, 0);
44
+ }
45
+ source.gainNode.gain.value = volume; // Math.min(2, Math.max(0, volume));
46
+ source.gainNode.gain.linearRampToValueAtTime(source.gainNode.gain.value, len);
47
+ source.gainNode.gain.linearRampToValueAtTime(0.0, len + fadeTimeSec);
51
48
 
52
- // connect all the nodes
53
- if (source.panNode) {
54
- source.panNode.connect(offlineCtx.destination);
55
- source.gainNode.connect(source.panNode);
56
- } else {
57
- source.gainNode.connect(offlineCtx.destination);
58
- }
59
- source.connect(source.gainNode);
49
+ if (sound.cents) {
50
+ source.playbackRate.value = centsToFactor(sound.cents);
51
+ }
60
52
 
61
- // Do the process of creating the sound and placing it in the buffer
62
- source.start(0);
53
+ // connect all the nodes
54
+ if (source.panNode) {
55
+ source.panNode.connect(offlineCtx.destination);
56
+ source.gainNode.connect(source.panNode);
57
+ } else {
58
+ source.gainNode.connect(offlineCtx.destination);
59
+ }
60
+ source.connect(source.gainNode);
63
61
 
64
- if (source.noteOff) {
65
- source.noteOff(len + 0.5);
66
- } else {
67
- source.stop(len + 0.5);
68
- }
69
- var fnResolve;
70
- offlineCtx.oncomplete = function(e) {
71
- if (e.renderedBuffer) { // If the system gets overloaded then this can start failing. Just drop the note if so.
72
- for (var i = 0; i < startArray.length; i++) {
73
- copyToChannel(outputAudioBuffer, e.renderedBuffer, Math.floor(startArray[i] * sound.tempoMultiplier * sampleRate));
62
+ // Do the process of creating the sound and placing it in the buffer
63
+ source.start(0);
64
+
65
+ if (source.noteOff) {
66
+ source.noteOff(len + fadeTimeSec);
67
+ } else {
68
+ source.stop(len + fadeTimeSec);
74
69
  }
75
- }
76
- fnResolve();
77
- };
78
- offlineCtx.startRendering();
79
- return new Promise(function(resolve, reject) {
80
- fnResolve = resolve;
81
- });
70
+ var fnResolve;
71
+ offlineCtx.oncomplete = function(e) {
72
+ if (e.renderedBuffer) { // If the system gets overloaded then this can start failing. Just drop the note if so.
73
+ for (var i = 0; i < startArray.length; i++) {
74
+ //Math.floor(startArray[i] * sound.tempoMultiplier * sampleRate)
75
+ var start = startArray[i] * sound.tempoMultiplier;
76
+ if (ofsMs)
77
+ start -=ofsMs/1000;
78
+ if (start < 0)
79
+ start = 0; // If the item that is moved back is at the very beginning of the buffer then don't move it back. To do that would be to push everything else forward. TODO-PER: this should probably be done at some point but then it would change timing in existing apps.
80
+ start = Math.floor(start*sampleRate);
81
+ copyToChannel(outputAudioBuffer, e.renderedBuffer, start);
82
+ }
83
+ }
84
+ fnResolve();
85
+ };
86
+ offlineCtx.startRendering();
87
+ return new Promise(function(resolve) {
88
+ fnResolve = resolve;
89
+ });
90
+ })
91
+ .catch(function () {});
82
92
  }
83
93
 
84
94
  var copyToChannel = function(toBuffer, fromBuffer, start) {