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

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     * *
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 schoenebeck 947 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 schoenebeck 201 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