From b2c35cdf69a9084806ac7930cf4475980d596cf6 Mon Sep 17 00:00:00 2001
From: Roland Reichwein <mail@reichwein.it>
Date: Sat, 4 Jan 2025 11:28:20 +0100
Subject: Separate out implementation from headers

---
 MIDI.h | 169 ++++-------------------------------------------------------------
 1 file changed, 8 insertions(+), 161 deletions(-)

(limited to 'MIDI.h')

diff --git a/MIDI.h b/MIDI.h
index e24c18a..177fd59 100644
--- a/MIDI.h
+++ b/MIDI.h
@@ -13,178 +13,25 @@
 class MIDI
 {
 public:
-  MIDI()
-  {
-    if (0 > snd_seq_open(&seq_handle, "default", SND_SEQ_OPEN_INPUT, SND_SEQ_NONBLOCK))
-    {
-      throw std::runtime_error("MIDI sequencer couldn't be opened");
-    }
-
-    if (0 > snd_seq_set_client_name(seq_handle, "Midi Listener"))
-    {
-      throw std::runtime_error("MIDI client name couldn't be set");
-    }
-
-    if (0 > ((in_port = snd_seq_create_simple_port(seq_handle, "24:0",
-                      SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE | SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ,
-                      SND_SEQ_PORT_TYPE_APPLICATION))))
-    {
-      throw std::runtime_error("MIDI port couldn't be opened");
-    }
-
-    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");
-    }
-
-    npfd = snd_seq_poll_descriptors_count(seq_handle, POLLIN);
-    if (npfd < 0) {
-      throw std::runtime_error("snd_seq_poll_descriptors_count() failed");
-    }
-    pfd = (struct pollfd *)malloc(npfd * sizeof(struct pollfd));
-    if (pfd == nullptr) {
-      throw std::runtime_error("alloca() error for MIDI");
-    }
-    if (0 > snd_seq_poll_descriptors(seq_handle, pfd, npfd, POLLIN))
-    {
-      throw std::runtime_error("snd_seq_poll_descriptors() failure");
-    }
-
-    if (npfd != 1) {
-      std::cout << "Warning: " << std::to_string(npfd) << " poll fds for MIDI" << std::endl;
-    } else if (fd() <= 2) {
-      std::cout << "Warning: Bad MIDI fd: " << std::to_string(fd()) << std::endl;
-    }
-  }
-
-  ~MIDI()
-  {
-    free(pfd);
-  }
+  MIDI();
+  ~MIDI();
 
   boost::signals2::signal<void(int, int, uint64_t)> signal_note;
   boost::signals2::signal<void()> signal_active_sensing;
   boost::signals2::signal<void()> signal_clock;
 
-  int fd()
-  {
-    return pfd->fd;
-  }
-
-  bool event_ready()
-  {
-    int result = snd_seq_event_input_pending(seq_handle, 1);
-    if (result < 0) {
-      throw std::runtime_error("snd_seq_event_input_pending() failed");
-    }
-
-    return result > 0;
-  }
+  int fd();
 
-  snd_seq_event_t *read(void)
-  {
-    snd_seq_event_t *ev = NULL;
-    if (0 > snd_seq_event_input(seq_handle, &ev))
-    {
-     std::cerr << "snd_seq_event_input(): -EAGAIN" << std::endl;
-    }
+  bool event_ready();
 
-    return ev;
-  }
-
-  uint64_t timestamp_from_event(const snd_seq_event_t *ev)
-  {
-    return ((ev->flags & SND_SEQ_TIME_STAMP_MASK) == SND_SEQ_TIME_STAMP_REAL) ? ev->time.time.tv_sec : ev->time.tick;
-  }
+  snd_seq_event_t *read(void);
 
   // returns if click starts
-  void process(snd_seq_event_t *ev)
-  {
-    uint64_t timestamp = timestamp_from_event(ev); // original timestamp
-
-    // TODO: fix timestamp to be set automatically
-    struct timespec t;
-    if (TIME_UTC != timespec_get(&t, TIME_UTC))
-    {
-      log_cout << "Error: timespec_get()" << std::endl;
-    }
-    else
-    {
-      ev->time.time.tv_sec = t.tv_sec;
-      ev->time.time.tv_nsec = t.tv_nsec;
-    }
-
-    if ((ev->type == SND_SEQ_EVENT_NOTEON) ||(ev->type == SND_SEQ_EVENT_NOTEOFF)) {
-      const char *type = (ev->type == SND_SEQ_EVENT_NOTEON) ? "on " : "off";
-      debug_cout << fmt::format("[{}] Note {}: {:2x} vel({:2x}), ch {:2x}\n", timestamp,
-                                              type,
-                                              ev->data.note.note,
-                                              ev->data.note.velocity,
-                                              ev->data.control.channel);
-      if (ev->type == SND_SEQ_EVENT_NOTEON) {
-        signal_note(ev->data.control.channel, ev->data.note.note, timestamp);
-      }
-    }
-    else if (ev->type == SND_SEQ_EVENT_CONTROLLER)
-    {
-      debug_cout << fmt::format("[{}] Control:  {:2x} val({:2x})\n", timestamp_from_event(ev),
-                                               ev->data.control.param,
-                                               ev->data.control.value);
-    }
-    else if (ev->type == SND_SEQ_EVENT_SENSING)
-    {
-      signal_active_sensing();
-      debug_cout << fmt::format("[{}] Active Sensing\n", timestamp_from_event(ev)) << std::endl;
-    }
-    else if (ev->type == SND_SEQ_EVENT_CLOCK)
-    {
-      signal_clock();
-      debug_cout << fmt::format("[{}] Clock\n", timestamp_from_event(ev)) << std::endl;
-    }
-    else
-    {
-      log_cout << fmt::format("[{}] Unknown MIDI event: {}\n", timestamp_from_event(ev), ev->type) << std::endl;
-    }
-  }
+  void process(snd_seq_event_t *ev);
 
-  void flush()
-  {
-    while (event_ready()) {
-      (void) read();
-    }
-  }
+  void flush();
 
-  void wait_for_event()
-  {
-    int result = poll(pfd, npfd, 10000);
-    if (result > 0)
-    {
-      // event
-    }
-    else if (result == 0) {
-      // timeout
-    } else {
-      throw std::runtime_error("Poll unsuccessful");
-    }
-  }
+  void wait_for_event();
 
 private:
   snd_seq_t *seq_handle;
-- 
cgit v1.2.3