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

Diff of /linuxsampler/trunk/src/drivers/Plugin.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1777 by persson, Mon Sep 15 16:58:10 2008 UTC revision 1992 by iliev, Fri Aug 28 07:48:47 2009 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2008 Andreas Persson                                    *   *   Copyright (C) 2008 - 2009 Andreas Persson                             *
4   *                                                                         *   *                                                                         *
5   *   This program is free software; you can redistribute it and/or modify  *   *   This program is free software; you can redistribute it and/or modify  *
6   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 18  Line 18 
18   *   MA  02110-1301  USA                                                   *   *   MA  02110-1301  USA                                                   *
19   ***************************************************************************/   ***************************************************************************/
20    
21    #include <limits>
22  #include <sstream>  #include <sstream>
23    
24  #include "Plugin.h"  #include "Plugin.h"
# Line 33  namespace LinuxSampler { Line 34  namespace LinuxSampler {
34          RefCount(0) {          RefCount(0) {
35          // we need to remove the ASIO driver, otherwise the lscp info          // we need to remove the ASIO driver, otherwise the lscp info
36          // methods will lock up the audio device          // methods will lock up the audio device
37          AudioOutputDeviceFactory::InnerFactories.erase("ASIO");          AudioOutputDeviceFactory::Unregister("ASIO");
         AudioOutputDeviceFactory::ParameterFactories.erase("ASIO");  
38    
39          REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDevicePlugin);          REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDevicePlugin);
40          REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterActive);          REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterActive);
41          REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterSampleRate);          REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterSampleRate);
42          REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterChannels);          REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterChannelsPlugin);
43          REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterFragmentSize);          REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterFragmentSize);
44    
45          REGISTER_MIDI_INPUT_DRIVER(MidiInputDevicePlugin);          REGISTER_MIDI_INPUT_DRIVER(MidiInputDevicePlugin);
46          REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDevicePlugin, ParameterActive);          REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDevicePlugin, ParameterActive);
47          REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDevicePlugin, ParameterPorts);          REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDevicePlugin, ParameterPortsPlugin);
48    
49          pSampler = new Sampler;          pSampler = new Sampler;
50    
# Line 63  namespace LinuxSampler { Line 63  namespace LinuxSampler {
63      PluginGlobal::~PluginGlobal() {      PluginGlobal::~PluginGlobal() {
64          pEventThread->StopThread();          pEventThread->StopThread();
65          pLSCPServer->StopThread();          pLSCPServer->StopThread();
66            pLSCPServer->RemoveListeners();
67    
68          delete pEventThread;          delete pEventThread;
69          delete pSampler;          delete pSampler;
# Line 84  namespace LinuxSampler { Line 85  namespace LinuxSampler {
85              sleep(1);              sleep(1);
86              pSampler->fireStatistics();              pSampler->fireStatistics();
87          }          }
88            return 0;
89      }      }
90    
91    
# Line 92  namespace LinuxSampler { Line 94  namespace LinuxSampler {
94    
95      PluginGlobal* Plugin::global = 0;      PluginGlobal* Plugin::global = 0;
96    
97      Plugin::Plugin() :      Plugin::Plugin(bool bDoPreInit) :
98          pAudioDevice(0),          pAudioDevice(0),
99          pMidiDevice(0) {          pMidiDevice(0) {
100            bPreInitDone = false;
101            if (bDoPreInit) PreInit();
102        }
103    
104        void Plugin::PreInit() {
105            if (bPreInitDone) return;
106    
107            bPreInitDone = true;
108          if (!global) {          if (!global) {
109              global = new PluginGlobal;              global = new PluginGlobal;
110          }          }
111          global->RefCount++;          global->RefCount++;
112      }      }
113    
114      void Plugin::Init(int SampleRate, int FragmentSize) {      void Plugin::Init(int SampleRate, int FragmentSize, int Channels) {
115            if (pAudioDevice && SampleRate == pAudioDevice->SampleRate() &&
116                FragmentSize == pAudioDevice->MaxSamplesPerCycle()) {
117                return; // nothing has changed
118            }
119    
120            String oldState;
121            if (pAudioDevice) {
122                oldState = GetState();
123                RemoveChannels();
124                AudioOutputDeviceFactory::DestroyPrivate(pAudioDevice);
125            }
126          std::map<String, String> params;          std::map<String, String> params;
127          params["SAMPLERATE"] = ToString(SampleRate);          params["SAMPLERATE"] = ToString(SampleRate);
128          params["FRAGMENTSIZE"] = ToString(FragmentSize);          params["FRAGMENTSIZE"] = ToString(FragmentSize);
129            if (Channels > 0) params["CHANNELS"] = ToString(Channels);
130          pAudioDevice = dynamic_cast<AudioOutputDevicePlugin*>(          pAudioDevice = dynamic_cast<AudioOutputDevicePlugin*>(
131              global->pSampler->CreateAudioOutputDevice(AudioOutputDevicePlugin::Name(), params));              AudioOutputDeviceFactory::CreatePrivate(
132                    AudioOutputDevicePlugin::Name(), params
133                )
134            );
135    
136            if (!pMidiDevice) {
137                pMidiDevice = dynamic_cast<MidiInputDevicePlugin*>(
138                    MidiInputDeviceFactory::CreatePrivate(
139                        MidiInputDevicePlugin::Name(), std::map<String,String>(),
140                        global->pSampler
141                    )
142                );
143            }
144    
145          pMidiDevice = dynamic_cast<MidiInputDevicePlugin*>(          if (!oldState.empty()) {
146              global->pSampler->CreateMidiInputDevice(MidiInputDevicePlugin::Name(),              SetState(oldState);
147                                                      std::map<String,String>()));          }
148      }      }
149    
150      Plugin::~Plugin() {      Plugin::~Plugin() {
151          RemoveChannels();          RemoveChannels();
152          if (pAudioDevice) global->pSampler->DestroyAudioOutputDevice(pAudioDevice);          if (pAudioDevice) AudioOutputDeviceFactory::DestroyPrivate(pAudioDevice);
153          if (pMidiDevice) global->pSampler->DestroyMidiInputDevice(pMidiDevice);          if (pMidiDevice) MidiInputDeviceFactory::DestroyPrivate(pMidiDevice);
154          if (--global->RefCount == 0) {          if (bPreInitDone) {
155              delete global;              if (--global->RefCount == 0) {
156              global = 0;                  delete global;
157                    global = 0;
158                }
159          }          }
160      }      }
161    
# Line 131  namespace LinuxSampler { Line 167  namespace LinuxSampler {
167          channel->SetMidiInputChannel(midi_chan_1);          channel->SetMidiInputChannel(midi_chan_1);
168      }      }
169    
170        /*
171          The sampler state is stored in a text base format, designed to
172          be easy to parse with the istream >> operator. Values are
173          separated by spaces or newlines. All string values that may
174          contain spaces end with a newline.
175    
176          The first line contains the global volume.
177    
178          The rest of the lines have an integer first representing the
179          type of information on the line, except for the two lines that
180          describe each sampler channel. The first of these two starts
181          with an integer from 0 to 16 (the midi channel for the sampler
182          channel).
183    
184          Note that we should try to keep the parsing of this format both
185          backwards and forwards compatible between versions. The parser
186          ignores lines with unknown type integers and accepts that new
187          types are missing.
188        */
189    
190        enum {
191            FXSEND = 17,
192            MIDIMAP,
193            MIDIMAPPING,
194            DEFAULTMIDIMAP
195        };
196    
197      String Plugin::GetState() {      String Plugin::GetState() {
198          std::stringstream s;          std::stringstream s;
199    
200          s << GLOBAL_VOLUME << '\n';          s << GLOBAL_VOLUME << '\n';
201    
202            std::vector<int> maps = MidiInstrumentMapper::Maps();
203            for (int i = 0 ; i < maps.size() ; i++) {
204                s << MIDIMAP << ' ' <<
205                    maps[i] << ' ' <<
206                    MidiInstrumentMapper::MapName(maps[i]) << '\n';
207    
208                std::map<midi_prog_index_t, MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(maps[i]);
209                for (std::map<midi_prog_index_t, MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin() ;
210                     iter != mappings.end(); iter++) {
211                    s << MIDIMAPPING << ' ' <<
212                        ((int(iter->first.midi_bank_msb) << 7) |
213                         int(iter->first.midi_bank_lsb)) << ' ' <<
214                        int(iter->first.midi_prog) << ' ' <<
215                        iter->second.EngineName << ' ' <<
216                        iter->second.InstrumentFile << '\n' <<
217                        MIDIMAPPING << ' ' <<
218                        iter->second.InstrumentIndex << ' ' <<
219                        iter->second.Volume << ' ' <<
220                        iter->second.LoadMode << ' ' <<
221                        iter->second.Name << '\n';
222                }
223            }
224            if (maps.size()) {
225                s << DEFAULTMIDIMAP << ' ' <<
226                    MidiInstrumentMapper::GetDefaultMap() << '\n';
227            }
228    
229          std::map<uint, SamplerChannel*> channels = global->pSampler->GetSamplerChannels();          std::map<uint, SamplerChannel*> channels = global->pSampler->GetSamplerChannels();
230          for (std::map<uint, SamplerChannel*>::iterator iter = channels.begin() ;          for (std::map<uint, SamplerChannel*>::iterator iter = channels.begin() ;
231               iter != channels.end() ; iter++) {               iter != channels.end() ; iter++) {
# Line 148  namespace LinuxSampler { Line 238  namespace LinuxSampler {
238                      filename << '\n' <<                      filename << '\n' <<
239                      engine_channel->InstrumentIndex() << ' ' <<                      engine_channel->InstrumentIndex() << ' ' <<
240                      engine_channel->GetSolo() << ' ' <<                      engine_channel->GetSolo() << ' ' <<
241                      (engine_channel->GetMute() == 1) << '\n';                      (engine_channel->GetMute() == 1) << ' ' <<
242                        engine_channel->OutputChannel(0) << ' ' <<
243                        engine_channel->OutputChannel(1) << ' ' <<
244                        (engine_channel->UsesNoMidiInstrumentMap() ? -2 :
245                         (engine_channel->UsesDefaultMidiInstrumentMap() ? -1 :
246                          engine_channel->GetMidiInstrumentMap())) << '\n';
247    
248                    for (int i = 0 ; i < engine_channel->GetFxSendCount() ; i++) {
249                        FxSend* fxsend = engine_channel->GetFxSend(i);
250                        s << FXSEND << ' ' <<
251                            fxsend->Level() << ' ' <<
252                            int(fxsend->MidiController()) << ' ' <<
253                            fxsend->DestinationChannel(0) << ' ' <<
254                            fxsend->DestinationChannel(1) << ' ' <<
255                            fxsend->Name() << '\n';
256                    }
257              }              }
258          }          }
259          return s.str();          return s.str();
260      }      }
261    
262      void Plugin::RemoveChannels() {      void Plugin::RemoveChannels() {
263            if(global == NULL) return;
264    
265          std::map<uint, SamplerChannel*> channels = global->pSampler->GetSamplerChannels();          std::map<uint, SamplerChannel*> channels = global->pSampler->GetSamplerChannels();
266    
267          for (std::map<uint, SamplerChannel*>::iterator iter = channels.begin() ;          for (std::map<uint, SamplerChannel*>::iterator iter = channels.begin() ;
268               iter != channels.end() ; iter++) {               iter != channels.end() ; iter++) {
269              if (iter->second->GetAudioOutputDevice() == pAudioDevice) {              if (iter->second->GetAudioOutputDevice() == pAudioDevice) {
# Line 166  namespace LinuxSampler { Line 274  namespace LinuxSampler {
274    
275      bool Plugin::SetState(String State) {      bool Plugin::SetState(String State) {
276          RemoveChannels();          RemoveChannels();
277            MidiInstrumentMapper::RemoveAllMaps();
278    
279          std::stringstream s(State);          std::stringstream s(State);
280          s >> GLOBAL_VOLUME;          s >> GLOBAL_VOLUME;
281    
282          int midiChannel;          EngineChannel* engine_channel;
283          float volume;          int midiMapId;
284          while (s >> midiChannel >> volume) {          std::map<int, int> oldToNewId;
285              s.ignore();          int type;
286              String filename;          while (s >> type) {
287              std::getline(s, filename);  
288              int index;              if (type <= 16) { // sampler channel
289              bool solo;                  int midiChannel = type;
290              bool mute;                  float volume;
291              s >> index >> solo >> mute;                  s >> volume;
292                    s.ignore();
293              SamplerChannel* channel = global->pSampler->AddSamplerChannel();                  String filename;
294              channel->SetEngineType("gig");                  std::getline(s, filename);
295              channel->SetAudioOutputDevice(pAudioDevice);                  int index;
296              channel->SetMidiInputDevice(pMidiDevice);                  bool solo;
297              channel->SetMidiInputChannel(midi_chan_t(midiChannel));                  bool mute;
298                    s >> index >> solo >> mute;
299              EngineChannel* engine_channel = channel->GetEngineChannel();  
300              engine_channel->Volume(volume);                  SamplerChannel* channel = global->pSampler->AddSamplerChannel();
301              if (!filename.empty() && index != -1) {                  channel->SetEngineType("gig");
302                  engine_channel->PrepareLoadInstrument(filename.c_str(), index);                  channel->SetAudioOutputDevice(pAudioDevice);
303                  engine_channel->LoadInstrument();                  channel->SetMidiInputDevice(pMidiDevice);
304                    channel->SetMidiInputChannel(midi_chan_t(midiChannel));
305    
306                    engine_channel = channel->GetEngineChannel();
307                    engine_channel->Volume(volume);
308                    if (s.get() == ' ') {
309                        int left;
310                        int right;
311                        int oldMapId;
312                        s >> left >> right >> oldMapId;
313                        engine_channel->SetOutputChannel(0, left);
314                        engine_channel->SetOutputChannel(1, right);
315    
316                        if (oldMapId == -1) {
317                            engine_channel->SetMidiInstrumentMapToDefault();
318                        } else if (oldMapId >= 0) {
319                            engine_channel->SetMidiInstrumentMap(oldToNewId[oldMapId]);
320                        }
321                        // skip rest of line
322                        s.ignore(std::numeric_limits<int>::max(), '\n');
323                    }
324                    if (!filename.empty() && index != -1) {
325                        InstrumentManager::instrument_id_t id;
326                        id.FileName = filename;
327                        id.Index    = index;
328                        InstrumentManager::LoadInstrumentInBackground(id, engine_channel);
329                    }
330                    if (solo) engine_channel->SetSolo(solo);
331                    if (mute) engine_channel->SetMute(1);
332    
333                } else if (type == FXSEND) {
334                    float level;
335                    int controller;
336                    int fxleft;
337                    int fxright;
338                    String name;
339    
340                    s >> level >> controller >> fxleft >> fxright;
341                    s.ignore();
342                    std::getline(s, name);
343                    FxSend* send = engine_channel->AddFxSend(controller, name);
344                    send->SetLevel(level);
345                    send->SetDestinationChannel(0, fxleft);
346                    send->SetDestinationChannel(1, fxright);
347    
348                } else if (type == MIDIMAP) {
349                    int oldId;
350                    s >> oldId;
351                    String name;
352                    s.ignore();
353                    std::getline(s, name);
354                    midiMapId = MidiInstrumentMapper::AddMap(name);
355                    oldToNewId[oldId] = midiMapId;
356    
357                } else if (type == MIDIMAPPING) {
358                    int bank;
359                    int prog;
360                    String engine;
361                    String file;
362                    int index;
363                    float volume;
364                    int loadmode;
365                    String name;
366    
367                    s >> bank >> prog >> engine;
368                    s.ignore();
369                    std::getline(s, file);
370                    s >> type >> index >> volume >> loadmode;
371                    s.ignore();
372                    std::getline(s, name);
373    
374                    global->pLSCPServer->AddOrReplaceMIDIInstrumentMapping(
375                        midiMapId, bank, prog, engine, file, index, volume,
376                        MidiInstrumentMapper::mode_t(loadmode), name, false);
377    
378                } else if (type == DEFAULTMIDIMAP) {
379                    int oldId;
380                    s >> oldId;
381                    MidiInstrumentMapper::SetDefaultMap(oldToNewId[oldId]);
382    
383                } else { // unknown type
384                    // try to be forward-compatible and just skip the line
385                    s.ignore(std::numeric_limits<int>::max(), '\n');
386              }              }
             if (solo) engine_channel->SetSolo(solo);  
             if (mute) engine_channel->SetMute(1);  
387          }          }
388    
389          return true;          return true;
390      }      }
391    
392        void Plugin::DestroyDevice(AudioOutputDevicePlugin* pDevice) {
393            AudioOutputDeviceFactory::DestroyPrivate(pDevice);
394        }
395    
396        void Plugin::DestroyDevice(MidiInputDevicePlugin* pDevice) {
397            MidiInputDeviceFactory::DestroyPrivate(pDevice);
398        }
399  }  }

Legend:
Removed from v.1777  
changed lines
  Added in v.1992

  ViewVC Help
Powered by ViewVC