1 /* 2 * Copyright (C) 2014-2017 Robin Gareus <robin@gareus.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License along 15 * with this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 */ 18 19 #ifndef __libbackend_alsa_midi_h__ 20 #define __libbackend_alsa_midi_h__ 21 22 #include <stdint.h> 23 #include <poll.h> 24 #include <pthread.h> 25 26 #include "pbd/ringbuffer.h" 27 #include "ardour/types.h" 28 29 /* max bytes per individual midi-event 30 * events larger than this are ignored */ 31 #define MaxAlsaMidiEventSize (256) 32 33 namespace ARDOUR { 34 35 class AlsaMidiIO { 36 public: 37 AlsaMidiIO (); 38 virtual ~AlsaMidiIO (); 39 state(void)40 int state (void) const { return _state; } 41 int start (); 42 int stop (); 43 44 void setup_timing (const size_t samples_per_period, const float samplerate); 45 void sync_time(uint64_t); 46 47 virtual void* main_process_thread () = 0; 48 name()49 const std::string & name () const { return _name; } 50 51 protected: 52 pthread_t _main_thread; 53 pthread_mutex_t _notify_mutex; 54 pthread_cond_t _notify_ready; 55 56 int _state; 57 bool _running; 58 59 int _npfds; 60 struct pollfd *_pfds; 61 62 double _sample_length_us; 63 double _period_length_us; 64 size_t _samples_per_period; 65 uint64_t _clock_monotonic; 66 67 struct MidiEventHeader { 68 uint64_t time; 69 size_t size; MidiEventHeaderMidiEventHeader70 MidiEventHeader(const uint64_t t, const size_t s) 71 : time(t) 72 , size(s) {} 73 }; 74 75 PBD::RingBuffer<uint8_t>* _rb; 76 77 std::string _name; 78 79 virtual void init (const char *device_name, const bool input) = 0; 80 81 }; 82 83 class AlsaMidiOut : virtual public AlsaMidiIO 84 { 85 public: 86 AlsaMidiOut (); 87 88 int send_event (const pframes_t, const uint8_t *, const size_t); 89 }; 90 91 class AlsaMidiIn : virtual public AlsaMidiIO 92 { 93 public: 94 AlsaMidiIn (); 95 96 size_t recv_event (pframes_t &, uint8_t *, size_t &); 97 98 protected: 99 int queue_event (const uint64_t, const uint8_t *, const size_t); 100 }; 101 102 } // namespace 103 104 #endif 105