void PlayingState::Play(microseconds_t delta_microseconds) { // Move notes, time tracking, everything // delta_microseconds = 0 means, that we are on pause MidiEventListWithTrackId evs = m_state.midi->Update(delta_microseconds); // These cycle is for keyboard updates (not falling keys) const size_t length = evs.size(); for(size_t i = 0; i < length; ++i) { const size_t &track_id = evs[i].first; const MidiEvent &ev = evs[i].second; // Draw refers to the keys lighting up (automatically) -- not necessarily // the falling notes. The KeyboardDisplay object contains its own logic // to decide how to draw the falling notes bool draw = false; bool play = false; switch (m_state.track_properties[track_id].mode) { case Track::ModeNotPlayed: draw = false; play = false; break; case Track::ModePlayedButHidden: draw = false; play = true; break; case Track::ModeYouPlay: draw = false; play = false; break; case Track::ModeYouPlaySilently: draw = false; play = false; break; case Track::ModeLearning: draw = false; play = false; break; case Track::ModeLearningSilently: draw = false; play = false; break; case Track::ModePlayedAutomatically: draw = true; play = true; break; case Track::ModeCount: break; } // Even in "You Play" tracks, we have to play the non-note // events as per usual. if (m_state.track_properties[track_id].mode && ev.Type() != MidiEventType_NoteOn && ev.Type() != MidiEventType_NoteOff) play = true; if (ev.Type() == MidiEventType_NoteOn || ev.Type() == MidiEventType_NoteOff) { int vel = ev.NoteVelocity(); const string name = MidiEvent::NoteName(ev.NoteNumber()); bool active = (vel > 0); // Display pressed or released a key based on information from a MIDI-file. // If this line is deleted, than no notes will be pressed automatically. // It is not related to falling notes. if (draw) m_keyboard->SetKeyActive(name, active, m_state.track_properties[track_id].color); filePressedKey(ev.NoteNumber(), active, track_id); } if (play && m_state.midi_out) { // Clone event MidiEvent ev_out = ev; int vel = ev.NoteVelocity(); // Scale note's volume before playing ev_out.SetVelocity(vel * m_state.base_volume); m_state.midi_out->Write(ev_out); } } }
void TitleState::PlayDevicePreview(microseconds_t delta_microseconds) { if (!m_output_tile->IsPreviewOn()) return; if (!m_state.midi_out) return; MidiEventListWithTrackId evs = m_state.midi->Update(delta_microseconds); for (MidiEventListWithTrackId::const_iterator i = evs.begin(); i != evs.end(); ++i) { m_state.midi_out->Write(i->second); } }
void TrackSelectionState::PlayTrackPreview(microseconds_t delta_microseconds) { if (!m_preview_on) return; MidiEventListWithTrackId evs = m_state.midi->Update(delta_microseconds); for (MidiEventListWithTrackId::const_iterator i = evs.begin(); i != evs.end(); ++i) { const MidiEvent &ev = i->second; if (i->first != m_preview_track_id) continue; if (m_state.midi_out) m_state.midi_out->Write(ev); } }