Skip to content

Commit

Permalink
Merge https://github.com/AaronDavidNewman/Smoosic into ui-button-array
Browse files Browse the repository at this point in the history
  • Loading branch information
AaronDavidNewman committed Sep 22, 2024
2 parents a5031da + 9a1ce0d commit 66a2d29
Show file tree
Hide file tree
Showing 21 changed files with 1,594 additions and 1,340 deletions.
Binary file removed .DS_Store
Binary file not shown.
337 changes: 187 additions & 150 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/application/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ import { SuiSampleMedia } from '../render/audio/samples';
import { SmoScore, engravingFontTypes, isEngravingFont } from '../smo/data/score';
import { UndoBuffer } from '../smo/xform/undo';
import { SmoNote } from '../smo/data/note';
import { SmoDuration } from '../smo/xform/tickDuration';
// import { SmoDuration } from '../smo/xform/tickDuration';
import { createLoadTests } from '../../tests/file-load';
import { SmoStaffHairpin, StaffModifierBase, SmoInstrument, SmoSlur, SmoTie, SmoStaffTextBracket,
SmoTabStave, SmoPedalMarking
Expand Down Expand Up @@ -256,7 +256,7 @@ export const Smo = {
SmoOrnament,
SmoArticulation, SmoDynamicText, SmoGraceNote, SmoMicrotone, SmoLyric, SmoArpeggio, SmoClefChange,
// Smo Transformers
SmoSelection, SmoSelector, SmoDuration, UndoBuffer, SmoToVex, SmoOperation,
SmoSelection, SmoSelector, /*SmoDuration,*/ UndoBuffer, SmoToVex, SmoOperation,
// new score bootstrap
// help strings
cardKeysHtmlEn, cardNotesLetterHtmlEn, cardNotesChromaticHtmlEn, cardNotesChordsHtmlEn,
Expand Down
15 changes: 7 additions & 8 deletions src/common/vex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ TabNoteStruct as VexTabNoteStruct, PedalMarking as VexPedalMarking, Stem as VexS
* Most of the differences are trivial - e.g. different naming conventions for variables.
*/
import { smoSerialize } from "./serializationHelpers";
import { SmoMusic } from "../smo/data/music";
import { SvgBox } from "../smo/data/common";
// export type Vex = SmoVex;
export const VexFlow = SmoVex.Flow;
Expand Down Expand Up @@ -65,8 +66,11 @@ export interface GlyphInfo {

// DI interfaces to create vexflow objects
export interface CreateVexNoteParams {
isTuplet: boolean, measureIndex: number, clef: string,
closestTicks: string, exactTicks: string, keys: string[],
isTuplet: boolean,
measureIndex: number,
clef: string,
stemTicks: string,
keys: string[],
noteType: string
};

Expand Down Expand Up @@ -202,12 +206,7 @@ export function getVexTuplets(params: SmoVexTupletParams) {
return vexTuplet;
}
export function getVexNoteParameters(params: CreateVexNoteParams): { noteParams: StaveNoteStruct, duration: string } {
// If this is a tuplet, we only get the duration so the appropriate stem
// can be rendered. Vex calculates the actual ticks later when the tuplet is made
var duration =
params.isTuplet ?
params.closestTicks :
params.exactTicks;
var duration: any = params.stemTicks;
if (typeof (duration) === 'undefined') {
console.warn('bad duration in measure ' + params.measureIndex);
duration = '8';
Expand Down
64 changes: 39 additions & 25 deletions src/render/vex/toVex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { SmoNote } from '../../smo/data/note';
import { SmoMeasure, SmoVoice, MeasureTickmaps } from '../../smo/data/measure';
import { SmoScore } from '../../smo/data/score';
import { SmoArticulation, SmoLyric, SmoOrnament } from '../../smo/data/noteModifiers';
import { VexFlow, StaveNoteStruct, TupletOptions, vexOrnaments } from '../../common/vex';
import {VexFlow, StaveNoteStruct, TupletOptions, vexOrnaments, getVexTuplets} from '../../common/vex';
import { SmoBarline, SmoRehearsalMark } from '../../smo/data/measureModifiers';
import { SmoSelection, SmoSelector } from '../../smo/xform/selections';
import { SmoSystemStaff } from '../../smo/data/systemStaff';
Expand All @@ -14,6 +14,7 @@ import { SmoSystemGroup } from '../../smo/data/scoreModifiers';
import { StaffModifierBase, SmoStaffHairpin, SmoSlur, SmoTie, SmoStaffTextBracket } from '../../smo/data/staffModifiers';
import { toVexBarlineType, vexBarlineType, vexBarlinePosition, toVexBarlinePosition, leftConnectorVx, rightConnectorVx,
toVexVolta, getVexChordBlocks } from '../../render/vex/smoAdapter';
import {SmoTuplet} from "../../smo/data/tuplet";



Expand Down Expand Up @@ -78,10 +79,7 @@ function smoNoteToGraceNotes(smoNote: SmoNote, strs: string[]) {
}
}
function smoNoteToStaveNote(smoNote: SmoNote) {
const duration =
smoNote.isTuplet ?
SmoMusic.closestVexDuration(smoNote.tickCount) :
SmoMusic.ticksToDuration[smoNote.tickCount];
const duration = SmoMusic.ticksToDuration[smoNote.stemTicks];
const sn: StaveNoteStruct = {
clef: smoNote.clef,
duration,
Expand Down Expand Up @@ -431,27 +429,36 @@ function createBeamGroups(smoMeasure: SmoMeasure, strs: string[]) {
}
function createTuplets(smoMeasure: SmoMeasure, strs: string[]) {
smoMeasure.voices.forEach((voice, voiceIx) => {
const tps = smoMeasure.tuplets.filter((tp) => tp.voice === voiceIx);
for (var i = 0; i < tps.length; ++i) {
const tp = tps[i];
const nar: string[] = [];
for (var j = 0; j < tp.notes.length; ++j) {
const note = tp.notes[j];
const vexNote = `${note.attrs.id}`;
nar.push(vexNote);
for (let i = 0; i < smoMeasure.tupletTrees.length; ++i) {
const tupletTree = smoMeasure.tupletTrees[i];
if (tupletTree.voice !== voiceIx) {
continue;
}
const direction = tp.getStemDirection(smoMeasure.clef) === SmoNote.flagStates.up ?
VF.Tuplet.LOCATION_TOP : VF.Tuplet.LOCATION_BOTTOM;
const tpParams: TupletOptions = {
num_notes: tp.num_notes,
notes_occupied: tp.notes_occupied,
const traverseTupletTree = ( parentTuplet: SmoTuplet): void => {
const vexNotes = [];
for (let smoNote of smoMeasure.tupletNotes(parentTuplet)) {
const vexNote = `${smoNote.attrs.id}`;
vexNotes.push(vexNote);
}
const direction = smoMeasure.getStemDirectionForTuplet(parentTuplet) === SmoNote.flagStates.up ?
VF.Tuplet.LOCATION_TOP : VF.Tuplet.LOCATION_BOTTOM;
const tpParams: TupletOptions = {
num_notes: parentTuplet.numNotes,
notes_occupied: parentTuplet.notesOccupied,
ratioed: false,
bracketed: true,
location: direction
};
const tpParamString = JSON.stringify(tpParams);
const narString = '[' + nar.join(',') + ']';
strs.push(`const ${tp.id} = new VF.Tuplet(${narString}, JSON.parse('${tpParamString}'));`);
};
const tpParamString = JSON.stringify(tpParams);
const vexNotesString = '[' + vexNotes.join(',') + ']';
strs.push(`const ${parentTuplet.attrs.id} = new VF.Tuplet(${vexNotesString}, JSON.parse('${tpParamString}'));`);

for (let i = 0; i < parentTuplet.childrenTuplets.length; i++) {
const tuplet = parentTuplet.childrenTuplets[i];
traverseTupletTree(tuplet);
}
}
traverseTupletTree(tupletTree.tuplet);
}
});
}
Expand Down Expand Up @@ -497,9 +504,16 @@ function createMeasure(smoMeasure: SmoMeasure, heightOffset: number, strs: strin
strs.push(`${bg.attrs.id}.setContext(context);`);
strs.push(`${bg.attrs.id}.draw();`)
});
smoMeasure.tuplets.forEach((tp) => {
strs.push(`${tp.id}.setContext(context).draw();`)
})
smoMeasure.tupletTrees.forEach((tp) => {
const traverseTupletTree = ( parentTuplet: SmoTuplet): void => {
strs.push(`${parentTuplet.attrs.id}.setContext(context).draw();`)
for (let i = 0; i < parentTuplet.childrenTuplets.length; i++) {
const tuplet = parentTuplet.childrenTuplets[i];
traverseTupletTree(tuplet);
}
}
traverseTupletTree(tp.tuplet);
});
}
// ## SmoToVex
// Simple serialize class that produced VEX note and voice objects
Expand Down
69 changes: 36 additions & 33 deletions src/render/vex/vxMeasure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { VexFlow, Stave,StemmableNote, Note, Beam, Tuplet, Voice,
} from '../../common/vex';

import { VxMeasureIf, VexNoteModifierIf, VxNote } from './vxNote';
import { SmoTuplet } from '../../smo/data/tuplet';
import { vexGlyph } from './glyphDimensions';
const VF = VexFlow;

Expand Down Expand Up @@ -155,16 +156,18 @@ export class VxMeasure implements VxMeasureIf {
let vexNote: Note | null = null;
let smoTabNote: SmoTabNote | null = null;
let timestamp = new Date().valueOf();
const stemTicks = SmoMusic.ticksToDuration[smoNote.stemTicks];
let tabNote: StemmableNote | null = null;
const closestTicks = SmoMusic.closestVexDuration(smoNote.tickCount);
const exactTicks = SmoMusic.ticksToDuration[smoNote.tickCount];
const noteHead = smoNote.isRest() ? 'r' : smoNote.noteHead;
const keys = SmoMusic.smoPitchesToVexKeys(smoNote.pitches, 0, noteHead);
const smoNoteParams: CreateVexNoteParams = {
isTuplet: smoNote.isTuplet, measureIndex: this.smoMeasure.measureNumber.measureIndex,
const smoNoteParams = {
isTuplet: smoNote.isTuplet,
measureIndex: this.smoMeasure.measureNumber.measureIndex,
clef: smoNote.clef,
closestTicks, exactTicks, keys,
noteType: smoNote.noteType };
stemTicks,
keys,
noteType: smoNote.noteType
};
const { noteParams, duration } = getVexNoteParameters(smoNoteParams);
if (this.tabStave && this.smoTabStave) {
smoTabNote = this.smoTabStave.getTabNoteFromNote(smoNote, this.smoMeasure.transposeIndex);
Expand All @@ -182,7 +185,7 @@ export class VxMeasure implements VxMeasureIf {
tabNote = new VF.StaveNote(noteParams);
}
}
}
}
}
if (smoNote.noteType === '/') {
// vexNote = new VF.GlyphNote('\uE504', { duration });
Expand Down Expand Up @@ -294,7 +297,7 @@ export class VxMeasure implements VxMeasureIf {
this.voiceNotes = [];
const voice = this.smoMeasure.voices[voiceIx];
let clefNoteAdded = false;

for (i = 0;
i < voice.notes.length; ++i) {
const smoNote = voice.notes[i];
Expand Down Expand Up @@ -366,37 +369,37 @@ export class VxMeasure implements VxMeasureIf {
}
}

/**
* Create the VF tuplet objects based on the smo tuplet objects
* @param vix
*/
//
createVexTuplets(vix: number) {
var j = 0;
var i = 0;
this.vexTuplets = [];
this.tupletToVexMap = {};
for (i = 0; i < this.smoMeasure.tuplets.length; ++i) {
const tp = this.smoMeasure.tuplets[i];
if (tp.voice !== vix) {
for (let i = 0; i < this.smoMeasure.tupletTrees.length; ++i) {
const tupletTree = this.smoMeasure.tupletTrees[i];
if (tupletTree.voice !== vix) {
continue;
}
const vexNotes: Note[] = [];
for (j = 0; j < tp.notes.length; ++j) {
const smoNote = tp.notes[j];
vexNotes.push(this.noteToVexMap[smoNote.attrs.id]);
}
const location = tp.getStemDirection(this.smoMeasure.clef) === SmoNote.flagStates.up ?
VF.Tuplet.LOCATION_TOP : VF.Tuplet.LOCATION_BOTTOM;
const smoTupletParams = {
vexNotes,
numNotes: tp.numNotes,
notesOccupied: tp.note_ticks_occupied,
location
const traverseTupletTree = ( parentTuplet: SmoTuplet): void => {
const vexNotes = [];
for (let smoNote of this.smoMeasure.tupletNotes(parentTuplet)) {
vexNotes.push(this.noteToVexMap[smoNote.attrs.id]);
}
const location = this.smoMeasure.getStemDirectionForTuplet(parentTuplet) === SmoNote.flagStates.up ?
VF.Tuplet.LOCATION_TOP : VF.Tuplet.LOCATION_BOTTOM;
const smoTupletParams = {
vexNotes,
numNotes: parentTuplet.numNotes,
notesOccupied: parentTuplet.notesOccupied,
location
}
const vexTuplet = getVexTuplets(smoTupletParams);

this.tupletToVexMap[parentTuplet.attrs.id] = vexTuplet;
this.vexTuplets.push(vexTuplet);
for (let i = 0; i < parentTuplet.childrenTuplets.length; i++) {
const tuplet = parentTuplet.childrenTuplets[i];
traverseTupletTree(tuplet);
}
}
const vexTuplet = getVexTuplets(smoTupletParams);
this.tupletToVexMap[tp.id] = vexTuplet;
this.vexTuplets.push(vexTuplet);
traverseTupletTree(tupletTree.tuplet);
}
}

Expand Down
Loading

0 comments on commit 66a2d29

Please sign in to comment.