diff options
| -rw-r--r-- | MIDI.cpp | 43 | ||||
| -rw-r--r-- | UI.cpp | 16 | ||||
| -rw-r--r-- | UI.h | 44 | 
3 files changed, 74 insertions, 29 deletions
| @@ -21,25 +21,29 @@ MIDI::MIDI()    debug_cout << "in_port: " << std::to_string(in_port) << std::endl; -#if 1 -  snd_seq_addr_t sender, dest; -  snd_seq_port_subscribe_t *subs; -  sender.client = 24; -  sender.port = 0; -  dest.client = snd_seq_client_id(seq_handle); -  dest.port = in_port; -  snd_seq_port_subscribe_alloca(&subs); -  snd_seq_port_subscribe_set_sender(subs, &sender); -  snd_seq_port_subscribe_set_dest(subs, &dest); -  snd_seq_port_subscribe_set_queue(subs, 1); -  snd_seq_port_subscribe_set_time_update(subs, 1); -  snd_seq_port_subscribe_set_time_real(subs, 1); -  // TODO: fix timestamp (currently always 0) -  if (0 > snd_seq_subscribe_port(seq_handle, subs)) -#endif -  //if (0 > snd_seq_connect_from(seq_handle, in_port, 24, 0)) -  { -    throw std::runtime_error("MIDI port couldn't be connected"); +  if (1) { +    snd_seq_addr_t sender, dest; +    snd_seq_port_subscribe_t *subs; +    sender.client = 24; +    sender.port = 0; +    dest.client = snd_seq_client_id(seq_handle); +    dest.port = in_port; +    snd_seq_port_subscribe_alloca(&subs); +    snd_seq_port_subscribe_set_sender(subs, &sender); +    snd_seq_port_subscribe_set_dest(subs, &dest); +    snd_seq_port_subscribe_set_queue(subs, 1); +    snd_seq_port_subscribe_set_time_update(subs, 1); +    snd_seq_port_subscribe_set_time_real(subs, 1); +    // TODO: fix timestamp (currently always 0) +    if (0 > snd_seq_subscribe_port(seq_handle, subs)) +    { +      throw std::runtime_error("MIDI port couldn't be connected"); +    } +  } else { +    if (0 > snd_seq_connect_from(seq_handle, in_port, 24, 0)) +    { +      throw std::runtime_error("MIDI port couldn't be connected"); +    }    }    npfd = snd_seq_poll_descriptors_count(seq_handle, POLLIN); @@ -150,6 +154,7 @@ void MIDI::process(snd_seq_event_t *ev)    }    signal_count_events(snd_seq_event_length(ev)); +  //log_cout << fmt::format("MIDI Bytes: {}", snd_seq_event_length(ev)) << std::endl;  }  void MIDI::flush() @@ -68,8 +68,8 @@ UI::UI(Config& config):    m_midi_notes{},    m_active_sensing_timestamp{},    m_midi_timestamp{}, -  m_note_bpm{}, -  m_clock_bpm{}, +  m_note_bpm{2000ms}, +  m_clock_bpm{2000ms},    m_touchpad{}  {  } @@ -108,9 +108,9 @@ void UI::draw()    int internal_bpm = m_config.get_bpm();    int bpm;    if (mode == 0) { -    bpm = m_note_bpm; +    bpm = m_note_bpm.value();    } else if (mode == 1) { -    bpm = m_clock_bpm; +    bpm = m_clock_bpm.value();    } else if (mode == 2) {      bpm = m_config.get_bpm();    } @@ -174,8 +174,8 @@ void UI::draw()    std::cout << fmt::format("  MIDI Events/s:{:3}", midi_events_per_second) << std::endl;    std::cout << fmt::format("  MIDI Notes/s: {:3}", midi_notes_per_second) << std::endl;    std::cout << fmt::format("  MIDI Bytes/s: {:3} ({}%)", midi_bytes_per_second, midi_bytes_per_second * 100 / midi_bandwidth) << std::endl; -  std::cout << fmt::format("  MIDI Click:   {:3} BPM", m_note_bpm) << std::endl; -  std::cout << fmt::format("  MIDI Clock:   {:3} BPM", m_clock_bpm) << std::endl; +  std::cout << fmt::format("  MIDI Click:   {:3} BPM", m_note_bpm.value()) << std::endl; +  std::cout << fmt::format("  MIDI Clock:   {:3} BPM", m_clock_bpm.value()) << std::endl;    std::cout << fmt::format("  Internal:     {:3} BPM", internal_bpm) << std::endl;    std::cout << fmt::format("  Main loops/s: {:3}", main_loops_per_second) << std::endl; @@ -268,11 +268,11 @@ void UI::slot_midi_note(int channel, int note, uint64_t timestamp)  void UI::slot_note_bpm(int bpm)  { -  m_note_bpm = bpm; +  m_note_bpm.update(bpm);  }  void UI::slot_clock_bpm(int bpm)  { -  m_clock_bpm = bpm; +  m_clock_bpm.update(bpm);  } @@ -26,6 +26,46 @@ private:    std::chrono::time_point<clock_type> m_checkpoint_timestamp{};  }; +template<typename T> +class AgeOutValue +{ +public: +  AgeOutValue(std::chrono::milliseconds timeout): +    m_timeout(timeout), +    m_checkpoint_timestamp(clock_type::now()), +    m_value{} +  { +  } + +  bool is_current() +  { +    return clock_type::now() - m_checkpoint_timestamp < m_timeout; +  } + +  // returns value, or 0 if aged-out +  T value() +  { +    T result{}; + +    if (is_current()) { +      result = m_value; +    } + +    return result; +  } + +  void update(const T& value) +  { +    m_value = value; +    m_checkpoint_timestamp = clock_type::now(); +  } + +private: +  const std::chrono::milliseconds m_timeout; +  std::chrono::time_point<clock_type> m_checkpoint_timestamp{}; +  T m_value; +}; +  class UI  {  public: @@ -66,8 +106,8 @@ private:    uint64_t m_midi_timestamp;    std::deque<std::pair<int,int>> m_midi_monitor; -  int m_note_bpm; -  int m_clock_bpm; +  AgeOutValue<int> m_note_bpm; +  AgeOutValue<int> m_clock_bpm;    Touchpad m_touchpad;    Temperature m_temperature; | 
