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,20 +1,6 @@
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 SynthSequence = require('./synth-sequence');
17
2
  var CreateSynth = require('./create-synth');
3
+ var activeAudioContext = require("./active-audio-context");
18
4
 
19
5
  function playEvent(midiPitches, midiGracePitches, millisecondsPerMeasure) {
20
6
  var sequence = new SynthSequence();
@@ -26,12 +12,23 @@ function playEvent(midiPitches, midiGracePitches, millisecondsPerMeasure) {
26
12
  if (i === 0 && midiGracePitches) {
27
13
  for (var j = 0; j < midiGracePitches.length; j++) {
28
14
  var grace = midiGracePitches[j];
29
- sequence.appendNote(trackNum, grace.pitch, 1 / 64, grace.volume);
15
+ sequence.appendNote(trackNum, grace.pitch, 1 / 64, grace.volume, grace.cents);
30
16
  }
31
17
  }
32
- sequence.appendNote(trackNum, note.pitch, note.durationInMeasures, note.volume);
18
+ sequence.appendNote(trackNum, note.pitch, note.duration, note.volume, note.cents);
33
19
  }
34
20
 
21
+ var ac = activeAudioContext();
22
+ if (ac.state === "suspended") {
23
+ return ac.resume().then(function () {
24
+ return doPlay(sequence, millisecondsPerMeasure);
25
+ });
26
+ } else {
27
+ return doPlay(sequence, millisecondsPerMeasure);
28
+ }
29
+ }
30
+
31
+ function doPlay(sequence, millisecondsPerMeasure) {
35
32
  var buffer = new CreateSynth();
36
33
  return buffer.init({
37
34
  sequence: sequence,
@@ -39,7 +36,9 @@ function playEvent(midiPitches, midiGracePitches, millisecondsPerMeasure) {
39
36
  }).then(function () {
40
37
  return buffer.prime();
41
38
  }).then(function () {
42
- return buffer.start();
39
+ buffer.start();
40
+ return Promise.resolve();
43
41
  });
44
42
  }
43
+
45
44
  module.exports = playEvent;
@@ -1,32 +1,20 @@
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
  // Call this when it is safe for the abcjs to produce sound. This is after the first user gesture on the page.
17
2
  // If you call it with no parameters, then an AudioContext is created and stored.
18
3
  // If you call it with a parameter, that is used as an already created AudioContext.
19
4
 
20
5
  function registerAudioContext(ac) {
21
- if (!window.abcjsAudioContext) {
22
- if (!ac) {
23
- ac = window.AudioContext ||
24
- window.webkitAudioContext ||
25
- navigator.mozAudioContext ||
26
- navigator.msAudioContext;
27
- ac = new ac();
28
- }
6
+ // If one is passed in, that is the one to use even if there was already one created.
7
+ if (ac)
29
8
  window.abcjsAudioContext = ac;
9
+ else {
10
+ // no audio context passed in, so create it unless there is already one from before.
11
+ if (!window.abcjsAudioContext) {
12
+ var AudioContext = window.AudioContext || window.webkitAudioContext;
13
+ if (AudioContext)
14
+ window.abcjsAudioContext = new AudioContext();
15
+ else
16
+ return false;
17
+ }
30
18
  }
31
19
  return window.abcjsAudioContext.state !== "suspended";
32
20
  }
@@ -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 soundsCache = {
17
2
  };
18
3
 
@@ -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 activeAudioContext = require('./active-audio-context');
17
2
 
18
3
  //
@@ -26,17 +11,18 @@ var activeAudioContext = require('./active-audio-context');
26
11
  // But then, call it again after a user interaction to test for resume.
27
12
 
28
13
  function supportsAudio() {
29
- var aac = activeAudioContext();
30
- if (aac)
31
- return aac.resume !== undefined;
32
-
33
14
  if (!window.Promise)
34
15
  return false;
35
16
 
36
- return window.AudioContext ||
37
- window.webkitAudioContext ||
38
- navigator.mozAudioContext ||
39
- navigator.msAudioContext;
17
+ if (!window.AudioContext &&
18
+ !window.webkitAudioContext &&
19
+ !navigator.mozAudioContext &&
20
+ !navigator.msAudioContext)
21
+ return false;
22
+
23
+ var aac = activeAudioContext();
24
+ if (aac)
25
+ return aac.resume !== undefined;
40
26
  }
41
27
 
42
28
  module.exports = supportsAudio;
@@ -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 CreateSynthControl = require('./create-synth-control');
17
2
  var CreateSynth = require('./create-synth');
18
3
  var TimingCallbacks = require('../api/abc_timing_callbacks');
@@ -31,6 +16,7 @@ function SynthController() {
31
16
  self.isLooping = false;
32
17
  self.isStarted = false;
33
18
  self.isLoaded = false;
19
+ self.isLoading = false;
34
20
 
35
21
  self.load = function (selector, cursorControl, visualOptions) {
36
22
  if (!visualOptions)
@@ -44,11 +30,17 @@ function SynthController() {
44
30
  afterResume: self.init
45
31
  });
46
32
  self.cursorControl = cursorControl;
33
+ self.disable(true);
34
+ };
35
+
36
+ self.disable = function(isDisabled) {
37
+ if (self.control)
38
+ self.control.disable(isDisabled);
47
39
  };
48
40
 
49
41
  self.setTune = function(visualObj, userAction, audioParams) {
50
- self.isLoaded = false;
51
42
  self.visualObj = visualObj;
43
+ self.disable(false);
52
44
  self.options = audioParams;
53
45
 
54
46
  if (self.control) {
@@ -68,6 +60,7 @@ function SynthController() {
68
60
  };
69
61
 
70
62
  self.go = function () {
63
+ self.isLoading = true;
71
64
  var millisecondsPerMeasure = self.visualObj.millisecondsPerMeasure() * 100 / self.warp;
72
65
  self.currentTempo = Math.round(self.visualObj.getBeatsPerMeasure() / millisecondsPerMeasure * 60000);
73
66
  if (self.control)
@@ -77,10 +70,12 @@ function SynthController() {
77
70
 
78
71
  if (!self.midiBuffer)
79
72
  self.midiBuffer = new CreateSynth();
80
- return self.midiBuffer.init({
81
- visualObj: self.visualObj,
82
- options: self.options,
83
- millisecondsPerMeasure: millisecondsPerMeasure
73
+ return activeAudioContext().resume().then(function (response) {
74
+ return self.midiBuffer.init({
75
+ visualObj: self.visualObj,
76
+ options: self.options,
77
+ millisecondsPerMeasure: millisecondsPerMeasure
78
+ });
84
79
  }).then(function (response) {
85
80
  loadingResponse = response;
86
81
  return self.midiBuffer.prime();
@@ -100,12 +95,13 @@ function SynthController() {
100
95
  qpm: self.currentTempo,
101
96
 
102
97
  extraMeasuresAtBeginning: self.cursorControl ? self.cursorControl.extraMeasuresAtBeginning : undefined,
103
- lineEndAnticipation: self.cursorControl ? self.cursorControl.lineEndAnticipation : undefined,
98
+ lineEndAnticipation: self.cursorControl ? self.cursorControl.lineEndAnticipation : 0,
104
99
  beatSubdivisions: subdivisions,
105
100
  });
106
101
  if (self.cursorControl && self.cursorControl.onReady && typeof self.cursorControl.onReady === 'function')
107
102
  self.cursorControl.onReady(self);
108
103
  self.isLoaded = true;
104
+ self.isLoading = false;
109
105
  return Promise.resolve({ status: "created", notesStatus: loadingResponse });
110
106
  });
111
107
  };
@@ -126,12 +122,32 @@ function SynthController() {
126
122
  };
127
123
 
128
124
  self.play = function () {
129
- if (!self.isLoaded) {
130
- return self.go().then(function() {
131
- return self._play();
125
+ return self.runWhenReady(self._play, undefined);
126
+ };
127
+
128
+ function sleep(ms) {
129
+ return new Promise(function (resolve) {
130
+ setTimeout(resolve, ms)
131
+ });
132
+ }
133
+
134
+ self.runWhenReady = function(fn, arg1) {
135
+ if (!self.visualObj)
136
+ return Promise.resolve({status: "loading"});
137
+ if (self.isLoading) {
138
+ // Some other promise is waiting for the tune to be loaded, so just wait.
139
+ return sleep(500).then(function() {
140
+ if (self.isLoading)
141
+ return self.runWhenReady(fn, arg1);
142
+ return fn(arg1);
143
+ })
144
+ } else if (!self.isLoaded) {
145
+ return self.go().then(function () {
146
+ return fn(arg1);
132
147
  });
133
- } else
134
- return self._play();
148
+ } else {
149
+ return fn(arg1);
150
+ }
135
151
  };
136
152
 
137
153
  self._play = function () {
@@ -141,7 +157,7 @@ function SynthController() {
141
157
  if (self.cursorControl && self.cursorControl.onStart && typeof self.cursorControl.onStart === 'function')
142
158
  self.cursorControl.onStart();
143
159
  self.midiBuffer.start();
144
- self.timer.start();
160
+ self.timer.start(self.percent);
145
161
  if (self.control)
146
162
  self.control.pushPlay(true);
147
163
  } else {
@@ -174,12 +190,7 @@ function SynthController() {
174
190
  };
175
191
 
176
192
  self.randomAccess = function (ev) {
177
- if (!self.isLoaded) {
178
- return self.go().then(function() {
179
- return self._randomAccess(ev);
180
- });
181
- } else
182
- return self._randomAccess(ev);
193
+ return self.runWhenReady(self._randomAccess, ev);
183
194
  };
184
195
 
185
196
  self._randomAccess = function (ev) {
@@ -187,29 +198,46 @@ function SynthController() {
187
198
  var percent = (ev.x - background.offsetLeft) / background.offsetWidth;
188
199
  if (percent < 0)
189
200
  percent = 0;
190
- if (percent > 100)
191
- percent = 100;
192
- self.timer.setProgress(percent);
193
- self.midiBuffer.seek(percent);
201
+ if (percent > 1)
202
+ percent = 1;
203
+ self.seek(percent);
204
+ return Promise.resolve({status: "ok"});
194
205
  };
195
206
 
196
- self.onWarp = function (ev) {
197
- var newWarp = ev.target.value;
207
+ self.seek = function (percent, units) {
208
+ if (self.timer && self.midiBuffer) {
209
+ self.timer.setProgress(percent, units);
210
+ self.midiBuffer.seek(percent, units);
211
+ }
212
+ };
213
+
214
+ self.setWarp = function (newWarp) {
198
215
  if (parseInt(newWarp, 10) > 0) {
199
216
  self.warp = parseInt(newWarp, 10);
200
217
  var wasPlaying = self.isStarted;
201
218
  var startPercent = self.percent;
202
219
  self.destroy();
203
220
  self.isStarted = false;
204
- self.go().then(function () {
221
+ return self.go().then(function () {
205
222
  self.setProgress(startPercent, self.midiBuffer.duration * 1000);
223
+ if (self.control)
224
+ self.control.setWarp(self.currentTempo, self.warp);
206
225
  if (wasPlaying) {
207
- self.play();
226
+ return self.play().then(function () {
227
+ self.seek(startPercent);
228
+ return Promise.resolve();
229
+ });
208
230
  }
209
- self.timer.setProgress(startPercent);
210
- self.midiBuffer.seek(startPercent);
231
+ self.seek(startPercent);
232
+ return Promise.resolve();
211
233
  });
212
234
  }
235
+ return Promise.resolve();
236
+ };
237
+
238
+ self.onWarp = function (ev) {
239
+ var newWarp = ev.target.value;
240
+ return self.setWarp(newWarp);
213
241
  };
214
242
 
215
243
  self.setProgress = function (percent, totalTime) {
@@ -221,14 +249,17 @@ function SynthController() {
221
249
  self.finished = function () {
222
250
  self.timer.reset();
223
251
  if (self.isLooping) {
224
- self.timer.start();
252
+ self.timer.start(0);
253
+ self.midiBuffer.finished();
225
254
  self.midiBuffer.start();
255
+ return "continue";
226
256
  } else {
227
257
  self.timer.stop();
228
258
  if (self.isStarted) {
229
259
  if (self.control)
230
260
  self.control.pushPlay(false);
231
261
  self.isStarted = false;
262
+ self.midiBuffer.finished();
232
263
  if (self.cursorControl && self.cursorControl.onFinished && typeof self.cursorControl.onFinished === 'function')
233
264
  self.cursorControl.onFinished();
234
265
  self.setProgress(0, 1);
@@ -236,11 +267,11 @@ function SynthController() {
236
267
  }
237
268
  };
238
269
 
239
- self.beatCallback = function (beatNumber, totalBeats, totalTime) {
270
+ self.beatCallback = function (beatNumber, totalBeats, totalTime, position) {
240
271
  var percent = beatNumber / totalBeats;
241
272
  self.setProgress(percent, totalTime);
242
273
  if (self.cursorControl && self.cursorControl.onBeat && typeof self.cursorControl.onBeat === 'function')
243
- self.cursorControl.onBeat(beatNumber, totalBeats, totalTime);
274
+ self.cursorControl.onBeat(beatNumber, totalBeats, totalTime, position);
244
275
  };
245
276
 
246
277
  self.eventCallback = function (event) {
@@ -248,13 +279,13 @@ function SynthController() {
248
279
  if (self.cursorControl && self.cursorControl.onEvent && typeof self.cursorControl.onEvent === 'function')
249
280
  self.cursorControl.onEvent(event);
250
281
  } else {
251
- self.finished();
282
+ return self.finished();
252
283
  }
253
284
  };
254
285
 
255
- self.lineEndCallback = function (data) {
286
+ self.lineEndCallback = function (lineEvent, leftEvent) {
256
287
  if (self.cursorControl && self.cursorControl.onLineEnd && typeof self.cursorControl.onLineEnd === 'function')
257
- self.cursorControl.onLineEnd(data);
288
+ self.cursorControl.onLineEnd(lineEvent, leftEvent);
258
289
  };
259
290
 
260
291
  self.getUrl = function () {
@@ -1,25 +1,14 @@
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 SynthSequence = function() {
17
2
  var self = this;
18
3
  self.tracks = [];
19
4
  self.totalDuration = 0;
5
+ self.currentInstrument = [];
6
+ self.starts = [];
20
7
 
21
8
  self.addTrack = function() {
22
9
  self.tracks.push([]);
10
+ self.currentInstrument.push(0);
11
+ self.starts.push(0);
23
12
  return self.tracks.length - 1;
24
13
  };
25
14
 
@@ -29,28 +18,25 @@ var SynthSequence = function() {
29
18
  cmd: "program",
30
19
  instrument: instrumentNumber
31
20
  });
21
+ self.currentInstrument[trackNumber] = instrumentNumber;
32
22
  };
33
23
 
34
- self.appendNote = function(trackNumber, pitch, durationInMeasures, volume) {
35
- self.tracks[trackNumber].push({
36
- cmd: "start",
37
- pitch: pitch - 60,
24
+ self.appendNote = function(trackNumber, pitch, durationInMeasures, volume, cents) {
25
+ var note = {
26
+ cmd: "note",
27
+ duration: durationInMeasures,
28
+ gap: 0,
29
+ instrument: self.currentInstrument[trackNumber],
30
+ pitch: pitch,
31
+ start: self.starts[trackNumber],
38
32
  volume: volume
39
- });
40
- self.tracks[trackNumber].push({
41
- cmd: "move",
42
- duration: durationInMeasures
43
- });
44
- self.tracks[trackNumber].push({
45
- cmd: "stop",
46
- pitch: pitch - 60
47
- });
48
- var duration = 0;
49
- self.tracks[trackNumber].forEach(function(event) {
50
- if (event.duration)
51
- duration += event.duration;
52
- });
53
- self.totalDuration = Math.max(self.totalDuration, duration);
33
+ };
34
+ if (cents)
35
+ note.cents = cents;
36
+ self.tracks[trackNumber].push(note);
37
+ self.starts[trackNumber] += durationInMeasures;
38
+
39
+ self.totalDuration = Math.max(self.totalDuration, self.starts[trackNumber]);
54
40
  };
55
41
  };
56
42
 
@@ -0,0 +1,19 @@
1
+
2
+ /**
3
+ * Dedicated fonts for violin tabs
4
+ */
5
+
6
+ /**
7
+ * Set here the fonts used by renderer/drawer
8
+ * for the violin plugin
9
+ * @param {} tune
10
+ */
11
+ // eslint-disable-next-line no-unused-vars
12
+ function setGuitarFonts(tune) {
13
+ /* enhance or change instrument fonts here */
14
+ // tune.formatting.tabnumberfont = { face: "\"Times New Roman\"", size: 9, weight: "normal", style: "normal", decoration: "none" };
15
+ // tune.formatting.tabgracefont = { face: "\"Times New Roman\"", size: 7, weight: "normal", style: "normal", decoration: "none" };
16
+ }
17
+
18
+ module.exports = setGuitarFonts;
19
+
@@ -0,0 +1,23 @@
1
+ var StringPatterns = require('../string-patterns');
2
+
3
+ function GuitarPatterns(plugin) {
4
+ this.tuning = plugin._super.params.tuning;
5
+ if (!this.tuning) {
6
+ this.tuning = ['E,', 'A', 'D', 'G' , 'B' , 'e'];
7
+ }
8
+ plugin.tuning = this.tuning;
9
+ this.strings = new StringPatterns(plugin);
10
+ }
11
+
12
+ GuitarPatterns.prototype.notesToNumber = function (notes, graces) {
13
+ var converter = this.strings;
14
+ return converter.notesToNumber(notes, graces);
15
+ };
16
+
17
+ GuitarPatterns.prototype.stringToPitch = function (stringNumber) {
18
+ var converter = this.strings;
19
+ return converter.stringToPitch(stringNumber);
20
+ };
21
+
22
+
23
+ module.exports = GuitarPatterns;
@@ -0,0 +1,50 @@
1
+ /*
2
+ Emit tab for Guitar staff
3
+ */
4
+ var StringTablature = require('../string-tablature');
5
+ var TabCommon = require('../../tab-common');
6
+ var TabRenderer = require('../../tab-renderer');
7
+ var GuitarPatterns = require('./guitar-patterns');
8
+ var setGuitarFonts = require('./guitar-fonts');
9
+
10
+ /**
11
+ * upon init mainly store provided instances for later usage
12
+ * @param {*} abcTune the parsed tune AST tree
13
+ * @param {*} tuneNumber the parsed tune AST tree
14
+ * @param {*} params complementary args provided to Tablature Plugin
15
+ */
16
+ Plugin.prototype.init = function (abcTune, tuneNumber, params) {
17
+ var _super = new TabCommon(abcTune, tuneNumber, params);
18
+ this._super = _super;
19
+ this.abcTune = abcTune;
20
+ this.linePitch = 3;
21
+ this.nbLines = 6;
22
+ this.isTabBig = true;
23
+ this.capo = params.capo;
24
+ this.transpose = params.visualTranspose;
25
+ this.tablature = new StringTablature(this.nbLines,
26
+ this.linePitch);
27
+
28
+ var semantics = new GuitarPatterns(this);
29
+ this.semantics = semantics;
30
+ };
31
+
32
+ Plugin.prototype.render = function (renderer, line, staffIndex) {
33
+ if (this._super.inError) return;
34
+ if (this.tablature.bypass(line)) return;
35
+ setGuitarFonts(this.abcTune);
36
+ var rndrer = new TabRenderer(this, renderer, line, staffIndex);
37
+ rndrer.doLayout();
38
+ };
39
+
40
+ function Plugin() {}
41
+
42
+ //
43
+ // Tablature plugin definition
44
+ //
45
+ var AbcGuitarTab = function () {
46
+ return { name: 'GuitarTab', tablature: Plugin };
47
+ };
48
+
49
+
50
+ module.exports = AbcGuitarTab;