Smoosic
Smoosic copied to clipboard
return notes position
I was trying your nice demo https://codepen.io/aarondavidnewman/pen/WNoRqgg and I'd like to reuse the library to create a simple melodic search.
I have a question. When my user submits, how can I get the final list of keys and their position in the score? Thanks in advance, it would save me some time!
Hi Marilena, I can think of three different things 'position' might mean :) And I think you mean position of note and not key signature. I'll try to answer for each.
- If you mean position in the SVG, each note, measure, and modifier will have an 'svg' structure that is filled in at run time. The structures vary, but they all contain a logicalBox which is the bounding box of the element.
- if you mean the position in time, you can add up all the tickCount of all the measure and note that came before. There are 4096 ticks to a beat.
- if you mean position in terms of how to reference the note in a selection, it would be the staff-measure-voice-note position, just like an array. A selection has an optional pitch array if it is a chord, with each entry being the index of the pitch.
I hope it helps. I'm honored that you're using my thing in your work.
Hi Aaron, thanks for your reply, and apologies for not being clear. I need to create a simple melodic search, with only two requirements: two measures, and the possibility to add only accidentals to make the pitch sharp. I'm building on the demo on top, using smoosic as a library (btw, I'm no music expert, in case you wonder).
When the user submits the form, I need to collect an object that includes (a) the sequence of pitches and (b) the sharp accidentals only (if any). I managed to get the the sequence of pitches (see screenshot) I need to perform the search on the dataset (this was my original question, I hoped there was an out-of-the-box method to get it), and it is automatically updated if the user moves left/right.
I'm using toggleEnharmonic to allow the user adding an accidental when pressing shift. I'd have two more questions here:
- is there a (smoosic-native) way to toggle only sharp
#? - is there a (smoosic-native) way I can store this information in my object above (e.g.
7: "b#")?
Below my tentative code so far.
const editorKeys = [];
'abcdefg'.split('').forEach((key) => {
editorKeys.push({
event: 'keydown',
key,
action: 'setPitch'
});
});
const trackerKeys = [{
event: "keydown",
key: "ArrowRight",
action: "moveSelectionRight"
}, {
event: "keydown",
key: "ArrowLeft",
action: "moveSelectionLeft"
}];
Smo.SuiApplication.configure({
mode: 'library',
scoreDomContainer: 'outer-container',
keys: { trackerKeys, editorKeys },
initialScore: Smo.basicJson,
}).then((application) => {
const view = application.view;
view.addMeasure(true);
var last = 7;
var pos = 0;
var final = new Object();
window.addEventListener('keydown', (evKey) => {
const trackerAction = trackerKeys.find((ev) => ev.key === evKey.key);
if (trackerAction) {
view[trackerAction.action](evKey);
// if moves left / right update the index of final
if (trackerAction.key == 'ArrowLeft') {
if (pos == 0) {pos = 0} else {pos = pos - 1;}
}
if (trackerAction.key == 'ArrowRight') {
if (pos == last) {pos = last} else {pos = pos + 1;}
}
return false;
}
// if enters a key
const editorAction = editorKeys.find((ev) => ev.key === evKey.key);
if (editorAction) {
view[editorAction.action](evKey.key);
final[pos] = evKey.key;
if (pos == last) {pos = last} else {pos = pos + 1;};
console.log("editorAction", editorAction.action,pos, final);
return false;
} else {
// change accidental
if (evKey.shiftKey) {
console.log('shift!', evKey);
view['toggleEnharmonic'](evKey.key);
console.log("view['toggleEnharmonic'](evKey.key)",view['toggleEnharmonic'](evKey.key));
}
}
});
// Get mouse move event to highlight mouseover. We pass the client coordinates
// into tracker (via view). The tracker maps client space to SVG space
document.getElementById('container1').addEventListener('mousemove', (ev) => {
view.intersectingArtifact({
x: ev.clientX,
y: ev.clientY
});
});
});
Thank you for your help!
I admit I have no idea why you are doing this :) but, if you want to force a sharp you could just go:
view.tracker.selections[0].note.pitches[0].accidental='#';
Or toggle the sharp, read the value first and set 'n' for natural and '#' for sharp, etc..
Edit: to access the score directly:
view.score.staves[0].measures[1].voices[0].notes[3].pitches[0].accidental='#';