06b8202f43c25e76ccbbe234d1fc8809ae43b5fc
[ardour.git] / libs / backends / portaudio / winmmemidi_input_device.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_INPUT_DEVICE_H
20 #define WINMME_MIDI_INPUT_DEVICE_H
21
22 #include <windows.h>
23 #include <mmsystem.h>
24
25 #include <stdint.h>
26
27 #include <string>
28
29 #include <boost/scoped_array.hpp>
30 #include <boost/scoped_ptr.hpp>
31
32 #include <pbd/ringbuffer.h>
33
34 namespace ARDOUR {
35
36 class WinMMEMidiInputDevice {
37 public: // ctors
38         WinMMEMidiInputDevice (int index);
39
40         ~WinMMEMidiInputDevice ();
41
42 public: // methods
43
44         /**
45          * Dequeue events that have accumulated in winmm_input_callback.
46          *
47          * This is called by the audio processing thread/callback to transfer events
48          * into midi ports before processing.
49          */
50         bool dequeue_midi_event (uint64_t timestamp_start,
51                                  uint64_t timestamp_end,
52                                  uint64_t& timestamp,
53                                  uint8_t* data,
54                                  size_t& size);
55
56         bool start ();
57         bool stop ();
58
59         void set_enabled (bool enable);
60
61         bool get_enabled ();
62
63         /**
64          * @return Name of midi device
65          */
66         std::string name () const { return m_name; }
67
68 private: // methods
69         bool open (UINT index, std::string& error_msg);
70         bool close (std::string& error_msg);
71
72         bool add_sysex_buffer (std::string& error_msg);
73         bool set_device_name (UINT index);
74
75         std::string get_error_string (MMRESULT error_code);
76
77         static void CALLBACK winmm_input_callback (HMIDIIN handle,
78                                                    UINT msg,
79                                                    DWORD_PTR instance,
80                                                    DWORD_PTR midi_msg,
81                                                    DWORD timestamp);
82
83         void handle_short_msg (const uint8_t* midi_data, uint32_t timestamp);
84
85         void handle_sysex_msg (MIDIHDR* const midi_header, uint32_t timestamp);
86
87         bool enqueue_midi_msg (const uint8_t* midi_data, size_t size, uint32_t timestamp);
88
89 private: // data
90         HMIDIIN m_handle;
91         MIDIHDR m_sysex_header;
92
93         bool m_started;
94         bool m_in_reset;
95
96         std::string m_name;
97
98         // can't use unique_ptr yet
99         boost::scoped_ptr<RingBuffer<uint8_t> > m_midi_buffer;
100         boost::scoped_array<uint8_t> m_sysex_buffer;
101 };
102
103 }
104
105 #endif // WINMME_MIDI_INPUT_DEVICE_H