/[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 1895 by persson, Sun May 3 12:15:40 2009 UTC revision 2165 by persson, Sun Feb 20 14:20:22 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 38  namespace LinuxSampler { Line 39  namespace LinuxSampler {
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 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          The sampler state is stored in a text base format, designed to
177          be easy to parse with the istream >> operator. Values are
178          separated by spaces or newlines. All string values that may
179          contain spaces end with a newline.
180    
181          The first line contains the global volume.
182    
183          The rest of the lines have an integer first representing the
184          type of information on the line, except for the two lines that
185          describe each sampler channel. The first of these two starts
186          with an integer from 0 to 16 (the midi channel for the sampler
187          channel).
188    
189          Note that we should try to keep the parsing of this format both
190          backwards and forwards compatible between versions. The parser
191          ignores lines with unknown type integers and accepts that new
192          types are missing.
193        */
194    
195        enum {
196            FXSEND = 17,
197            MIDIMAP,
198            MIDIMAPPING,
199            DEFAULTMIDIMAP
200        };
201    
202      String Plugin::GetState() {      String Plugin::GetState() {
203          std::stringstream s;          std::stringstream s;
204    
205          s << GLOBAL_VOLUME << '\n';          s << GLOBAL_VOLUME << '\n';
206    
207            std::vector<int> maps = MidiInstrumentMapper::Maps();
208            for (int i = 0 ; i < maps.size() ; i++) {
209                s << MIDIMAP << ' ' <<
210                    maps[i] << ' ' <<
211                    MidiInstrumentMapper::MapName(maps[i]) << '\n';
212    
213                std::map<midi_prog_index_t, MidiInstrumentMapper::entry_t> mappings = MidiInstrumentMapper::Entries(maps[i]);
214                for (std::map<midi_prog_index_t, MidiInstrumentMapper::entry_t>::iterator iter = mappings.begin() ;
215                     iter != mappings.end(); iter++) {
216                    s << MIDIMAPPING << ' ' <<
217                        ((int(iter->first.midi_bank_msb) << 7) |
218                         int(iter->first.midi_bank_lsb)) << ' ' <<
219                        int(iter->first.midi_prog) << ' ' <<
220                        iter->second.EngineName << ' ' <<
221                        iter->second.InstrumentFile << '\n' <<
222                        MIDIMAPPING << ' ' <<
223                        iter->second.InstrumentIndex << ' ' <<
224                        iter->second.Volume << ' ' <<
225                        iter->second.LoadMode << ' ' <<
226                        iter->second.Name << '\n';
227                }
228            }
229            if (maps.size()) {
230                s << DEFAULTMIDIMAP << ' ' <<
231                    MidiInstrumentMapper::GetDefaultMap() << '\n';
232            }
233    
234          std::map<uint, SamplerChannel*> channels = global->pSampler->GetSamplerChannels();          std::map<uint, SamplerChannel*> channels = global->pSampler->GetSamplerChannels();
235          for (std::map<uint, SamplerChannel*>::iterator iter = channels.begin() ;          for (std::map<uint, SamplerChannel*>::iterator iter = channels.begin() ;
236               iter != channels.end() ; iter++) {               iter != channels.end() ; iter++) {
# Line 177  namespace LinuxSampler { Line 243  namespace LinuxSampler {
243                      filename << '\n' <<                      filename << '\n' <<
244                      engine_channel->InstrumentIndex() << ' ' <<                      engine_channel->InstrumentIndex() << ' ' <<
245                      engine_channel->GetSolo() << ' ' <<                      engine_channel->GetSolo() << ' ' <<
246                      (engine_channel->GetMute() == 1) << '\n';                      (engine_channel->GetMute() == 1) << ' ' <<
247                        engine_channel->OutputChannel(0) << ' ' <<
248                        engine_channel->OutputChannel(1) << ' ' <<
249                        (engine_channel->UsesNoMidiInstrumentMap() ? -2 :
250                         (engine_channel->UsesDefaultMidiInstrumentMap() ? -1 :
251                          engine_channel->GetMidiInstrumentMap())) << ' ' <<
252                        engine_channel->EngineName() << '\n';
253    
254                    for (int i = 0 ; i < engine_channel->GetFxSendCount() ; i++) {
255                        FxSend* fxsend = engine_channel->GetFxSend(i);
256                        s << FXSEND << ' ' <<
257                            fxsend->Level() << ' ' <<
258                            int(fxsend->MidiController()) << ' ' <<
259                            fxsend->DestinationChannel(0) << ' ' <<
260                            fxsend->DestinationChannel(1) << ' ' <<
261                            fxsend->Name() << '\n';
262                    }
263              }              }
264          }          }
265          return s.str();          return s.str();
# Line 198  namespace LinuxSampler { Line 280  namespace LinuxSampler {
280    
281      bool Plugin::SetState(String State) {      bool Plugin::SetState(String State) {
282          RemoveChannels();          RemoveChannels();
283            MidiInstrumentMapper::RemoveAllMaps();
284    
285          std::stringstream s(State);          std::stringstream s(State);
286          s >> GLOBAL_VOLUME;          s >> GLOBAL_VOLUME;
287    
288          int midiChannel;          EngineChannel* engine_channel;
289          float volume;          int midiMapId;
290          while (s >> midiChannel >> volume) {          std::map<int, int> oldToNewId;
291              s.ignore();          int type;
292              String filename;          while (s >> type) {
293              std::getline(s, filename);  
294              int index;              if (type <= 16) { // sampler channel
295              bool solo;                  int midiChannel = type;
296              bool mute;                  float volume;
297              s >> index >> solo >> mute;                  s >> volume;
298                    s.ignore();
299              SamplerChannel* channel = global->pSampler->AddSamplerChannel();                  String filename;
300              channel->SetEngineType("gig");                  std::getline(s, filename);
301              channel->SetAudioOutputDevice(pAudioDevice);                  int index;
302              channel->SetMidiInputDevice(pMidiDevice);                  bool solo;
303              channel->SetMidiInputChannel(midi_chan_t(midiChannel));                  bool mute;
304                    s >> index >> solo >> mute;
305              EngineChannel* engine_channel = channel->GetEngineChannel();  
306              engine_channel->Volume(volume);                  int left = -1;
307              if (!filename.empty() && index != -1) {                  int right;
308                  InstrumentManager::instrument_id_t id;                  int oldMapId;
309                  id.FileName = filename;                  String engineType = "gig";
310                  id.Index    = index;                  if (s.get() == ' ') {
311                  InstrumentManager::LoadInstrumentInBackground(id, engine_channel);                      s >> left >> right >> oldMapId;
312                        if (s.get() == ' ') {
313                            s >> engineType;
314                            // skip rest of line
315                            s.ignore(std::numeric_limits<int>::max(), '\n');
316                        }
317                    }
318                    SamplerChannel* channel = global->pSampler->AddSamplerChannel();
319                    channel->SetEngineType(engineType);
320                    channel->SetAudioOutputDevice(pAudioDevice);
321                    channel->SetMidiInputDevice(pMidiDevice);
322                    channel->SetMidiInputChannel(midi_chan_t(midiChannel));
323    
324                    engine_channel = channel->GetEngineChannel();
325                    engine_channel->Volume(volume);
326    
327                    if (left != -1) {
328                        engine_channel->SetOutputChannel(0, left);
329                        engine_channel->SetOutputChannel(1, right);
330    
331                        if (oldMapId == -1) {
332                            engine_channel->SetMidiInstrumentMapToDefault();
333                        } else if (oldMapId >= 0) {
334                            engine_channel->SetMidiInstrumentMap(oldToNewId[oldMapId]);
335                        }
336                    }
337                    if (!filename.empty() && index != -1) {
338                        InstrumentManager::instrument_id_t id;
339                        id.FileName = filename;
340                        id.Index    = index;
341                        InstrumentManager::LoadInstrumentInBackground(id, engine_channel);
342                    }
343                    if (solo) engine_channel->SetSolo(solo);
344                    if (mute) engine_channel->SetMute(1);
345    
346                } else if (type == FXSEND) {
347                    float level;
348                    int controller;
349                    int fxleft;
350                    int fxright;
351                    String name;
352    
353                    s >> level >> controller >> fxleft >> fxright;
354                    s.ignore();
355                    std::getline(s, name);
356                    FxSend* send = engine_channel->AddFxSend(controller, name);
357                    send->SetLevel(level);
358                    send->SetDestinationChannel(0, fxleft);
359                    send->SetDestinationChannel(1, fxright);
360    
361                } else if (type == MIDIMAP) {
362                    int oldId;
363                    s >> oldId;
364                    String name;
365                    s.ignore();
366                    std::getline(s, name);
367                    midiMapId = MidiInstrumentMapper::AddMap(name);
368                    oldToNewId[oldId] = midiMapId;
369    
370                } else if (type == MIDIMAPPING) {
371                    int bank;
372                    int prog;
373                    String engine;
374                    String file;
375                    int index;
376                    float volume;
377                    int loadmode;
378                    String name;
379    
380                    s >> bank >> prog >> engine;
381                    s.ignore();
382                    std::getline(s, file);
383                    s >> type >> index >> volume >> loadmode;
384                    s.ignore();
385                    std::getline(s, name);
386    
387                    global->pLSCPServer->AddOrReplaceMIDIInstrumentMapping(
388                        midiMapId, bank, prog, engine, file, index, volume,
389                        MidiInstrumentMapper::mode_t(loadmode), name, false);
390    
391                } else if (type == DEFAULTMIDIMAP) {
392                    int oldId;
393                    s >> oldId;
394                    MidiInstrumentMapper::SetDefaultMap(oldToNewId[oldId]);
395    
396                } else { // unknown type
397                    // try to be forward-compatible and just skip the line
398                    s.ignore(std::numeric_limits<int>::max(), '\n');
399              }              }
             if (solo) engine_channel->SetSolo(solo);  
             if (mute) engine_channel->SetMute(1);  
400          }          }
401    
402          return true;          return true;
403      }      }
404    
405        void Plugin::DestroyDevice(AudioOutputDevicePlugin* pDevice) {
406            AudioOutputDeviceFactory::DestroyPrivate(pDevice);
407        }
408    
409        void Plugin::DestroyDevice(MidiInputDevicePlugin* pDevice) {
410            MidiInputDeviceFactory::DestroyPrivate(pDevice);
411        }
412  }  }

Legend:
Removed from v.1895  
changed lines
  Added in v.2165

  ViewVC Help
Powered by ViewVC