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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 123 - (hide annotations) (download)
Mon Jun 14 19:33:16 2004 UTC (19 years, 9 months ago) by schoenebeck
File size: 9974 byte(s)
* src/common: added template class 'optional<>' which can be used e.g. as
  return type whenever a value might be returned, but don't has to; this
  template class pretty much acts like a pointer of the given type, but is
  much more safer than a simple pointer
* src/audiodriver: added static class AudioDeviceFactory to create audio
  devices at runtime by using a string and to obtain driver informations
  of drivers at runtime, driver classes should simply use the macro
  REGISTER_AUDIO_OUTPUT_DRIVER(DriverName,DriverClass) in their cpp file
  to register the driver to LinuxSampler (no changes needed anymore in the
  LS code to add a new audio output driver)
* src/drivers: added classes to dynamically manage driver parameters; there
  are two different kinds of parameters: parameters which are need to
  create a new device (DeviceCreationParameterX) used to e.g. create an
  audio output device or a MIDI input device and parameters which are only
  available at runtime, means when a device is already created
  (DeviceRuntimeParameterX) which will be e.g. used as audio channel
  parameters and MIDI port parameters
* src/linuxsampler.cpp: all registered audio output drivers will be shown
  on the console on startup
* src/network: implemented configuration of audio output devices via LSCP

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 123 #include "audiodriver/AudioOutputDeviceFactory.h"
28 schoenebeck 53 #include "mididriver/MidiInputDeviceAlsa.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     iIndex = -1;
42     }
43    
44     SamplerChannel::~SamplerChannel() {
45     if (pEngine) {
46     if (pMidiInputDevice) pMidiInputDevice->Disconnect(pEngine);
47     if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(pEngine);
48     delete pEngine;
49     }
50     }
51    
52 schoenebeck 64 void SamplerChannel::LoadEngine(Engine::type_t EngineType) {
53     dmsg(2,("SamplerChannel: Loading engine..."));
54 schoenebeck 53
55     // create new engine
56     Engine* pNewEngine = NULL;
57     switch (EngineType) {
58 schoenebeck 64 case Engine::type_gig:
59 schoenebeck 53 pNewEngine = new gig::Engine;
60     break;
61     default:
62     throw LinuxSamplerException("Unknown engine type");
63     }
64    
65     // disconnect old engine
66     if (pEngine) {
67     if (pMidiInputDevice) pMidiInputDevice->Disconnect(pEngine);
68     if (pAudioOutputDevice) pAudioOutputDevice->Disconnect(pEngine);
69     delete pEngine;
70     }
71    
72     // connect new engine
73     pEngine = pNewEngine;
74     if (pMidiInputDevice) pMidiInputDevice->Connect(pNewEngine, (MidiInputDevice::midi_chan_t) Index());
75     if (pAudioOutputDevice) pAudioOutputDevice->Connect(pNewEngine);
76 schoenebeck 64 dmsg(2,("OK\n"));
77 schoenebeck 53 }
78    
79 schoenebeck 123 void SamplerChannel::SetAudioOutputDevice(AudioOutputDevice* pDevice) {
80 schoenebeck 53 // disconnect old device
81     if (pAudioOutputDevice && pEngine) pAudioOutputDevice->Disconnect(pEngine);
82    
83     // connect new device
84     pAudioOutputDevice = pDevice;
85     if (pEngine) pAudioOutputDevice->Connect(pEngine);
86     }
87    
88 schoenebeck 64 void SamplerChannel::SetMidiInputDevice(MidiInputDevice::type_t MidiType, MidiInputDevice::midi_chan_t MidiChannel) {
89 schoenebeck 53 // get / create desired midi device
90     MidiInputDevice* pDevice = pSampler->GetMidiInputDevice(MidiType);
91     if (!pDevice) pDevice = pSampler->CreateMidiInputDevice(MidiType);
92    
93     // disconnect old device
94     if (pMidiInputDevice && pEngine) pMidiInputDevice->Disconnect(pEngine);
95    
96     // connect new device
97     pMidiInputDevice = pDevice;
98     if (pEngine) pMidiInputDevice->Connect(pEngine, MidiChannel);
99     }
100    
101     Engine* SamplerChannel::GetEngine() {
102     return pEngine;
103     }
104    
105     MidiInputDevice* SamplerChannel::GetMidiInputDevice() {
106     return pMidiInputDevice;
107     }
108    
109     AudioOutputDevice* SamplerChannel::GetAudioOutputDevice() {
110     return pAudioOutputDevice;
111     }
112    
113     uint SamplerChannel::Index() {
114     if (iIndex >= 0) return iIndex;
115    
116     std::vector<SamplerChannel*>::iterator iter = pSampler->vSamplerChannels.begin();
117     for (int i = 0; iter != pSampler->vSamplerChannels.end(); i++, iter++) {
118     if (*iter == this) {
119     iIndex = i;
120     return i;
121     }
122     }
123    
124     throw LinuxSamplerException("SamplerChannel index not found");
125     }
126    
127    
128     // ******************************************************************
129     // * Sampler
130    
131     Sampler::Sampler() {
132     }
133    
134     Sampler::~Sampler() {
135     // delete sampler channels
136     {
137     std::vector<SamplerChannel*>::iterator iter = vSamplerChannels.begin();
138     for (; iter != vSamplerChannels.end(); iter++) delete *iter;
139     }
140    
141     // delete midi input devices
142     {
143     MidiInputDeviceMap::iterator iter = MidiInputDevices.begin();
144     for (; iter != MidiInputDevices.end(); iter++) {
145     MidiInputDevice* pDevice = iter->second;
146     pDevice->StopListen();
147     delete pDevice;
148     }
149     }
150    
151     // delete audio output devices
152     {
153 schoenebeck 123 AudioOutputDeviceMap::iterator iter = mAudioOutputDevices.begin();
154     for (; iter != mAudioOutputDevices.end(); iter++) {
155 schoenebeck 53 AudioOutputDevice* pDevice = iter->second;
156     pDevice->Stop();
157     delete pDevice;
158     }
159     }
160     }
161    
162     uint Sampler::SamplerChannels() {
163 schoenebeck 64 return vSamplerChannels.size();
164 schoenebeck 53 }
165    
166     SamplerChannel* Sampler::AddSamplerChannel() {
167     SamplerChannel* pChannel = new SamplerChannel(this);
168     vSamplerChannels.push_back(pChannel);
169     return pChannel;
170     }
171    
172     SamplerChannel* Sampler::GetSamplerChannel(uint uiSamplerChannel) {
173     if (uiSamplerChannel >= SamplerChannels()) return NULL;
174     return vSamplerChannels[uiSamplerChannel];
175     }
176    
177     void Sampler::RemoveSamplerChannel(SamplerChannel* pSamplerChannel) {
178     std::vector<SamplerChannel*>::iterator iterChan = vSamplerChannels.begin();
179     for (; iterChan != vSamplerChannels.end(); iterChan++) {
180     if (*iterChan == pSamplerChannel) {
181     vSamplerChannels.erase(iterChan);
182     delete pSamplerChannel;
183     return;
184     }
185     }
186     }
187    
188     void Sampler::RemoveSamplerChannel(uint uiSamplerChannel) {
189     SamplerChannel* pChannel = GetSamplerChannel(uiSamplerChannel);
190     if (!pChannel) return;
191     RemoveSamplerChannel(pChannel);
192     }
193    
194 schoenebeck 123 std::vector<String> Sampler::AvailableAudioOutputDrivers() {
195     return AudioOutputDeviceFactory::AvailableDrivers();
196     }
197 schoenebeck 53
198 schoenebeck 123 AudioOutputDevice* Sampler::CreateAudioOutputDevice(String AudioDriver, std::map<String,String> Parameters) throw (LinuxSamplerException) {
199 schoenebeck 53 // create new device
200 schoenebeck 123 AudioOutputDevice* pDevice = AudioOutputDeviceFactory::Create(AudioDriver, Parameters);
201 schoenebeck 53
202     // activate device
203     pDevice->Play();
204    
205 schoenebeck 64 // add new audio device to the audio device list
206 schoenebeck 123 for (uint i = 0; ; i++) { // seek for a free place starting from the beginning
207     if (!mAudioOutputDevices[i]) {
208     mAudioOutputDevices[i] = pDevice;
209     break;
210     }
211     }
212 schoenebeck 64
213 schoenebeck 53 return pDevice;
214     }
215    
216 schoenebeck 123 uint Sampler::AudioOutputDevices() {
217     return mAudioOutputDevices.size();
218 schoenebeck 53 }
219    
220 schoenebeck 123 std::map<uint, AudioOutputDevice*> Sampler::GetAudioOutputDevices() {
221     return mAudioOutputDevices;
222     }
223    
224     void Sampler::DestroyAudioOutputDevice(AudioOutputDevice* pDevice) throw (LinuxSamplerException) {
225     AudioOutputDeviceMap::iterator iter = mAudioOutputDevices.begin();
226     for (; iter != mAudioOutputDevices.end(); iter++) {
227     if (iter->second == pDevice) {
228     // check if there are still sampler engines connected to this device
229     for (uint i = 0; i < SamplerChannels(); i++)
230     if (GetSamplerChannel(i)->GetAudioOutputDevice() == pDevice) throw LinuxSamplerException("Sampler channel " + ToString(i) + " is still connected to the audio output device.");
231    
232     // disable device
233     pDevice->Stop();
234    
235     // remove device from the device list
236     mAudioOutputDevices.erase(iter);
237    
238     // destroy and free device from memory
239     delete pDevice;
240     }
241     }
242     }
243    
244 schoenebeck 64 MidiInputDevice* Sampler::CreateMidiInputDevice(MidiInputDevice::type_t MidiType) {
245 schoenebeck 53 // check if device already created
246     MidiInputDevice* pDevice = GetMidiInputDevice(MidiType);
247     if (pDevice) return pDevice;
248    
249     // create new device
250     switch (MidiType) {
251 schoenebeck 64 case MidiInputDevice::type_alsa:
252 schoenebeck 53 pDevice = new MidiInputDeviceAlsa;
253     break;
254     default:
255     throw LinuxSamplerException("Unknown audio output device type");
256     }
257    
258     // activate device
259     pDevice->Listen();
260    
261 schoenebeck 64 // add new MIDI device to the MIDI device list
262     MidiInputDevices[MidiType] = pDevice;
263    
264 schoenebeck 53 return pDevice;
265     }
266    
267 schoenebeck 64 MidiInputDevice* Sampler::GetMidiInputDevice(MidiInputDevice::type_t MidiType) {
268 schoenebeck 53 MidiInputDeviceMap::iterator iter = MidiInputDevices.find(MidiType);
269     return (iter != MidiInputDevices.end()) ? iter->second : NULL;
270     }
271    
272     } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC