pinobatch / pently

Scalable music engine for NES games
zlib License
72 stars 4 forks source link

Legato does not change pitch of attack #7

Closed pinobatch closed 8 years ago

pinobatch commented 8 years ago

The LEGATO_ON feature to change an existing note's pitch doesn't take effect immediately if an attack is active. The pitch change becomes audible once the note hits its sustain phase.

MCVE provided by NovaSquirrel:

durations stick
notenames english

instrument New_instrument
  // This is a whole second long
  volume 15 15 15 15 15 14 14 14 14 13 13 13 13 12 12 12 12 12 11 11 11 11 10 10 10 10 9 9 9 9 8 8 8 8 7 7 7 7 6 6 6 6 5 5 5 5 4 4 4 4 4 3 3 3 3 2 2 2 2 1 1 1 1 0 0 0 
  timbre 1 

song New_song
  time 4/4
  scale 16
  tempo 150.00

  pattern pat_1_0_0 with New_instrument on pulse1
    absolute
    c'8 d'8 e'4 c'16~ d'16~ e'16~ f'8 w16 e'8 e'8 c'16~ a#8 w16 c'16~ c#'2 w16 
  at 1
  play pat_1_0_0
  at 3
  dal segno

The root cause is that attackPitch and notePitch are separate, and legato modifies only notePitch. Right now, bit 7 of arpPhase is true if the attack is injected, so as to prevent the victim channel's arpeggio effect from affecting the injected attack. A quick fix would overwrite attackPitch if bit 7 of arpPhase is false.

A proper fix would switch the attack track from injecting attacks onto existing channels to being a lookaside source of timbre/pitch pairs (like the sound effects currently are). Then each channel wouldn't need its own attackPitch, as the attack track's notePitch would serve for that. This would also allow the attack track to have its own arpeggio effect, but that can be filed as a separate issue.