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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2500 - (hide annotations) (download)
Fri Jan 10 12:20:05 2014 UTC (10 years, 3 months ago) by schoenebeck
File size: 8757 byte(s)
* Added support for multiple MIDI input ports per sampler channel (added
  various new C++ API methods for this new feature/design, old C++ API
  methods are now marked as deprecated but should still provide full
  behavior backward compatibility).
* LSCP Network interface: Added the following new LSCP commands for the new
  feature mentioned above: "ADD CHANNEL MIDI_INPUT",
  "REMOVE CHANNEL MIDI_INPUT" and "LIST CHANNEL MIDI_INPUTS". As with the
  C++ API changes, the old LSCP commands for MIDI input management are now
  marked as deprecated, but are still there and should provide full behavior
  backward compatibility.
* New LSCP specification document (LSCP v1.6).
* AbstractEngine::GSCheckSum(): don't allocate memory on the stack (was
  unsafe and caused compilation error with old clang 2.x).
* Bumped version (1.0.0.svn25).

1 schoenebeck 201 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 2500 * Copyright (C) 2005 - 2014 Christian Schoenebeck *
7 schoenebeck 201 * *
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 "MidiInputDevice.h"
25    
26 schoenebeck 1424 #include "../../common/global_private.h"
27 iliev 1295 #include "../../Sampler.h"
28 schoenebeck 2500 #include "MidiInputDeviceFactory.h"
29 iliev 1295
30 schoenebeck 201 namespace LinuxSampler {
31    
32 schoenebeck 221 // *************** ParameterActive ***************
33     // *
34    
35     MidiInputDevice::ParameterActive::ParameterActive() : DeviceCreationParameterBool() {
36     InitWithDefault();
37 schoenebeck 201 }
38    
39 schoenebeck 221 MidiInputDevice::ParameterActive::ParameterActive(String active) : DeviceCreationParameterBool(active) {
40 schoenebeck 201 }
41    
42 schoenebeck 221 String MidiInputDevice::ParameterActive::Description() {
43     return "Enable / disable device";
44 schoenebeck 201 }
45    
46 schoenebeck 221 bool MidiInputDevice::ParameterActive::Fix() {
47     return false;
48 schoenebeck 201 }
49    
50 schoenebeck 221 bool MidiInputDevice::ParameterActive::Mandatory() {
51     return false;
52 schoenebeck 201 }
53    
54 schoenebeck 221 std::map<String,DeviceCreationParameter*> MidiInputDevice::ParameterActive::DependsAsParameters() {
55     return std::map<String,DeviceCreationParameter*>();
56 schoenebeck 201 }
57    
58 schoenebeck 221 optional<bool> MidiInputDevice::ParameterActive::DefaultAsBool(std::map<String,String> Parameters) {
59     return true;
60 schoenebeck 201 }
61    
62 schoenebeck 880 void MidiInputDevice::ParameterActive::OnSetValue(bool b) throw (Exception) {
63 schoenebeck 221 if (b) ((MidiInputDevice*)pDevice)->Listen();
64     else ((MidiInputDevice*)pDevice)->StopListen();
65 schoenebeck 201 }
66    
67 schoenebeck 221 String MidiInputDevice::ParameterActive::Name() {
68     return "ACTIVE";
69 schoenebeck 201 }
70    
71 schoenebeck 221
72    
73     // *************** ParameterPorts ***************
74     // *
75    
76     MidiInputDevice::ParameterPorts::ParameterPorts() : DeviceCreationParameterInt() {
77     InitWithDefault();
78 schoenebeck 201 }
79    
80 schoenebeck 221 MidiInputDevice::ParameterPorts::ParameterPorts(String val) : DeviceCreationParameterInt(val) {
81 schoenebeck 201 }
82    
83 schoenebeck 221 String MidiInputDevice::ParameterPorts::Description() {
84     return "Number of ports";
85 schoenebeck 201 }
86    
87 schoenebeck 221 bool MidiInputDevice::ParameterPorts::Fix() {
88     return false;
89 schoenebeck 201 }
90    
91 schoenebeck 221 bool MidiInputDevice::ParameterPorts::Mandatory() {
92     return false;
93 schoenebeck 201 }
94    
95 schoenebeck 221 std::map<String,DeviceCreationParameter*> MidiInputDevice::ParameterPorts::DependsAsParameters() {
96     return std::map<String,DeviceCreationParameter*>();
97     }
98    
99     optional<int> MidiInputDevice::ParameterPorts::DefaultAsInt(std::map<String,String> Parameters) {
100 schoenebeck 226 return 1;
101 schoenebeck 221 }
102    
103     optional<int> MidiInputDevice::ParameterPorts::RangeMinAsInt(std::map<String,String> Parameters) {
104 iliev 1305 return 1;
105 schoenebeck 221 }
106    
107     optional<int> MidiInputDevice::ParameterPorts::RangeMaxAsInt(std::map<String,String> Parameters) {
108 schoenebeck 2140 return optional<int>::nothing;
109 schoenebeck 221 }
110    
111     std::vector<int> MidiInputDevice::ParameterPorts::PossibilitiesAsInt(std::map<String,String> Parameters) {
112     return std::vector<int>();
113     }
114    
115 schoenebeck 880 void MidiInputDevice::ParameterPorts::OnSetValue(int i) throw (Exception) {
116 iliev 1295 MidiInputDevice* dev = static_cast<MidiInputDevice*> (pDevice);
117     Sampler* s = static_cast<Sampler*> (dev->pSampler);
118     std::map<uint, SamplerChannel*> channels = s->GetSamplerChannels();
119     std::map<uint, SamplerChannel*>::iterator iter = channels.begin();
120     for (; iter != channels.end(); iter++) {
121     SamplerChannel* chn = iter->second;
122 schoenebeck 2500 std::vector<MidiInputPort*> vPorts = chn->GetMidiInputPorts();
123     for (int k = 0; k < vPorts.size(); ++k) {
124     if (vPorts[k]->GetDevice() != pDevice)
125     continue;
126     int port = vPorts[k]->GetPortNumber();
127     if (port >= i) {
128     String err = "Sampler channel " + ToString(iter->first);
129     err += " is still connected to MIDI port " + ToString(port);
130     throw Exception(err);
131     }
132 iliev 1295 }
133     }
134 schoenebeck 1695
135 schoenebeck 221 ((MidiInputDevice*)pDevice)->AcquirePorts(i);
136     }
137    
138     String MidiInputDevice::ParameterPorts::Name() {
139     return "PORTS";
140     }
141    
142    
143    
144     // *************** MidiInputDevice ***************
145     // *
146    
147 schoenebeck 551 MidiInputDevice::MidiInputDevice(std::map<String,DeviceCreationParameter*> DriverParameters, void* pSampler) {
148     this->Parameters = DriverParameters;
149     this->pSampler = pSampler;
150 schoenebeck 221 }
151    
152     MidiInputDevice::~MidiInputDevice() {
153 persson 835 std::map<String,DeviceCreationParameter*>::iterator iter = Parameters.begin();
154     while (iter != Parameters.end()) {
155     delete iter->second;
156     iter++;
157     }
158     Parameters.clear();
159 schoenebeck 221 }
160    
161     MidiInputPort* MidiInputDevice::GetPort(uint iPort) throw (MidiInputException) {
162     if (iPort >= Ports.size()) throw MidiInputException("There is no port " + ToString(iPort));
163     return Ports[iPort];
164     }
165    
166 schoenebeck 1695 uint MidiInputDevice::PortCount() {
167     return Ports.size();
168     }
169    
170 schoenebeck 221 std::map<String,DeviceCreationParameter*> MidiInputDevice::DeviceParameters() {
171 schoenebeck 1695 return Parameters;
172 schoenebeck 221 }
173    
174 schoenebeck 2500 int MidiInputDevice::MidiInputDeviceID() {
175     std::map<uint, MidiInputDevice*> mDevices = MidiInputDeviceFactory::Devices();
176     for (std::map<uint, MidiInputDevice*>::const_iterator it = mDevices.begin(); it != mDevices.end(); ++it) {
177     if (it->second == this) {
178     return it->first;
179     }
180     }
181     return -1;
182     }
183    
184 schoenebeck 1695 void MidiInputDevice::AddMidiPortCountListener(MidiPortCountListener* l) {
185     portCountListeners.AddListener(l);
186     }
187    
188     void MidiInputDevice::RemoveMidiPortCountListener(MidiPortCountListener* l) {
189     portCountListeners.RemoveListener(l);
190     }
191    
192     void MidiInputDevice::fireMidiPortCountChanged(int NewCount) {
193     for (int i = 0; i < portCountListeners.GetListenerCount(); i++) {
194     portCountListeners.GetListener(i)->MidiPortCountChanged(NewCount);
195     }
196     }
197    
198     void MidiInputDevice::fireMidiPortToBeRemoved(MidiInputPort* pPort) {
199     for (int i = 0; i < portCountListeners.GetListenerCount(); i++) {
200     portCountListeners.GetListener(i)->MidiPortToBeRemoved(pPort);
201     }
202     }
203    
204     void MidiInputDevice::fireMidiPortAdded(MidiInputPort* pPort) {
205     for (int i = 0; i < portCountListeners.GetListenerCount(); i++) {
206     portCountListeners.GetListener(i)->MidiPortAdded(pPort);
207     }
208     }
209    
210 schoenebeck 201 void MidiInputDevice::AcquirePorts(uint newPorts) {
211 schoenebeck 1695 //FIXME: hooo, this looks scary, no synchronization AT ALL yet!
212     int diff = this->Ports.size() - newPorts;
213     if (!diff)
214     return; // number of ports matches already, nothing to do
215 schoenebeck 201
216 schoenebeck 1695 while (diff != 0) {
217     if (diff > 0) { // we've got too many ports, remove one
218     std::map<int,MidiInputPort*>::iterator portsIter = Ports.end();
219     --portsIter;
220    
221     fireMidiPortToBeRemoved(portsIter->second);
222     delete portsIter->second;
223     Ports.erase(portsIter);
224     diff--;
225     }
226     if (diff < 0) { // we don't have enough ports, create one
227     MidiInputPort* midiPort = this->CreateMidiPort();
228     Ports[midiPort->portNumber] = midiPort;
229     diff++;
230     fireMidiPortAdded(midiPort);
231     }
232     }
233     fireMidiPortCountChanged(Ports.size());
234 schoenebeck 201 }
235    
236     } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC