85 // index which chords are used in the song |
85 // index which chords are used in the song |
86 foreach ( $chord_list as $chord ) |
86 foreach ( $chord_list as $chord ) |
87 { |
87 { |
88 // discard bass note |
88 // discard bass note |
89 list($chord) = explode('/', $chord); |
89 list($chord) = explode('/', $chord); |
|
90 // skip chord if it has a "!" |
|
91 if ( $chord{0} == '!' ) |
|
92 { |
|
93 continue; |
|
94 } |
|
95 |
90 $match = array(); |
96 $match = array(); |
91 preg_match('/((?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?)$/', $chord, $match); |
97 preg_match('/((?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?)$/', $chord, $match); |
92 if ( !empty($match[1]) ) |
98 if ( !empty($match[1]) ) |
93 { |
99 { |
94 $chord = str_replace_once($match[1], '', $chord); |
100 $chord = str_replace_once($match[1], '', $chord); |
221 } |
227 } |
222 else if ( $chord{1} == '#' ) |
228 else if ( $chord{1} == '#' ) |
223 { |
229 { |
224 $chord = $chord{0} . '♯' . substr($chord, 2); |
230 $chord = $chord{0} . '♯' . substr($chord, 2); |
225 } |
231 } |
226 return $chord; |
232 return ltrim($chord, '!'); |
227 } |
233 } |
228 |
234 |
229 function transpose_chord($chord, $increment, $accidental = false) |
235 function transpose_chord($chord, $increment, $accidental = false) |
230 { |
236 { |
231 global $circle_of_fifths; |
237 global $circle_of_fifths; |
234 { |
240 { |
235 list($upper, $lower) = explode('/', $chord); |
241 list($upper, $lower) = explode('/', $chord); |
236 return transpose_chord($upper, $increment, $accidental) . '/' . transpose_chord($lower, $increment, $accidental); |
242 return transpose_chord($upper, $increment, $accidental) . '/' . transpose_chord($lower, $increment, $accidental); |
237 } |
243 } |
238 // shave off any wacky things we're doing to the chord (minor, seventh, etc.) |
244 // shave off any wacky things we're doing to the chord (minor, seventh, etc.) |
|
245 $prechord = ''; |
|
246 if ( $chord{0} == '!' ) |
|
247 { |
|
248 $prechord = '!'; |
|
249 $chord = substr($chord, 1); |
|
250 } |
239 preg_match('/((?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?)$/', $chord, $match); |
251 preg_match('/((?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?)$/', $chord, $match); |
240 // find base chord |
252 // find base chord |
241 if ( !empty($match[1]) ) |
253 if ( !empty($match[1]) ) |
242 $chord = str_replace($match[1], '', $chord); |
254 $chord = str_replace($match[1], '', $chord); |
243 // what's our accidental? allow it to be specified, and autodetect if it isn't |
255 // what's our accidental? allow it to be specified, and autodetect if it isn't |
253 // return result |
265 // return result |
254 $kname = key_to_name($key, $accidental); |
266 $kname = key_to_name($key, $accidental); |
255 if ( !$kname ) |
267 if ( !$kname ) |
256 // again, should never happen |
268 // again, should never happen |
257 return "[TRANSPOSITION FAILED: " . $chord . $match[1] . " + $increment (->$key)]"; |
269 return "[TRANSPOSITION FAILED: " . $chord . $match[1] . " + $increment (->$key)]"; |
258 $result = $kname . $match[1]; |
270 $result = $prechord . $kname . $match[1]; |
259 // echo "$chord{$match[1]} + $increment = $result<br />"; |
271 // echo "$chord{$match[1]} + $increment = $result<br />"; |
260 return $result; |
272 return $result; |
261 } |
273 } |
262 |
274 |
263 function halftone_process_tags(&$text) |
275 function halftone_process_tags(&$text) |
360 $transpose = isset($_GET['transpose']) ? intval($_GET['transpose']) : $transpose; |
372 $transpose = isset($_GET['transpose']) ? intval($_GET['transpose']) : $transpose; |
361 $transpose_accidental = $inkey ? $accidentals[$inkey] : false; |
373 $transpose_accidental = $inkey ? $accidentals[$inkey] : false; |
362 foreach ( explode("\n", $inner) as $line ) |
374 foreach ( explode("\n", $inner) as $line ) |
363 { |
375 { |
364 $chordline = false; |
376 $chordline = false; |
365 $chords_regex = '/(\((?:[A-G][#b]?(?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?(?:\/[A-G][#b]?)?)\))/'; |
377 $chords_regex = '/(\((?:\!?[A-G][#b]?(?:[Mm]?7?|2|5|6|add9|sus4|[Mm]aj[79]|dim|aug)?(?:\/[A-G][#b]?)?)\))/'; |
366 $line_split = preg_split($chords_regex, $line, -1, PREG_SPLIT_DELIM_CAPTURE); |
378 $line_split = preg_split($chords_regex, $line, -1, PREG_SPLIT_DELIM_CAPTURE); |
367 $line_pattern = ''; |
379 $line_pattern = ''; |
368 if ( preg_match_all($chords_regex, $line, $chords) ) |
380 if ( preg_match_all($chords_regex, $line, $chords) ) |
369 { |
381 { |
370 // this is a line with lyrics + chords |
382 // this is a line with lyrics + chords |
371 // echo out the line, adding spans around chords. here is where we also do transposition |
383 // echo out the line, adding spans around chords. |
372 // (if requested) and |
|
373 $line_final = array(); |
384 $line_final = array(); |
374 $last_was_chord = false; |
385 $last_was_chord = false; |
375 foreach ( $line_split as $entry ) |
386 foreach ( $line_split as $entry ) |
376 { |
387 { |
377 if ( preg_match($chords_regex, $entry) ) |
388 if ( preg_match($chords_regex, $entry) ) |