Skip to content

Commit

Permalink
meter time attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
stephband committed Apr 22, 2024
1 parent 3475bb9 commit 413c35a
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 104 deletions.
58 changes: 18 additions & 40 deletions modules/create-symbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,6 @@ const rdoublesharp = /##|𝄪/;

const cScale = [0,2,4,5,7,9,11];


function toPitch(stave, key, transpose, pitch) {
return stave.getSpelling(
// key
mod12(key + transpose),
// number
toNoteNumber(pitch) + transpose,
// type
'note'
);
}

function toChord(stave, key, transpose, string) {
return stave.getSpelling(
// key
mod12(key + transpose),
// chord name
transposeChord(string, transpose),
// type
'chord'
);
}

const fathercharles = [
// Father Charles Goes Down And Ends Battle,
'F♯', 'C♯', 'G♯', 'D♯', 'A♯', 'E♯', 'B♯',
Expand All @@ -59,9 +36,9 @@ function byFatherCharlesPitch(a, b) {
return ai > bi ? 1 : ai < bi ? -1 : 0 ;
}

function getStemDirection(note, head) {
function getStemDirection(centerPitch, head) {
return head && head.stemDirection || (
toNoteNumber(note) < toNoteNumber(head.pitch) ?
toNoteNumber(centerPitch) < toNoteNumber(head.pitch) ?
'down' :
'up' );
}
Expand All @@ -78,9 +55,9 @@ function toDuration(event) {
event[4] ;
}

function insertTail(symbols, stemNote, i) {
function insertTail(symbols, stave, i) {
const head = symbols[i];
const stemDirection = getStemDirection(stemNote, head) ;
const stemDirection = getStemDirection(stave.centerPitch, head) ;

// Splice stem and tail in before head
symbols.splice(i, 0, assign({}, head, {
Expand Down Expand Up @@ -152,7 +129,7 @@ function subtractStaveRows(stave, r1, r2) {
return n + (octave2 - octave1) * 7;
}

function createBeam(symbols, stave, beam, stemNote, n) {
function createBeam(symbols, stave, beam, n) {
const part = symbols[0].part;

// Not enough stems for a beam, give it a tail
Expand All @@ -161,14 +138,14 @@ function createBeam(symbols, stave, beam, stemNote, n) {
throw new Error('Last beam index (' + i + ') cant be greater than n (' + n + ')');
}

return insertTail(symbols, stemNote, beam[0]);
return insertTail(symbols, stave, beam[0]);
}

// Render stems and beam
const stemDirection = symbols[beam[0]] && symbols[beam[0]].stemDirection ?
symbols[beam[0]].stemDirection :
(beam
.map((i) => subtractStaveRows(stave, stemNote, symbols[i].pitch))
.map((i) => subtractStaveRows(stave, stave.centerPitch, symbols[i].pitch))
.reduce((t, u) => t + u, 0) / beam.length) < 0 ?
'up' :
'down' ;
Expand All @@ -185,7 +162,7 @@ function createBeam(symbols, stave, beam, stemNote, n) {
while (beam[++b] !== undefined) {
i = beam[b];
head = symbols[i];
line = subtractStaveRows(stave, stemNote, head.pitch);
line = subtractStaveRows(stave, stave.centerPitch, head.pitch);

head.stemDirection = stemDirection;
head.tieDirection = stemDirection === 'up' ? 'down' : 'up' ;
Expand Down Expand Up @@ -258,9 +235,10 @@ function createBeam(symbols, stave, beam, stemNote, n) {
return stems.length + buffer.length + 1;
}

function createSymbols(symbols, bar, stemNote) {
function createSymbols(symbols, bar) {
// All events in symbols have the same part
const part = symbols[0].part;
const part = symbols[0].part;
const stave = bar.stave;

// Populate accidentals with key signature sharps and flats
const accidentals = bar.key.reduce((accidentals, n, i) => {
Expand Down Expand Up @@ -355,7 +333,7 @@ function createSymbols(symbols, bar, stemNote) {
|| isAfterBreak(bar.breaks, symbols[beam[beam.length - 1]].beat, head.beat)
) {
// Close the current beam
n += createBeam(symbols, bar.stave, beam, stemNote, n);
n += createBeam(symbols, bar.stave, beam, n);
beam = undefined;
}
}
Expand All @@ -377,7 +355,7 @@ function createSymbols(symbols, bar, stemNote) {
}
// Otherwise render the stem immediately
else {
let stemDirection = getStemDirection(stemNote, head);
let stemDirection = getStemDirection(stave.centerPitch, head);
symbols.splice(n++, 0, assign({}, head, {
type: 'stem',
stemDirection
Expand All @@ -396,7 +374,7 @@ function createSymbols(symbols, bar, stemNote) {
}
else {
if (head.tie === 'begin' || head.tie === 'middle') {
let stemDirection = getStemDirection(stemNote, head);
let stemDirection = getStemDirection(stave.centerPitch, head);
symbols.splice(n++, 0, assign({}, head, {
type: 'tie',
// Move tie into following grid column
Expand All @@ -410,7 +388,7 @@ function createSymbols(symbols, bar, stemNote) {

// Close the current beam
if (beam && beam.length) {
n += createBeam(symbols, bar.stave, beam, stemNote, n);
n += createBeam(symbols, bar.stave, beam, n);
beam = undefined;
}

Expand Down Expand Up @@ -533,7 +511,7 @@ function createBars(events, beatkeys, stave, keyscale, meter, transpose) {

const events0 = eventsAtBeat(events, 0);
meter = events0.find((event) => event[1] === 'meter') || meter ;

console.log(meter);
// First bar. Where meter is at beat 0, also inserts a time signature.
let bar = createBar(0, stave, keyscale, meter, tieheads);
bars.push(bar);
Expand Down Expand Up @@ -605,7 +583,7 @@ function createBars(events, beatkeys, stave, keyscale, meter, transpose) {
toDuration(event) ;

if (event[1] === 'note') {
let pitch = toPitch(stave, key, transpose, event[2]);
let pitch = stave.getSpelling(key, event[2], event[1], transpose);
let head = assign({
type: 'head',
beat,
Expand All @@ -631,7 +609,7 @@ function createBars(events, beatkeys, stave, keyscale, meter, transpose) {
beat,
duration,
transpose,
value: toChord(stave, key, transpose, event[2]),
value: stave.getSpelling(key, event[2], event[1], transpose),
event: event
});
}
Expand Down
8 changes: 5 additions & 3 deletions modules/event/to-spelling.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ const accidentals = {

const rroot = /^[A-G][b#𝄫𝄪]?/;

export default function toSpelling(key, note) {
export default function toSpelling(key, note, type, transpose) {
key = mod12(key + transpose);

// Make sure key is a key object
key = typeof key === 'number' ? keys[key] :
typeof key === 'string' ? keys.find((o) => o.name === key) :
Expand All @@ -37,8 +39,8 @@ export default function toSpelling(key, note) {
rest = toNoteOctave(note) || '' ;
}

const spelling = key.spellings[mod12(r)];
const name = noteNames[mod12(r - spelling)];
const spelling = key.spellings[mod12(r + transpose)];
const name = noteNames[mod12(r + transpose - spelling)];
const accidental = accidentals[spelling];

if (window.DEBUG && name === undefined) {
Expand Down
32 changes: 23 additions & 9 deletions modules/staves.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,37 +10,44 @@ export const chords = {

export const treble = {
clef: 'treble',
centerPitch: 'B4',
getSpelling: toSpelling
};

export const bass = {
clef: 'bass',
centerPitch: 'D3',
getSpelling: toSpelling
};

export const piano = {
clef: 'piano',

getSpelling: toSpelling,

// TEMP
centerPitch: 'B4',

// TODO: there should be four parts available, soprano alto, tenor bass
getPart: function(pitch) {
// A part is an object of properties assigned to a symbol.
// Render anything below Bb3 on the lower part.
return /[012]$|[AC-G][b#𝄫𝄪]*3$/.test(pitch) ? {
part: 'lower',
centerRow: 'stave-lower'
part: 'lower',
centerPitch: 'D3',
centerRow: 'stave-lower'
} : {
centerRow: 'stave-upper'
centerPitch: 'B4',
centerRow: 'stave-upper'
} ;
}
};

export const drums = {
clef: 'drums',

getSpelling: (key, name, type) => {
getSpelling: (key, name, type, transpose) => {
if (type === 'chord') {
return getSpelling(key, name);
return getSpelling(key, name, 'chord', transpose);
}
else if (type === 'note') {
// Use standard MIDI note names. We don't want any spelling happening
Expand All @@ -53,6 +60,7 @@ export const drums = {
/*"C♯2": "head[1]", /* Side Stick */
"E♭2": "head[x]", /* Hand Clap */
"F♯2": "head[x]", /* Closed Hi-Hat */
"G♯2": "head[x]",
"A♭2": "head[x]", /* Pedal Hi-Hat */
"B♭2": "head[x]", /* Open Hi-Hat */
"C♯3": "head[x]", /* Crash Cymbal 1 */
Expand All @@ -61,6 +69,7 @@ export const drums = {
"F3": "head[x]", /* Ride Bell */
"F♯3": "head[x]", /* Tambourine */
"G3": "head[x]", /* Splash Cymbal */
"G♯3": "head[v]",
"A♭3": "head[v]", /* Cowbell*/
"A3": "head[x]", /* Crash Symbol 2 */
"B♭3": "head[v]", /* Vibraslap */
Expand Down Expand Up @@ -103,14 +112,16 @@ export const drums = {
Returns an object of properties assigned to symbols that belong to a part.
**/

// TEMP
centerPitch: 'B4',
getPart: function(pitch) {
// A part is an object of properties assigned to a symbol.
// Render kick and hihatpedal as part 'feet'.
return ("B1 C1 A♭2 G♯2").includes(pitch) ? {
part: 'feet',
stemDirection: 'down',
tieDirection: 'down',
centerRow: 'stave-lower'
centerRow: 'stave-lower',
} : {
// part: Leave part undefined to group with main render
stemDirection: 'up',
Expand All @@ -133,9 +144,12 @@ export const drums = {
export const percussion = {
clef: 'percussion',

getSpelling: (key, name, type) => {
// TEMP
centerPitch: 'B4',

getSpelling: (key, name, type, transpose) => {
if (type === 'chord') {
return getSpelling(key, name);
return getSpelling(key, name, 'chord', transpose);
}
else if (type === 'note') {
// Use standard MIDI note names. We don't want any spelling happening
Expand Down
Loading

0 comments on commit 413c35a

Please sign in to comment.