PortAudio backend RT-safe MIDI buffer allocation
[ardour.git] / libs / backends / portaudio / winmmemidi_io.h
1 /*
2  * Copyright (C) 2015 Tim Mayberry <mojofunk@gmail.com>
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
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #ifndef WINMME_MIDI_IO_H
20 #define WINMME_MIDI_IO_H
21
22 #include <map>
23 #include <vector>
24 #include <string>
25 #include <stdint.h>
26 #include <pthread.h>
27
28 #include <boost/shared_ptr.hpp>
29 #include "pbd/ringbuffer.h"
30
31 #include "winmmemidi_input_device.h"
32 #include "winmmemidi_output_device.h"
33
34 #include "midi_device_info.h"
35
36 namespace ARDOUR {
37
38 struct WinMMEMIDIPacket {
39
40 #if 0
41         WinMMEMIDIPacket (const WinMMEMIDIPacket& other)
42             : timeStamp (other.timeStamp)
43             , length (other.length)
44         {
45                 if (length > 0) {
46                         memcpy (data, other.data, length);
47                 }
48         }
49 #endif
50
51         // MIDITimeStamp timeStamp;
52         uint16_t length;
53         uint8_t data[MaxWinMidiEventSize];
54 };
55
56 typedef std::vector<boost::shared_ptr<WinMMEMIDIPacket> > WinMMEMIDIQueue;
57
58 class WinMMEMidiIO {
59 public:
60         WinMMEMidiIO ();
61         ~WinMMEMidiIO ();
62
63         void start ();
64         void stop ();
65
66         bool dequeue_input_event (uint32_t port,
67                                   uint64_t timestamp_start,
68                                   uint64_t timestamp_end,
69                                   uint64_t& timestamp,
70                                   uint8_t* data,
71                                   size_t& size);
72
73         bool enqueue_output_event (uint32_t port,
74                                    uint64_t timestamp,
75                                    const uint8_t* data,
76                                    const size_t size);
77
78         uint32_t n_midi_inputs (void) const { return m_inputs.size(); }
79         uint32_t n_midi_outputs (void) const { return m_outputs.size(); }
80
81         std::vector<WinMMEMidiInputDevice*> get_inputs () { return m_inputs; }
82         std::vector<WinMMEMidiOutputDevice*> get_outputs () { return m_outputs; }
83
84         void update_device_info ();
85
86         std::vector<MidiDeviceInfo*> get_device_info () { return m_device_info; }
87
88         MidiDeviceInfo* get_device_info (const std::string& name);
89
90         std::string port_id (uint32_t, bool input);
91         std::string port_name (uint32_t, bool input);
92
93         void set_enabled (bool yn = true) { m_enabled = yn; }
94         bool enabled (void) const { return m_active && m_enabled; }
95
96         void set_port_changed_callback (void (changed_callback (void*)), void *arg) {
97                 m_changed_callback = changed_callback;
98                 m_changed_arg = arg;
99         }
100
101 private: // Methods
102
103         void clear_device_info ();
104
105         static bool get_input_name_from_index (int index, std::string& name);
106         static bool get_output_name_from_index (int index, std::string& name);
107
108         void discover ();
109         void cleanup ();
110
111         void create_input_devices ();
112         void create_output_devices ();
113
114         void destroy_input_devices ();
115         void destroy_output_devices ();
116
117         void start_devices ();
118         void stop_devices ();
119
120 private: // Data
121
122         std::vector<MidiDeviceInfo*> m_device_info;
123
124         std::vector<WinMMEMidiInputDevice*> m_inputs;
125         std::vector<WinMMEMidiOutputDevice*> m_outputs;
126
127         bool              m_active;
128         bool              m_enabled;
129         bool              m_run;
130
131         void (* m_changed_callback) (void*);
132         void  * m_changed_arg;
133
134         // protects access to m_inputs and m_outputs
135         pthread_mutex_t m_device_lock;
136 };
137
138 } // namespace
139
140 #endif // WINMME_MIDI_IO_H
141