# HG changeset patch # User Dan Fuhry # Date 1346644080 14400 # Node ID c36fbf04faac7a10c4a9b7e1da53c4e3c158da63 # Parent bb3789db954ac82e85104db15a85c1907f508154 Added "!" trick to give hints to the key detection algorithm. It's all Chris Tomlin's fault. diff -r bb3789db954a -r c36fbf04faac Halftone.php --- a/Halftone.php Tue May 08 01:38:29 2012 -0400 +++ b/Halftone.php Sun Sep 02 23:48:00 2012 -0400 @@ -87,6 +87,12 @@ { // discard bass note list($chord) = explode('/', $chord); + // skip chord if it has a "!" + if ( $chord{0} == '!' ) + { + continue; + } + $match = array(); preg_match('/((?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?)$/', $chord, $match); if ( !empty($match[1]) ) @@ -223,7 +229,7 @@ { $chord = $chord{0} . '♯' . substr($chord, 2); } - return $chord; + return ltrim($chord, '!'); } function transpose_chord($chord, $increment, $accidental = false) @@ -236,6 +242,12 @@ 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.) + $prechord = ''; + if ( $chord{0} == '!' ) + { + $prechord = '!'; + $chord = substr($chord, 1); + } preg_match('/((?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?)$/', $chord, $match); // find base chord if ( !empty($match[1]) ) @@ -255,7 +267,7 @@ if ( !$kname ) // again, should never happen return "[TRANSPOSITION FAILED: " . $chord . $match[1] . " + $increment (->$key)]"; - $result = $kname . $match[1]; + $result = $prechord . $kname . $match[1]; // echo "$chord{$match[1]} + $increment = $result
"; return $result; } @@ -362,14 +374,13 @@ foreach ( explode("\n", $inner) as $line ) { $chordline = false; - $chords_regex = '/(\((?:[A-G][#b]?(?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?(?:\/[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 - // echo out the line, adding spans around chords. here is where we also do transposition - // (if requested) and + // echo out the line, adding spans around chords. $line_final = array(); $last_was_chord = false; foreach ( $line_split as $entry ) diff -r bb3789db954a -r c36fbf04faac README --- a/README Tue May 08 01:38:29 2012 -0400 +++ b/README Sun Sep 02 23:48:00 2012 -0400 @@ -5,9 +5,10 @@ Halftone markup example: -Intro: (E) (B) (C#m) (A) (E) (B) (G#m) (A) += Intro = +(E) (B) (C#m) (A) (E) (B) (G#m) (A) -Verse 1: += Verse 1 = (E)Just a (B)small town girl (C#m)Living in a (A)lonely world, (E)She took the (B)midnight train going @@ -24,4 +25,22 @@ if you put chords so close to each other. An example would be using "(G#m)any(A)where" in the sample verse above - depending on your theme/font G#m would be directly adjacent to A (confusing) or A would even overlap. So -be sure to space out your lyrics accordingly. +be sure to space out your lyrics accordingly. You can use HTML entities (like +" " or so) to space things out. + +You may also find it beneficial, if the key detection algorithm goofs up, to +prepend a "!" to the beginning of a chord expression which does not fit into +the consonant chords for a given key. Consider the following passage, taken +from a song in the key of A (this is the pre-chorus): + + (E)And together we (B)sing (D) + Everyone (B)sing (D) + +The key detection actually caused Halftone to think this song was in D. You can +rewrite this as, + + (E)And together we (!B)sing (D) + Everyone (!B)sing (D) + +...which causes the key detection algorithm to ignore that random B, which is +considered to be dissonant to the key of A.