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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2500 - (show annotations) (download)
Fri Jan 10 12:20:05 2014 UTC (10 years, 2 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 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005 - 2014 Christian Schoenebeck *
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 "MidiInputDevice.h"
25
26 #include "../../common/global_private.h"
27 #include "../../Sampler.h"
28 #include "MidiInputDeviceFactory.h"
29
30 namespace LinuxSampler {
31
32 // *************** ParameterActive ***************
33 // *
34
35 MidiInputDevice::ParameterActive::ParameterActive() : DeviceCreationParameterBool() {
36 InitWithDefault();
37 }
38
39 MidiInputDevice::ParameterActive::ParameterActive(String active) : DeviceCreationParameterBool(active) {
40 }
41
42 String MidiInputDevice::ParameterActive::Description() {
43 return "Enable / disable device";
44 }
45
46 bool MidiInputDevice::ParameterActive::Fix() {
47 return false;
48 }
49
50 bool MidiInputDevice::ParameterActive::Mandatory() {
51 return false;
52 }
53
54 std::map<String,DeviceCreationParameter*> MidiInputDevice::ParameterActive::DependsAsParameters() {
55 return std::map<String,DeviceCreationParameter*>();
56 }
57
58 optional<bool> MidiInputDevice::ParameterActive::DefaultAsBool(std::map<String,String> Parameters) {
59 return true;
60 }
61
62 void MidiInputDevice::ParameterActive::OnSetValue(bool b) throw (Exception) {
63 if (b) ((MidiInputDevice*)pDevice)->Listen();
64 else ((MidiInputDevice*)pDevice)->StopListen();
65 }
66
67 String MidiInputDevice::ParameterActive::Name() {
68 return "ACTIVE";
69 }
70
71
72
73 // *************** ParameterPorts ***************
74 // *
75
76 MidiInputDevice::ParameterPorts::ParameterPorts() : DeviceCreationParameterInt() {
77 InitWithDefault();
78 }
79
80 MidiInputDevice::ParameterPorts::ParameterPorts(String val) : DeviceCreationParameterInt(val) {
81 }
82
83 String MidiInputDevice::ParameterPorts::Description() {
84 return "Number of ports";
85 }
86
87 bool MidiInputDevice::ParameterPorts::Fix() {
88 return false;
89 }
90
91 bool MidiInputDevice::ParameterPorts::Mandatory() {
92 return false;
93 }
94
95 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 return 1;
101 }
102
103 optional<int> MidiInputDevice::ParameterPorts::RangeMinAsInt(std::map<String,String> Parameters) {
104 return 1;
105 }
106
107 optional<int> MidiInputDevice::ParameterPorts::RangeMaxAsInt(std::map<String,String> Parameters) {
108 return optional<int>::nothing;
109 }
110
111 std::vector<int> MidiInputDevice::ParameterPorts::PossibilitiesAsInt(std::map<String,String> Parameters) {
112 return std::vector<int>();
113 }
114
115 void MidiInputDevice::ParameterPorts::OnSetValue(int i) throw (Exception) {
116 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 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 }
133 }
134
135 ((MidiInputDevice*)pDevice)->AcquirePorts(i);
136 }
137
138 String MidiInputDevice::ParameterPorts::Name() {
139 return "PORTS";
140 }
141
142
143
144 // *************** MidiInputDevice ***************
145 // *
146
147 MidiInputDevice::MidiInputDevice(std::map<String,DeviceCreationParameter*> DriverParameters, void* pSampler) {
148 this->Parameters = DriverParameters;
149 this->pSampler = pSampler;
150 }
151
152 MidiInputDevice::~MidiInputDevice() {
153 std::map<String,DeviceCreationParameter*>::iterator iter = Parameters.begin();
154 while (iter != Parameters.end()) {
155 delete iter->second;
156 iter++;
157 }
158 Parameters.clear();
159 }
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 uint MidiInputDevice::PortCount() {
167 return Ports.size();
168 }
169
170 std::map<String,DeviceCreationParameter*> MidiInputDevice::DeviceParameters() {
171 return Parameters;
172 }
173
174 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 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 void MidiInputDevice::AcquirePorts(uint newPorts) {
211 //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
216 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 }
235
236 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC