/[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 1835 by iliev, Mon Feb 16 17:56:50 2009 UTC revision 2185 by persson, Sun Jun 19 09:09:38 2011 UTC
# Line 1  Line 1 
1  /***************************************************************************  /***************************************************************************
2   *                                                                         *   *                                                                         *
3   *   Copyright (C) 2008 Andreas Persson                                    *   *   Copyright (C) 2008 - 2011 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    
51            #if defined(__APPLE__)
52            // AU plugin sometimes hangs if bound to loopback
53            pLSCPServer = new LSCPServer(pSampler, htonl(INADDR_ANY), htons(LSCP_PORT));
54            #else
55          // using LOOPBACK instead of ANY to prevent windows firewall          // using LOOPBACK instead of ANY to prevent windows firewall
56          // warnings          // warnings
57          pLSCPServer = new LSCPServer(pSampler, htonl(INADDR_LOOPBACK),          pLSCPServer = new LSCPServer(pSampler, htonl(INADDR_LOOPBACK), htons(LSCP_PORT));
58                                       htons(LSCP_PORT));          #endif
59    
60          pLSCPServer->StartThread();          pLSCPServer->StartThread();
61          pLSCPServer->WaitUntilInitialized();          pLSCPServer->WaitUntilInitialized();
62    
# Line 82  namespace LinuxSampler { Line 87  namespace LinuxSampler {
87    
88      int EventThread::Main() {      int EventThread::Main() {
89          for (;;) {          for (;;) {
90                TestCancel();
91              sleep(1);              sleep(1);
92              pSampler->fireStatistics();              pSampler->fireStatistics();
93          }          }
94            return 0;
95      }      }
96    
97    
# Line 111  namespace LinuxSampler { Line 118  namespace LinuxSampler {
118      }      }
119    
120      void Plugin::Init(int SampleRate, int FragmentSize, int Channels) {      void Plugin::Init(int SampleRate, int FragmentSize, int Channels) {
121            if (pAudioDevice && SampleRate == pAudioDevice->SampleRate() &&
122                FragmentSize == pAudioDevice->MaxSamplesPerCycle()) {
123                return; // nothing has changed
124            }
125    
126            String oldState;
127            if (pAudioDevice) {
128                oldState = GetState();
129                RemoveChannels();
130                AudioOutputDeviceFactory::DestroyPrivate(pAudioDevice);
131            }
132          std::map<String, String> params;          std::map<String, String> params;
133          params["SAMPLERATE"] = ToString(SampleRate);          params["SAMPLERATE"] = ToString(SampleRate);
134          params["FRAGMENTSIZE"] = ToString(FragmentSize);          params["FRAGMENTSIZE"] = ToString(FragmentSize);
135          if (Channels > 0) params["CHANNELS"] = ToString(Channels);          if (Channels > 0) params["CHANNELS"] = ToString(Channels);
136          pAudioDevice = dynamic_cast<AudioOutputDevicePlugin*>(          pAudioDevice = dynamic_cast<AudioOutputDevicePlugin*>(
137              global->pSampler->CreateAudioOutputDevice(AudioOutputDevicePlugin::Name(), params));              AudioOutputDeviceFactory::CreatePrivate(
138                    AudioOutputDevicePlugin::Name(), params
139                )
140            );
141    
142            if (!pMidiDevice) {
143                pMidiDevice = dynamic_cast<MidiInputDevicePlugin*>(
144                    MidiInputDeviceFactory::CreatePrivate(
145                        MidiInputDevicePlugin::Name(), std::map<String,String>(),
146                        global->pSampler
147                    )
148                );
149            }
150    
151          pMidiDevice = dynamic_cast<MidiInputDevicePlugin*>(          if (!oldState.empty()) {
152              global->pSampler->CreateMidiInputDevice(MidiInputDevicePlugin::Name(),              SetState(oldState);
153                                                      std::map<String,String>()));          }
154      }      }
155    
156      Plugin::~Plugin() {      Plugin::~Plugin() {
157          RemoveChannels();          RemoveChannels();
158          if (pAudioDevice) global->pSampler->DestroyAudioOutputDevice(pAudioDevice);          if (pAudioDevice) AudioOutputDeviceFactory::DestroyPrivate(pAudioDevice);
159          if (pMidiDevice) global->pSampler->DestroyMidiInputDevice(pMidiDevice);          if (pMidiDevice) MidiInputDeviceFactory::DestroyPrivate(pMidiDevice);
160          if (bPreInitDone) {          if (bPreInitDone) {
161              if (--global->RefCount == 0) {              if (--global->RefCount == 0) {
162                  delete global;                  delete global;
# Line 143  namespace LinuxSampler { Line 173  namespace LinuxSampler {
173          channel->SetMidiInputChannel(midi_chan_1);          channel->SetMidiInputChannel(midi_chan_1);
174      }      }
175    
176        /*
177          These methods can be overloaded by different plugin types to map
178          file names to/from file names to be used in the state text, making
179          it possible for state to be self-contained and/or movable.
180        */
181    
182        String Plugin::PathToState(const String& string) {
183            return string;
184        }
185    
186        String Plugin::PathFromState(const String& string) {
187            return string;
188        }
189    
190        /*
191          The sampler state is stored in a text base format, designed to
192          be easy to parse with the istream >> operator. Values are
193          separated by spaces or newlines. All string values that may
194          contain spaces end with a newline.
195    
196          The first line contains the global volume.
197    
198          The rest of the lines have an integer first representing the
199          type of information on the line, except for the two lines that
200          describe each sampler channel. The first of these two starts
201          with an integer from 0 to 16 (the midi channel for the sampler
202          channel).
203    
204          Note that we should try to keep the parsing of this format both
205          backwards and forwards compatible between versions. The parser
206          ignores lines with unknown type integers and accepts that new
207          types are missing.
208        */
209    
210        enum {
211            FXSEND = 17,
212            MIDIMAP,
213            MIDIMAPPING,
214            DEFAULTMIDIMAP
215        };
216    
217      String Plugin::GetState() {      String Plugin::GetState() {
218          std::stringstream s;          std::stringstream s;
219    
220          s << GLOBAL_VOLUME << '\n';          s << GLOBAL_VOLUME << '\n';
221    
222            std::vector<int> maps = MidiInstrumentMapper::Maps();
223            for (int i = 0 ; i < maps.size() ; i++) {
224                s << MIDIMAP << ' ' <<
225                    maps[i] << ' ' <<
226                    MidiInstrumentMapper::MapName(maps[i]) << '\n';
227    
228                std::map<midi_prog_index_t, MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(maps[i]);
229                for (std::map<midi_prog_index_t, MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin() ;
230                     iter != mappings.end(); iter++) {
231                    s << MIDIMAPPING << ' ' <<
232                        ((int(iter->first.midi_bank_msb) << 7) |
233                         int(iter->first.midi_bank_lsb)) << ' ' <<
234                        int(iter->first.midi_prog) << ' ' <<
235                        iter->second.EngineName << ' ' <<
236                        PathToState(iter->second.InstrumentFile) << '\n' <<
237                        MIDIMAPPING << ' ' <<
238                        iter->second.InstrumentIndex << ' ' <<
239                        iter->second.Volume << ' ' <<
240                        iter->second.LoadMode << ' ' <<
241                        iter->second.Name << '\n';
242                }
243            }
244            if (maps.size()) {
245                s << DEFAULTMIDIMAP << ' ' <<
246                    MidiInstrumentMapper::GetDefaultMap() << '\n';
247            }
248    
249          std::map<uint, SamplerChannel*> channels = global->pSampler->GetSamplerChannels();          std::map<uint, SamplerChannel*> channels = global->pSampler->GetSamplerChannels();
250          for (std::map<uint, SamplerChannel*>::iterator iter = channels.begin() ;          for (std::map<uint, SamplerChannel*>::iterator iter = channels.begin() ;
251               iter != channels.end() ; iter++) {               iter != channels.end() ; iter++) {
# Line 157  namespace LinuxSampler { Line 255  namespace LinuxSampler {
255                  String filename = engine_channel->InstrumentFileName();                  String filename = engine_channel->InstrumentFileName();
256                  s << channel->GetMidiInputChannel() << ' ' <<                  s << channel->GetMidiInputChannel() << ' ' <<
257                      engine_channel->Volume() << ' ' <<                      engine_channel->Volume() << ' ' <<
258                      filename << '\n' <<                      PathToState(filename) << '\n' <<
259                      engine_channel->InstrumentIndex() << ' ' <<                      engine_channel->InstrumentIndex() << ' ' <<
260                      engine_channel->GetSolo() << ' ' <<                      engine_channel->GetSolo() << ' ' <<
261                      (engine_channel->GetMute() == 1) << '\n';                      (engine_channel->GetMute() == 1) << ' ' <<
262                        engine_channel->OutputChannel(0) << ' ' <<
263                        engine_channel->OutputChannel(1) << ' ' <<
264                        (engine_channel->UsesNoMidiInstrumentMap() ? -2 :
265                         (engine_channel->UsesDefaultMidiInstrumentMap() ? -1 :
266                          engine_channel->GetMidiInstrumentMap())) << ' ' <<
267                        engine_channel->EngineName() << '\n';
268    
269                    for (int i = 0 ; i < engine_channel->GetFxSendCount() ; i++) {
270                        FxSend* fxsend = engine_channel->GetFxSend(i);
271                        s << FXSEND << ' ' <<
272                            fxsend->Level() << ' ' <<
273                            int(fxsend->MidiController()) << ' ' <<
274                            fxsend->DestinationChannel(0) << ' ' <<
275                            fxsend->DestinationChannel(1) << ' ' <<
276                            fxsend->Name() << '\n';
277                    }
278              }              }
279          }          }
280          return s.str();          return s.str();
# Line 181  namespace LinuxSampler { Line 295  namespace LinuxSampler {
295    
296      bool Plugin::SetState(String State) {      bool Plugin::SetState(String State) {
297          RemoveChannels();          RemoveChannels();
298            MidiInstrumentMapper::RemoveAllMaps();
299    
300          std::stringstream s(State);          std::stringstream s(State);
301          s >> GLOBAL_VOLUME;          s >> GLOBAL_VOLUME;
302    
303          int midiChannel;          EngineChannel* engine_channel;
304          float volume;          int midiMapId;
305          while (s >> midiChannel >> volume) {          std::map<int, int> oldToNewId;
306              s.ignore();          int type;
307              String filename;          while (s >> type) {
308              std::getline(s, filename);  
309              int index;              if (type <= 16) { // sampler channel
310              bool solo;                  int midiChannel = type;
311              bool mute;                  float volume;
312              s >> index >> solo >> mute;                  s >> volume;
313                    s.ignore();
314              SamplerChannel* channel = global->pSampler->AddSamplerChannel();                  String filename;
315              channel->SetEngineType("gig");                  std::getline(s, filename);
316              channel->SetAudioOutputDevice(pAudioDevice);                  int index;
317              channel->SetMidiInputDevice(pMidiDevice);                  bool solo;
318              channel->SetMidiInputChannel(midi_chan_t(midiChannel));                  bool mute;
319                    s >> index >> solo >> mute;
320              EngineChannel* engine_channel = channel->GetEngineChannel();  
321              engine_channel->Volume(volume);                  int left = -1;
322              if (!filename.empty() && index != -1) {                  int right;
323                  engine_channel->PrepareLoadInstrument(filename.c_str(), index);                  int oldMapId;
324                  engine_channel->LoadInstrument();                  String engineType = "gig";
325                    if (s.get() == ' ') {
326                        s >> left >> right >> oldMapId;
327                        if (s.get() == ' ') {
328                            s >> engineType;
329                            // skip rest of line
330                            s.ignore(std::numeric_limits<int>::max(), '\n');
331                        }
332                    }
333                    SamplerChannel* channel = global->pSampler->AddSamplerChannel();
334                    channel->SetEngineType(engineType);
335                    channel->SetAudioOutputDevice(pAudioDevice);
336                    channel->SetMidiInputDevice(pMidiDevice);
337                    channel->SetMidiInputChannel(midi_chan_t(midiChannel));
338    
339                    engine_channel = channel->GetEngineChannel();
340                    engine_channel->Volume(volume);
341    
342                    if (left != -1) {
343                        engine_channel->SetOutputChannel(0, left);
344                        engine_channel->SetOutputChannel(1, right);
345    
346                        if (oldMapId == -1) {
347                            engine_channel->SetMidiInstrumentMapToDefault();
348                        } else if (oldMapId >= 0) {
349                            engine_channel->SetMidiInstrumentMap(oldToNewId[oldMapId]);
350                        }
351                    }
352                    if (!filename.empty() && index != -1) {
353                        InstrumentManager::instrument_id_t id;
354                        id.FileName = PathFromState(filename);
355                        id.Index    = index;
356                        InstrumentManager::LoadInstrumentInBackground(id, engine_channel);
357                    }
358                    if (solo) engine_channel->SetSolo(solo);
359                    if (mute) engine_channel->SetMute(1);
360    
361                } else if (type == FXSEND) {
362                    float level;
363                    int controller;
364                    int fxleft;
365                    int fxright;
366                    String name;
367    
368                    s >> level >> controller >> fxleft >> fxright;
369                    s.ignore();
370                    std::getline(s, name);
371                    FxSend* send = engine_channel->AddFxSend(controller, name);
372                    send->SetLevel(level);
373                    send->SetDestinationChannel(0, fxleft);
374                    send->SetDestinationChannel(1, fxright);
375    
376                } else if (type == MIDIMAP) {
377                    int oldId;
378                    s >> oldId;
379                    String name;
380                    s.ignore();
381                    std::getline(s, name);
382                    midiMapId = MidiInstrumentMapper::AddMap(name);
383                    oldToNewId[oldId] = midiMapId;
384    
385                } else if (type == MIDIMAPPING) {
386                    int bank;
387                    int prog;
388                    String engine;
389                    String file;
390                    int index;
391                    float volume;
392                    int loadmode;
393                    String name;
394    
395                    s >> bank >> prog >> engine;
396                    s.ignore();
397                    std::getline(s, file);
398                    s >> type >> index >> volume >> loadmode;
399                    s.ignore();
400                    std::getline(s, name);
401    
402                    global->pLSCPServer->AddOrReplaceMIDIInstrumentMapping(
403                        midiMapId, bank, prog, engine, file, index, volume,
404                        MidiInstrumentMapper::mode_t(loadmode), name, false);
405    
406                } else if (type == DEFAULTMIDIMAP) {
407                    int oldId;
408                    s >> oldId;
409                    MidiInstrumentMapper::SetDefaultMap(oldToNewId[oldId]);
410    
411                } else { // unknown type
412                    // try to be forward-compatible and just skip the line
413                    s.ignore(std::numeric_limits<int>::max(), '\n');
414              }              }
             if (solo) engine_channel->SetSolo(solo);  
             if (mute) engine_channel->SetMute(1);  
415          }          }
416    
417          return true;          return true;
418      }      }
419    
420        void Plugin::DestroyDevice(AudioOutputDevicePlugin* pDevice) {
421            AudioOutputDeviceFactory::DestroyPrivate(pDevice);
422        }
423    
424        void Plugin::DestroyDevice(MidiInputDevicePlugin* pDevice) {
425            MidiInputDeviceFactory::DestroyPrivate(pDevice);
426        }
427  }  }

Legend:
Removed from v.1835  
changed lines
  Added in v.2185

  ViewVC Help
Powered by ViewVC