/[svn]/linuxsampler/trunk/src/drivers/midi/MidiInputDeviceMidiShare.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/drivers/midi/MidiInputDeviceMidiShare.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2559 - (show annotations) (download)
Sun May 18 17:38:25 2014 UTC (9 years, 11 months ago) by schoenebeck
File size: 6857 byte(s)
* Aftertouch: extended API to explicitly handle channel pressure and
  polyphonic key pressure events (so far polyphonic pressure was not
  supported at all, and channel pressure was rerouted as CC128 but not
  used so far).
* Gig Engine: Fixed support for 'aftertouch' attenuation controller.
* Bumped version (1.0.0.svn39).

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2004 Grame *
7 * Copyright (C) 2014 Christian Schoenebeck *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the Free Software *
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
22 * MA 02111-1307 USA *
23 ***************************************************************************/
24
25 #include "MidiInputDeviceMidiShare.h"
26
27 namespace LinuxSampler {
28
29 #define MSHSlotName "LinuxSampler"
30 #define MSHDriverName "LinuxSampler"
31
32 #define MidiShareDrvRef 127
33
34 /**
35 * Create MidiShare input device for LinuxSampler.
36 *
37 * @param AutoConnectPortID - (optional) Alsa client and port ID of a
38 * MIDI source we should auto connect to
39 * (e.g. "64:0")
40 * @throws MidiInputException if initialization failed
41 */
42 MidiInputDeviceMidiShare::MidiInputDeviceMidiShare(char* AutoConnectPortID) : MidiInputDevice(MidiInputDevice::type_midishare)
43 {
44 if (!MidiShare())
45 throw MidiInputException("MidiShare not installed");
46
47 #if defined(MIDISHARE_DRIVER)
48 OpenDriver();
49 #else
50 OpenAppl();
51 #endif
52
53 hMidiFilter = MidiNewFilter();
54
55 if (hMidiFilter == 0) {
56 MidiClose(hRefnum);
57 throw MidiInputException("MidiShare filter can not be allocated");
58 }
59
60 for (int i = 0 ; i < 256; i++) {
61 MidiAcceptPort(hMidiFilter, i, 1); /* accept all ports */
62 MidiAcceptType(hMidiFilter, i, 0); /* reject all types */
63 }
64
65 for (int i = 0 ; i < 16; i++) {
66 MidiAcceptChan(hMidiFilter, i, 1); /* accept all chan */
67 }
68 /* accept only the following types */
69 MidiAcceptType(hMidiFilter, typeNote, 1);
70 MidiAcceptType(hMidiFilter, typeKeyOn, 1);
71 MidiAcceptType(hMidiFilter, typeKeyOff, 1);
72 MidiAcceptType(hMidiFilter, typeCtrlChange, 1);
73 MidiAcceptType(hMidiFilter, typeProgChange, 1);
74 MidiAcceptType(hMidiFilter, typePitchWheel, 1);
75 MidiAcceptType(hMidiFilter, typeChanPress, 1);
76 MidiAcceptType(hMidiFilter, typeKeyPress, 1);
77
78 /* set the filter */
79 MidiSetFilter(hRefnum, hMidiFilter);
80
81 MidiSetRcvAlarm(hRefnum,ReceiveEvents);
82 MidiSetApplAlarm(hRefnum,ApplAlarm);
83 MidiSetInfo(hRefnum,this);
84 MidiConnect(0,hRefnum,true);
85 }
86
87
88 MidiInputDeviceMidiShare::~MidiInputDeviceMidiShare()
89 {
90 #if defined(MIDISHARE_DRIVER)
91 CloseDriver();
92 #else
93 CloseAppl();
94 #endif
95 MidiFreeFilter(hMidiFilter);
96 }
97
98 void MidiInputDeviceMidiShare::OpenAppl()
99 {
100 hRefnum = MidiOpen(MSHDriverName);
101 if (hRefnum < 0) {
102 throw MidiInputException("MidiShare client can not be opened");
103 }
104 MidiSetRcvAlarm(hRefnum,ReceiveEvents);
105 MidiSetApplAlarm(hRefnum,ApplAlarm);
106 }
107
108 void MidiInputDeviceMidiShare::CloseAppl()
109 {
110 MidiClose(hRefnum);
111 }
112
113 void MidiInputDeviceMidiShare::OpenDriver()
114 {
115 /* gcc wanted me to use {0,0} to initialize the reserved[2] fields */
116 TDriverInfos infos = { MSHDriverName, 100, 0, { 0, 0 } };
117 TDriverOperation op = { WakeUp, Sleep, { 0, 0, 0 } };
118 hRefnum = MidiRegisterDriver(&infos, &op);
119 if (hRefnum < 0) {
120 throw MidiInputException("MidiShare driver can not be opened");
121 }
122 hSlotRef = MidiAddSlot(hRefnum,MSHSlotName,MidiOutputSlot);
123 MidiSetRcvAlarm(hRefnum,ReceiveEvents);
124 }
125
126 void MidiInputDeviceMidiShare::CloseDriver()
127 {
128 MidiUnregisterDriver(hRefnum);
129 }
130
131 void MidiInputDeviceMidiShare::WakeUp(short r)
132 {
133 MidiConnect(MidiShareDrvRef, r, true);
134 MidiConnect(r, MidiShareDrvRef, true);
135 }
136
137 void MidiInputDeviceMidiShare::Sleep(short r){}
138
139
140 void MidiInputDeviceMidiShare::SetInputPort(const char * MidiSource)
141 {
142
143 }
144
145 void MidiInputDeviceMidiShare::ApplAlarm(short ref, long code)
146 {
147
148 }
149
150 void MidiInputDeviceMidiShare::KeyOffTask(long date, short ref, long a1, long a2, long a3)
151 {
152 MidiInputDeviceMidiShare* driver = (MidiInputDeviceMidiShare*)MidiGetInfo(ref);
153 MidiEvPtr ev =(MidiEvPtr)a1;
154 driver->DispatchNoteOn(Pitch(ev),Vel(ev),Chan(ev));
155 MidiFreeEv(ev);
156 }
157
158 void MidiInputDeviceMidiShare::ReceiveEvents(short ref)
159 {
160 MidiInputDeviceMidiShare* driver = (MidiInputDeviceMidiShare*)MidiGetInfo(ref);
161 MidiEvPtr ev;
162
163 while ((ev = MidiGetEv(ref)))
164
165 switch(EvType(ev)) {
166
167 case typeCtrlChange:
168 if (MidiGetField(ev,0) == 0)
169 driver->DispatchBankSelectMsb(MidiGetField(ev,0),Chan(ev));
170 else if (MidiGetField(ev,0) == 32)
171 driver->DispatchBankSelectLsb(MidiGetField(ev,0),Chan(ev));
172 driver->DispatchControlChange(MidiGetField(ev,0),MidiGetField(ev,0),Chan(ev));
173 MidiFreeEv(ev);
174 break;
175
176 case typePitchWheel:
177 driver->DispatchPitchbend(((MidiGetField(ev,0)+(MidiGetField(ev,1) << 7)) - 8192),Chan(ev));
178 MidiFreeEv(ev);
179 break;
180
181 case typeChanPress:
182 driver->DispatchChannelPressure(MidiGetField(ev,0),Chan(ev));
183 MidiFreeEv(ev);
184 break;
185
186 case typeKeyPress:
187 driver->DispatchPolyphonicKeyPressure(Pitch(ev),Vel(ev),Chan(ev));
188 MidiFreeEv(ev);
189 break;
190
191 case typeNote:
192 driver->DispatchNoteOn(Pitch(ev),Vel(ev),Chan(ev));
193 MidiTask(KeyOffTask,Date(ev)+Dur(ev),ref,(long)ev,0,0);
194 break;
195
196 case typeKeyOn:
197 if (Vel(ev) > 0)
198 driver->DispatchNoteOn(Pitch(ev),Vel(ev),Chan(ev));
199 else
200 driver->DispatchNoteOff(Pitch(ev),Vel(ev),Chan(ev));
201 MidiFreeEv(ev);
202 break;
203
204 case typeKeyOff:
205 driver->DispatchNoteOff(Pitch(ev),Vel(ev),Chan(ev));
206 MidiFreeEv(ev);
207 break;
208 }
209 }
210
211
212 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC