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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2559 - (hide 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 schoenebeck 201 /***************************************************************************
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 schoenebeck 2559 * Copyright (C) 2014 Christian Schoenebeck *
8 schoenebeck 201 * *
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 schoenebeck 2559 MidiAcceptType(hMidiFilter, typeProgChange, 1);
74 schoenebeck 201 MidiAcceptType(hMidiFilter, typePitchWheel, 1);
75 schoenebeck 2559 MidiAcceptType(hMidiFilter, typeChanPress, 1);
76     MidiAcceptType(hMidiFilter, typeKeyPress, 1);
77 schoenebeck 201
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 schoenebeck 947 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 schoenebeck 1715 driver->DispatchControlChange(MidiGetField(ev,0),MidiGetField(ev,0),Chan(ev));
173 schoenebeck 201 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 schoenebeck 2559
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 schoenebeck 201 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