/[svn]/linuxsampler/trunk/src/Sampler.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/Sampler.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 159 - (show annotations) (download)
Tue Jun 29 21:11:50 2004 UTC (19 years, 9 months ago) by capela
File size: 12434 byte(s)
* Unconsolidaded MIDI input related channel commands are back:
  SET CHANNEL MIDI_INPUT_DEVICE <chan> <midi-device>
  SET CHANNEL MIDI_INPUT_PORT <chan> <midi-port>
  SET CHANNEL MIDI_INPUT_CHANNEL <chan> <midi-chan>

* Still useful for compability with legacy clients, an almost
  deprecated command gets re-implemented:
  SET CHANNEL MIDI_INPUT_TYPE <chan> <midi-driver>

* Optional parameter list on MIDI input device creation fixed,
  but not quite fully effective yet:
  CREATE MIDI_INPUT_DEVICE <midi-driver> [<key>=<val>...]

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #include <sstream>
24
25 #include "Sampler.h"
26
27 #include "audiodriver/AudioOutputDeviceFactory.h"
28 #include "mididriver/MidiInputDeviceFactory.h"
29 #include "engines/gig/Engine.h"
30
31 namespace LinuxSampler {
32
33 // ******************************************************************
34 // * SamplerChannel
35
36 SamplerChannel::SamplerChannel(Sampler* pS) {
37 pSampler = pS;
38 pEngine = NULL;
39 pMidiInputDevice = NULL;
40 pAudioOutputDevice = NULL;
41 midiPort = 0;
42 midiChannel = MidiInputDevice::MidiInputPort::midi_chan_all;
43 iIndex = -1;
44 }
45
46 SamplerChannel::~SamplerChannel() {
47 if (pEngine) {
48 MidiInputDevice::MidiInputPort *pMidiInputPort = GetMidiInputDevicePort(this->midiPort);
49 if (pMidiInputPort) pMidiInputPort->Disconnect(pEngine);
50 if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(pEngine);
51 delete pEngine;
52 }
53 }
54
55 void SamplerChannel::LoadEngine(Engine::type_t EngineType) {
56 dmsg(2,("SamplerChannel: Loading engine..."));
57
58 // create new engine
59 Engine* pNewEngine = NULL;
60 switch (EngineType) {
61 case Engine::type_gig:
62 pNewEngine = new gig::Engine;
63 break;
64 default:
65 throw LinuxSamplerException("Unknown engine type");
66 }
67
68 // dereference midi input port.
69 MidiInputDevice::MidiInputPort *pMidiInputPort = GetMidiInputDevicePort(this->midiPort);
70 // disconnect old engine
71 if (pEngine) {
72 if (pMidiInputPort) pMidiInputPort->Disconnect(pEngine);
73 if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(pEngine);
74 delete pEngine;
75 }
76
77 // connect new engine
78 pEngine = pNewEngine;
79 if (pMidiInputPort) pMidiInputPort->Connect(pNewEngine, this->midiChannel);
80 if (pAudioOutputDevice) pAudioOutputDevice->Connect(pNewEngine);
81 dmsg(2,("OK\n"));
82 }
83
84 void SamplerChannel::SetAudioOutputDevice(AudioOutputDevice* pDevice) {
85 // disconnect old device
86 if (pAudioOutputDevice && pEngine) pAudioOutputDevice->Disconnect(pEngine);
87 // connect new device
88 pAudioOutputDevice = pDevice;
89 if (pEngine) pAudioOutputDevice->Connect(pEngine);
90 }
91
92 void SamplerChannel::SetMidiInputDevice(MidiInputDevice* pDevice) {
93 SetMidiInput(pDevice, this->midiPort, this->midiChannel);
94 }
95
96 void SamplerChannel::SetMidiInputPort(int MidiPort) {
97 SetMidiInput(pMidiInputDevice, MidiPort, this->midiChannel);
98 }
99
100 void SamplerChannel::SetMidiInputChannel(MidiInputDevice::MidiInputPort::midi_chan_t MidiChannel) {
101 SetMidiInput(pMidiInputDevice, this->midiPort, MidiChannel);
102 }
103
104 void SamplerChannel::SetMidiInput(MidiInputDevice* pDevice, int MidiPort, MidiInputDevice::MidiInputPort::midi_chan_t MidiChannel) {
105 // dereference old midi input port.
106 MidiInputDevice::MidiInputPort *pMidiInputPort = GetMidiInputDevicePort(this->midiPort);
107 // disconnect old device port
108 if (pMidiInputPort && pEngine) pMidiInputPort->Disconnect(pEngine);
109 // new device, port and channel
110 pMidiInputDevice = pDevice;
111 this->midiPort = MidiPort;
112 this->midiChannel = MidiChannel;
113 // connect new device port
114 pMidiInputPort = GetMidiInputDevicePort(this->midiPort);
115 if (pMidiInputPort && pEngine) pMidiInputPort->Connect(pEngine, MidiChannel);
116 // Ooops.
117 if (pMidiInputPort == NULL)
118 throw LinuxSamplerException("There is no MIDI input port with index " + ToString(MidiPort) + ".");
119 }
120
121 Engine* SamplerChannel::GetEngine() {
122 return pEngine;
123 }
124
125 MidiInputDevice::MidiInputPort::midi_chan_t SamplerChannel::GetMidiInputChannel() {
126 return this->midiChannel;
127 }
128
129 int SamplerChannel::GetMidiInputPort() {
130 MidiInputDevice::MidiInputPort *pMidiInputPort = GetMidiInputDevicePort(this->midiPort);
131 return (pMidiInputPort ? (int) pMidiInputPort->GetPortNumber() : -1);
132 }
133
134 AudioOutputDevice* SamplerChannel::GetAudioOutputDevice() {
135 return pAudioOutputDevice;
136 }
137
138 MidiInputDevice* SamplerChannel::GetMidiInputDevice() {
139 return pMidiInputDevice;
140 }
141
142 uint SamplerChannel::Index() {
143 if (iIndex >= 0) return iIndex;
144
145 std::vector<SamplerChannel*>::iterator iter = pSampler->vSamplerChannels.begin();
146 for (int i = 0; iter != pSampler->vSamplerChannels.end(); i++, iter++) {
147 if (*iter == this) {
148 iIndex = i;
149 return i;
150 }
151 }
152
153 throw LinuxSamplerException("SamplerChannel index not found");
154 }
155
156 MidiInputDevice::MidiInputPort* SamplerChannel::GetMidiInputDevicePort(int MidiPort) {
157 MidiInputDevice::MidiInputPort *pMidiInputPort = NULL;
158 if (pMidiInputDevice)
159 pMidiInputPort = pMidiInputDevice->GetPort(MidiPort);
160 return pMidiInputPort;
161 }
162
163 // ******************************************************************
164 // * Sampler
165
166 Sampler::Sampler() {
167 }
168
169 Sampler::~Sampler() {
170 // delete sampler channels
171 {
172 std::vector<SamplerChannel*>::iterator iter = vSamplerChannels.begin();
173 for (; iter != vSamplerChannels.end(); iter++) delete *iter;
174 }
175
176 // delete midi input devices
177 {
178 MidiInputDeviceMap::iterator iter = mMidiInputDevices.begin();
179 for (; iter != mMidiInputDevices.end(); iter++) {
180 MidiInputDevice* pDevice = iter->second;
181 pDevice->StopListen();
182 delete pDevice;
183 }
184 }
185
186 // delete audio output devices
187 {
188 AudioOutputDeviceMap::iterator iter = mAudioOutputDevices.begin();
189 for (; iter != mAudioOutputDevices.end(); iter++) {
190 AudioOutputDevice* pDevice = iter->second;
191 pDevice->Stop();
192 delete pDevice;
193 }
194 }
195 }
196
197 uint Sampler::SamplerChannels() {
198 return vSamplerChannels.size();
199 }
200
201 SamplerChannel* Sampler::AddSamplerChannel() {
202 SamplerChannel* pChannel = new SamplerChannel(this);
203 vSamplerChannels.push_back(pChannel);
204 return pChannel;
205 }
206
207 SamplerChannel* Sampler::GetSamplerChannel(uint uiSamplerChannel) {
208 if (uiSamplerChannel >= SamplerChannels()) return NULL;
209 return vSamplerChannels[uiSamplerChannel];
210 }
211
212 void Sampler::RemoveSamplerChannel(SamplerChannel* pSamplerChannel) {
213 std::vector<SamplerChannel*>::iterator iterChan = vSamplerChannels.begin();
214 for (; iterChan != vSamplerChannels.end(); iterChan++) {
215 if (*iterChan == pSamplerChannel) {
216 vSamplerChannels.erase(iterChan);
217 delete pSamplerChannel;
218 return;
219 }
220 }
221 }
222
223 void Sampler::RemoveSamplerChannel(uint uiSamplerChannel) {
224 SamplerChannel* pChannel = GetSamplerChannel(uiSamplerChannel);
225 if (!pChannel) return;
226 RemoveSamplerChannel(pChannel);
227 }
228
229 std::vector<String> Sampler::AvailableAudioOutputDrivers() {
230 return AudioOutputDeviceFactory::AvailableDrivers();
231 }
232
233 AudioOutputDevice* Sampler::CreateAudioOutputDevice(String AudioDriver, std::map<String,String> Parameters) throw (LinuxSamplerException) {
234 // create new device
235 AudioOutputDevice* pDevice = AudioOutputDeviceFactory::Create(AudioDriver, Parameters);
236
237 // activate device
238 pDevice->Play();
239
240 // add new audio device to the audio device list
241 for (uint i = 0; ; i++) { // seek for a free place starting from the beginning
242 if (!mAudioOutputDevices[i]) {
243 mAudioOutputDevices[i] = pDevice;
244 break;
245 }
246 }
247
248 return pDevice;
249 }
250
251 uint Sampler::AudioOutputDevices() {
252 return mAudioOutputDevices.size();
253 }
254
255 uint Sampler::MidiInputDevices() {
256 return mMidiInputDevices.size();
257 }
258
259 std::map<uint, AudioOutputDevice*> Sampler::GetAudioOutputDevices() {
260 return mAudioOutputDevices;
261 }
262
263 std::map<uint, MidiInputDevice*> Sampler::GetMidiInputDevices() {
264 return mMidiInputDevices;
265 }
266
267 void Sampler::DestroyAudioOutputDevice(AudioOutputDevice* pDevice) throw (LinuxSamplerException) {
268 AudioOutputDeviceMap::iterator iter = mAudioOutputDevices.begin();
269 for (; iter != mAudioOutputDevices.end(); iter++) {
270 if (iter->second == pDevice) {
271 // check if there are still sampler engines connected to this device
272 for (uint i = 0; i < SamplerChannels(); i++)
273 if (GetSamplerChannel(i)->GetAudioOutputDevice() == pDevice) throw LinuxSamplerException("Sampler channel " + ToString(i) + " is still connected to the audio output device.");
274
275 // disable device
276 pDevice->Stop();
277
278 // remove device from the device list
279 mAudioOutputDevices.erase(iter);
280
281 // destroy and free device from memory
282 delete pDevice;
283 }
284 }
285 }
286
287 void Sampler::DestroyMidiInputDevice(MidiInputDevice* pDevice) throw (LinuxSamplerException) {
288 MidiInputDeviceMap::iterator iter = mMidiInputDevices.begin();
289 for (; iter != mMidiInputDevices.end(); iter++) {
290 if (iter->second == pDevice) {
291 // check if there are still sampler engines connected to this device
292 for (uint i = 0; i < SamplerChannels(); i++)
293 if (GetSamplerChannel(i)->GetMidiInputDevice() == pDevice) throw LinuxSamplerException("Sampler channel " + ToString(i) + " is still connected to the midi input device.");
294
295 // disable device
296 pDevice->StopListen();
297
298 // remove device from the device list
299 mMidiInputDevices.erase(iter);
300
301 // destroy and free device from memory
302 delete pDevice;
303 }
304 }
305 }
306
307 MidiInputDevice* Sampler::CreateMidiInputDevice(String MidiDriver, std::map<String,String> Parameters) throw (LinuxSamplerException) {
308 // create new device
309 MidiInputDevice* pDevice = MidiInputDeviceFactory::Create(MidiDriver, Parameters);
310
311 // activate device
312 pDevice->Listen();
313
314 // add new device to the midi device list
315 for (uint i = 0; ; i++) { // seek for a free place starting from the beginning
316 if (!mMidiInputDevices[i]) {
317 mMidiInputDevices[i] = pDevice;
318 break;
319 }
320 }
321
322 return pDevice;
323 }
324
325 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC