移调乐器场景下按实际音高为特定音域外音符上色的问题
解决移调乐器谱表音符颜色按实际音高判定的问题
你的问题核心在于:当前代码通过ly:pitch-semitones获取的是记谱音高的半音数,而移调乐器谱表经过\transposition处理后,记谱音高和实际音乐会音高存在偏移,导致颜色判定逻辑失效,两个谱表的音符颜色无法匹配。
解决方案
要让颜色判定基于实际音高而非记谱音高,需要获取谱表的移调偏移量,将记谱音高转换为音乐会音高后再进行半音数计算。
修改你的clarinet-range函数如下:
#(define (clarinet-range grob) (let* ((pch (ly:event-property (event-cause grob) 'pitch)) ; 获取当前谱表的移调偏移量 (transp (ly:staff-transposition (ly:grob-parent grob Staff))) ; 将记谱音高转换为实际音乐会音高 (concert-pch (ly:pitch-transpose pch transp)) (semitones (ly:pitch-semitones concert-pch))) (cond ((and (>= semitones clarinet_amateur_low) (<= semitones clarinet_amateur_high) ) black) ((and (>= semitones clarinet_pro_low) (<= semitones clarinet_pro_high) ) darkyellow) (else red))))
代码说明
ly:grob-parent grob Staff:获取当前音符所在的谱表对象ly:staff-transposition:提取谱表的移调偏移量(比如降B调单簧管的偏移量为-2半音)ly:pitch-transpose pch transp:将记谱音高pch转换为实际音乐会音高concert-pch- 后续的颜色判定逻辑保持不变,但基于实际音高的半音数执行
完整修改后代码
#(define clarinet_amateur_low -10) % D3 #(define clarinet_amateur_high 29) % F6 #(define clarinet_pro_low -10) % D3 #(define clarinet_pro_high 34) % A#6 #(define (clarinet-range grob) (let* ((pch (ly:event-property (event-cause grob) 'pitch)) (transp (ly:staff-transposition (ly:grob-parent grob Staff))) (concert-pch (ly:pitch-transpose pch transp)) (semitones (ly:pitch-semitones concert-pch))) (cond ((and (>= semitones clarinet_amateur_low) (<= semitones clarinet_amateur_high) ) black) ((and (>= semitones clarinet_pro_low) (<= semitones clarinet_pro_high) ) darkyellow) (else red)))) notes = \relative c { \key c \major c4 d e f g a b c d e f g a b c d e f g a b c d e f g a ais b c } \score { << % concert pitch \new Staff { \override NoteHead.color = #clarinet-range \notes } % transposed pitch \new Staff { \override NoteHead.color = #clarinet-range \transposition bes \transpose c d \notes } >> }
修改后,两个谱表的音符颜色会完全一致,因为颜色判定逻辑统一基于实际音乐会音高执行。
内容的提问来源于stack exchange,提问作者Simão Leal
相关产品推荐
相关产品推荐

