Carl Worth [Tue, 1 Oct 2013 15:47:34 +0000 (08:47 -0700)]
Rework computer keyboard input to be mapped piano keyboard
Instead of using computer keyboard letter names for piano note names,
(which allowed only entering natural notes), we now map the piano
keyboard onto the computer keyboard. The naturals are on the home row,
(middle C is on 'A' and the next higher C is on 'K'), and the sharps
map onto the top row in the obvious position, (C# on 'W, D# on 'E',
etc.).
Carl Worth [Mon, 30 Sep 2013 05:42:15 +0000 (22:42 -0700)]
Fix bugs in mismatched spelling of chord name and notes
When the notes of a chord were re-spelled to match the degrees of the
matching signature, the root note was not being updated, so the
chord-name symbol still reflected the name of the un-respelled root
note. This was a bug introduced in the recent shakeup to do analysis
more entirely in the scherzo layer without using score_note_t.
Fixing this required a fair amount of refactoring. Hopefully the
result is cleaner and more maintainable.
Carl Worth [Sun, 29 Sep 2013 21:56:47 +0000 (14:56 -0700)]
Fix scherzo to use pitch_t rather than score_note_t for computation
The score_note_t type is constructed as a side effect of performing
drawing. This is a poor fit for scherzo's computation and reasoning
since it often wants to perform analysis on notes that it has never
drawn.
Meanwhile, the new pitch_t is a simple integer, making it very easy
for scherzo to use pitch_t in all of its calculations.
The goal is for no functional changes with this commit, but we know
that some bugs have likely been changed or moved around.
Carl Worth [Fri, 27 Sep 2013 23:11:40 +0000 (16:11 -0700)]
Drop the enumerated pitch values.
It's really just as easy to use macros such as PITCH_LITERAL,
PITCH_NAME, or PITCH_ACCIDENTAL in some combination instead of using
an enumerated pitch_t value.
In place of the enum, we now have pitch_t as a uint32_t type.
The real purpose for doing this is to prepare for pitch_t to be able
to hold the octave as well which should be remarkably convenient.
Carl Worth [Fri, 27 Sep 2013 15:24:53 +0000 (08:24 -0700)]
Use matched chord signature to guide spelling of note on staff.
We now use the chord's signature to choose the correct spelling of
each enharmonic note. For example, an A mjor triad has a C-sharp in
it, not a D-flat. We can determine this since a major triad should
have a note of the 3 scale degree (as recorded in the chord
signature).
Still to be done is to draw note heads without collision, draw
accidentals without collision, and to improve the heuristic for
deciding between ambiguous chord signatures.
Carl Worth [Fri, 27 Sep 2013 15:23:05 +0000 (08:23 -0700)]
Fix signature for "sus" chord
This signature had an ''augmented'' 3rd in it rather than the perfect
4th that was intended. The perfect 4th is the thing that will allow
the chord to be spelled correctly.
Carl Worth [Fri, 27 Sep 2013 05:36:00 +0000 (22:36 -0700)]
Put all chord signatures into a single array
This simplifies the code quite a bit. Instead of a big switch
statement based on number of notes in the chord, with each case a
nearly-identical for loop, we can have one single for loop for all
signatures.
More importantly, this means that after the for loop has matched a
signature, we can have a single variable pointing to the matching
signature. That will be important for using the signature to guide in
spelling the chord correctly, which we hope to do soon.
Carl Worth [Fri, 27 Sep 2013 05:12:14 +0000 (22:12 -0700)]
Don't print the inversion names
These were just too long for a very little bit of information,
(perhaps in the future I'll decide to bring back the inversion
information but with a style such as C/G for a C major triad in 2nd
inversion).
Carl Worth [Fri, 27 Sep 2013 04:43:35 +0000 (21:43 -0700)]
Add voicings of m6/9 and m6/♭9 with no 5th.
This clears up a FIXME comment suggesting that we were missing some
chords with perfect 5ths. The comment was somewhat incorrect. One
chord was present all along. One should have been present, but was
incorrect (until the last commit). The third was legitimately missing
(until the last commit).
Now that we have all of these in place with perfect 5ths, we can also
add the versions voiced with no 5th at all and delete the comment.
Carl Worth [Thu, 26 Sep 2013 21:56:18 +0000 (14:56 -0700)]
Comment a couple of ambiguous chords
I noticed these while going through Bach's Prelude #1, comparing what
scherzo gave with what Andrea Pauly gave for each chord.
The right thing to do is probably to make scherzo display all chord
names (and spellings) when more than one chord naming can be matched
against a set of notes.
Carl Worth [Thu, 26 Sep 2013 15:00:27 +0000 (08:00 -0700)]
Reduce overuse of superscripting in chord names.
In particular, the presence of "sus" now no longer triggers
superscripting in the rest of the chord name, (since I've moved "sus"
to the end of the chord name instead).
Carl Worth [Thu, 26 Sep 2013 14:43:19 +0000 (07:43 -0700)]
Add 11th chords
Working from:
http://en.wikipedia.org/wiki/Chord_notation#11ths
I still have some confusion about half-diminished and diminished
chords larger than 7th chords. The 9th and 11th versions of these as
currently programmed seem inconsistent. So I need to double-check
against some additional sources rather than just relying on wikipedia.
Carl Worth [Thu, 26 Sep 2013 00:23:17 +0000 (17:23 -0700)]
Add recognition of 6, m6, and 7-flat-5 chords.
One trick here is the ambiguity that, for example, C6 looks the same
as Am7 in first inversion and Cm7 looks the same as D#6 in 3rd
inversion. We rework the recognition code a bit so that chords with a
smaller inversion number will be preferred over chords with a larger
inversion number. That way, with the above examples, scherzo will
report C6 and Cm7 rather than "Am7 1st inversion" and "D#6 3rd
inversion".
Carl Worth [Mon, 23 Sep 2013 04:10:58 +0000 (21:10 -0700)]
Add a few initializations to quiet compiler warnings.
My manual analysis says that none of these are strictly necessary,
(the various conditionals currently ensure that none of the variables
are ever used uninitialized). But "gcc -O2" likes to complain, so
these initializations keep it quiet.
Carl Worth [Sun, 22 Sep 2013 22:57:14 +0000 (15:57 -0700)]
Switch to a degree-specific scheme for specifying chord signatures
The old scheme specified each chord signature by the number of half
steps between the root note and each note of the chord. This made it
impossible to distinguish between alternate names of enharmonic chords
(such as an augmented 4th and a diminished 5th which both have 6 half
steps).
The new specification indicates which degree should appear in the
chord, and which modification each degree has, (from -2 to +2 half
steps).
So, under the old scheme an augmented 5th/diminished 4th would appear as:
{0, 6} /* Half steps from root to each note */
And in the new scheme these can be identified separately as:
We don't yet have much of a user-visibile change with this commit,
(other than that the above interval will now only be identified as a
"Diminished 5th" rathern than the "Augmented 4th/Diminished 5th" we
had before).
But this gives us the necessary information we will need in order to
correctly spell chords on a staff after the chord has been identified.
Carl Worth [Sun, 22 Sep 2013 22:15:03 +0000 (15:15 -0700)]
Allow computer-keyboard input of accidentals, and draw accidentals.
All accidentals are drawn assuming the key of C major, for now. That is,
natural symbols will not be drawn, but all other accidental symbols will
be drawn.
No care is taken to avoid accidentals colliding with each other when drawn.
Carl Worth [Sun, 22 Sep 2013 21:29:41 +0000 (14:29 -0700)]
Add a new SCORE_PITCH macro and rename SCORE_PITCH_VALUE to SCORE_PITCH_LITERAL
The original SCORE_PITCH_VALUE macro was of limited use. It could only
be used with literal values such as "G" and "FLAT" and could not be
used to construct a score_pitch_t value from two variables. This was
particularly useless since a user could just use a literal value of
SCORE_PITCH_Gf instead of SCORE_PITCH_VALUE(G, FLAT).
So we rename SCORE_PITCH_VALUE to SCORE_PITCH_LITERAL to make its
limitations more clear in its name. (The one important use remaining
for the macro is in the initial construction of the score_pitch_t
values for the enum declaration).
And here we add the SCORE_PITCH macro which *can* be used to construct
a score_pitch_t value from two variables, (one holding the pitch name,
and one holding the accidental).
Carl Worth [Wed, 18 Sep 2013 18:21:34 +0000 (11:21 -0700)]
Simplify chord-signature matching by dropping duplicates first
Previously, all the duplicate notes were still present in the chord
while trying to determine if the duplicate matched. Now, we cull out
the duplicates before looking for a match, which makes the matching
code much simpler.
Carl Worth [Wed, 18 Sep 2013 18:00:02 +0000 (11:00 -0700)]
Avoid duplicating notes within note_group_t and score_staff_t
Previously, it was possible to have notes "stick" on the staff and not
clear off after releasing the note or pedal in some circumstances. We
fix a number of these bugs by checking to see if a note is already
present in a list before adding a duplicate copy of it.
Carl Worth [Wed, 18 Sep 2013 03:41:32 +0000 (20:41 -0700)]
Fix bugs in analysis for out-of-order chords
When the various notes of a chord were in different octaves, scherzo
was sometimes getting confused and was unable to match the chord to
its known signatures. We fix this by adding a secondary sort, (first
sort by absolute pitch to find bass note so to compute relative pitch,
and then second sort by relative pitch).
Carl Worth [Wed, 18 Sep 2013 03:04:06 +0000 (20:04 -0700)]
Add support for pedal
As scherzo listens to the pedal, it will analyze the chord harmony based on
notes that continue to sustain due to the pedal.
I'm not 100% comfortable with the empirically-derived value of 64 for
the sustain pedal. I'd feel a bit better if I had found a symbolic
constant for this in the ALSA header files. As things stand now, I'm
not sure if the sustain pedal on another keyboard will return the same
value.
Carl Worth [Tue, 17 Sep 2013 20:31:04 +0000 (13:31 -0700)]
Fix the broken SCORE_PITCH_NAME macro to work correctly
For no good reason, the score_pitch_name_t enum had previously been
defined with pre-shifted values. That could have worked, but the
SCORE_PITCH_NAME macro was shiftin the masked value down as if the
enum values were not pre-shifted. So SCORE_PITCH_NAME was yielding
unexpected values, (that did not correspond to score_pitch_name_t
enum values).
We fix this by making the enum sane, (with unshifted values), leaving
the shifting in place in SCORE_PIATCH_NAME and tracking the new style
of the enum by adding shifting to the SCORE_PITCH_VALUE macro.
That is, the macro that is changed by this commit reamins working, and
the macro that is left unchaged by this commit is now fixed.
Carl Worth [Wed, 28 Sep 2011 00:34:55 +0000 (17:34 -0700)]
Add ability to perform input with computer (not midi) keyboard.
This is useful for testing when away from a keyboard, and also useful
in its own right for ensuring that the user knows the names of the
notes (not just their position on the piano keyboard).
When using a computer keyboard for input only the note name itself is
needed---the correct octave is chosen automatically.
Carl Worth [Mon, 26 Sep 2011 17:34:52 +0000 (10:34 -0700)]
Fix another bug with stuck notes.
When multiple MIDI messages were received in a single buffer, the code
was neglecting to advance the string pointer it was using to
parse. This was causing it to parse the first message several times
and ignore all following messages.
Carl Worth [Mon, 26 Sep 2011 16:42:20 +0000 (09:42 -0700)]
Fix bug with stuck notes when challenge would switch staves.
In this case we were failing to remove a note beacuse we were looking
at the new staff (where the new challenge is) rather than the old staff
where the note was originally created.
Fix this by having each note remember the staff it's created on. This
also impacts the API a bit (no longer need a staff argument to
remove_note, so drop the "_staff" portion of the name from both
add_note and remove_note).
Carl Worth [Mon, 26 Sep 2011 06:34:46 +0000 (23:34 -0700)]
Integrate some simple mnemon quizzing into scherzo.
This will be a lot more interesting once we start drawing ledger lines
and accidentals. But it's already useful for white-key practice for
the notes directly on the staff. Could definitely use better feedback
such as different colors (or even just different horizontal spacing
for challenge vs. response notes).
Carl Worth [Sat, 24 Sep 2011 21:39:56 +0000 (14:39 -0700)]
Open MIDI device and display notes being played in real time.
Every time a key on the MIDI input device is pressed, a whole note appears
on the appropriate staff. When the key is released, the note disappears.
No ledger lines are drawn yet, and there appears to be a bug where notes
get stuck on (refusing to disappear after a key is released) triggered
most easily by pressing *many* keys simultaneously several times.
Carl Worth [Fri, 23 Sep 2011 06:04:53 +0000 (23:04 -0700)]
Start drawing some very rudimentary notes.
I'm picking the correct (but hard-coded by glyph index) noteheads
out of the Gonville font. But I'm not drawing any stems nor flags
yet. Also the spacing between the notes isn't interesting yet, nor
do I have measure lines, nor ledger lines.
Oh, and the notes I added here for testing aren't even musically
interesting either. Anyway, we're still getting started obviously.
Carl Worth [Fri, 23 Sep 2011 00:22:22 +0000 (17:22 -0700)]
Restructure code to manually add staves, braces, and notes.
Previously, the program was hard-coded to draw a grand staff, (two staves
connected by a brace). Now, at the level of the score library, each staff
and any braces are added manually and any set of staves and braces can be
drawn, (the only the two-staves-connected-by-one-brace has been tested).
There's also functionality for ading notes, though no notes are drawn yet.
Carl Worth [Sat, 17 Sep 2011 15:55:09 +0000 (08:55 -0700)]
Add some (particularly cheesy) drawing of a brace and clefs on the grand staff.
This assumes the presence of the Gonville-26 and Gonville-Brace fonts, (by
Simon Tatham). Though it would be simple enough to change the code to use
any Lilypond-compatible font, (if the glyph selection were also update or
just fixed to lookup glyphs by name instead of hard-coding the index).
Carl Worth [Sat, 17 Sep 2011 06:55:51 +0000 (23:55 -0700)]
Draw a second staff (and vertical lines at the beginning and end of staff).
This is almost the grand staff necessary for a piano score, (missing
the brace). The _draw_grand_staff function is a bit too specialized. A
more general approach will involve the ability to add an arbitrary
number of staffs (staves?) to the score, and selectively tie some
together (with or without a brace).