Sunday, September 27, 2009

- Finding note pitches without accidentals/key sigs.
- Linking accidentals to primary notes.
- Finding all note pitches without applying 8vas/8vbs etc.
- Need to calculate note timings/positions in midi. Grace notes can wait coz I cbf tonight.
- Setting note positions in terms of whole notes relative to parent bars. I should now have note pitches, lengths and start ticks for most cases.
- Checking if ledgers intersect with grace notes will probably fail if note is in space. Er.
- There are seven half spaces in an octave on the score (seven major keys in octave) but twelve midi pitches (accidentals). Makes calculating the pitch a little messy. I'll need to store both half space count (from stave bottom) and midi pitch (where middle C = 60).
- Now storing half space count.

Saturday, September 26, 2009

- Starting on finding pitch of notes and accidentals not in key sigs. Requires a little more work on ledgers.
- Finding/grouping all ledgers between staves and connecting them to stems/staves/bars, but not yet finding ledgers at top and bottom of line.
- Finding all ledgers. It looks like some ledgers are duplicated and should be removed (todo).
- Starting to match accidentals to notes. An accidental (not in a key signature) will reference its primary note, but multiple notes in a bar may reference an accidental.
- That will be easier after I've found natural note pitches. Starting that first.

Or better yet, going out.

Friday, September 25, 2009

- Finding key signatures.
- How do I find a key change to C major from something else?
- I should add all ambiguous element matches to a list and rerun them after everything else has run so that the user can process them all in one go.

Wednesday, September 23, 2009

- Small notes are likely to be grace notes if the bar voices resolve without them.
- I think it's fair to assume that all staves within a line will have the same key signature changes. If signatures across staves match there's a decent chance they're correct.
- Regular accidentals can be very close to key sig accidentals. I guess there's only 14 well defined key sigs to worry about (multiplied by two clefs that I care about), and they grow in a simple pattern anyway. I'll just check that the accidentals at the start of a bar match this pattern.
- Finding the pitch value of a flat is a little harder than I thought. Next time.

Tuesday, September 22, 2009

- Finding rests within beam runs. Not yet handling rests that are part of a tuplet but are at the start or end.
- Throwing assert if a voice disappears mid bar (but on a beat) without a rest at the start of the next beat.
- Starting on grace notes. For now I just need to match them up to owning stems. Need to handle beamed grace notes, grace notes that appear at the end of a line (attached to note on next line) and grace notes that appear twice (end of line and start of next line).
- It'd be useful to have note pitches for this. I might start that now instead.
- Finding clefs. Clefs used to be associated with notes. I guess that still makes sense. I'll associate them with staves and all stems played immediately after clef change.
- I'll only associate them after voices are done, so it'll be a slow(ish) search each time before that (done, not too slow).

Monday, September 21, 2009

- Now finding tuplets other than triplets that are numbered. I'll need to account for series of tuplets where only the first is numbered (ie 7 played in 6 etc).
- Now looking for number on all suspected tuplets by default (even triplets).
- Need to handle rests within beam runs. Position of rest between stems (to what extent?), extra wide gab between stems around rest and resolution of time compression might be enough to confirm a rest is in a beam run.
- Need to work out how to discern between grace notes and notes which are small just for fun.
- Need to handle beams that cross over bars (ugh).

Sunday, September 20, 2009

- Matching dots to notes.
- Voices need to start and end on beats, and can be between one beat and one bar long.
- Refactoring beams a little to make finding note length a little easier.
- Need to disregard whole bar rests.
- Need to associate quaver/semiquaver etc tails with stems.
- Now parsing voices of first line of Schubert Op90 #1 in full.
- Will start on Chopin Op72 #1 with tuplets (lots of triplets and a few odd ones).
- todo: Notes that cannot be connected to staves are probably garbage (such as notes shown in the tempo thingy at the start of the score).
- Notes in a tuplet aren't always of the same length.

My feet are cold.

- Now parsing voices of first page of Chopin Op72 #1.
- Who the fuck puts a dot for a dotted note on a line in the space below the line? Ugh. I think it only happens on select upside-down stems.
- Parsing two pages of Chopin Op72 #1, now working on odd tuplets. Would like to tackle simple ornaments and grace notes next.

Saturday, September 19, 2009

- All notes and stems now linked to staves.
- Need to do the same for rests. Very fews rests not on a stave, but those that aren't don't have ledgers.
- It's picking up some partial beams as rests :/. Fixed by including semibreve and minim rests in beam search.
- Matching rests that intersect with staves, will handle other rests later.
- Will try to find voices. Main assumption is that overlapping stems (on X axis) are in different voices. Overlapping beams are different voices and all stems connected by beams are in the same voice. A stem can be in only one voice but a note can be on multiple stems.
- Need to filter out grace notes.
- Need to associate dots with notes. Ties can wait.
- Voices are not per stave, they can traverse staves.
- Need to include rests within beam runs.

Tuesday, September 15, 2009

- Continuing to find stave for stems. Going to find ledger lines moving from stave outwards until one intersects with note or none are found. Ledgers must be correct distance apart, thin, centred about stem (kinda).

Monday, September 14, 2009

- Made some progress with associating notes/stems with staves.

Saturday, September 12, 2009

- Adding time signatures to bars. Looking for commonTime elements or pairs of glyphRuns containing only numerical characters.
- Nearly all elements in a line must belong to a bar and a stave (including time signatures). Trying to find a nice way to represent this.
- Deciding to make 'get' methods [like public TimeSig GetTimeSig(Stave stave)] throw exceptions if value isn't found rather than returning null.
- Need a method to return the full real string from a Glyphs element. Fiddly.
- todo Need to combine bar lines that actually make up one bar (double bar line etc).
- todo Need to reinstate mass update of chars.
- Got time signatures sorted out (I think).
- Beams aren't always divided into beats as nicely as I'd hoped, but I guess I'd have to make it work for outlying cases anyway so no big loss.
- Time to associate stems with staves.

Wednesday, September 9, 2009

- Going to add all notes to stems, and some stems are implicit with only one note (ie semibreves).
- I'll then need to work out time signatures and beats before I can begin on voices.

Monday, September 7, 2009

I think I figured out something important while trying to sleep last night.. I don't want to put notes in chords until after voices are done, and chords are only an afterthought for other stuff further down the track.

Notes are grouped on stems etc for a reason, and if two notes overlap on the x axis without being on the same stem, they mustn't be in the same voice. Notes not on stems (semibreve and longer) aren't going to be shorter than a beat, and beats are more important than bars. Since semibreves etc are at least a beat long and (I assume) always on the start of a beat, it won't matter if they are treated as separate voices. Rests might be a bit difficult...

Sunday, September 6, 2009

- If two notes are in the same chord, one pitch apart and on different stems, the stems almost line up but the notes are on the outsides of the two stems and don't overlap at all on the x axis. Will look for stems that almost line up with notes that go in opposite directions and have notes that overlap on the y axis.
- Added left and right brackets as element types (rather than just regular characters).
- Saving character templates after glyphs are confirmed.
- Fucked around for a few hours looking at some anomalies in the detection of characters. I think it's sorted now... maybe.
- It looks like semibreves are aligned with other notes in chords by their left side, not their centre.
- Notes in a chord seem to be left aligned unless a stem is shifted to avoid overlap (which is a pain in the arse when combined with tuplets etc). I think the lower note/stem is always shifted right regardless of stem directions etc.
- Will sort notes/stems so they are added to bars from left to right. Working better.
- Grouping notes into chords would be easier if I knew their pitches.
- Handling notes/stems shifted because of other (disconnected) notes/stems in same chord. It's currently pretty accurate, but since in some places it can even be difficult to figure out manually without looking at previous note lengths/voices, I may have to work out voices as notes are added to bars to ensure chord groupings are correct. Gonna be hard :/
- I think I'll work out voices after grouping into chords and see how difficult it might be to merge them later.

Saturday, September 5, 2009

- Added some boilerplate code for sorting/enumerating/adding/removing lines/bars/chords/stems/notes.
- Lines contain set of elements which (mostly) have known types, but not wrapping objects (Notes etc). I'm not keen to go breaking existing code, so I'll let the lines hunt down wrappers the long way.
- I think I need to get rid of distinction between grace note and normal note types for now since normal notes in long tuplets can be as small as grace notes. Code can try to figure it out after detection is done.
- Todo (later): since a positive template for one element type effectively acts as a negative template for all other types, I should store character templates when user confirms glyph set (but not actually try to match those characters afterwards).
- A chord is actually comprised of a set of stems (where stems of breves etc are implied, and a note can have two stems). I'm not sure what the implications of this are yet, but I'll definitely be using stems (and stem associations via beams) for finding voices. I'll pass stems to bars first, then orphaned notes, then rests.
- Maybe I need a panel that lists the main steps in the whole score parsing process that shows the current step. If non-modal user interaction is required (such as confirming Paths), they could click a button on this panel to confirm that a step is complete. It would require all of the current stuff to happen on a background thread with invokes to UI thread, but I should probably do that anyway.
- Adding notes to chords in bars. Not yet handling grace notes or rests.
- Going to keep all elements in main bits array.
- Improved performance of show/hide all element types.
- Created Bar object (which holds an existing element with type of 'bar'). Will pass in notes to be grouped into chords tomorrow. Based on experience, I'm not at all concerned about redundant data structures or causing the GC to take an extra ms to do its job. Chewing cpu cycles with derived object properties rather than storing values (such as a note's clef) for efficiency also looks good.

Thursday, September 3, 2009

- Not quite sure what to start next. I'll leave detection of hairpins and annoyances such as repeats, 8vas and ornament stave thingies until later.
- Dumping all detection templates to disk as bitmaps for debugging.

Tuesday, September 1, 2009

- Last night's problem fixed. Algorithm was fine, but a break statement snuck it's way in somewhere it shouldn't have...
- I'll make pedals always belong to the line above just in case. Done.
- Will also make phrase marks belong to the line from which they 'bulge' away. Done.
- I think I need two kinds of 'ignore' buttons on the element type form: ignore now and ignore forever. I also might need to make a set of temporarily templates for ignored elements so if you ignore one element, it ignores all elements that look similar.
- I suppose it's time to start putting notes in chords, finding time/key signatures etc.