~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to libs/surfaces/generic_midi/midiinvokable.cc

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 2009 Paul Davis
 
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
#include <cstring>
 
20
 
 
21
#include "midi++/port.h"
 
22
 
 
23
#include "midifunction.h"
 
24
#include "generic_midi_control_protocol.h"
 
25
 
 
26
using namespace MIDI;
 
27
 
 
28
MIDIInvokable::MIDIInvokable (MIDI::Port& p)
 
29
        : _port (p)
 
30
{
 
31
        data_size = 0;
 
32
        data = 0;
 
33
}
 
34
 
 
35
MIDIInvokable::~MIDIInvokable ()
 
36
{
 
37
        delete [] data;
 
38
}
 
39
 
 
40
int
 
41
MIDIInvokable::init (GenericMidiControlProtocol& ui, const std::string& name, MIDI::byte* msg_data, size_t data_sz)
 
42
{
 
43
        _ui = &ui;
 
44
        _invokable_name = name;
 
45
 
 
46
        if (data_sz) {
 
47
                /* we take ownership of the sysex data */
 
48
                data = msg_data;
 
49
                data_size = data_sz;
 
50
        }
 
51
 
 
52
        return 0;
 
53
}
 
54
 
 
55
void
 
56
MIDIInvokable::midi_sense_note_on (Parser &p, EventTwoBytes *tb)
 
57
{
 
58
        midi_sense_note (p, tb, true);
 
59
}
 
60
 
 
61
void
 
62
MIDIInvokable::midi_sense_note_off (Parser &p, EventTwoBytes *tb)
 
63
{
 
64
        midi_sense_note (p, tb, false);
 
65
}
 
66
 
 
67
void
 
68
MIDIInvokable::midi_sense_note (Parser &, EventTwoBytes *msg, bool /* is_on */)
 
69
{
 
70
        if (msg->note_number == control_additional) {
 
71
                execute ();
 
72
        }
 
73
}
 
74
 
 
75
void
 
76
MIDIInvokable::midi_sense_controller (Parser &, EventTwoBytes *msg)
 
77
{
 
78
        if (control_additional == msg->controller_number) {
 
79
                execute ();
 
80
        }
 
81
}
 
82
 
 
83
void
 
84
MIDIInvokable::midi_sense_program_change (Parser &, byte msg)
 
85
{
 
86
        if (msg == control_additional) {
 
87
                execute ();
 
88
        }
 
89
}
 
90
 
 
91
void
 
92
MIDIInvokable::midi_sense_sysex (Parser &, byte* msg, size_t sz)
 
93
{
 
94
        if (sz != data_size) {
 
95
                return;
 
96
        }
 
97
 
 
98
        if (memcmp (msg, data, data_size) != 0) {
 
99
                return;
 
100
        }
 
101
 
 
102
        execute ();
 
103
}
 
104
 
 
105
void
 
106
MIDIInvokable::midi_sense_any (Parser &, byte* msg, size_t sz)
 
107
{
 
108
        if (sz != data_size) {
 
109
                return;
 
110
        }
 
111
 
 
112
        if (memcmp (msg, data, data_size) != 0) {
 
113
                return;
 
114
        }
 
115
 
 
116
        execute ();
 
117
}
 
118
 
 
119
 
 
120
void
 
121
MIDIInvokable::bind_midi (channel_t chn, eventType ev, MIDI::byte additional)
 
122
{
 
123
        midi_sense_connection[0].disconnect ();
 
124
        midi_sense_connection[1].disconnect ();
 
125
 
 
126
        control_type = ev;
 
127
        control_channel = chn;
 
128
        control_additional = additional;
 
129
 
 
130
        if (_port.parser() == 0) {
 
131
                return;
 
132
        }
 
133
 
 
134
        Parser& p = *_port.parser();
 
135
 
 
136
        int chn_i = chn;
 
137
 
 
138
        /* incoming MIDI is parsed by Ardour' MidiUI event loop/thread, and we want our handlers to execute in that context, so we use
 
139
           Signal::connect_same_thread() here.
 
140
        */
 
141
 
 
142
        switch (ev) {
 
143
        case MIDI::off:
 
144
                p.channel_note_off[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_note_off, this, _1, _2));
 
145
                break;
 
146
 
 
147
        case MIDI::on:
 
148
                p.channel_note_on[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_note_on, this, _1, _2));
 
149
                break;
 
150
                
 
151
        case MIDI::controller:
 
152
                p.channel_controller[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_controller, this, _1, _2));
 
153
                break;
 
154
 
 
155
        case MIDI::program:
 
156
                p.channel_program_change[chn_i].connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_program_change, this, _1, _2));
 
157
                break;
 
158
 
 
159
        case MIDI::sysex:
 
160
                p.sysex.connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_sysex, this, _1, _2, _3));
 
161
                break;
 
162
 
 
163
        case MIDI::any:
 
164
                p.any.connect_same_thread (midi_sense_connection[0], boost::bind (&MIDIInvokable::midi_sense_any, this, _1, _2, _3));
 
165
                break;
 
166
 
 
167
        default:
 
168
                break;
 
169
        }
 
170
}
 
171