| 147 | } |
| 148 | |
| 149 | void stChannelState::HandleNote(const stChanNote &Note, unsigned EffColumns) { |
| 150 | if (Note.Note != note_t::none && Note.Note != note_t::release) { |
| 151 | for (int i = 0; i < std::min(BufferPos, (int)std::size(Echo)); ++i) { |
| 152 | if (Echo[i] == ECHO_BUFFER_ECHO) { |
| 153 | UpdateEchoTranspose(Note, Transpose[i], EffColumns); |
| 154 | switch (Note.Note) { |
| 155 | case note_t::halt: Echo[i] = ECHO_BUFFER_HALT; break; |
| 156 | case note_t::echo: Echo[i] = ECHO_BUFFER_ECHO + Note.Octave; break; |
| 157 | default: |
| 158 | int NewNote = Note.ToMidiNote() + Transpose[i]; |
| 159 | NewNote = std::clamp(NewNote, 0, NOTE_COUNT - 1); |
| 160 | Echo[i] = NewNote; |
| 161 | } |
| 162 | } |
| 163 | else if (Echo[i] > ECHO_BUFFER_ECHO && Echo[i] < ECHO_BUFFER_ECHO + (int)ECHO_BUFFER_LENGTH) |
| 164 | --Echo[i]; |
| 165 | } |
| 166 | if (BufferPos >= 0 && BufferPos < (int)ECHO_BUFFER_LENGTH) { |
| 167 | int Value; |
| 168 | switch (Note.Note) { |
| 169 | case note_t::halt: Value = ECHO_BUFFER_HALT; break; |
| 170 | case note_t::echo: Value = ECHO_BUFFER_ECHO + Note.Octave; break; |
| 171 | default: |
| 172 | Value = Note.ToMidiNote(); |
| 173 | UpdateEchoTranspose(Note, Value, EffColumns); |
| 174 | Value = std::clamp(Value, 0, NOTE_COUNT - 1); |
| 175 | } |
| 176 | Echo[BufferPos] = Value; |
| 177 | UpdateEchoTranspose(Note, Transpose[BufferPos], EffColumns); |
| 178 | } |
| 179 | ++BufferPos; |
| 180 | } |
| 181 | if (BufferPos < 0) |
| 182 | BufferPos = 0; |
| 183 | |
| 184 | if (Instrument == MAX_INSTRUMENTS) |
| 185 | if (Note.Instrument != MAX_INSTRUMENTS && Note.Instrument != HOLD_INSTRUMENT) // // // 050B |
| 186 | Instrument = Note.Instrument; |
| 187 | |
| 188 | if (Volume == MAX_VOLUME) |
| 189 | if (Note.Vol != MAX_VOLUME) |
| 190 | Volume = Note.Vol; |
| 191 | } |
| 192 | |
| 193 | void stChannelState::HandleNormalCommand(stEffectCommand cmd) { |
| 194 | if (Effect[value_cast(cmd.fx)] == -1) |
no test coverage detected