Unsorted keys in note will be sorted

215 views Asked by At

I'm creating a stave note with multiple keys:

const staveNote: vexflow.Flow.StaveNote = new this.VF.StaveNote({
  keys: this.renderNotesSortedByPitch(placedChord.notes),
  duration: chordDuration,
  auto_stem: true,
  clef: Clef.TREBLE
});

private renderNotesSortedByPitch(notes: Array<Note>): Array<string> {
  const vexflowNotes: Array<string> = new Array<string>();
  notes
  // this.sortNotesByPitch(notes)
  .forEach((note: Note) => {
    vexflowNotes.push(this.renderNote(note));
  });
  return vexflowNotes;
}

private sortNotesByPitch(notes: Array<Note>): Array<Note> {
  return notes.sort((noteA: Note, noteB: Note) => {
    return noteA.pitch.chroma.value - noteB.pitch.chroma.value   <--- No arithmetic operation on strings
  });
}

and I get the following warning in the browser console:

Warning:  Unsorted keys in note will be sorted. See https://github.com/0xfe/vexflow/issues/104 for details. Error
    at Function.b.StackTrace (http://localhost:4200/vendor.js:93990:4976)
    at Function.b.W (http://localhost:4200/vendor.js:93990:5134)
    at http://localhost:4200/vendor.js:93990:255605
    at Array.forEach (<anonymous>)
    at e.value (http://localhost:4200/vendor.js:93990:255572)
    at new e (http://localhost:4200/vendor.js:93990:250357)
    at SheetService.vexflowRenderSoundtrack (http://localhost:4200/main.js:2083:51)
    at SheetService.createSoundtrackSheet (http://localhost:4200/main.js:2004:14)
    at SheetComponent.createSheet (http://localhost:4200/main.js:2465:35)
    at SheetComponent.ngAfterViewInit (http://localhost:4200/main.js:2452:14)

I understand I need to provide the keys already sorted the way Vexflow is sorting them.

A similar issue is also described there.

How to sort the keys with the note.pitch.chroma.value being a string ?

It'd be nice to have some method in the same fashion as:

staveNote.setKeyStyle(0, { fillStyle: 'red' });

Say, some such method:

staveNote.setDotted(0);

Or:

staveNote.setKeyStyle(0, { fillStyle: 'red', dotted: true });

UPDATE: Following a suggestion I could create the methods to sort the notes before adding them as keys in the stave:

  private getNoteFrequency(note: Note): number {
    return Tone.Frequency(note.renderAbc()).toFrequency();
  }

  private sortNotesByPitch(notes: Array<Note>): Array<Note> {
    return notes.sort((noteA: Note, noteB: Note) => {
      return this.getNoteFrequency(noteA) - this.getNoteFrequency(noteB);
    });
  }

The Vexflow warning message was no longer displayed in the browser console.

1

There are 1 answers

8
sschmidTU On BEST ANSWER

Vexflow expects your notes to be sorted vertically, no way around that. You need to write your own function to compare two notes given as strings.

here's a working note-string-comparison-function which doesn't take accidentals into account: repl.it/repls/WobblyFavorableYottabyte

edited for clarity, thanks @gristow for the correction!