1 /*************************************************************************** 2 * * 3 * LinuxSampler - modular, streaming capable sampler * 4 * * 5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * 6 * Copyright (C) 2005 - 2016 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 ParameterActive()35 MidiInputDevice::ParameterActive::ParameterActive() : DeviceCreationParameterBool() { 36 InitWithDefault(); 37 } 38 ParameterActive(String active)39 MidiInputDevice::ParameterActive::ParameterActive(String active) : DeviceCreationParameterBool(active) { 40 } 41 Description()42 String MidiInputDevice::ParameterActive::Description() { 43 return "Enable / disable device"; 44 } 45 Fix()46 bool MidiInputDevice::ParameterActive::Fix() { 47 return false; 48 } 49 Mandatory()50 bool MidiInputDevice::ParameterActive::Mandatory() { 51 return false; 52 } 53 DependsAsParameters()54 std::map<String,DeviceCreationParameter*> MidiInputDevice::ParameterActive::DependsAsParameters() { 55 return std::map<String,DeviceCreationParameter*>(); 56 } 57 DefaultAsBool(std::map<String,String> Parameters)58 optional<bool> MidiInputDevice::ParameterActive::DefaultAsBool(std::map<String,String> Parameters) { 59 return true; 60 } 61 OnSetValue(bool b)62 void MidiInputDevice::ParameterActive::OnSetValue(bool b) throw (Exception) { 63 if (b) ((MidiInputDevice*)pDevice)->Listen(); 64 else ((MidiInputDevice*)pDevice)->StopListen(); 65 } 66 Name()67 String MidiInputDevice::ParameterActive::Name() { 68 return "ACTIVE"; 69 } 70 71 72 73 // *************** ParameterPorts *************** 74 // * 75 ParameterPorts()76 MidiInputDevice::ParameterPorts::ParameterPorts() : DeviceCreationParameterInt() { 77 InitWithDefault(); 78 } 79 ParameterPorts(String val)80 MidiInputDevice::ParameterPorts::ParameterPorts(String val) : DeviceCreationParameterInt(val) { 81 } 82 Description()83 String MidiInputDevice::ParameterPorts::Description() { 84 return "Number of ports"; 85 } 86 Fix()87 bool MidiInputDevice::ParameterPorts::Fix() { 88 return false; 89 } 90 Mandatory()91 bool MidiInputDevice::ParameterPorts::Mandatory() { 92 return false; 93 } 94 DependsAsParameters()95 std::map<String,DeviceCreationParameter*> MidiInputDevice::ParameterPorts::DependsAsParameters() { 96 return std::map<String,DeviceCreationParameter*>(); 97 } 98 DefaultAsInt(std::map<String,String> Parameters)99 optional<int> MidiInputDevice::ParameterPorts::DefaultAsInt(std::map<String,String> Parameters) { 100 return 1; 101 } 102 RangeMinAsInt(std::map<String,String> Parameters)103 optional<int> MidiInputDevice::ParameterPorts::RangeMinAsInt(std::map<String,String> Parameters) { 104 return 1; 105 } 106 RangeMaxAsInt(std::map<String,String> Parameters)107 optional<int> MidiInputDevice::ParameterPorts::RangeMaxAsInt(std::map<String,String> Parameters) { 108 return optional<int>::nothing; 109 } 110 PossibilitiesAsInt(std::map<String,String> Parameters)111 std::vector<int> MidiInputDevice::ParameterPorts::PossibilitiesAsInt(std::map<String,String> Parameters) { 112 return std::vector<int>(); 113 } 114 OnSetValue(int i)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 Name()138 String MidiInputDevice::ParameterPorts::Name() { 139 return "PORTS"; 140 } 141 142 143 144 // *************** MidiInputDevice *************** 145 // * 146 MidiInputDevice(std::map<String,DeviceCreationParameter * > DriverParameters,void * pSampler)147 MidiInputDevice::MidiInputDevice(std::map<String,DeviceCreationParameter*> DriverParameters, void* pSampler) { 148 this->Parameters = DriverParameters; 149 this->pSampler = pSampler; 150 } 151 ~MidiInputDevice()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 GetPort(uint iPort)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 PortCount()166 uint MidiInputDevice::PortCount() { 167 return (uint) Ports.size(); 168 } 169 DeviceParameters()170 std::map<String,DeviceCreationParameter*> MidiInputDevice::DeviceParameters() { 171 return Parameters; 172 } 173 MidiInputDeviceID()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 AddMidiPortCountListener(MidiPortCountListener * l)184 void MidiInputDevice::AddMidiPortCountListener(MidiPortCountListener* l) { 185 portCountListeners.AddListener(l); 186 } 187 RemoveMidiPortCountListener(MidiPortCountListener * l)188 void MidiInputDevice::RemoveMidiPortCountListener(MidiPortCountListener* l) { 189 portCountListeners.RemoveListener(l); 190 } 191 fireMidiPortCountChanged(int NewCount)192 void MidiInputDevice::fireMidiPortCountChanged(int NewCount) { 193 for (int i = 0; i < portCountListeners.GetListenerCount(); i++) { 194 portCountListeners.GetListener(i)->MidiPortCountChanged(NewCount); 195 } 196 } 197 fireMidiPortToBeRemoved(MidiInputPort * pPort)198 void MidiInputDevice::fireMidiPortToBeRemoved(MidiInputPort* pPort) { 199 for (int i = 0; i < portCountListeners.GetListenerCount(); i++) { 200 portCountListeners.GetListener(i)->MidiPortToBeRemoved(pPort); 201 } 202 } 203 fireMidiPortAdded(MidiInputPort * pPort)204 void MidiInputDevice::fireMidiPortAdded(MidiInputPort* pPort) { 205 for (int i = 0; i < portCountListeners.GetListenerCount(); i++) { 206 portCountListeners.GetListener(i)->MidiPortAdded(pPort); 207 } 208 } 209 AcquirePorts(uint newPorts)210 void MidiInputDevice::AcquirePorts(uint newPorts) { 211 //FIXME: hooo, this looks scary, no synchronization AT ALL yet! 212 int diff = int(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((int)Ports.size()); 234 } 235 236 } // namespace LinuxSampler 237