/[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 947 - (show annotations) (download)
Mon Nov 27 21:34:55 2006 UTC (17 years, 4 months ago) by schoenebeck
File size: 6447 byte(s)
* implemented MIDI instrument mapping according to latest LSCP draft

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

  ViewVC Help
Powered by ViewVC