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.
- package/.github/workflows/tests.yml +29 -0
- package/CODE_OF_CONDUCT.md +76 -0
- package/CONTRIBUTING.md +1 -0
- package/LICENSE.md +1 -1
- package/README.md +92 -3
- package/RELEASE.md +959 -1
- package/abcjs-audio.css +14 -5
- package/dist/.gitignore +1 -2
- package/dist/abcjs-basic-min.js +3 -0
- package/dist/abcjs-basic-min.js.LICENSE +23 -0
- package/dist/abcjs-basic.js +28232 -0
- package/dist/abcjs-basic.js.map +1 -0
- package/dist/abcjs-plugin-min.js +3 -0
- package/dist/abcjs-plugin-min.js.LICENSE +23 -0
- package/dist/report-basic.html +37 -0
- package/dist/report-before-glyph-compress.html +37 -0
- package/dist/report-brown-ts-target-es5.html +37 -0
- package/dist/report-dev-orig-no-babel.html +37 -0
- package/dist/report-synth.html +37 -0
- package/docker-build.sh +1 -0
- package/glyphs.json +1 -0
- package/index.js +27 -2
- package/{static-wrappers/license.js → license.js} +1 -1
- package/package.json +26 -29
- package/{src/plugin/abc_plugin.js → plugin.js} +31 -19
- package/src/api/abc_animation.js +1 -17
- package/src/api/abc_tablatures.js +144 -0
- package/src/api/abc_timing_callbacks.js +239 -116
- package/src/api/abc_tunebook.js +18 -67
- package/src/api/abc_tunebook_svg.js +38 -46
- package/src/data/abc_tune.js +232 -972
- package/src/data/deline-tune.js +199 -0
- package/src/edit/abc_editarea.js +112 -0
- package/src/edit/abc_editor.js +95 -221
- package/src/midi/abc_midi_create.js +48 -50
- package/src/parse/abc_common.js +0 -14
- package/src/parse/abc_parse.js +167 -1321
- package/src/parse/abc_parse_book.js +62 -0
- package/src/parse/abc_parse_directive.js +164 -41
- package/src/parse/abc_parse_header.js +116 -145
- package/src/parse/abc_parse_key_voice.js +26 -20
- package/src/parse/abc_parse_music.js +1337 -0
- package/src/parse/abc_tokenizer.js +21 -15
- package/src/parse/abc_transpose.js +3 -15
- package/src/parse/tune-builder.js +896 -0
- package/src/parse/wrap_lines.js +205 -453
- package/src/synth/abc_midi_flattener.js +1292 -0
- package/src/{midi → synth}/abc_midi_renderer.js +44 -17
- package/src/synth/abc_midi_sequencer.js +648 -0
- package/src/synth/active-audio-context.js +3 -14
- package/src/synth/cents-to-factor.js +10 -0
- package/src/synth/create-note-map.js +21 -32
- package/src/synth/create-synth-control.js +20 -103
- package/src/synth/create-synth.js +185 -77
- package/src/synth/download-buffer.js +7 -21
- package/src/synth/get-midi-file.js +13 -20
- package/src/synth/images/{loading.svg → loading.svg.js} +4 -0
- package/src/synth/images/loop.svg.js +65 -0
- package/src/synth/images/pause.svg.js +10 -0
- package/src/synth/images/play.svg.js +9 -0
- package/src/synth/images/{reset.svg → reset.svg.js} +5 -1
- package/src/synth/instrument-index-to-name.js +1 -16
- package/src/synth/load-note.js +37 -76
- package/src/synth/pitch-to-note-name.js +0 -15
- package/src/synth/pitches-to-perc.js +64 -0
- package/src/synth/place-note.js +78 -68
- package/src/synth/play-event.js +17 -18
- package/src/synth/register-audio-context.js +11 -23
- package/src/synth/sounds-cache.js +0 -15
- package/src/synth/supports-audio.js +9 -23
- package/src/synth/synth-controller.js +80 -49
- package/src/synth/synth-sequence.js +20 -34
- package/src/tablatures/instruments/guitar/guitar-fonts.js +19 -0
- package/src/tablatures/instruments/guitar/guitar-patterns.js +23 -0
- package/src/tablatures/instruments/guitar/tab-guitar.js +50 -0
- package/src/tablatures/instruments/string-patterns.js +277 -0
- package/src/tablatures/instruments/string-tablature.js +56 -0
- package/src/tablatures/instruments/tab-note.js +282 -0
- package/src/tablatures/instruments/tab-notes.js +41 -0
- package/src/tablatures/instruments/violin/tab-violin.js +47 -0
- package/src/tablatures/instruments/violin/violin-fonts.js +19 -0
- package/src/tablatures/instruments/violin/violin-patterns.js +23 -0
- package/src/tablatures/tab-absolute-elements.js +310 -0
- package/src/tablatures/tab-common.js +29 -0
- package/src/tablatures/tab-renderer.js +243 -0
- package/src/tablatures/transposer.js +110 -0
- package/src/test/abc_midi_lint.js +5 -22
- package/src/test/abc_midi_sequencer_lint.js +11 -14
- package/src/test/abc_parser_lint.js +136 -32
- package/src/test/abc_vertical_lint.js +94 -32
- package/src/test/rendering-lint.js +38 -5
- package/src/write/abc_absolute_element.js +112 -120
- package/src/write/abc_abstract_engraver.js +102 -253
- package/src/write/abc_beam_element.js +30 -290
- package/src/write/abc_brace_element.js +12 -121
- package/src/write/abc_create_clef.js +21 -32
- package/src/write/abc_create_key_signature.js +8 -26
- package/src/write/abc_create_note_head.js +107 -0
- package/src/write/abc_create_time_signature.js +2 -21
- package/src/write/abc_crescendo_element.js +3 -50
- package/src/write/abc_decoration.js +7 -30
- package/src/write/abc_dynamic_decoration.js +3 -37
- package/src/write/abc_ending_element.js +1 -57
- package/src/write/abc_engraver_controller.js +111 -234
- package/src/write/abc_glyphs.js +8 -18
- package/src/write/abc_relative_element.js +57 -97
- package/src/write/abc_renderer.js +10 -832
- package/src/write/abc_spacing.js +0 -15
- package/src/write/abc_staff_group_element.js +14 -349
- package/src/write/abc_tempo_element.js +9 -117
- package/src/write/abc_tie_element.js +5 -68
- package/src/write/abc_triplet_element.js +6 -124
- package/src/write/abc_voice_element.js +7 -222
- package/src/write/add-chord.js +103 -0
- package/src/write/add-text-if.js +33 -0
- package/src/write/bottom-text.js +79 -0
- package/src/write/calcHeight.js +17 -0
- package/src/write/classes.js +100 -0
- package/src/write/draw/absolute.js +68 -0
- package/src/write/draw/beam.js +56 -0
- package/src/write/draw/brace.js +106 -0
- package/src/write/draw/crescendo.js +38 -0
- package/src/write/draw/debug-box.js +8 -0
- package/src/write/draw/draw.js +56 -0
- package/src/write/draw/dynamics.js +20 -0
- package/src/write/draw/ending.js +46 -0
- package/src/write/draw/group-elements.js +66 -0
- package/src/write/draw/horizontal-line.js +25 -0
- package/src/write/draw/non-music.js +50 -0
- package/src/write/draw/print-line.js +24 -0
- package/src/write/draw/print-path.js +7 -0
- package/src/write/draw/print-stem.js +30 -0
- package/src/write/draw/print-symbol.js +59 -0
- package/src/write/draw/print-vertical-line.js +18 -0
- package/src/write/draw/relative.js +77 -0
- package/src/write/draw/round-number.js +5 -0
- package/src/write/draw/selectables.js +59 -0
- package/src/write/draw/separator.js +16 -0
- package/src/write/draw/set-paper-size.js +45 -0
- package/src/write/{sprintf.js → draw/sprintf.js} +0 -0
- package/src/write/draw/staff-group.js +226 -0
- package/src/write/draw/staff-line.js +9 -0
- package/src/write/draw/staff.js +33 -0
- package/src/write/draw/tab-line.js +40 -0
- package/src/write/draw/tempo.js +45 -0
- package/src/write/draw/text.js +71 -0
- package/src/write/draw/tie.js +97 -0
- package/src/write/draw/triplet.js +46 -0
- package/src/write/draw/voice.js +102 -0
- package/src/write/format-jazz-chord.js +15 -0
- package/src/write/free-text.js +41 -0
- package/src/write/get-font-and-attr.js +37 -0
- package/src/write/get-text-size.js +56 -0
- package/src/write/highlight.js +11 -0
- package/src/write/layout/VoiceElements.js +121 -0
- package/src/write/layout/beam.js +213 -0
- package/src/write/layout/get-left-edge-of-staff.js +56 -0
- package/src/write/layout/getBarYAt.js +6 -0
- package/src/write/layout/layout.js +94 -0
- package/src/write/layout/setUpperAndLowerElements.js +232 -0
- package/src/write/layout/staffGroup.js +146 -0
- package/src/write/layout/triplet.js +75 -0
- package/src/write/layout/voice.js +137 -0
- package/src/write/selection.js +188 -70
- package/src/write/separator.js +10 -0
- package/src/write/set-class.js +21 -0
- package/src/write/subtitle.js +12 -0
- package/src/write/svg.js +95 -43
- package/src/write/top-text.js +54 -0
- package/src/write/unhighlight.js +11 -0
- package/temp.txt +15256 -0
- package/test.js +27 -64
- package/types/index.d.ts +1095 -0
- package/version.js +1 -1
- package/.babelrc +0 -5
- package/.eslintrc +0 -3
- package/.gitmodules +0 -3
- package/abcjs-midi.css +0 -166
- package/build-utils/loadPresets.js +0 -14
- package/build-utils/presets/webpack.analyze.js +0 -6
- package/build-utils/presets/webpack.optimize.js +0 -30
- package/build-utils/webpack.development.js +0 -14
- package/build-utils/webpack.production.js +0 -35
- package/deploy-docs.sh +0 -25
- package/docs/README.md +0 -33
- package/fix-versions.sh +0 -23
- package/mei.js +0 -43
- package/midi.js +0 -62
- package/src/api/abc_tunebook_midi.js +0 -116
- package/src/midi/abc_midi_controls.js +0 -701
- package/src/midi/abc_midi_flattener.js +0 -1119
- package/src/midi/abc_midi_js_preparer.js +0 -243
- package/src/midi/abc_midi_sequencer.js +0 -401
- package/src/midi/abc_midi_ui_generator.js +0 -86
- package/src/plugin/abc_plugin_midi.js +0 -220
- package/src/synth/images/loop.svg +0 -61
- package/src/synth/images/pause.svg +0 -6
- package/src/synth/images/play.svg +0 -5
- package/src/transform/abc2abc_write.js +0 -395
- package/static-wrappers/basic.js +0 -2
- package/static-wrappers/midi.js +0 -2
- package/static-wrappers/plugin-midi.js +0 -6
- package/static-wrappers/plugin.js +0 -6
- package/webpack.config.js +0 -29
package/src/synth/play-event.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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
|
|
22
|
-
|
|
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
|
-
|
|
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
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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 :
|
|
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
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
|
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
|
-
|
|
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 >
|
|
191
|
-
percent =
|
|
192
|
-
self.
|
|
193
|
-
|
|
201
|
+
if (percent > 1)
|
|
202
|
+
percent = 1;
|
|
203
|
+
self.seek(percent);
|
|
204
|
+
return Promise.resolve({status: "ok"});
|
|
194
205
|
};
|
|
195
206
|
|
|
196
|
-
self.
|
|
197
|
-
|
|
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.
|
|
210
|
-
|
|
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 (
|
|
286
|
+
self.lineEndCallback = function (lineEvent, leftEvent) {
|
|
256
287
|
if (self.cursorControl && self.cursorControl.onLineEnd && typeof self.cursorControl.onLineEnd === 'function')
|
|
257
|
-
self.cursorControl.onLineEnd(
|
|
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
|
-
|
|
36
|
-
cmd: "
|
|
37
|
-
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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;
|