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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 212 - (hide annotations) (download)
Wed Jul 28 14:17:29 2004 UTC (19 years, 8 months ago) by schoenebeck
File size: 14135 byte(s)
* introduced and implemented new LSCP command "RESET" which resets the
  whole sampler instance
* src/drivers/audio/AudioOutputDeviceAlsa.cpp: parameter 'card' now
  returns all available sound cards as possibility, added dependency to
  parameter 'card' to parameters 'fragments' and 'fragmentsize'
* src/drivers/DeviceParameter.cpp: fixed return value(s) for classes
  'DeviceCreationParameterString' and 'DeviceCreationParameterStrings'
  which returned the default value(s) not encapsulated into apostrophes
* src/network/lscpserver.cpp: fixed implementation of LSCP commands
  "GET MIDI_INPUT_DRIVER_PARAMETER INFO" and
  "GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO"

1 schoenebeck 53 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5 schoenebeck 61 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck *
6 schoenebeck 53 * *
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 schoenebeck 123 #include <sstream>
24    
25 schoenebeck 53 #include "Sampler.h"
26    
27 schoenebeck 203 #include "drivers/audio/AudioOutputDeviceFactory.h"
28     #include "drivers/midi/MidiInputDeviceFactory.h"
29 schoenebeck 53 #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 capela 159 pMidiInputDevice = NULL;
40 schoenebeck 53 pAudioOutputDevice = NULL;
41 capela 159 midiPort = 0;
42     midiChannel = MidiInputDevice::MidiInputPort::midi_chan_all;
43 schoenebeck 53 iIndex = -1;
44     }
45    
46     SamplerChannel::~SamplerChannel() {
47     if (pEngine) {
48 capela 159 MidiInputDevice::MidiInputPort *pMidiInputPort = GetMidiInputDevicePort(this->midiPort);
49 senkov 155 if (pMidiInputPort) pMidiInputPort->Disconnect(pEngine);
50 schoenebeck 53 if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(pEngine);
51     delete pEngine;
52     }
53     }
54    
55 schoenebeck 64 void SamplerChannel::LoadEngine(Engine::type_t EngineType) {
56     dmsg(2,("SamplerChannel: Loading engine..."));
57 schoenebeck 53
58     // create new engine
59     Engine* pNewEngine = NULL;
60     switch (EngineType) {
61 schoenebeck 64 case Engine::type_gig:
62 schoenebeck 53 pNewEngine = new gig::Engine;
63     break;
64     default:
65     throw LinuxSamplerException("Unknown engine type");
66     }
67    
68 capela 159 // dereference midi input port.
69     MidiInputDevice::MidiInputPort *pMidiInputPort = GetMidiInputDevicePort(this->midiPort);
70 schoenebeck 53 // disconnect old engine
71     if (pEngine) {
72 senkov 155 if (pMidiInputPort) pMidiInputPort->Disconnect(pEngine);
73 schoenebeck 53 if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(pEngine);
74     delete pEngine;
75     }
76    
77     // connect new engine
78     pEngine = pNewEngine;
79 capela 159 if (pMidiInputPort) pMidiInputPort->Connect(pNewEngine, this->midiChannel);
80 schoenebeck 53 if (pAudioOutputDevice) pAudioOutputDevice->Connect(pNewEngine);
81 schoenebeck 64 dmsg(2,("OK\n"));
82 schoenebeck 53 }
83    
84 schoenebeck 123 void SamplerChannel::SetAudioOutputDevice(AudioOutputDevice* pDevice) {
85 schoenebeck 53 // 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 capela 159 void SamplerChannel::SetMidiInputDevice(MidiInputDevice* pDevice) {
93     SetMidiInput(pDevice, this->midiPort, this->midiChannel);
94     }
95 schoenebeck 203
96 capela 159 void SamplerChannel::SetMidiInputPort(int MidiPort) {
97     SetMidiInput(pMidiInputDevice, MidiPort, this->midiChannel);
98     }
99 schoenebeck 203
100 capela 159 void SamplerChannel::SetMidiInputChannel(MidiInputDevice::MidiInputPort::midi_chan_t MidiChannel) {
101     SetMidiInput(pMidiInputDevice, this->midiPort, MidiChannel);
102     }
103 schoenebeck 203
104 capela 159 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 senkov 155 if (pMidiInputPort && pEngine) pMidiInputPort->Disconnect(pEngine);
109 capela 159 // 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 schoenebeck 53 }
120    
121     Engine* SamplerChannel::GetEngine() {
122     return pEngine;
123     }
124    
125 capela 159 MidiInputDevice::MidiInputPort::midi_chan_t SamplerChannel::GetMidiInputChannel() {
126     return this->midiChannel;
127 schoenebeck 53 }
128    
129 capela 159 int SamplerChannel::GetMidiInputPort() {
130     MidiInputDevice::MidiInputPort *pMidiInputPort = GetMidiInputDevicePort(this->midiPort);
131     return (pMidiInputPort ? (int) pMidiInputPort->GetPortNumber() : -1);
132     }
133    
134 schoenebeck 53 AudioOutputDevice* SamplerChannel::GetAudioOutputDevice() {
135     return pAudioOutputDevice;
136     }
137    
138 senkov 155 MidiInputDevice* SamplerChannel::GetMidiInputDevice() {
139 capela 159 return pMidiInputDevice;
140 senkov 155 }
141    
142 schoenebeck 53 uint SamplerChannel::Index() {
143     if (iIndex >= 0) return iIndex;
144    
145 schoenebeck 209 Sampler::SamplerChannelMap::iterator iter = pSampler->mSamplerChannels.begin();
146     for (; iter != pSampler->mSamplerChannels.end(); iter++) {
147     if (iter->second == this) {
148     iIndex = iter->first;
149     return iIndex;
150 schoenebeck 53 }
151     }
152    
153 schoenebeck 209 throw LinuxSamplerException("Internal error: SamplerChannel index not found");
154 schoenebeck 53 }
155    
156 capela 159 MidiInputDevice::MidiInputPort* SamplerChannel::GetMidiInputDevicePort(int MidiPort) {
157     MidiInputDevice::MidiInputPort *pMidiInputPort = NULL;
158     if (pMidiInputDevice)
159     pMidiInputPort = pMidiInputDevice->GetPort(MidiPort);
160     return pMidiInputPort;
161     }
162 schoenebeck 53
163 schoenebeck 212
164    
165 schoenebeck 53 // ******************************************************************
166     // * Sampler
167    
168     Sampler::Sampler() {
169     }
170    
171     Sampler::~Sampler() {
172 schoenebeck 212 Reset();
173 schoenebeck 53 }
174    
175     uint Sampler::SamplerChannels() {
176 schoenebeck 209 return mSamplerChannels.size();
177 schoenebeck 53 }
178    
179     SamplerChannel* Sampler::AddSamplerChannel() {
180 schoenebeck 209 // if there's no sampler channel yet
181     if (!mSamplerChannels.size()) {
182     SamplerChannel* pChannel = new SamplerChannel(this);
183     mSamplerChannels[0] = pChannel;
184     return pChannel;
185     }
186    
187     // get the highest used sampler channel index
188     uint lastIndex = (--(mSamplerChannels.end()))->first;
189    
190     // check if we reached the index limit
191     if (lastIndex + 1 < lastIndex) {
192     // search for an unoccupied sampler channel index starting from 0
193     for (uint i = 0; i < lastIndex; i++) {
194     if (mSamplerChannels.find(i) != mSamplerChannels.end()) continue;
195     // we found an unused index, so insert the new channel there
196     SamplerChannel* pChannel = new SamplerChannel(this);
197     mSamplerChannels[i] = pChannel;
198     return pChannel;
199     }
200     throw LinuxSamplerException("Internal error: could not find unoccupied sampler channel index.");
201     }
202    
203     // we have not reached the index limit so we just add the channel past the highest index
204 schoenebeck 53 SamplerChannel* pChannel = new SamplerChannel(this);
205 schoenebeck 209 mSamplerChannels[lastIndex + 1] = pChannel;
206 schoenebeck 53 return pChannel;
207     }
208    
209     SamplerChannel* Sampler::GetSamplerChannel(uint uiSamplerChannel) {
210 schoenebeck 209 return (mSamplerChannels.find(uiSamplerChannel) != mSamplerChannels.end()) ? mSamplerChannels[uiSamplerChannel] : NULL;
211 schoenebeck 53 }
212    
213 schoenebeck 209 std::map<uint, SamplerChannel*> Sampler::GetSamplerChannels() {
214     return mSamplerChannels;
215     }
216    
217 schoenebeck 53 void Sampler::RemoveSamplerChannel(SamplerChannel* pSamplerChannel) {
218 schoenebeck 209 SamplerChannelMap::iterator iterChan = mSamplerChannels.begin();
219     for (; iterChan != mSamplerChannels.end(); iterChan++) {
220     if (iterChan->second == pSamplerChannel) {
221     mSamplerChannels.erase(iterChan);
222 schoenebeck 53 delete pSamplerChannel;
223     return;
224     }
225     }
226     }
227    
228     void Sampler::RemoveSamplerChannel(uint uiSamplerChannel) {
229     SamplerChannel* pChannel = GetSamplerChannel(uiSamplerChannel);
230     if (!pChannel) return;
231     RemoveSamplerChannel(pChannel);
232     }
233    
234 schoenebeck 123 std::vector<String> Sampler::AvailableAudioOutputDrivers() {
235     return AudioOutputDeviceFactory::AvailableDrivers();
236     }
237 schoenebeck 53
238 schoenebeck 123 AudioOutputDevice* Sampler::CreateAudioOutputDevice(String AudioDriver, std::map<String,String> Parameters) throw (LinuxSamplerException) {
239 schoenebeck 53 // create new device
240 schoenebeck 123 AudioOutputDevice* pDevice = AudioOutputDeviceFactory::Create(AudioDriver, Parameters);
241 schoenebeck 53
242 schoenebeck 64 // add new audio device to the audio device list
243 schoenebeck 123 for (uint i = 0; ; i++) { // seek for a free place starting from the beginning
244     if (!mAudioOutputDevices[i]) {
245     mAudioOutputDevices[i] = pDevice;
246     break;
247     }
248     }
249 schoenebeck 64
250 schoenebeck 53 return pDevice;
251     }
252    
253 schoenebeck 123 uint Sampler::AudioOutputDevices() {
254     return mAudioOutputDevices.size();
255 schoenebeck 53 }
256    
257 senkov 155 uint Sampler::MidiInputDevices() {
258     return mMidiInputDevices.size();
259     }
260    
261 schoenebeck 123 std::map<uint, AudioOutputDevice*> Sampler::GetAudioOutputDevices() {
262     return mAudioOutputDevices;
263     }
264    
265 senkov 155 std::map<uint, MidiInputDevice*> Sampler::GetMidiInputDevices() {
266     return mMidiInputDevices;
267     }
268    
269 schoenebeck 123 void Sampler::DestroyAudioOutputDevice(AudioOutputDevice* pDevice) throw (LinuxSamplerException) {
270     AudioOutputDeviceMap::iterator iter = mAudioOutputDevices.begin();
271     for (; iter != mAudioOutputDevices.end(); iter++) {
272     if (iter->second == pDevice) {
273     // check if there are still sampler engines connected to this device
274     for (uint i = 0; i < SamplerChannels(); i++)
275     if (GetSamplerChannel(i)->GetAudioOutputDevice() == pDevice) throw LinuxSamplerException("Sampler channel " + ToString(i) + " is still connected to the audio output device.");
276    
277     // disable device
278     pDevice->Stop();
279    
280     // remove device from the device list
281     mAudioOutputDevices.erase(iter);
282    
283     // destroy and free device from memory
284     delete pDevice;
285     }
286     }
287     }
288    
289 senkov 155 void Sampler::DestroyMidiInputDevice(MidiInputDevice* pDevice) throw (LinuxSamplerException) {
290     MidiInputDeviceMap::iterator iter = mMidiInputDevices.begin();
291     for (; iter != mMidiInputDevices.end(); iter++) {
292     if (iter->second == pDevice) {
293     // check if there are still sampler engines connected to this device
294     for (uint i = 0; i < SamplerChannels(); i++)
295     if (GetSamplerChannel(i)->GetMidiInputDevice() == pDevice) throw LinuxSamplerException("Sampler channel " + ToString(i) + " is still connected to the midi input device.");
296 schoenebeck 53
297 senkov 155 // disable device
298     pDevice->StopListen();
299    
300     // remove device from the device list
301     mMidiInputDevices.erase(iter);
302    
303     // destroy and free device from memory
304     delete pDevice;
305     }
306 schoenebeck 53 }
307 senkov 155 }
308 schoenebeck 53
309 senkov 155 MidiInputDevice* Sampler::CreateMidiInputDevice(String MidiDriver, std::map<String,String> Parameters) throw (LinuxSamplerException) {
310     // create new device
311     MidiInputDevice* pDevice = MidiInputDeviceFactory::Create(MidiDriver, Parameters);
312    
313     // add new device to the midi device list
314     for (uint i = 0; ; i++) { // seek for a free place starting from the beginning
315     if (!mMidiInputDevices[i]) {
316     mMidiInputDevices[i] = pDevice;
317     break;
318     }
319     }
320 schoenebeck 64
321 schoenebeck 53 return pDevice;
322     }
323    
324 schoenebeck 212 void Sampler::Reset() {
325     // delete sampler channels
326     try {
327     SamplerChannelMap::iterator iter = mSamplerChannels.begin();
328     for (; iter != mSamplerChannels.end(); iter++) {
329     RemoveSamplerChannel(iter->second);
330     }
331     }
332     catch(...) {
333     std::cerr << "Sampler::Reset(): Exception occured while trying to delete all sampler channels, exiting.\n" << std::flush;
334     exit(EXIT_FAILURE);
335     }
336    
337     // delete midi input devices
338     try {
339     MidiInputDeviceMap::iterator iter = mMidiInputDevices.begin();
340     for (; iter != mMidiInputDevices.end(); iter++) {
341     DestroyMidiInputDevice(iter->second);
342     }
343     }
344     catch(...) {
345     std::cerr << "Sampler::Reset(): Exception occured while trying to delete all MIDI input devices, exiting.\n" << std::flush;
346     exit(EXIT_FAILURE);
347     }
348    
349     // delete audio output devices
350     try {
351     AudioOutputDeviceMap::iterator iter = mAudioOutputDevices.begin();
352     for (; iter != mAudioOutputDevices.end(); iter++) {
353     DestroyAudioOutputDevice(iter->second);
354     }
355     }
356     catch(...) {
357     std::cerr << "Sampler::Reset(): Exception occured while trying to delete all audio output devices, exiting.\n" << std::flush;
358     exit(EXIT_FAILURE);
359     }
360     }
361    
362 schoenebeck 53 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC