~ubuntu-branches/ubuntu/vivid/midisnoop/vivid

« back to all changes in this revision

Viewing changes to .pc/03-fix_build_with_rtmidi_2_1.patch/src/engine.cpp

  • Committer: Package Import Robot
  • Author(s): Jaromír Mikeš
  • Date: 2014-06-09 20:50:45 UTC
  • Revision ID: package-import@ubuntu.com-20140609205045-g17o5avepxxxvzto
Tags: 0.1.2~repack0-3
* Removed hardening wrapper.
* Added patch to fix build with rtmidi 2.1.
* Bump Standards.
* Build against rtmidi 2.1.
* Added keywords to desktop file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * midisnoop - MIDI monitor and prober
 
3
 * Copyright (C) 2012 Devin Anderson
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify it
 
6
 * under the terms of the GNU General Public License as published by the Free
 
7
 * Software Foundation; either version 2 of the License, or (at your option)
 
8
 * any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful, but WITHOUT
 
11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 
13
 * more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License along with
 
16
 * this program; if not, write to the Free Software Foundation, Inc., 675 Mass
 
17
 * Ave, Cambridge, MA 02139, USA.
 
18
 */
 
19
 
 
20
#include <cassert>
 
21
 
 
22
#include <QtCore/QDateTime>
 
23
#include <QtCore/QDebug>
 
24
 
 
25
#include "engine.h"
 
26
#include "error.h"
 
27
 
 
28
// Static functions
 
29
 
 
30
void
 
31
Engine::handleMidiInput(double timeStamp, std::vector<unsigned char> *message,
 
32
                        void *engine)
 
33
{
 
34
    static_cast<Engine *>(engine)->handleMidiInput(timeStamp, message);
 
35
}
 
36
 
 
37
// Class definition
 
38
 
 
39
Engine::Engine(QObject *parent):
 
40
    QObject(parent)
 
41
{
 
42
    // Get available MIDI drivers.
 
43
    std::vector<RtMidi::Api> apis;
 
44
    RtMidi::getCompiledApi(apis);
 
45
    int apiCount = apis.size();
 
46
 
 
47
    for (int i = 0; i < apiCount; i++) {
 
48
        RtMidi::Api api = apis[i];
 
49
        switch (api) {
 
50
        case RtMidi::LINUX_ALSA:
 
51
            driverNames.append(tr("ALSA Sequencer"));
 
52
            break;
 
53
        case RtMidi::MACOSX_CORE:
 
54
            driverNames.append(tr("CoreMidi"));
 
55
            break;
 
56
        case RtMidi::UNIX_JACK:
 
57
            driverNames.append(tr("JACK Audio Connection Kit"));
 
58
            break;
 
59
        case RtMidi::WINDOWS_KS:
 
60
            driverNames.append(tr("Windows Kernel Streaming"));
 
61
            break;
 
62
        case RtMidi::WINDOWS_MM:
 
63
            driverNames.append(tr("Windows Multimedia MIDI"));
 
64
            break;
 
65
        default:
 
66
            qWarning() << tr("Unexpected MIDI API constant: %1").
 
67
                arg(static_cast<int>(api));
 
68
            // Fallthrough on purpose
 
69
        case RtMidi::RTMIDI_DUMMY:
 
70
        case RtMidi::UNSPECIFIED:
 
71
            continue;
 
72
        }
 
73
        driverAPIs.append(api);
 
74
    }
 
75
 
 
76
    driver = -1;
 
77
    ignoreActiveSensingEvents = true;
 
78
    ignoreSystemExclusiveEvents = true;
 
79
    ignoreTimeEvents = true;
 
80
    inputPort = -1;
 
81
    outputPort = -1;
 
82
}
 
83
 
 
84
Engine::~Engine()
 
85
{
 
86
    setDriver(-1);
 
87
}
 
88
 
 
89
int
 
90
Engine::getDriver() const
 
91
{
 
92
    return driver;
 
93
}
 
94
 
 
95
int
 
96
Engine::getDriverCount() const
 
97
{
 
98
    return driverAPIs.count();
 
99
}
 
100
 
 
101
QString
 
102
Engine::getDriverName(int index) const
 
103
{
 
104
    assert((index >= 0) && (index < driverAPIs.count()));
 
105
    return driverNames[index];
 
106
}
 
107
 
 
108
bool
 
109
Engine::getIgnoreActiveSensingEvents() const
 
110
{
 
111
    return ignoreActiveSensingEvents;
 
112
}
 
113
 
 
114
bool
 
115
Engine::getIgnoreSystemExclusiveEvents() const
 
116
{
 
117
    return ignoreSystemExclusiveEvents;
 
118
}
 
119
 
 
120
bool
 
121
Engine::getIgnoreTimeEvents() const
 
122
{
 
123
    return ignoreTimeEvents;
 
124
}
 
125
 
 
126
int
 
127
Engine::getInputPort() const
 
128
{
 
129
    return inputPort;
 
130
}
 
131
 
 
132
int
 
133
Engine::getInputPortCount() const
 
134
{
 
135
    return inputPortNames.count();
 
136
}
 
137
 
 
138
QString
 
139
Engine::getInputPortName(int index) const
 
140
{
 
141
    assert((index >= 0) && (index < inputPortNames.count()));
 
142
    return inputPortNames[index];
 
143
}
 
144
 
 
145
int
 
146
Engine::getOutputPort() const
 
147
{
 
148
    return outputPort;
 
149
}
 
150
 
 
151
int
 
152
Engine::getOutputPortCount() const
 
153
{
 
154
    return outputPortNames.count();
 
155
}
 
156
 
 
157
QString
 
158
Engine::getOutputPortName(int index) const
 
159
{
 
160
    assert((index >= 0) && (index < outputPortNames.count()));
 
161
    return outputPortNames[index];
 
162
}
 
163
 
 
164
void
 
165
Engine::handleMidiInput(double /*timeStamp*/,
 
166
                        std::vector<unsigned char> *message)
 
167
{
 
168
    quint64 timeStamp = QDateTime::currentDateTime().toMSecsSinceEpoch();
 
169
    QByteArray msg;
 
170
    int size = static_cast<int>(message->size());
 
171
    for (int i = 0; i < size; i++) {
 
172
        msg.append(message->at(i));
 
173
    }
 
174
    emit messageReceived(timeStamp, msg);
 
175
}
 
176
 
 
177
void
 
178
Engine::removePorts()
 
179
{
 
180
    setInputPort(-1);
 
181
    setOutputPort(-1);
 
182
    for (int i = inputPortNames.count() - 1; i >= 0; i--) {
 
183
        inputPortNames.removeAt(i);
 
184
        emit inputPortRemoved(i);
 
185
    }
 
186
    for (int i = outputPortNames.count() - 1; i >= 0; i--) {
 
187
        outputPortNames.removeAt(i);
 
188
        emit outputPortRemoved(i);
 
189
    }
 
190
}
 
191
 
 
192
quint64
 
193
Engine::sendMessage(const QByteArray &message)
 
194
{
 
195
    assert(outputPort != -1);
 
196
    std::vector<unsigned char> msg;
 
197
    for (int i = 0; i < message.count(); i++) {
 
198
        msg.push_back(static_cast<unsigned char>(message[i]));
 
199
    }
 
200
    try {
 
201
        output->sendMessage(&msg);
 
202
    } catch (RtError &e) {
 
203
        throw Error(e.what());
 
204
    }
 
205
    return QDateTime::currentDateTime().toMSecsSinceEpoch();
 
206
}
 
207
 
 
208
void
 
209
Engine::setDriver(int index)
 
210
{
 
211
    assert((index >= -1) && (index < driverAPIs.count()));
 
212
    if (driver != index) {
 
213
 
 
214
        // Close the currently open MIDI driver.
 
215
        if (driver != -1) {
 
216
            removePorts();
 
217
            delete input;
 
218
            delete output;
 
219
            driver = -1;
 
220
            emit driverChanged(-1);
 
221
        }
 
222
 
 
223
        // Open the new driver.
 
224
        if (index != -1) {
 
225
            RtMidi::Api api = driverAPIs[index];
 
226
            try {
 
227
                input = new RtMidiIn(api, "midisnoop");
 
228
                QScopedPointer<RtMidiIn> inputPtr(input);
 
229
                output = new RtMidiOut(api, "midisnoop");
 
230
                QScopedPointer<RtMidiOut> outputPtr(output);
 
231
                input->setCallback(handleMidiInput, this);
 
232
 
 
233
                // Add ports.
 
234
                try {
 
235
                    unsigned int count = input->getPortCount();
 
236
                    QString name;
 
237
                    for (unsigned int i = 0; i < count; i++) {
 
238
                        name = QString::fromStdString(input->getPortName(i));
 
239
                        inputPortNames.append(name);
 
240
                        emit inputPortAdded(i, name);
 
241
                    }
 
242
                    count = output->getPortCount();
 
243
                    for (unsigned int i = 0; i < count; i++) {
 
244
                        name = QString::fromStdString(output->getPortName(i));
 
245
                        outputPortNames.append(name);
 
246
                        emit outputPortAdded(i, name);
 
247
                    }
 
248
 
 
249
                    // Add a virtual port to drivers that support virtual ports.
 
250
                    switch (api) {
 
251
                    case RtMidi::LINUX_ALSA:
 
252
                    case RtMidi::MACOSX_CORE:
 
253
                    case RtMidi::UNIX_JACK:
 
254
                        name = tr("[virtual input]");
 
255
                        inputPortNames.append(name);
 
256
                        emit inputPortAdded(inputPortNames.count() - 1, name);
 
257
                        name = tr("[virtual output]");
 
258
                        outputPortNames.append(name);
 
259
                        emit outputPortAdded(outputPortNames.count() - 1, name);
 
260
                        virtualPortsAdded = true;
 
261
                        break;
 
262
                    default:
 
263
                        virtualPortsAdded = false;
 
264
                    }
 
265
                } catch (...) {
 
266
                    removePorts();
 
267
                    throw;
 
268
                }
 
269
                inputPtr.take();
 
270
                outputPtr.take();
 
271
            } catch (RtError &e) {
 
272
                throw Error(e.what());
 
273
            }
 
274
            driver = index;
 
275
            emit driverChanged(index);
 
276
        }
 
277
    }
 
278
}
 
279
 
 
280
void
 
281
Engine::setIgnoreActiveSensingEvents(bool ignore)
 
282
{
 
283
    if (ignoreActiveSensingEvents != ignore) {
 
284
        ignoreActiveSensingEvents = ignore;
 
285
        updateEventFilter();
 
286
        emit ignoreActiveSensingEventsChanged(ignore);
 
287
    }
 
288
}
 
289
 
 
290
void
 
291
Engine::setIgnoreSystemExclusiveEvents(bool ignore)
 
292
{
 
293
    if (ignoreSystemExclusiveEvents != ignore) {
 
294
        ignoreSystemExclusiveEvents = ignore;
 
295
        updateEventFilter();
 
296
        emit ignoreSystemExclusiveEventsChanged(ignore);
 
297
    }
 
298
}
 
299
 
 
300
void
 
301
Engine::setIgnoreTimeEvents(bool ignore)
 
302
{
 
303
    if (ignoreTimeEvents != ignore) {
 
304
        ignoreTimeEvents = ignore;
 
305
        updateEventFilter();
 
306
        emit ignoreTimeEventsChanged(ignore);
 
307
    }
 
308
}
 
309
 
 
310
void
 
311
Engine::setInputPort(int index)
 
312
{
 
313
    assert((index >= -1) && (index < inputPortNames.count()));
 
314
    if (inputPort != index) {
 
315
 
 
316
        // Close the currently open input port.
 
317
        if (inputPort != -1) {
 
318
            try {
 
319
                input->closePort();
 
320
            } catch (RtError &e) {
 
321
                qWarning() << e.what();
 
322
            }
 
323
            inputPort = -1;
 
324
            emit inputPortChanged(-1);
 
325
        }
 
326
 
 
327
        // Open the new input port.
 
328
        if (index != -1) {
 
329
            try {
 
330
                if (virtualPortsAdded &&
 
331
                    (index == (inputPortNames.count() - 1))) {
 
332
                    input->openVirtualPort("MIDI Input");
 
333
                } else {
 
334
                    input->openPort(index, "MIDI Input");
 
335
                }
 
336
            } catch (RtError &e) {
 
337
                throw Error(e.what());
 
338
            }
 
339
            inputPort = index;
 
340
            updateEventFilter();
 
341
            emit inputPortChanged(index);
 
342
        }
 
343
    }
 
344
}
 
345
 
 
346
void
 
347
Engine::setOutputPort(int index)
 
348
{
 
349
    assert((index >= -1) && (index < outputPortNames.count()));
 
350
    if (outputPort != index) {
 
351
 
 
352
        // Close the currently open output port.
 
353
        if (outputPort != -1) {
 
354
            try {
 
355
                output->closePort();
 
356
            } catch (RtError &e) {
 
357
                qWarning() << e.what();
 
358
            }
 
359
            outputPort = -1;
 
360
            emit outputPortChanged(-1);
 
361
        }
 
362
 
 
363
        // Open the new output port.
 
364
        if (index != -1) {
 
365
            try {
 
366
                if (virtualPortsAdded &&
 
367
                    (index == (outputPortNames.count() - 1))) {
 
368
                    output->openVirtualPort("MIDI Output");
 
369
                } else {
 
370
                    output->openPort(index, "MIDI Output");
 
371
                }
 
372
            } catch (RtError &e) {
 
373
                throw Error(e.what());
 
374
            }
 
375
            outputPort = index;
 
376
            emit outputPortChanged(index);
 
377
        }
 
378
    }
 
379
}
 
380
 
 
381
void
 
382
Engine::updateEventFilter()
 
383
{
 
384
    if (inputPort != -1) {
 
385
        input->ignoreTypes(ignoreSystemExclusiveEvents, ignoreTimeEvents,
 
386
                           ignoreActiveSensingEvents);
 
387
    }
 
388
}