Skip to content

Commit

Permalink
formatting flags, beam group formatting
Browse files Browse the repository at this point in the history
After loading a midi file, auto-format the beam groups.
  • Loading branch information
AaronDavidNewman committed May 27, 2024
1 parent d0d7050 commit 2ac40c1
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/render/sui/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,9 @@ export class SuiLayoutFormatter {
// TODO: Consider engraving font and adjust grace note size?
noteWidth += (headWidth + vexGlyph.dimensions.noteHead.spacingRight) * note.graceNotes.length;
noteWidth += dotWidth * dots + vexGlyph.dimensions.dot.spacingRight * dots;
if (!note.isRest() && note.endBeam) {
noteWidth += vexGlyph.dimensions.flag.width;
}
note.pitches.forEach((pitch) => {
const keyAccidental = SmoMusic.getAccidentalForKeySignature(pitch, smoMeasure.keySignature);
const accidentals = tmObj.accidentalArray.filter((ar) =>
Expand Down
4 changes: 2 additions & 2 deletions src/render/sui/scoreView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ export abstract class SuiScoreView {
* await on the full update of the score, also resetting the viewport (to reflect layout changes)
* @returns
*/
refreshViewport(): Promise<any> {
async refreshViewport(): Promise<any> {
this.renderer.preserveScroll();
this.renderer.setViewport();
this.renderer.setRefresh();
return this.renderer.renderPromise();
await this.renderer.renderPromise();
}
handleScrollEvent(scrollLeft: number, scrollTop: number) {
this.tracker.scroller.handleScroll(scrollLeft, scrollTop);
Expand Down
15 changes: 15 additions & 0 deletions src/render/sui/scoreViewOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,21 @@ export class SuiScoreViewOperations extends SuiScoreView {
this._renderChangedMeasures(measureSelections);
await this.renderer.updatePromise();
}
async clearAllBeams(): Promise<void> {
this._undoScore('clearAllBeams');
SmoOperation.clearAllBeamGroups(this.score);
SmoOperation.clearAllBeamGroups(this.storeScore);
await this.awaitRender();
}
async clearSelectedBeams() {
const selections = this.tracker.selections;
const measures = SmoSelection.getMeasureList(selections);
const altSelections = this._getEquivalentSelections(selections);
SmoOperation.clearBeamGroups(this.score, selections);
SmoOperation.clearBeamGroups(this.storeScore, altSelections);
this._renderChangedMeasures(measures);
await this.renderer.updatePromise();
}
/**
* toggle the 'end beam' flag for selected notes
* @returns
Expand Down
6 changes: 3 additions & 3 deletions src/smo/data/systemStaff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -625,14 +625,14 @@ export class SmoSystemStaff implements SmoObjectParams {
|| SmoSelector.gteq(tb.endSelector, nb.startSelector) || tb.position !== nb.position);

brackets.push(new SmoStaffTextBracket(bracketParams));

this.textBrackets = brackets;
}
removeTextBracket(bracketParams: SmoStaffTextBracket) {
const nb = new SmoStaffTextBracket(bracketParams);
const brackets = this.textBrackets.filter((tb) => SmoSelector.lteq(tb.startSelector, nb.startSelector)
|| SmoSelector.gteq(tb.endSelector, nb.startSelector) || tb.position !== nb.position);
brackets.push(new SmoStaffTextBracket(bracketParams));
this.textBrackets = brackets;
brackets.push(new SmoStaffTextBracket(bracketParams));
this.textBrackets = brackets;
}
getTextBracketsStartingAt(selector: SmoSelector) {
return this.textBrackets.filter((tb) => SmoSelector.eq(tb.startSelector, selector));
Expand Down
2 changes: 2 additions & 0 deletions src/smo/midi/midiToSmo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { SmoLayoutManager } from "../data/scoreModifiers";
import { SmoTie } from "../data/staffModifiers";
import { SmoSystemStaff } from "../data/systemStaff";
import { SmoTuplet } from "../data/tuplet";
import { SmoOperation } from "../xform/operations";

export type MidiEventType = 'text' | 'copyrightNotice' | 'trackName' | 'instrumentName' | 'lyrics' | 'marker' |
'cuePoint' | 'channelPrefix' | 'portPrefix' | 'endOfTrack' | 'setTempo' | 'smpteOffset' | 'timeSignature' | 'keySignature' |
Expand Down Expand Up @@ -656,6 +657,7 @@ export class MidiToSmo {
// if no scale given in score, default to something small.
layoutDefaults.globalLayout.svgScale = 0.65;
layoutDefaults.globalLayout.zoomScale = 1.5;
SmoOperation.clearAllBeamGroups(rv);
return rv;
}
}
11 changes: 10 additions & 1 deletion src/smo/xform/beamers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export class SmoBeamer {
}
measure: SmoMeasure;
duration: number;
measureDuration: number;
meterNumbers: number[];
beamBeats: number;
skipNext: number;
Expand All @@ -65,6 +66,7 @@ export class SmoBeamer {
this.measure = measure;
this._removeVoiceBeam(measure, voice);
this.duration = 0;
this.measureDuration = 0;
this.meterNumbers = [measure.timeSignature.actualBeats, measure.timeSignature.beatDuration];
// beam on 1/4 notes in most meter, triple time dotted quarter
this.beamBeats = 2 * 2048;
Expand Down Expand Up @@ -139,6 +141,7 @@ export class SmoBeamer {
beamNote(tickmap: TickMap, index: number, note: SmoNote) {
this.beamBeats = note.beamBeats;
this.duration += tickmap.deltaMap[index];
this.measureDuration += tickmap.deltaMap[index];
if (note.noteType === '/') {
this._completeGroup(tickmap.voice);
this._advanceGroup();
Expand Down Expand Up @@ -193,7 +196,13 @@ export class SmoBeamer {
this._advanceGroup();
}
}

// If we are aligned to a beat on the measure, and we are in common time
if (this.currentGroup.length > 1 && this.measure.timeSignature.beatDuration === 4 &&
this.measureDuration % 4096 === 0) {
this._completeGroup(tickmap.voice);
this._advanceGroup();
return;
}
if (this.duration === this.beamBeats) {
this._completeGroup(tickmap.voice);
this._advanceGroup();
Expand Down
23 changes: 23 additions & 0 deletions src/smo/xform/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,29 @@ export class SmoOperation {
}
}
}
static clearAllBeamGroups(score: SmoScore) {
score.staves.forEach((ss) => {
ss.measures.forEach((mm) => {
mm.voices.forEach((vv) => {
const triple = mm.timeSignature.actualBeats % 3 === 0;
vv.notes.forEach((note) => {
note.beamBeats = triple ? score.preferences.defaultTripleDuration : score.preferences.defaultDupleDuration;
note.endBeam = false;
});
});
});
});
}
static clearBeamGroups(score: SmoScore, selections: SmoSelection[]) {
selections.forEach((ss) => {
if (ss.note) {
const triple = ss.measure.timeSignature.actualBeats % 3 === 0;
const note = ss.note;
note.beamBeats = triple ? score.preferences.defaultTripleDuration : score.preferences.defaultDupleDuration;
note.endBeam = false;
}
});
}

static toggleBeamDirection(selections: SmoSelection[]) {
const note0 = selections[0].note as SmoNote;
Expand Down

0 comments on commit 2ac40c1

Please sign in to comment.