import { OpenSheetMusicDisplay } from '../src/OpenSheetMusicDisplay/OpenSheetMusicDisplay'; import { BackendType } from '../src/OpenSheetMusicDisplay/OSMDOptions'; import { PlaybackManager, LinearTimingSource, BasicAudioPlayer, ControlPanel } from '../src/Playback'; import * as jsPDF from '../node_modules/jspdf/dist/jspdf.es.min'; import * as svg2pdf from '../node_modules/svg2pdf.js/dist/svg2pdf.umd.min'; import { TransposeCalculator } from '../src/Plugins/Transpose/TransposeCalculator'; /*jslint browser:true */ (function () { "use strict"; var openSheetMusicDisplay; var sampleFolder = "", samples = { "Beethoven, L.v. - An die ferne Geliebte": "Beethoven_AnDieFerneGeliebte.xml", "Clementi, M. - Sonatina Op.36 No.1 Pt.1": "MuzioClementi_SonatinaOpus36No1_Part1.xml", "Clementi, M. - Sonatina Op.36 No.1 Pt.2": "MuzioClementi_SonatinaOpus36No1_Part2.xml", "Clementi, M. - Sonatina Op.36 No.3 Pt.1": "MuzioClementi_SonatinaOpus36No3_Part1.xml", "Clementi, M. - Sonatina Op.36 No.3 Pt.2": "MuzioClementi_SonatinaOpus36No3_Part2.xml", "Bach, J.S. - Praeludium in C-Dur BWV846 1": "JohannSebastianBach_PraeludiumInCDur_BWV846_1.xml", "Bach, J.S. - Air": "JohannSebastianBach_Air.xml", "Gounod, C. - Méditation": "CharlesGounod_Meditation.xml", "Haydn, J. - Concertante Cello": "JosephHaydn_ConcertanteCello.xml", "Joplin, S. - Elite Syncopations": "ScottJoplin_EliteSyncopations.xml", "Joplin, S. - The Entertainer": "ScottJoplin_The_Entertainer.xml", "Mozart, W.A. - An Chloe": "Mozart_AnChloe.xml", "Mozart, W.A. - Das Veilchen": "Mozart_DasVeilchen.xml", "Mozart, W.A. - Clarinet Quintet (Excerpt)": "Mozart_Clarinet_Quintet_Excerpt.mxl", "Mozart, W.A. - String Quartet in G, K. 387, 1st Mvmt Excerpt": "Mozart_String_Quartet_in_G_K._387_1st_Mvmnt_excerpt.musicxml", "Mozart/Holzer - Land der Berge (national anthem of Austria)": "Land_der_Berge.musicxml", "OSMD Function Test - All": "OSMD_function_test_all.xml", "OSMD Function Test - Accidentals": "OSMD_function_test_accidentals.musicxml", "OSMD Function Test - Autobeam": "OSMD_function_test_autobeam.musicxml", "OSMD Function Test - Auto-/Custom-Coloring": "OSMD_function_test_auto-custom-coloring-entchen.musicxml", "OSMD Function Test - Bar lines": "OSMD_function_test_bar_lines.musicxml", "OSMD Function Test - Chord Symbols": "OSMD_function_test_chord_symbols.musicxml", "OSMD Function Test - Chord Spacing": "OSMD_function_test_chord_spacing.mxl", "OSMD Function Test - Chord Symbols - Various Chords": "OSMD_function_test_chord_tests_various.musicxml", "OSMD Function Test - Chord Symbols - BrookeWestSample": "BrookeWestSample.mxl", "OSMD Function Test - Color (from XML)": "OSMD_function_test_color.musicxml", "OSMD Function Test - Container height (compacttight mode)": "OSMD_Function_Test_Container_height.musicxml", "OSMD Function Test - Drumset": "OSMD_function_test_drumset.musicxml", "OSMD Function Test - Drums on one Line": "OSMD_Function_Test_Drums_one_line_snare_plus_piano.musicxml", "OSMD Function Test - Expressions": "OSMD_function_test_expressions.musicxml", "OSMD Function Test - Expressions Overlap": "OSMD_function_test_expressions_overlap.musicxml", "OSMD Function Test - Grace Notes": "OSMD_function_test_GraceNotes.xml", "OSMD Function Test - Metronome Marks": "OSMD_function_test_metronome_marks.mxl", "OSMD Function Test - Multiple Rest Measures": "OSMD_function_test_multiple_rest_measures.musicxml", "OSMD Function Test - Invisible Notes": "OSMD_function_test_invisible_notes.musicxml", "OSMD Function Test - Notehead Shapes": "OSMD_function_test_noteheadShapes.musicxml", "OSMD Function Test - Ornaments": "OSMD_function_test_Ornaments.xml", "OSMD Function Test - Pedals": "OSMD_Function_Test_Pedals.musicxml", "OSMD Function Test - Selecting Measures To Draw": "OSMD_function_test_measuresToDraw_Beethoven_AnDieFerneGeliebte.xml", "OSMD Function Test - System and Page Breaks": "OSMD_Function_Test_System_and_Page_Breaks_4_pages.mxl", "OSMD Function Test - Tabulature": "OSMD_Function_Test_Tabulature_hayden_study_1.mxl", "OSMD Function Test - Tabulature MultiBends": "OSMD_Function_Test_Tablature_Multibends.musicxml", "OSMD Function Test - Tabulature All Effects": "OSMD_Function_Test_Tablature_Alleffects.musicxml", "OSMD Function Test - Tremolo": "OSMD_Function_Test_Tremolo_2bars.musicxml", "OSMD Function Test - Labels": "OSMD_Function_Test_Labels.musicxml", "OSMD Function Test - High Slur Test": "test_slurs_highNotes.musicxml", "OSMD Function Test - Auto Multirest Measures Single Staff": "Test_Auto_Multirest_1.musicxml", "OSMD Function Test - Auto Multirest Measures Multiple Staves": "Test_Auto_Multirest_2.musicxml", "OSMD Function Test - String number collisions": "test_string_number_collisions.musicxml", "OSMD Function Test - Repeat Stave Connectors": "OSMD_function_Test_Repeat.musicxml", "OSMD Function Test - Trill Lines": "OSMD_Trill_Line_Function_Test.musicxml", "OSMD Function Test - Voice Alignment": "OSMD_Function_Test_Voice_Alignment.musicxml", "Schubert, F. - An Die Musik": "Schubert_An_die_Musik.xml", "Actor, L. - Prelude (Large Sample, loading time)": "ActorPreludeSample.xml", "Actor, L. - Prelude (Large, No Print Part Names)": "ActorPreludeSample_PartName.xml", "Anonymous - Saltarello": "Saltarello.mxl", "Debussy, C. - Mandoline": "Debussy_Mandoline.xml", "Levasseur, F. - Parlez Mois": "Parlez-moi.mxl", "Schumann, R. - Dichterliebe": "Dichterliebe01.xml", "Telemann, G.P. - Sonate-Nr.1.1-Dolce": "TelemannWV40.102_Sonate-Nr.1.1-Dolce.xml", "Telemann, G.P. - Sonate-Nr.1.2-Allegro": "TelemannWV40.102_Sonate-Nr.1.2-Allegro-F-Dur.xml", }, comments = { "Beethoven_AnDieFerneGeliebte.xml": ["Beethoven_AnDieFerneGeliebte_comments.xml", "Beethoven_AnDieFerneGeliebte_comments_2.xml"] }, zoom = 1.0, // HTML Elements in the page divControls, zoomControls, header, err, error_tr, canvas, selectSample, selectBounding, skylineDebug, bottomlineDebug, zoomIns, zoomOuts, zoomDivs, custom, nextCursorBtn, resetCursorBtn, followCursorCheckbox, showCursorBtn, hideCursorBtn, backendSelect, backendSelectDiv, debugReRenderBtn, debugClearBtn, selectPageSizes, printPdfBtns, transpose, transposeBtn, performanceMode, performanceModeBtn, playbackControlsButton, playbackControl; // manage option setting and resetting for specific samples, e.g. in the autobeam sample autobeam is set to true, otherwise reset to previous state // TODO design a more elegant option state saving & restoring system, though that requires saving the options state in OSMD var minMeasureToDrawStashed = 1; var maxMeasureToDrawStashed = Number.MAX_SAFE_INTEGER; var measureToDrawRangeNeedsReset = false; var drawingParametersStashed = "default"; var drawingParametersNeedsReset = false; var autobeamOptionNeedsReset = false; var autobeamOptionStashedValue = false; var autoCustomColoringOptionNeedsReset = false; var autoCustomColoringOptionStashedValue = false; var drawPartNamesOptionStashedValue = true; var drawPartAbbreviationsStashedValue = true; var drawPartNamesOptionNeedsReset = false; var pageBreaksOptionStashedValue = false; var pageBreaksOptionNeedsReset = false; var systemBreaksOptionStashedValue = false; // reset handled by pageBreaksOptionNeedsReset var showControls = true; var showExportPdfControl = false; var showPageFormatControl = false; var showZoomControl = true; var showHeader = true; var showDebugControls = false; document.title = "OpenSheetMusicDisplay Demo"; // Initialization code function init() { var name, option; // Handle window parameter var paramEmbedded = findGetParameter('embedded'); var paramShowControls = findGetParameter('showControls'); var paramShowPageFormatControl = findGetParameter('showPageFormatControl'); var paramShowExportPdfControl = findGetParameter('showExportPdfControl'); var paramShowZoomControl = findGetParameter('showZoomControl'); var paramShowHeader = findGetParameter('showHeader'); var paramZoom = findGetParameter('zoom'); var paramOverflow = findGetParameter('overflow'); var paramOpenUrl = findGetParameter('openUrl'); var paramDebugControls = findGetParameter('debugControls'); var paramCompactMode = findGetParameter('compactMode'); var paramMeasureRangeStart = findGetParameter('measureRangeStart'); var paramMeasureRangeEnd = findGetParameter('measureRangeEnd'); var paramPageFormat = findGetParameter('pageFormat'); var paramPageBackgroundColor = findGetParameter('pageBackgroundColor'); var paramBackendType = findGetParameter('backendType'); var paramPageWidth = findGetParameter('pageWidth'); var paramPageHeight = findGetParameter('pageHeight'); var paramHorizontalScrolling = findGetParameter('horizontalScrolling'); var paramSingleHorizontalStaffline = findGetParameter('singleHorizontalStaffline'); showHeader = (paramShowHeader !== '0'); showControls = false; if (paramEmbedded) { showControls = paramShowControls !== '0'; showZoomControl = paramShowZoomControl !== '0'; showPageFormatControl = paramShowPageFormatControl !== '0'; showExportPdfControl = paramShowExportPdfControl !== '0'; } if (paramZoom) { if (paramZoom > 0.1 && paramZoom < 5.0) { zoom = paramZoom; } } if (paramOverflow && typeof paramOverflow === 'string') { if (paramOverflow === 'hidden' || paramOverflow === 'auto' || paramOverflow === 'scroll' || paramOverflow === 'visible') { document.body.style.overflow = paramOverflow; } } var compactMode = paramCompactMode && paramCompactMode !== '0'; var measureRangeStart = paramMeasureRangeStart ? Number.parseInt(paramMeasureRangeStart) : 0; var measureRangeEnd = paramMeasureRangeEnd ? Number.parseInt(paramMeasureRangeEnd) : Number.MAX_SAFE_INTEGER; if (measureRangeStart && measureRangeEnd && measureRangeEnd < measureRangeStart) { console.log("[OSMD] warning: measure range end parameter should not be smaller than measure range start. We've set start measure = end measure now.") measureRangeStart = measureRangeEnd; } let pageFormat = paramPageFormat ? paramPageFormat : "Endless"; if (paramPageHeight && paramPageWidth) { pageFormat = `${paramPageWidth}x${paramPageHeight}` } var pageBackgroundColor = paramPageBackgroundColor ? "#" + paramPageBackgroundColor : undefined; // vexflow format, see OSMDOptions. can't use # in parameters. //console.log("demo: osmd pagebgcolor: " + pageBackgroundColor); var backendType = (paramBackendType && paramBackendType.toLowerCase) ? paramBackendType : "svg"; var horizontalScrolling = paramHorizontalScrolling === '1'; var singleHorizontalStaffline = paramSingleHorizontalStaffline === '1'; // set the backendSelect debug controls dropdown menu selected item //console.log("true: " + backendSelect && backendType.toLowerCase && backendType.toLowerCase() === "canvas"); // TODO somehow backendSelect becomes undefined here: /*if (backendSelect && backendType.toLowerCase && backendType.toLowerCase() === "canvas") { console.log("here1"); for (var i=0; i pageWidth ? "p" : "l"; // create a new jsPDF instance const pdf = new jsPDF.jsPDF({ orientation: orientation, unit: "mm", format: [pageWidth, pageHeight] }); //const scale = pageWidth / svgElement.clientWidth; for (let idx = 0, len = backends.length; idx < len; ++idx) { if (idx > 0) { pdf.addPage(); } svgElement = backends[idx].getSvgElement(); if (!pdf.svg && !svg2pdf) { // this line also serves to make the svg2pdf not unused, though it's still necessary // we need svg2pdf to have pdf.svg defined console.log("svg2pdf missing, necessary for jspdf.svg()."); return; } await pdf.svg(svgElement, { x: 0, y: 0, width: pageWidth, height: pageHeight, }) } pdf.save(pdfName); // save/download the created pdf //pdf.output("pdfobjectnewwindow", {filename: "osmd_createPDF.pdf"}); // open PDF in new tab/window // note that using jspdf with svg2pdf creates unnecessary console warnings "AcroForm-Classes are not populated into global-namespace..." // this will hopefully be fixed with a new jspdf release, see https://github.com/yWorks/jsPDF/pull/32 } var demoPlaybackControl = function(osmd) { var playbackListener = { play() { followCursorCheckbox.checked = true; openSheetMusicDisplay.FollowCursor = true; }, pause() {}, reset() {}, bpmChanged() {}, volumeChanged() {}, volumeMute() {}, volumeUnmute() {} } var timingSource = new LinearTimingSource(); var playbackManager = new PlaybackManager(timingSource, undefined, new BasicAudioPlayer(), undefined); playbackManager.DoPlayback = true; playbackManager.DoPreCount = false; playbackManager.PreCountMeasures = 1; // note that DoPreCount has to be true for a precount to happen var playbackControlPanel = new ControlPanel(); playbackControlPanel.addListener(playbackManager); playbackControlPanel.addListener(playbackListener); function initialize() { timingSource.reset(); timingSource.pause(); timingSource.Settings = osmd.Sheet.playbackSettings; playbackManager.initialize(osmd.Sheet.musicPartManager); playbackManager.addListener(osmd.cursor); playbackManager.reset(); osmd.PlaybackManager = playbackManager; playbackControlPanel.clearVolumeTracks(); playbackControlPanel.addVolumeTrack(playbackManager.Metronome.Name, playbackManager.Metronome.Id, playbackManager.Metronome.Volume*100); for(const instrId of playbackManager.InstrumentIdMapping.keys()) { const instr = playbackManager.InstrumentIdMapping.getValue(instrId); playbackControlPanel.addVolumeTrack(instr.Name, instrId, instr.Volume * 100); } playbackControlPanel.bpmChanged(osmd.Sheet.DefaultStartTempoInBpm); } function showControls() { playbackControlPanel.show(); } function hideControls() { playbackControlPanel.hideAndClear(); } function IsClosed() { return playbackControlPanel.IsClosed; } return { initialize: initialize, showControls: showControls, hideControls: hideControls, IsClosed: IsClosed } }; // Register events: load, drag&drop window.addEventListener("load", function () { init(); }); window.addEventListener("dragenter", function (event) { event.preventDefault(); disable(); }); window.addEventListener("dragover", function (event) { event.preventDefault(); }); window.addEventListener("dragleave", function (event) { enable(); }); window.addEventListener("drop", function (event) { event.preventDefault(); if (!event.dataTransfer || !event.dataTransfer.files || event.dataTransfer.files.length === 0) { return; } // Add "Custom..." score selectSample.appendChild(custom); custom.selected = "selected"; // Read dragged file var reader = new FileReader(); reader.onload = function (res) { selectSampleOnChange(res.target.result); }; var filename = event.dataTransfer.files[0].name; if (filename.toLowerCase().indexOf(".xml") > 0 || filename.toLowerCase().indexOf(".musicxml") > 0) { reader.readAsText(event.dataTransfer.files[0]); } else if (event.dataTransfer.files[0].name.toLowerCase().indexOf(".mxl") > 0) { reader.readAsBinaryString(event.dataTransfer.files[0]); } else { alert("No vaild .xml/.mxl/.musicxml file!"); } }); }());