add correct copyright statements to all files in Waves backend except those derived...
[ardour.git] / libs / backends / wavesaudio / waves_midi_device_manager.cc
1 /*
2     Copyright (C) 2013 Waves Audio Ltd.
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
20 #include "waves_midi_device_manager.h"
21 #include "waves_audiobackend.h"
22
23 #ifdef PLATFORM_WINDOWS
24
25 #include "windows.h"
26 #include "mmsystem.h"
27
28 #else if defined(__APPLE__)
29
30 #include <CoreMIDI/MIDIServices.h>
31
32 #define midiInGetNumDevs MIDIGetNumberOfSources
33 #define midiOutGetNumDevs MIDIGetNumberOfDestinations
34
35 #endif
36
37 using namespace ARDOUR;
38
39 WavesMidiDeviceManager::WavesMidiDeviceManager (WavesAudioBackend& audiobackend)
40     : _active (false)
41     , _streaming (false)
42     , _input_device_count (0)
43     , _output_device_count (0)
44     , _audiobackend (audiobackend)
45 {
46 }
47
48
49 WavesMidiDeviceManager::~WavesMidiDeviceManager ()
50 {
51 }
52
53
54 int
55 WavesMidiDeviceManager::start ()
56 {
57     // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::stream ():" << std::endl;
58     if ( _active == true ) {
59         return -1;
60     }
61
62     if (Pm_Initialize () != pmNoError) {
63         return -1;
64     }
65
66     _create_devices ();
67
68     _input_device_count = midiInGetNumDevs ();
69     _output_device_count = midiOutGetNumDevs ();
70
71     _active = true;
72
73     return 0;
74 }
75
76
77 int
78 WavesMidiDeviceManager::stream (bool yn)
79 {
80     // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::stream ():" << std::endl;
81     if (!_active) {
82         std::cerr << "WavesMidiDeviceManager::stream (): the midi device manager is not started up !" << std::endl;
83         return -1;
84     }
85
86     if (_streaming == yn) {
87         return 0;
88     }
89
90     if (yn)    {
91         if ( Pt_Start (1, __portmidi_callback, this) != ptNoError) {
92             std::cerr << "WavesMidiDeviceManager::stream (): Pt_Start () failed!" << std::endl;
93             return -1;
94         }
95     }
96     else {
97         if (Pt_Stop () != ptNoError) {
98             std::cerr << "WavesMidiDeviceManager::stream (): Pt_Stop () failed!" << std::endl;
99             return -1;
100         }
101     }
102
103     _streaming = yn;
104     return 0;
105 }
106
107
108 int
109 WavesMidiDeviceManager::stop ()
110 {
111     // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::stop ():" << std::endl;
112
113     if ( _active == false )
114         return 0;
115     
116     stream (false);
117
118     _close_devices ();
119     _active = false;
120
121     if (Pm_Terminate () != pmNoError) {
122         std::cerr << "WavesMidiDeviceManager::stop (): Pt_Terminate () failed!" << std::endl;
123         return -1;
124     }
125
126     return 0;
127 }
128
129 void 
130 WavesMidiDeviceManager::__portmidi_callback (PtTimestamp timestamp, void * userData)
131 {
132     // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::__portmidi_callback ():" << std::endl;
133     WavesMidiDeviceManager *dm = (WavesMidiDeviceManager *)userData;
134     
135     if (dm == NULL) {
136         return;
137     }
138     
139     dm->_portmidi_callback (timestamp);
140 }
141
142 void
143 WavesMidiDeviceManager::_portmidi_callback (PtTimestamp timestamp)
144 {
145     if ((!_active) || (!_streaming)) {
146         return;
147     }
148
149     if ((_input_device_count != midiInGetNumDevs ()) || (_output_device_count != midiOutGetNumDevs ())) {
150         _audiobackend._changed_midi_devices ();
151         return;
152     }
153 }
154
155 void WavesMidiDeviceManager::do_read ()
156 {
157     for (std::vector<WavesMidiDevice *>::const_iterator it = _devices.begin ();  it != _devices.end (); ++it) {
158         (*it)->read_midi ();
159     }
160 }
161
162
163 void WavesMidiDeviceManager::do_write ()
164 {
165     for (std::vector<WavesMidiDevice *>::const_iterator it = _devices.begin ();  it != _devices.end (); ++it) {
166         (*it)->write_midi ();
167     }
168 }
169
170
171 PmTimestamp
172 WavesMidiDeviceManager::__get_time_ms (void *time_info)
173
174     return ((WavesAudioBackend*)time_info)->sample_time ();
175 }
176
177
178 WavesMidiDevice* WavesMidiDeviceManager::_get_device (const std::string& name)
179 {
180     for (size_t i = 0; i < _devices.size (); i++) {
181         if (name == _devices[i]->name ()) {
182             return _devices[i];
183         }
184     }
185     return NULL;
186 }
187
188
189 int
190 WavesMidiDeviceManager::_create_devices ()
191 {
192     int count = Pm_CountDevices ();
193
194     for (int i = 0; i < count; i++) {
195
196         const PmDeviceInfo* pm_device_info = Pm_GetDeviceInfo (i);
197
198         if (pm_device_info == NULL) {
199             std::cerr << "WavesMidiDeviceManager::_create_devices (): Pm_GetDeviceInfo (" << i << ") failed!" << std::endl;
200             continue;
201         }
202
203         WavesMidiDevice *device = _get_device (pm_device_info->name);
204         if (device) {
205             device->validate ();
206         }
207         else
208         {
209             device = new WavesMidiDevice (pm_device_info->name);
210             _devices.push_back (device);
211         }
212
213         if (device->open (__get_time_ms, (void*)&_audiobackend)) {
214             std::cerr << "WavesMidiDeviceManager::_create_devices (): [" << device->name () << "]->open () failed!" << std::endl;
215         }
216     }
217
218     return 0;
219 }
220
221
222 int
223 WavesMidiDeviceManager::_delete_devices ()
224 {
225     // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::_delete_devices ():" << std::endl;
226     while (!_devices.empty ()) {
227         WavesMidiDevice * device = _devices.back ();
228         _devices.pop_back ();
229         delete device;
230     }
231     return 0;
232 }
233
234
235 void
236 WavesMidiDeviceManager::_close_devices ()
237 {
238     // COMMENTED DBG LOGS */ std::cout << "WavesMidiDeviceManager::_delete_devices ():" << std::endl;
239     for (size_t i = 0; i < _devices.size (); i++) {
240         _devices[i]->close ();
241     }
242 }