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

Legend:
Removed from v.1907  
changed lines
  Added in v.2174

  ViewVC Help
Powered by ViewVC