Several bugfixes and improvements.
- Better key detection by using sus4 as a hint
- Recognize major seventh, diminished and augmented chords
- Better handling of lines which are a label followed by several chords (i.e. "Intro: (C) (G) (Am) (F)")
--- a/Halftone.php Tue Mar 27 18:48:23 2012 -0400
+++ b/Halftone.php Tue May 08 01:38:29 2012 -0400
@@ -79,15 +79,22 @@
$majors = array();
$minors = array();
$sharp_or_flat = ACC_SHARP;
+ // sus4 chords are also a great indicator since they are almost always
+ // used exclusively on the fifth
+ $have_sus4 = false;
// index which chords are used in the song
foreach ( $chord_list as $chord )
{
// discard bass note
list($chord) = explode('/', $chord);
$match = array();
- preg_match('/((?:m?7?|2|add9|sus4|[Mm]aj[79])?)$/', $chord, $match);
+ preg_match('/((?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?)$/', $chord, $match);
if ( !empty($match[1]) )
+ {
$chord = str_replace_once($match[1], '', $chord);
+ if ( $match[1] === 'sus4' )
+ $have_sus4 = $chord;
+ }
$sharp_or_flat = get_sharp($chord) == $chord ? ACC_SHARP : ACC_FLAT;
$chord = get_sharp($chord);
if ( $match[1] == 'm' || $match[1] == 'm7' )
@@ -105,6 +112,14 @@
$majors[$chord]++;
}
}
+ /*
+ // remove very low scorers
+ foreach ( $majors as $key => $count )
+ {
+ if ( $count < 1 )
+ unset($majors[$key]);
+ }
+ */
// now we go through each of the detected major chords, calculate its consonants, and determine how many of its consonants are present in the song.
$scores = array();
foreach ( $majors as $key => $count )
@@ -114,7 +129,7 @@
if ( isset($majors[key_to_name($consonants['fourth'])]) )
$scores[$key] += 2;
if ( isset($majors[key_to_name($consonants['fifth'])]) )
- $scores[$key] += 2;
+ $scores[$key] += $have_sus4 === key_to_name($consonants['fifth']) ? 4 : 2;
if ( isset($majors[key_to_name($consonants['minors'][0])]) )
$scores[$key] += 1;
if ( isset($majors[key_to_name($consonants['minors'][1])]) )
@@ -221,7 +236,7 @@
return transpose_chord($upper, $increment, $accidental) . '/' . transpose_chord($lower, $increment, $accidental);
}
// shave off any wacky things we're doing to the chord (minor, seventh, etc.)
- preg_match('/((?:m?7?|2|add9|sus4|[Mm]aj[79])?)$/', $chord, $match);
+ preg_match('/((?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?)$/', $chord, $match);
// find base chord
if ( !empty($match[1]) )
$chord = str_replace($match[1], '', $chord);
@@ -269,6 +284,9 @@
top: 0pt;
color: rgb(27, 104, 184);
}
+ span.halftone-line.labeled span.halftone-chord {
+ position: static;
+ }
span.halftone-chord.sequential {
padding-left: 20pt;
}
@@ -344,8 +362,9 @@
foreach ( explode("\n", $inner) as $line )
{
$chordline = false;
- $chords_regex = '/(\((?:[A-G][#b]?(?:m?7?|2|add9|sus4|[Mm]aj[79])?(?:\/[A-G][#b]?)?)\))/';
+ $chords_regex = '/(\((?:[A-G][#b]?(?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?(?:\/[A-G][#b]?)?)\))/';
$line_split = preg_split($chords_regex, $line, -1, PREG_SPLIT_DELIM_CAPTURE);
+ $line_pattern = '';
if ( preg_match_all($chords_regex, $line, $chords) )
{
// this is a line with lyrics + chords
@@ -370,6 +389,7 @@
$line_final[] = '<span class="halftone-chord">' . prettify_accidentals($chord_list[] = transpose_chord(trim($entry, '()'), $transpose, $transpose_accidental)) . '</span>';
}
$last_was_chord = true;
+ $line_pattern .= 'c';
}
else
{
@@ -377,10 +397,12 @@
{
$last_was_chord = false;
$line_final[] = $entry;
+ $line_pattern .= 'w';
}
}
}
- $song .= '<span class="halftone-line">' . implode("", $line_final) . "</span>\n";
+ $class_append = preg_match('/^w?c+$/', $line_pattern) ? ' labeled' : '';
+ $song .= '<span class="halftone-line' . $class_append . '">' . implode("", $line_final) . "</span>\n";
}
else if ( preg_match('/^=\s*(.+?)\s*=$/', $line, $match) )
{
--- a/chords2halftone.php Tue Mar 27 18:48:23 2012 -0400
+++ b/chords2halftone.php Tue May 08 01:38:29 2012 -0400
@@ -38,7 +38,7 @@
}
echo "\n[{$match[1]}]\n";
}
- else if ( preg_match('/^(\s*([A-G][#b]?(?:m?7?|2|add9|sus4|[Mm]aj[79])?)(\/[A-G][#b]?)?\s*)*$/', $line) )
+ else if ( preg_match('/^(\s*([A-G][#b]?(?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?)(\/[A-G][#b]?)?\s*)*$/', $line) )
{
if ( $chordline )
{