Ardour  9.0-pre0-582-g084a23a80d
alsa_rawmidi.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014-2015 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_rawmidi_h__
20 #define __libbackend_alsa_rawmidi_h__
21 
22 #include <stdint.h>
23 #include <poll.h>
24 #include <pthread.h>
25 
26 #include <alsa/asoundlib.h>
27 
28 #include "pbd/ringbuffer.h"
29 #include "ardour/types.h"
30 #include "alsa_midi.h"
31 
32 namespace ARDOUR {
33 
34 class AlsaRawMidiIO : virtual public AlsaMidiIO {
35 public:
36  AlsaRawMidiIO (const std::string &name, const char *device, const bool input);
37  virtual ~AlsaRawMidiIO ();
38 
39 protected:
40  snd_rawmidi_t *_device;
41 
42 private:
43  void init (const char *device_name, const bool input);
44 };
45 
47 {
48 public:
49  AlsaRawMidiOut (const std::string &name, const char *device);
51 };
52 
53 class AlsaRawMidiIn : public AlsaRawMidiIO, public AlsaMidiIn
54 {
55 public:
56  AlsaRawMidiIn (const std::string &name, const char *device);
57 
59 
60 protected:
61  int queue_event (const uint64_t, const uint8_t *, const size_t);
62 private:
63  void parse_events (const uint64_t, const uint8_t *, const size_t);
64  bool process_byte (const uint64_t, const uint8_t);
65 
66  void record_byte(uint8_t byte) {
67  if (_total_bytes < sizeof(_parser_buffer)) {
69  } else {
71  }
72  ++_total_bytes;
73  }
74 
75  void prepare_byte_event(const uint64_t time, const uint8_t byte) {
76  _parser_buffer[0] = byte;
77  _event.prepare(time, 1);
78  }
79 
80  bool prepare_buffered_event(const uint64_t time) {
81  const bool result = _unbuffered_bytes == 0;
82  if (result) {
84  }
85  _total_bytes = 0;
87  if (_status_byte >= 0xf0) {
88  _expected_bytes = 0;
89  _status_byte = 0;
90  }
91  return result;
92  }
93 
94  struct ParserEvent {
95  uint64_t _time;
96  size_t _size;
97  bool _pending;
98  ParserEvent (const uint64_t time, const size_t size)
99  : _time(time)
100  , _size(size)
101  , _pending(false) {}
102 
103  void prepare(const uint64_t time, const size_t size) {
104  _time = time;
105  _size = size;
106  _pending = true;
107  }
109 
112  size_t _total_bytes;
114  uint8_t _status_byte;
115  uint8_t _parser_buffer[1024];
116 };
117 
118 } // namespace
119 
120 #endif
const std::string & name() const
Definition: alsa_midi.h:49
AlsaRawMidiIO(const std::string &name, const char *device, const bool input)
snd_rawmidi_t * _device
Definition: alsa_rawmidi.h:40
void init(const char *device_name, const bool input)
bool prepare_buffered_event(const uint64_t time)
Definition: alsa_rawmidi.h:80
void * main_process_thread()
void prepare_byte_event(const uint64_t time, const uint8_t byte)
Definition: alsa_rawmidi.h:75
void parse_events(const uint64_t, const uint8_t *, const size_t)
struct ARDOUR::AlsaRawMidiIn::ParserEvent _event
bool process_byte(const uint64_t, const uint8_t)
AlsaRawMidiIn(const std::string &name, const char *device)
int queue_event(const uint64_t, const uint8_t *, const size_t)
void record_byte(uint8_t byte)
Definition: alsa_rawmidi.h:66
uint8_t _parser_buffer[1024]
Definition: alsa_rawmidi.h:115
AlsaRawMidiOut(const std::string &name, const char *device)
void prepare(const uint64_t time, const size_t size)
Definition: alsa_rawmidi.h:103
ParserEvent(const uint64_t time, const size_t size)
Definition: alsa_rawmidi.h:98