# HG changeset patch # User Dan Fuhry # Date 1336455509 14400 # Node ID bb3789db954ac82e85104db15a85c1907f508154 # Parent c3150cee8dd96a2ecb1a27b33a17fee11bfbbbb2 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)") diff -r c3150cee8dd9 -r bb3789db954a Halftone.php --- 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[] = '' . prettify_accidentals($chord_list[] = transpose_chord(trim($entry, '()'), $transpose, $transpose_accidental)) . ''; } $last_was_chord = true; + $line_pattern .= 'c'; } else { @@ -377,10 +397,12 @@ { $last_was_chord = false; $line_final[] = $entry; + $line_pattern .= 'w'; } } } - $song .= '' . implode("", $line_final) . "\n"; + $class_append = preg_match('/^w?c+$/', $line_pattern) ? ' labeled' : ''; + $song .= '' . implode("", $line_final) . "\n"; } else if ( preg_match('/^=\s*(.+?)\s*=$/', $line, $match) ) { diff -r c3150cee8dd9 -r bb3789db954a chords2halftone.php --- 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 ) {