// This is an example of how to detect true note lengths in MuseScore // plugins. import QtQuick 2.0 import MuseScore 3.0 MuseScore { menuPath: "Plugins.TupletDetection" description: "Detect tuplets" version: "1.0" onRun: { ... your plugin code goes here ... // FIXME: The API doesn't yet provide any way to figure out // whether a note is part of a tuplet, so we have to find the // delta to the tick of the next segment to figure out the real // length of the note. The API shouldn't make us do this. var next_note = find_adjacent_note(note, 1); // Note that we fall back to using the Chord duration, in case // something goes wrong with finding the next note. var orig_tick_len = next_note ? next_note.parent.parent.tick - note.parent.parent.tick : note.parent.duration.ticks; var orig_quaver_len = orig_tick_len / 240; ... your plugin code goes here ... } function cursor_at(track, tick) { var cursor = curScore.newCursor(); cursor.staffIdx = track / 4; cursor.voice = track % 4; cursor.rewind(Cursor.SCORE_START); // FIXME: this is horribly inefficient while (cursor.segment.tick != tick) { cursor.next(); } return cursor; } function find_adjacent_note(note, direction) { var seg = note.parent.parent; var cursor = cursor_at(note.track, seg.tick); var el; do { if (direction > 0) { cursor.next(); } else { cursor.prev(); } if (! cursor.segment) { return null; } el = cursor.segment.elementAt(note.track); } while (! (el && el.type == Element.CHORD)); var notes = el.notes; // We probably don't need to know which note is highest in // this example, but that can be useful in other scenarios. var highest = notes[0]; for (var i = 1; i < notes.length; i++) { if (notes[i].pitch > highest.pitch) { highest = notes[i]; } } return highest; } }