소스 검색

Merge commit '7006eebfcbe7b0065605c909ff02d26fd59aed30' into feature/OSMD-6_Porting

Matthias 9 년 전
부모
커밋
dc27e2ae03

+ 2 - 10
Gruntfile.js

@@ -114,14 +114,6 @@ module.exports = function (grunt) {
         typings: {
             install: {}
         },
-        // Documentation
-        docco: {
-            src: src,
-            options: {
-                layout: 'linear',
-                output: 'build/docs'
-            }
-        },
         // Cleaning task setup
         clean: {
             options: {
@@ -141,7 +133,6 @@ module.exports = function (grunt) {
 
     // Load Npm tasks
     grunt.loadNpmTasks('grunt-karma');
-    grunt.loadNpmTasks('grunt-docco');
     grunt.loadNpmTasks('grunt-tslint');
     grunt.loadNpmTasks('grunt-typings');
     grunt.loadNpmTasks('grunt-browserify');
@@ -154,10 +145,11 @@ module.exports = function (grunt) {
     grunt.registerTask('all',     ['typings', 'default']);
     grunt.registerTask('start',   ['typings']);
     grunt.registerTask('default', ['browserify', 'lint', 'karma:ci', 'uglify']);
+    grunt.registerTask('npmtest', ['typings', 'test']);
     grunt.registerTask('test',    ['browserify:debug', 'lint', 'karma:ci']);
     grunt.registerTask('fasttest', ['browserify:debug', 'karma:ci']);
     grunt.registerTask('rebuild', ['clean', 'default']);
-    grunt.registerTask('publish', ['clean', 'browserify:dist', 'docco']);
+    grunt.registerTask('publish', ['clean', 'typings', 'browserify', 'uglify']);
     grunt.registerTask('lint',    ['jshint', 'tslint']);
     // Fix these in the future:
     // grunt.registerTask('test debug Firefox', ['browserify:debug', 'karma:debugWithFirefox']);

+ 1 - 1
external/vexflow/vexflow.d.ts

@@ -113,7 +113,7 @@ declare namespace Vex {
     }
 
     export class Beam {
-      constructor(notes: StaveNote[]);
+      constructor(notes: StaveNote[], auto_stem: boolean);
       public setContext(ctx: CanvasContext): Beam;
       public draw(): void;
     }

+ 1 - 1
karma.conf.js

@@ -55,7 +55,7 @@ module.exports = function (config) {
 
         // level of logging
         // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
-        logLevel: config.LOG_INFO,
+        logLevel: config.LOG_DEBUG,
 
         // enable / disable watching file and executing tests whenever any file changes
         autoWatch: false,

+ 16 - 16
package.json

@@ -2,10 +2,11 @@
   "name": "opensheetmusicdisplay",
   "version": "0.0.0",
   "description": "Open Sheet Music Display library",
-  "main": "",
+  "main": "build/osmd.min.js",
   "scripts": {
-    "start": "grunt start",
-    "test": "grunt test"
+    "start": "alias grunt=\"'PATH=$(npm bin):$PATH' grunt\"",
+    "test": "grunt npmtest",
+    "prepublish": "grunt publish"
   },
   "repository": {
     "type": "git",
@@ -25,7 +26,6 @@
   "homepage": "http://opensheetmusicdisplay.org",
   "dependencies": {
     "browserify": "",
-    "chai": "^3.4.1",
     "es6-promise": "",
     "grunt": "",
     "grunt-browserify": "",
@@ -33,20 +33,10 @@
     "grunt-contrib-jshint": "",
     "grunt-contrib-uglify": "",
     "grunt-contrib-watch": "",
-    "grunt-docco": "",
-    "grunt-karma": "",
     "grunt-tslint": "",
     "grunt-typings": "",
+    "grunt-karma": "",
     "jszip": "",
-    "karma": "",
-    "karma-chai": "",
-    "karma-chrome-launcher": "",
-    "karma-firefox-launcher": "",
-    "karma-mocha": "",
-    "karma-mocha-reporter": "",
-    "karma-phantomjs-launcher": "",
-    "mocha": "^2.5.2",
-    "phantomjs-prebuilt": "",
     "tsify": "",
     "tslint": "3.8.0",
     "typescript": "",
@@ -54,7 +44,17 @@
     "vexflow": ""
   },
   "devDependencies": {
+    "chai": "^3.4.1",
+    "karma": "",
+    "karma-chai": "",
+    "karma-chrome-launcher": "",
+    "karma-firefox-launcher": "",
+    "karma-mocha": "",
+    "karma-mocha-reporter": "",
+    "karma-phantomjs-launcher": "",
     "karma-xml2js-preprocessor": "",
-    "karma-base64-to-js-preprocessor": ""
+    "karma-base64-to-js-preprocessor": "",
+    "mocha": "^2.5.2",
+    "phantomjs-prebuilt": ""
   }
 }

+ 2 - 0
src/Common/FileIO/Xml.ts

@@ -22,6 +22,8 @@ export class IXmlElement {
         // Look for a value
         if (elem.childNodes.length === 1 && elem.childNodes[0].nodeType === Node.TEXT_NODE) {
             this.value = elem.childNodes[0].nodeValue;
+        } else {
+            this.value = "";
         }
     }
 

+ 28 - 21
src/MusicalScore/Graphical/VexFlow/VexFlowConverter.ts

@@ -24,21 +24,20 @@ export class VexFlowConverter {
 
     public static duration(fraction: Fraction): string {
         let dur: number = fraction.RealValue;
-        switch (dur) {
-            case 0.25:
-                return "q";
-            case 0.5:
-                return "h";
-            case 1:
-                return "w";
-            case 0.125:
-                return "8";
-            case 0.0625:
-                return "16";
-            // FIXME TODO
-            default:
-                return "16";
+        if (dur === 1) {
+            return "w";
+        } else if (dur < 1 && dur >= 0.5) {
+            return "h";
+        } else if (dur < 0.5 && dur >= 0.25) {
+            return "q";
+        } else if (dur < 0.25 && dur >= 0.125) {
+            return "8";
+        } else if (dur < 0.125 && dur >= 0.0625) {
+            return "16";
+        } else if (dur < 0.0625 && dur >= 0.03125) {
+            return "32";
         }
+        return "128";
     }
 
     /**
@@ -47,9 +46,9 @@ export class VexFlowConverter {
      * @param pitch
      * @returns {string[]}
      */
-    public static pitch(pitch: Pitch, octaveOffset: number): [string, string] {
+    public static pitch(pitch: Pitch, clef: ClefInstruction): [string, string, ClefInstruction] {
         let fund: string = NoteEnum[pitch.FundamentalNote].toLowerCase();
-        let octave: number = pitch.Octave + octaveOffset + 3;
+        let octave: number = pitch.Octave + clef.OctaveOffset + 3; // FIXME + 3
         let acc: string = "";
 
         switch (pitch.Accidental) {
@@ -69,15 +68,17 @@ export class VexFlowConverter {
                 break;
             default:
         }
-        return [fund + acc + "/" + octave, acc];
+        return [fund + acc + "/" + octave, acc, clef];
     }
 
     public static StaveNote(notes: GraphicalNote[]): Vex.Flow.StaveNote {
         let keys: string[] = [];
-        let duration: string = VexFlowConverter.duration(notes[0].sourceNote.Length);
+        let frac: Fraction = notes[0].sourceNote.Length;
+        let duration: string = VexFlowConverter.duration(frac);
         let accidentals: string[] = [];
+        let vfclef: string;
         for (let note of notes) {
-            let res: [string, string] = (note as VexFlowGraphicalNote).vfpitch;
+            let res: [string, string, ClefInstruction] = (note as VexFlowGraphicalNote).vfpitch;
             if (res === undefined) {
                 keys = ["b/4"];
                 accidentals = [];
@@ -86,11 +87,18 @@ export class VexFlowConverter {
             }
             keys.push(res[0]);
             accidentals.push(res[1]);
+            if (!vfclef) {
+                vfclef = VexFlowConverter.Clef(res[2]);
+            }
         }
         let vfnote: Vex.Flow.StaveNote = new Vex.Flow.StaveNote({
             auto_stem: true,
-            clef: "treble", // FIXME!!
+            clef: vfclef,
             duration: duration,
+            duration_override: {
+                denominator: frac.Denominator,
+                numerator: frac.Numerator,
+            },
             keys: keys,
         });
         for (let i: number = 0, len: number = keys.length; i < len; i += 1) {
@@ -122,7 +130,6 @@ export class VexFlowConverter {
                 break;
             default:
         }
-        console.log("CLEF", clef, type);
         return type;
     }
 

+ 2 - 2
src/MusicalScore/Graphical/VexFlow/VexFlowGraphicalNote.ts

@@ -8,11 +8,11 @@ export class VexFlowGraphicalNote extends GraphicalNote {
     constructor(note: Note, parent: GraphicalStaffEntry, activeClef: ClefInstruction) {
         super(note, parent);
         if (note.Pitch) {
-            this.vfpitch = VexFlowConverter.pitch(note.Pitch, activeClef.OctaveOffset);
+            this.vfpitch = VexFlowConverter.pitch(note.Pitch, activeClef);
         } else {
             this.vfpitch = undefined;
         }
     }
 
-    public vfpitch: [string, string];
+    public vfpitch: [string, string, ClefInstruction];
 }

+ 13 - 17
src/MusicalScore/Graphical/VexFlow/VexFlowMeasure.ts

@@ -26,15 +26,14 @@ export class VexFlowMeasure extends StaffMeasure {
     public vfVoices: { [voiceID: number]: Vex.Flow.Voice; };
     public formatVoices: (width: number) => void;
     public unit: number = 10.0;
+
     private stave: Vex.Flow.Stave;
 
     private beams: { [voiceID: number]: [Beam, VexFlowStaffEntry[]][]; } = {};
     private vfbeams: { [voiceID: number]: Vex.Flow.Beam[]; } = {};
-    //private duration: Fraction;
 
     public setAbsoluteCoordinates(x: number, y: number): void {
-        this.stave.setX(x);
-        this.stave.setY(y);
+        this.stave.setX(x).setY(y);
     }
 
     /**
@@ -55,17 +54,17 @@ export class VexFlowMeasure extends StaffMeasure {
         // FIXME: See values in VexFlow's stavebarline.js
         switch (line) {
             case SystemLinesEnum.SingleThin:
-                return 5;
+                return 5 / this.unit;
             case SystemLinesEnum.DoubleThin:
-                return 5;
+                return 5 / this.unit;
             case SystemLinesEnum.ThinBold:
-                return 5;
+                return 5 / this.unit;
             case SystemLinesEnum.BoldThinDots:
-                return 5;
+                return 5 / this.unit;
             case SystemLinesEnum.DotsThinBold:
-                return 5;
+                return 5 / this.unit;
             case SystemLinesEnum.DotsBoldBoldDots:
-                return 5;
+                return 5 / this.unit;
             case SystemLinesEnum.None:
                 return 0;
             default:
@@ -130,17 +129,14 @@ export class VexFlowMeasure extends StaffMeasure {
      * @param width
      */
     public setWidth(width: number): void {
-        // Widths in PS and VexFlow work differently.
-        // In VexFlow, width is only the width of the actual voices, without considering
-        // modifiers like clefs. In PS, width is the total width of the stave.
-        // @Andrea: The following could be improved by storing the values in this object.
-        //          Now it calls .format() implicitly.
-        //
         super.setWidth(width);
+        // Set the width of the Vex.Flow.Stave
         this.stave.setWidth(width * this.unit);
+        // If this is the first stave in the vertical measure, call the format
+        // method to set the width of all the voices
         if (this.formatVoices) {
+            // The width of the voices does not include the instructions (StaveModifiers)
             this.formatVoices((width - this.beginInstructionsWidth - this.endInstructionsWidth) * this.unit);
-            this.formatVoices = undefined;
         }
     }
 
@@ -212,7 +208,7 @@ export class VexFlowMeasure extends StaffMeasure {
                     for (let entry of beam[1]) {
                         notes.push((entry as VexFlowStaffEntry).vfNotes[voiceID]);
                     }
-                    vfbeams.push(new Vex.Flow.Beam(notes));
+                    vfbeams.push(new Vex.Flow.Beam(notes, true));
                 }
             }
         }

+ 1 - 1
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetCalculator.ts

@@ -73,7 +73,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
                 if (mvoices.hasOwnProperty(voiceID)) {
                     voices.push(mvoices[voiceID]);
                     allVoices.push(mvoices[voiceID]);
-    }
+                }
             }
             if (voices.length === 0) {
                 console.log("Found a measure with no voices... Continuing anyway.", mvoices);

+ 1 - 2
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer.ts

@@ -23,7 +23,6 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
 
     private renderer: Vex.Flow.Renderer;
     private ctx: Vex.Flow.CanvasContext;
-    private counter: number = 0;
 
     public drawSheet(graphicalMusicSheet: GraphicalMusicSheet): void {
         // FIXME units
@@ -39,7 +38,7 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
     protected drawMeasure(measure: VexFlowMeasure): void {
         measure.setAbsoluteCoordinates(
             measure.PositionAndShape.AbsolutePosition.x * (measure as VexFlowMeasure).unit,
-            measure.PositionAndShape.AbsolutePosition.y * (measure as VexFlowMeasure).unit + (this.counter += 5)
+            measure.PositionAndShape.AbsolutePosition.y * (measure as VexFlowMeasure).unit
         );
         return measure.draw(this.ctx);
     }

+ 1 - 1
src/MusicalScore/ScoreIO/VoiceGenerator.ts

@@ -648,7 +648,7 @@ export class VoiceGenerator {
         return this.openTupletNumber;
     }
     private handleTimeModificationNode(noteNode: IXmlElement): void {
-        if (Object.keys(this.tupletDict).length !== 0) {
+        if (this.openTupletNumber in this.tupletDict) {
             try {
                 let tuplet: Tuplet = this.tupletDict[this.openTupletNumber];
                 let notes: Note[] = CollectionUtil.last(tuplet.Notes);

+ 17 - 0
src/MusicalScore/VoiceData/Note.ts

@@ -8,6 +8,7 @@ import {Tie} from "./Tie";
 import {Staff} from "./Staff";
 import {Slur} from "./Expressions/ContinuousExpressions/Slur";
 import {NoteState} from "../Graphical/DrawingEnums";
+import {MusicSymbol} from "../Graphical/MusicSymbol";
 
 export class Note {
 
@@ -158,6 +159,22 @@ export class Note {
         }
         return false;
     }
+
+    //public calculateTailSymbol(): number {
+    //    let length: number = this.Length.RealValue;
+    //    if (this.NoteTuplet) {
+    //        length = this.NoteTuplet.Fractions[this.NoteTuplet.getNoteIndex(this)].RealValue;
+    //    }
+    //    if (length < 0.25 && length >= 0.125) {
+    //        return 8;
+    //    } else if (length < 0.125 && length >= 0.0625) {
+    //        return 16;
+    //    } else if (length < 0.0625 && length >= 0.03125) {
+    //        return 32;
+    //    } else {
+    //        return 64;
+    //    }
+    //}
 }
 
 export enum Appearance {

+ 1 - 0
test/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer.ts

@@ -10,6 +10,7 @@ describe("VexFlow Music Sheet Drawer", () => {
 
     it(".drawSheet (Clementi pt. 1)", (done: MochaDone) => {
         let path: string = "test/data/MuzioClementi_SonatinaOpus36No1_Part1.xml";
+        // "test/data/MuzioClementi_SonatinaOpus36No1_Part1.xml";
         let score: IXmlElement = TestUtils.getScore(path);
         chai.expect(score).to.not.be.undefined;
         let calc: VexFlowMusicSheetCalculator = new VexFlowMusicSheetCalculator();