### Mocha and Tarp Setup for Audio Tests Source: https://github.com/paulrosen/abcjs/blob/main/tests/audio.html Sets up the Mocha testing environment and Tarp for loading the ABC.js library. This is the initial setup for running audio tests. ```javascript mocha.setup({ui: 'bdd', globals: ['__VUE_DEVTOOLS_TOAST__']}); mocha.checkLeaks(); Tarp.require({main: "../index.js"}).then(function (response) { window.abcjs = response; mocha.run(); }); ``` -------------------------------- ### Render ABC Notation Tune 8: begin Source: https://github.com/paulrosen/abcjs/blob/main/examples/plugin/abc_plugin.html An ABC notation example labeled 'begin'. ```abc X:1 T: 7 begin G ``` -------------------------------- ### Whole Rest Glyph Example Source: https://github.com/paulrosen/abcjs/blob/main/font_generator/font_editor.html This example demonstrates the path data for a whole rest glyph. It uses a sequence of 'M' (moveto) and 'l' (lineto relative) commands, ending with 'z' (closepath). Ensure all 'l' commands are lowercase for relative coordinates. ```svg M0.06 0.03 l0.09 -0.06 l5.46 0.00 l5.49 0.00 l0.09 0.06 l0.06 0.09 l0.00 2.19 l0.00 2.19 l-0.06 0.09 l-0.09 0.06 l-5.49 0.00 l-5.46 0.00 l-0.09 -0.06 l-0.06 -0.09 l0.00 -2.19 l0.00 -2.19 z ``` -------------------------------- ### Render ABC Notation Tune 12: begin (with key) Source: https://github.com/paulrosen/abcjs/blob/main/examples/plugin/abc_plugin.html An ABC notation example labeled 'begin', including key specification. ```abc X:1 T:11 begin K:G G ``` -------------------------------- ### Play Synth Buffers Source: https://github.com/paulrosen/abcjs/blob/main/examples/synth-reuse.html Starts playback of pre-rendered audio buffers. Each function corresponds to a specific pre-generated buffer. ```javascript function play1() { buffers[0].start(); } function play12() { buffers[1].start(); } function play23() { buffers[2].start(); } function play123() { buffers[3].start(); } function play1s() { buffers[4].start(); } function play3s() { buffers[5].start(); } ``` -------------------------------- ### Initialize and Run Audio Tests Source: https://github.com/paulrosen/abcjs/blob/main/tests/web-audio.html Sets up Mocha for testing and initializes the abcjs library. The tests will run after a user clicks a button to start them, which also hides introductory elements. ```javascript mocha.setup({ui: 'bdd', globals: ['__VUE_DEVTOOLS_TOAST__', 'abcjsAudioContext']}); mocha.checkLeaks(); Tarp.require({main: "../index.js"}).then(function (response) { window.abcjs = response; var el = document.querySelector(".start-test"); el.addEventListener("click", function() { var els = document.querySelectorAll(".intro") for (var i = 0; i < els.length; i++) { els[i].style = "display:none;"; } mocha.run(); }); }); ``` -------------------------------- ### Example ABC Input String Source: https://github.com/paulrosen/abcjs/blob/main/examples/output-transpose.html A sample ABC notation string for a reel in E minor, used as input for transposition. ```abc X: 1 T: Cooley's M: 4/4 L: 1/8 R: reel K: Em V: Melody |:D2|EB{c}BA B2 EB|~B2 AB dBAG|FDAD BDAD|FDAD dAFD| EBBA B2 EB|B2 AB defg|afe^c dBAF|DEFD E2:| |:gf|eB B2 efge|eB B2 gedB|A2 FA DAFA|A2 FA defg| eB B2 eBgB|eB B2 defg|afe^c dBAF|DEFD E2:| ``` -------------------------------- ### Initialize Editor and Event Listener Source: https://github.com/paulrosen/abcjs/blob/main/examples/output-transpose.html Sets up the ABCJS editor, selects DOM elements for input and output, and attaches an event listener for transposition parameter changes. This is the initial setup for the transposition tool. ```javascript var editor; var renderParams = { responsive: "resize", selectTypes: false }; var outputEl; var abcEl; var currentAbc = "" window.onload = function () { abcEl = document.querySelector("#abc"); outputEl = document.querySelector("#transposed"); visualTransposeEl = document.querySelector(".transpose"); editor = new ABCJS.Editor("abc", { canvas_id: "paper", warnings_id: "warnings", abcjsParams: renderParams }); visualTransposeEl.addEventListener("change", paramChanged); paramChanged(false); }; ``` -------------------------------- ### Render ABC Notation Tune 6: Here is a title Source: https://github.com/paulrosen/abcjs/blob/main/examples/plugin/abc_plugin.html An ABC notation example with a title and key specified. Demonstrates rendering within a paragraph. ```abc X: 1 T: 5 Here is a title K: Emin CDEFGABcdefgab ``` -------------------------------- ### Browser Compatibility Polyfill and Test Setup Source: https://github.com/paulrosen/abcjs/blob/main/tests/browser-compatibility.html This code configures the testing environment for browser compatibility. It polyfills 'Error.captureStackTrace' if it's not available and sets up the Mocha test runner. ```javascript // The tests were written for the node version, so just make either entry point valid. window.abcjs = window.ABCJS; // This is the one polyfill needed for the test runner. if (!Error.captureStackTrace) { console.log("Polyfill captureStackTrace") var container = new Error(); Object.defineProperty({}, 'stack', { configurable: true, get: function getStack() { var stack = container.stack; Object.defineProperty(this, 'stack', { value: stack }); return stack; } }); } mocha.setup({ui: 'bdd', globals: ['__VUE_DEVTOOLS_TOAST__']}); mocha.checkLeaks(); mocha.run(); ``` -------------------------------- ### Initialize and Play ABC Notation with Repeat Source: https://github.com/paulrosen/abcjs/blob/main/examples/play-on-repeat.html This snippet initializes the ABCJS synth and renders the ABC notation. It sets up event listeners for play and stop buttons, and manages the audio context. Use this to enable interactive playback with user-defined start and end points for repetition. ```javascript var abc = "T: Cooley's\n" + "%%barnumbers 1\n" + "M: 4/4\n" + "L: 1/8\n" + "R: reel\n" + "K: Emin\n" + "EBBA B2 EB|~B2 AB dBAG|FDAD BDAD|FDAD dAFD|\n" + "EBBA B2 EB|B2 AB defg|afe^c dBAF|DEFD E2 gf|\n" + "|eB B2 efge|eB B2 gedB|A2 FA DAFA|A2 FA defg|\n" + "eB B2 eBgB|eB B2 defg|afe^c dBAF|DEFD E2 D2||"; var NUM_MEASURES = 16; var NUM_BEATS_PER_MEASURE = 4; var synth = new ABCJS.synth.CreateSynth(); var startMeasure; var endMeasure; var timingCallbacks; function load() { // First draw the music - this supplies an object that has a lot of information about how to create the synth. // NOTE: If you want just the sound without showing the music, use "*" instead of "paper" in the renderAbc call. var visualObj = ABCJS.renderAbc("paper", abc, { responsive: "resize" })[0]; var startAudioButton = document.querySelector(".activate-audio"); var stopAudioButton = document.querySelector(".stop-audio"); var explanationDiv = document.querySelector(".suspend-explanation"); startMeasure = document.querySelector("#start-measure"); endMeasure = document.querySelector("#end-measure"); startAudioButton.addEventListener("click", function() { startAudioButton.setAttribute("style", "display:none;"); explanationDiv.setAttribute("style", "opacity: 0;"); if (ABCJS.synth.supportsAudio()) { stopAudioButton.setAttribute("style", ""); // An audio context is needed - this can be passed in for two reasons: // 1) So that you can share this audio context with other elements on your page. // 2) So that you can create it during a user interaction so that the browser doesn't block the sound. // Setting this is optional - if you don't set an audioContext, then abcjs will create one. window.AudioContext = window.AudioContext || window.webkitAudioContext || navigator.mozAudioContext || navigator.msAudioContext; var audioContext = new window.AudioContext(); audioContext.resume().then(function() { // In theory the AC shouldn't start suspended because it is being initialized in a click handler, but iOS seems to anyway. synth.init({ audioContext: audioContext, visualObj: visualObj }).then(function() { timingCallbacks = new ABCJS.TimingCallbacks(visualObj, { beatCallback: cursorControl.onBeat, eventCallback: cursorControl.onEvent }); cursorControl.onStart(); synth.prime().then(function() { var start = (startMeasure.value - 1) / NUM_MEASURES; synth.seek(start); timingCallbacks.setProgress(start); synth.start(); timingCallbacks.start(); }); }).catch(function(error) { console.log("Audio Failed", error); }); }); } else { var audioError = document.querySelector(".audio-error"); audioError.setAttribute("style", ""); } }); stopAudioButton.addEventListener("click", function() { startAudioButton.setAttribute("style", ""); explanationDiv.setAttribute("style", ""); stopAudioButton.setAttribute("style", "display:none;"); synth.stop(); timingCallbacks.stop(); }); } ``` -------------------------------- ### Initialize and Play Karaoke Synth Source: https://github.com/paulrosen/abcjs/blob/main/examples/karaoke-synth.html Initializes the abcjs synthesizer with a musical score and plays it. Handles audio context creation and management, and provides options to control playback of chords, melody, and harmony. Requires user interaction to start audio. ```javascript var abc = 'T:Cindy\n' + 'M:4/4\n' + 'K:G\n' + '%%score (harmony melody)\n' + 'L:1/4\n' + ' [V: harmony]' + 'g||"G"gggg|dB2g|gggd|g3g|\n' + '"G"gggd|dcB2|dccA|Bzz2|\n' + '"C"G2cc|ccd/c/B|"G"G4-|Gzz2|\n' + '"C"G2cc|cc2c|"D7"dddc|"G"B2z2|]\n' + ' [V: melody]' + 'd||"G"eddB|AG2d|eddB|d3d|\n' + '"G"eddB|BAG2|"D7"BGGE|"G"GzB/A/G|\n' + '"C"E2GG|AGB/A/G|"G"D4-|DzB/A/G|\n' + '"C"E2GG|AG2A|"D7"BBBA|"G"G2z2|]\n'; function load() { // First draw the music - this supplies an object that has a lot of information about how to create the synth. var visualObj = ABCJS.renderAbc("paper", abc, { responsive: "resize" })[0]; // This object is the class that will contain the buffer var midiBuffer; var startChordsButton = document.querySelector(".play-chords"); var startMelodiesButton = document.querySelector(".play-melodies"); var startHarmonyButton = document.querySelector(".play-harmony"); var startMelodyButton = document.querySelector(".play-melody"); var startAllButton = document.querySelector(".play-all"); var stopAudioButton = document.querySelector(".stop-audio"); startChordsButton.addEventListener("click", function() { var options = {voicesOff: true}; play(options); }); startMelodiesButton.addEventListener("click", function() { var options = {chordsOff: true}; play(options); }); startHarmonyButton.addEventListener("click", function() { var options = {chordsOff: true, voicesOff: [1]}; play(options); }); startMelodyButton.addEventListener("click", function() { var options = {chordsOff: true, voicesOff: [0]}; play(options); }); startAllButton.addEventListener("click", function() { var options = {}; play(options); }); function play(options) { startChordsButton.setAttribute("style", "display:none;"); startMelodiesButton.setAttribute("style", "display:none;"); startHarmonyButton.setAttribute("style", "display:none;"); startMelodyButton.setAttribute("style", "display:none;"); startAllButton.setAttribute("style", "display:none;"); if (ABCJS.synth.supportsAudio()) { stopAudioButton.setAttribute("style", ""); // An audio context is needed - this can be passed in for two reasons: // 1) So that you can share this audio context with other elements on your page. // 2) So that you can create it during a user interaction so that the browser doesn't block the sound. // Setting this is optional - if you don't set an audioContext, then abcjs will create one. window.AudioContext = window.AudioContext || window.webkitAudioContext || navigator.mozAudioContext || navigator.msAudioContext; var audioContext = new window.AudioContext(); audioContext.resume().then(function () { // In theory the AC shouldn't start suspended because it is being initialized in a click handler, but iOS seems to anyway. // This does a bare minimum so this object could be created in advance, or whenever convenient. midiBuffer = new ABCJS.synth.CreateSynth(); // midiBuffer.init preloads and caches all the notes needed. There may be significant network traffic here. return midiBuffer.init({ visualObj: visualObj, audioContext: audioContext, millisecondsPerMeasure: visualObj.millisecondsPerMeasure(), options: options }).then(function (response) { // console.log(response); // this contains the list of notes that were loaded. // midiBuffer.prime actually builds the output buffer. return midiBuffer.prime(); }).then(function () { // At this point, everything slow has happened. midiBuffer.start will return very quickly and will start playing very quickly without lag. midiBuffer.start(); return Promise.resolve(); }).catch(function (error) { if (error.status === "NotSupported") { stopAudioButton.setAttribute("style", "display:none;"); var audioError = document.querySelector(".audio-error"); audioError.setAttribute("style", ""); } else console.warn("synth error", error); }); }); } else { var audioError = document.querySelector(".audio-error"); audioError.setAttribute("style", ""); } } stopAudioButton.addEventListener("click", function() { startChordsButton.setAttribute("style", ""); startMelodiesButton.setAttribute("style", ""); startHarmonyButton.setAttribute("style", ""); startMelodyButton.setAttribute("style", ""); startAllButton.setAttribute("style", ""); stopAudioButton.setAttribute("style", "display:none;"); if (midiBuffer) midiBuffer.stop(); }); } ``` -------------------------------- ### Render Viola Tablature using ABCJS Source: https://github.com/paulrosen/abcjs/blob/main/examples/tablatures.html Renders a musical piece as a viola tablature. This example configures the instrument as 'violin' but labels it for Viola/Mandola, using a specific tuning. ```javascript var abc4 = "X:1\n" + "T:Home On The Range\n" + "M:3/4\n" + "L:1/4\n" + "K:C clef=alto\n" + "G,|G,CE|E2 C/B,/|A,3/2 F/F|F2|]\t\n"; var options4 = { tablature: [ { instrument: 'violin', label: 'Viola/Mandola (%T)', tuning: ['C,', 'G,', 'D', 'A'] } ] } ABCJS.renderAbc("paper4", abc4, options4 ) ``` -------------------------------- ### Initialize Synth Player and Load Tune Source: https://github.com/paulrosen/abcjs/blob/main/examples/synth-player.html Sets up the synth controller, loads the audio player interface, and renders the ABC notation. It checks for audio support and provides a fallback message if not supported. ```javascript var abc = "T: Cooley's\n" + "M: 4/4\n" + "Q: 1/4=120\n" + "L: 1/8\n" + "R: reel\n" + "K: Emin\n" + "|:{E}D2|EB{c}BA B2 EB|~B2 AB dBAG|FDAD BDAD|FDAD dAFD|\n" + "EBBA B2 EB|B2 AB defg|afe^c dBAF|DEFD E2:\n" + "|:gf|eB B2 efge|eB B2 gedB|A2 FA DAFA|A2 FA defg|\n" + "eB B2 eBgB|eB B2 defg|afe^c dBAF|DEFD E2:|" var abcOptions = { add_classes: true, responsive: "resize" }; function CursorControl() { var self = this; self.onReady = function() { }; self.onStart = function() { var svg = document.querySelector("#paper svg"); var cursor = document.createElementNS("http://www.w3.org/2000/svg", "line"); cursor.setAttribute("class", "abcjs-cursor"); cursor.setAttributeNS(null, 'x1', 0); cursor.setAttributeNS(null, 'y1', 0); cursor.setAttributeNS(null, 'x2', 0); cursor.setAttributeNS(null, 'y2', 0); svg.appendChild(cursor); }; self.beatSubdivisions = 2; self.onBeat = function(beatNumber, totalBeats, totalTime) { }; self.onEvent = function(ev) { if (ev.measureStart && ev.left === null) return; // this was the second part of a tie across a measure line. Just ignore it. var lastSelection = document.querySelectorAll("#paper svg .highlight"); for (var k = 0; k < lastSelection.length; k++) lastSelection[k].classList.remove("highlight"); for (var i = 0; i < ev.elements.length; i++ ) { var note = ev.elements[i]; for (var j = 0; j < note.length; j++) { note[j].classList.add("highlight"); } } var cursor = document.querySelector("#paper svg .abcjs-cursor"); if (cursor) { cursor.setAttribute("x1", ev.left - 2); cursor.setAttribute("x2", ev.left - 2); cursor.setAttribute("y1", ev.top); cursor.setAttribute("y2", ev.top + ev.height); } }; self.onFinished = function() { var els = document.querySelectorAll("svg .highlight"); for (var i = 0; i < els.length; i++ ) { els[i].classList.remove("highlight"); } var cursor = document.querySelector("#paper svg .abcjs-cursor"); if (cursor) { cursor.setAttribute("x1", 0); cursor.setAttribute("x2", 0); cursor.setAttribute("y1", 0); cursor.setAttribute("y2", 0); } }; } var cursorControl = new CursorControl(); var synthControl; function load() { if (ABCJS.synth.supportsAudio()) { synthControl = new ABCJS.synth.SynthController(); synthControl.load("#audio", cursorControl, { displayLoop: true, displayRestart: true, displayPlay: true, displayProgress: true, displayWarp: true }); } else { document.querySelector("#audio").innerHTML = "
Audio is not supported in this browser.
"; } setTune(false); } function setTune(userAction) { synthControl.disable(true); var visualObj = ABCJS.renderAbc("paper", abc, abcOptions)[0]; var midiBuffer = new ABCJS.synth.CreateSynth(); midiBuffer.init({ visualObj: visualObj, }).then(function (response) { console.log(response); if (synthControl) { synthControl.setTune(visualObj, userAction).then(function (response) { console.log("Audio successfully loaded.") }).catch(function (error) { console.warn("Audio problem:", error); }); } }).catch(function (error) { console.warn("Audio problem:", error); }); } ``` -------------------------------- ### ABC Notation Example: Me Mother Won't Let Me Marry Source: https://github.com/paulrosen/abcjs/blob/main/examples/plugin/abc_plugin-midi.html An example of ABC notation for a jig tune titled 'Me Mother Won\'t Let Me Marry'. This notation can be rendered by ABCJS. ```abc X: 1 T: Me Mother Won't Let Me Marry M: 6/8 L: 1/8 R: jig K: D DFA B2A|FGF F2E|DFA B2A|G3-G2 F| EGE EFG|c2c c2B|A^GA B2A|F3-F2 E| DFA B2A|F=GF F2E|DFA B2A|G3-G2 F| E2E EFG|c2c c2B|A^GA ABc|d3 e2 z|\] f2f f2e|d2d d2e|ded c2d|e3-e2 f| g2g g2e|c2c c2B|A^GA B2A|F3-F2 d| f2f f2e|d2d d2e|ded c2d|e3-e2 f| g2g g2e|c2c c2B|A^GA ABc|d3-d2 z|\] ``` -------------------------------- ### Initialize SynthController and Load Audio Controls Source: https://github.com/paulrosen/abcjs/blob/main/examples/full-synth.html Initializes the SynthController and loads the audio playback interface. This should be done after checking for audio support. ```javascript if (ABCJS.synth.supportsAudio()) { synthControl = new ABCJS.synth.SynthController(); synthControl.load("#audio", cursorControl, { displayLoop: true, displayRestart: true, displayPlay: true, displayProgress: true, displayWarp: true }); } else { document.querySelector("#audio").innerHTML = "
Audio is not supported in this browser.
"; } ``` -------------------------------- ### Play Music Source: https://github.com/paulrosen/abcjs/blob/main/examples/full-synth.html Starts or pauses the music playback. This function is triggered by the 'Start/Pause' button. ```javascript function start() { if (synthControl) synthControl.play(); } ``` -------------------------------- ### Initialize Mocha and Load abcjs Source: https://github.com/paulrosen/abcjs/blob/main/tests/tablature.html Sets up the Mocha testing environment and loads the abcjs library. This is the initial step before running any tests. ```javascript mocha.setup({ui: 'bdd', globals: ['__VUE_DEVTOOLS_TOAST__']}); mocha.checkLeaks(); Tarp.require({main: "../index.js"}).then(function (response) { window.abcjs = response; mocha.run(); }); ``` -------------------------------- ### Render ABC Notation Tune 11: end Source: https://github.com/paulrosen/abcjs/blob/main/examples/plugin/abc_plugin.html An ABC notation example labeled 'end'. ```abc X:1 T:10 end G ``` -------------------------------- ### Initialize and Render ABC Notation Source: https://github.com/paulrosen/abcjs/blob/main/examples/synth-reuse.html Sets up event listeners for playback controls and renders the initial ABC notation. This is the entry point for the interactive demo. ```javascript var abc = "X:1\n" + "T: Sonata (fragment)\n" + "C: J.S. Bach\n" + "M: C\n" + "L: 1/8\n" + "K:C\n" + "[V:1] c/gf/ E/ed/ c/c'b/ A/ag/ | ^f/e/d- d/(c/B/A/) G/(e/c/e/) Aa| d2-d/g/\b/a/ a3 g/=f/|\n" + "[V:2] c8- | cB/A/ {A}B>c (e/c/A/c/) (E//^F//E//F//TF3//E///F///) | G/(D/G/A/) _B/G/g/e/ ^cA d2|\n" + "[V:3] edcB AG^FE | D^FGg c3d/c/| _BG g2-gf/e/ f>g|\n"; var synthControl; var abcOptions = { add_classes: true, responsive: "resize" }; var visualObj; function load() { document.querySelector(".prime").addEventListener("click", prime); document.querySelector(".play1").addEventListener("click", play1); document.querySelector(".play12").addEventListener("click", play12); document.querySelector(".play23").addEventListener("click", play23); document.querySelector(".play123").addEventListener("click", play123); document.querySelector(".play1s").addEventListener("click", play1s); document.querySelector(".play3s").addEventListener("click", play3s); visualObj = ABCJS.renderAbc("paper", abc, abcOptions)[0]; } ``` -------------------------------- ### Render ABC Notation Tune 9: middle Source: https://github.com/paulrosen/abcjs/blob/main/examples/plugin/abc_plugin.html An ABC notation example labeled 'middle', demonstrating mid-line rendering. ```abc X:1 T:8 middle G ``` -------------------------------- ### ABCJS Initialization and Event Handling Source: https://github.com/paulrosen/abcjs/blob/main/examples/full-synth.html Sets up ABCJS options, including class addition, click listener, and responsive resizing. It also defines a click listener function to handle user interactions with musical elements. ```javascript function clickListener(abcElem, tuneNumber, classes, analysis, drag, mouseEvent) { var output = "currentTrackMilliseconds: " + abcElem.currentTrackMilliseconds + "
" + "currentTrackWholeNotes: " + abcElem.currentTrackWholeNotes + "
" + "midiPitches: " + JSON.stringify(abcElem.midiPitches, null, 4) + "
" + "gracenotes: " + JSON.stringify(abcElem.gracenotes, null, 4) + "
" + "midiGraceNotePitches: " + JSON.stringify(abcElem.midiGraceNotePitches, null, 4) + "
"; document.querySelector(".clicked-info").innerHTML = "
Clicked info:
" +output; var lastClicked = abcElem.midiPitches; if (!lastClicked) return; ABCJS.synth.playEvent(lastClicked, abcElem.midiGraceNotePitches, synthControl.visualObj.millisecondsPerMeasure()).then(function (response) { console.log("note played"); }).catch(function (error) { console.log("error playing note", error); }); } var abcOptions = { add_classes: true, clickListener: self.clickListener, responsive: "resize" }; function load() { document.querySelector(".next").addEventListener("click", nex ``` -------------------------------- ### Render ABC Notation Tune 4: div child Source: https://github.com/paulrosen/abcjs/blob/main/examples/plugin/abc_plugin.html A simple ABC notation example labeled 'div child'. ```abc X: 1 T: 3 div child A ``` -------------------------------- ### Render ABC Notation Tune 3: body child Source: https://github.com/paulrosen/abcjs/blob/main/examples/plugin/abc_plugin.html A simple ABC notation example labeled 'body child'. ```abc X: 1 T: 2 body child A ``` -------------------------------- ### Render ABC Notation Tune 1: Speed the Plough Source: https://github.com/paulrosen/abcjs/blob/main/examples/plugin/abc_plugin.html A standard ABC notation example for the tune 'Speed the Plough'. ```abc X:1 T: 1 Speed the Plough M:4/4 L:1/8 C:Trad K:G |:GABc dedB|dedB dedB|c2ec B2dB|c2A2A2BA| |GABc dedB|dedB dedB|c2ec B2dB|A2F2G4:| |:g2gf g2Bd|g2fe dBGB|c2ec B2dB|c2A2A2df| g2gfg2Bd|g2fe dBGB|c2ec B2dB|A2F2G4:| ``` -------------------------------- ### Initialize ABCJS Editor with Guitar Tablature Source: https://github.com/paulrosen/abcjs/blob/main/examples/tablatures.html Initializes the ABCJS Editor for a guitar tablature. Specify the instrument, label, tuning, and capo settings. ```javascript window.onload = function () { // Guitar and Editor new ABCJS.Editor("abc", { canvas_id: "paper1", warnings_id: "warnings", abcjsParams: { tablature: [ // first and only staff { instrument: 'guitar', label: 'Guitar (%T)', tuning: ['D,', 'A,', 'D', 'G', 'A', 'd'], capo: 0 } ] } }); ``` -------------------------------- ### Basic Transposition with Visual and Audio Controls Source: https://github.com/paulrosen/abcjs/blob/main/examples/basic-transpose.html This snippet initializes the abcjs visualizer and audio synthesizer, then sets up event listeners to handle transposition based on user input. It demonstrates how to re-render the music visually and update the audio synthesizer when transposition values change. ```javascript var abc = "T: Cooley\n" + "M: 4/4\n" + "L: 1/8\n" + "R: reel\n" + "K: Emin\n" + "|:D2|EB{c}BA B2 EB|~B2 AB dBAG|FDAD BDAD|FDAD dAFD|\n" + "EBBA B2 EB|B2 AB defg|afe^c dBAF|DEFD E2:|\n" + "|:gf|eB B2 efge|eB B2 gedB|A2 FA DAFA|A2 FA defg|\n" + "eB B2 eBgB|eB B2 defg|afe^c dBAF|DEFD E2:|"; function load() { var showPlayer = document.querySelector('#show-player'); var transposeHalfSteps = document.querySelector(".transpose-half-steps"); var transposeVisual = document.querySelector(".transpose-visual"); var transposeAudio = document.querySelector(".transpose-audio"); var visualObj = ABCJS.renderAbc("paper", abc); var createSynth; var synthControl; // Initialize sound buffer and playback widget on a user gesture because of browser constraints on AudioContexts. showPlayer.addEventListener('click', () => { if (ABCJS.synth.supportsAudio()){ createSynth = new ABCJS.synth.CreateSynth(); // sound buffer synthControl = new ABCJS.synth.SynthController(); // widget // preloads and caches the notes to be played createSynth.init({ visualObj: visualObj[0] }).then(function() { redraw(); }); // creates playback widget with no visual cursor var cursorControl = null; synthControl.load('#audio', cursorControl, { displayRestart: true, displayPlay: true, displayProgress: true, }); } else { document.querySelector('#audio').innerHTML = 'Audio is not supported in this browser.' } showPlayer.style.display = 'none'; }); function redraw() { var transposeBy = transposeHalfSteps.value; var doVisual = transposeVisual.checked ? transposeBy : 0; var doAudio = transposeAudio.checked ? transposeBy : 0; // re-render visualObj visualObj = ABCJS.renderAbc("paper", abc, { visualTranspose: doVisual }); if(createSynth && synthControl) { // re-set tune stored in SynthController synthControl.setTune(visualObj[0], true, { midiTranspose: doAudio }) .then(function(){ console.log('Audio successfully loaded.') }).catch(function(error) { console.warn('Audio problem: ', error); }); } } transposeHalfSteps.addEventListener("change", function() { redraw(); }); transposeVisual.addEventListener("change", function() { redraw(); }); transposeAudio.addEventListener("change", function() { redraw(); }); } ``` -------------------------------- ### Mocha Test Setup Source: https://github.com/paulrosen/abcjs/blob/main/tests/all.html Configures Mocha for running tests, including disabling certain global variables and checking for memory leaks. ```javascript mocha.setup({ui: 'bdd', globals: ['__VUE_DEVTOOLS_TOAST__']}); mocha.checkLeaks(); ``` -------------------------------- ### Render ABC Notation Tune 15: end (with key) Source: https://github.com/paulrosen/abcjs/blob/main/examples/plugin/abc_plugin.html An ABC notation example labeled 'end', including key specification. ```abc X:1 T:14 end G ``` -------------------------------- ### Initialize and Play Synth Audio Source: https://github.com/paulrosen/abcjs/blob/main/examples/synth-only.html This snippet initializes the abcjs synthesizer and plays ABC notation from a textarea. It checks for audio support and handles potential errors. ```javascript function load() { document.querySelector(".play").addEventListener("click", play); } function play() { if (ABCJS.synth.supportsAudio()) { var abc = document.querySelector("#source").value; var visualObj = ABCJS.renderAbc("*", abc)[0]; var midiBuffer = new ABCJS.synth.CreateSynth(); midiBuffer.init({ //audioContext: new AudioContext(), visualObj: visualObj, // sequence: [], // millisecondsPerMeasure: 1000, // debugCallback: function(message) { console.log(message) }, options: { // soundFontUrl: "https://paulrosen.github.io/midi-js-soundfonts/FluidR3_GM/", // sequenceCallback: function(noteMapTracks, callbackContext) { return noteMapTracks; }, // callbackContext: this, // onEnded: function(callbackContext), // pan: [ -0.5, 0.5 ] } }).then(function (response) { console.log(response); midiBuffer.prime().then(function (response) { midiBuffer.start(); }); }).catch(function (error) { console.warn("Audio problem:", error); }); } else { document.querySelector(".error").innerHTML = "
Audio is not supported in this browser.
"; } } ``` -------------------------------- ### Render Music and Initialize Synth Source: https://github.com/paulrosen/abcjs/blob/main/examples/modify-synth-input.html Renders the ABC notation music to a specified HTML element and initializes the audio synthesizer. It handles audio context creation and user interaction requirements for browser audio playback. ```javascript var abc = "T: Cooley's\\n" + "%%barnumbers 1\\n" + "M: 4/4\\n" + "L: 1/8\\n" + "Q: 1/4=120\\n" + "R: reel\\n" + "K: Emin\\n" + "EBBA B2 EB|~B2 AB dBAG|FDAD BDAD|FDAD dAFD|\n" + "EBBA B2 EB|B2 AB defg|afe^c dBAF|DEFD E2 gf|\n" + "|eB B2 efge|eB B2 gedB|A2 FA DAFA|A2 FA defg|\n" + "eB B2 eBgB|eB B2 defg|afe^c dBAF|DEFD E2 D2||"; var synth = new ABCJS.synth.CreateSynth(); function load() { // First draw the music - this supplies an object that has a lot of information about how to create the synth. // NOTE: If you want just the sound without showing the music, use "*" instead of "paper" in the renderAbc call. var visualObj = ABCJS.renderAbc("paper", abc, { responsive: "resize" })[0]; var startAudioButton = document.querySelector(".activate-audio"); var stopAudioButton = document.querySelector(".stop-audio"); var explanationDiv = document.querySelector(".suspend-explanation"); startAudioButton.addEventListener("click", function() { startAudioButton.setAttribute("style", "display:none;"); explanationDiv.setAttribute("style", "opacity: 0;"); if (ABCJS.synth.supportsAudio()) { stopAudioButton.setAttribute("style", ""); // An audio context is needed - this can be passed in for two reasons: // 1) So that you can share this audio context with other elements on your page. // 2) So that you can create it during a user interaction so that the browser doesn't block the sound. // Setting this is optional - if you don't set an audioContext, then abcjs will create one. window.AudioContext = window.AudioContext || window.webkitAudioContext || navigator.mozAudioContext || navigator.msAudioContext; var audioContext = new window.AudioContext(); audioContext.resume().then(function () { // In theory the AC shouldn't start suspended because it is being initialized in a click handler, but iOS seems to anyway. synth.init({ audioContext: audioContext, visualObj: visualObj, options: { sequenceCallback: sequenceCallback } }).then(function () { synth.prime().then(function () { synth.start(); }); }).catch(function (error) { console.log("Audio Failed", error); }); }); } else { var audioError = document.querySelector(".audio-error"); audioError.setAttribute("style", ""); } }); stopAudioButton.addEventListener("click", function() { startAudioButton.setAttribute("style", ""); explanationDiv.setAttribute("style", ""); stopAudioButton.setAttribute("style", "display:none;"); synth.stop(); }); function sequenceCallback(tracks) { // The beats are 0.25 long so the amount of swing needs to be between 0 and 0.125, // but practically it needs to be a bit smaller so that it doesn't sound like a grace note. var swing = 0.1 - 0.1 / document.getElementById("swing").value; document.getElementById("coefficient").innerText = swing; var track = tracks[0]; for (var i = 0; i < track.length; i++) { var event = track[i]; if (event.start % 0.25) { // This is the off beat event.start += swing; } else { // This is the beat event.end += swing; } } } } ``` -------------------------------- ### Escaping Special Characters in JavaScript Source: https://github.com/paulrosen/abcjs/blob/main/examples/annotating.html When working with ABCJS in JavaScript, the backslash character (\) must be escaped. This example highlights the need for proper escaping. ```javascript Note that \ is a character which must be escaped in JavaScript. ``` -------------------------------- ### Initialize and Play Music with abcjs Synth Source: https://github.com/paulrosen/abcjs/blob/main/examples/basic-synth.html This snippet initializes the abcjs synthesizer, renders music notation, and handles audio playback in response to user interaction. It includes error handling for unsupported audio features. Use this when you need to play ABC notation music with sound in a web page. ```javascript var abc = "T: Cooley's\n" + "M: 4/4\n" + "L: 1/8\n" + "R: reel\n" + "K: Emin\n" + "|:D2|EB{c}BA B2 EB|~B2 AB dBAG|FDAD BDAD|FDAD dAFD|\n" + "EBBA B2 EB|B2 AB defg|afe^c dBAF|DEFD E2:|\n" + "|:gf|eB B2 efge|eB B2 gedB|A2 FA DAFA|A2 FA defg|\n" + "eB B2 eBgB|eB B2 defg|afe^c dBAF|DEFD E2:|\n"; function load() { // First draw the music - this supplies an object that has a lot of information about how to create the synth. // NOTE: If you want just the sound without showing the music, use "*" instead of "paper" in the renderAbc call. var visualObj = ABCJS.renderAbc("paper", abc, { responsive: "resize" })[0]; // This object is the class that will contain the buffer var midiBuffer; var startAudioButton = document.querySelector(".activate-audio"); var stopAudioButton = document.querySelector(".stop-audio"); var explanationDiv = document.querySelector(".suspend-explanation"); var statusDiv = document.querySelector(".status"); startAudioButton.addEventListener("click", function() { startAudioButton.setAttribute("style", "display:none;"); explanationDiv.setAttribute("style", "opacity: 0;"); statusDiv.innerHTML = "
Testing browser
"; if (ABCJS.synth.supportsAudio()) { stopAudioButton.setAttribute("style", ""); // An audio context is needed - this can be passed in for two reasons: // 1) So that you can share this audio context with other elements on your page. // 2) So that you can create it during a user interaction so that the browser doesn't block the sound. // Setting this is optional - if you don't set an audioContext, then abcjs will create one. window.AudioContext = window.AudioContext || window.webkitAudioContext || navigator.mozAudioContext || navigator.msAudioContext; var audioContext = new window.AudioContext(); audioContext.resume().then(function () { statusDiv.innerHTML += "
AudioContext resumed
"; // In theory the AC shouldn't start suspended because it is being initialized in a click handler, but iOS seems to anyway. // This does a bare minimum so this object could be created in advance, or whenever convenient. midiBuffer = new ABCJS.synth.CreateSynth(); // midiBuffer.init preloads and caches all the notes needed. There may be significant network traffic here. return midiBuffer.init({ visualObj: visualObj, audioContext: audioContext, millisecondsPerMeasure: visualObj.millisecondsPerMeasure() }).then(function (response) { console.log("Notes loaded: ", response) statusDiv.innerHTML += "
Audio object has been initialized
"; // console.log(response); // this contains the list of notes that were loaded. // midiBuffer.prime actually builds the output buffer. return midiBuffer.prime(); }).then(function (response) { statusDiv.innerHTML += "
Audio object has been primed (" + response.duration + " seconds).
"; statusDiv.innerHTML += "
status = " + response.status + "
" // At this point, everything slow has happened. midiBuffer.start will return very quickly and will start playing very quickly without lag. midiBuffer.start(); statusDiv.innerHTML += "
Audio started
"; return Promise.resolve(); }).catch(function (error) { if (error.status === "NotSupported") { stopAudioButton.setAttribute("style", "display:none;"); var audioError = document.querySelector(".audio-error"); audioError.setAttribute("style", ""); } else console.warn("synth error", error); }); }); } else { var audioError = document.querySelector(".audio-error"); audioError.setAttribute("style", ""); } }); stopAudioButton.addEventListener("click", function() { startAudioButton.setAttribute("style", ""); explanationDiv.setAttribute("style", ""); stopAudioButton.setAttribute("style", "display:none;"); if (midiBuffer) midiBuffer.stop(); }); } ``` -------------------------------- ### Render ABC Notation Tune 16: Ciaran � Raghallaigh Source: https://github.com/paulrosen/abcjs/blob/main/examples/plugin/abc_plugin.html An ABC notation example for 'Ciaran � Raghallaigh' by Charlie Lennon. ```abc X:1 T:Ciaran � Raghallaigh T:Master Seamus C:Charlie Lennon M:4/4 L:1/8 Z:Ted Hastings K:G B,C|DB, ~B,2 DGBG|FC ~C2 EGcG|FD ~D2 FAdc|edcd BGEG| DG,B,D GB,DG|ECDE GCEG|FADF AcBA|1 GFAF G2:|2 GEDB, G,2|| Bc|dggf gdBd|eccB ceag|fddc dfc'b|agfe dcBc| d2 Bd gdBd|~c2 Bc ABAF|EccB cBAG|FDCA, G,2:|| ```