/[svn]/linuxsampler/trunk/src/hostplugins/dssi/PluginDssi.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/hostplugins/dssi/PluginDssi.cpp

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

revision 1857 by persson, Mon Sep 15 16:58:10 2008 UTC revision 1858 by persson, Sun Mar 8 09:57:19 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 26  Line 26 
26    
27  #include "PluginDssi.h"  #include "PluginDssi.h"
28    
29    #include "../../engines/gig/EngineChannel.h"
30    
31  namespace {  namespace {
32    
33  // *************** PluginDssi ***************  // *************** PluginDssi ***************
34  // *  // *
35    
36      PluginDssi::PluginDssi(unsigned long SampleRate) {      PluginDssi::PluginDssi(unsigned long SampleRate) :
37          Out[0] = 0;          RefCount(0) {
         Out[1] = 0;  
   
38          // As there is no way in DSSI of knowing a max value of the          // As there is no way in DSSI of knowing a max value of the
39          // output buffer size, we set the audio device buffer size to          // output buffer size, we set the audio device buffer size to
40          // 128 and let RunSynth call Render in a loop if needed.          // 128 and let RunSynth call Render in a loop if needed.
41          Init(SampleRate, 128);          Init(SampleRate, 128);
42        }
43    
44        PluginDssi* PluginInstance::plugin = 0;
45    
46        PluginInstance::PluginInstance(unsigned long SampleRate) {
47            Out[0] = 0;
48            Out[1] = 0;
49    
50            uint outputChannel = 0;
51            uint midiPort = 0;
52            if (!plugin) {
53                plugin = new PluginDssi(SampleRate);
54            }
55            plugin->RefCount++;
56    
57          pChannel = global->pSampler->AddSamplerChannel();          pChannel = plugin->global->pSampler->AddSamplerChannel();
58          pChannel->SetEngineType("gig");          pChannel->SetEngineType("gig");
59          pChannel->SetAudioOutputDevice(pAudioDevice);          pChannel->SetAudioOutputDevice(plugin->pAudioDevice);
60          pChannel->SetMidiInputDevice(pMidiDevice);          LinuxSampler::MidiInputPort* port = plugin->pMidiDevice->CreateMidiPort();
61      }          port->Connect(pChannel->GetEngineChannel(), LinuxSampler::midi_chan_all);
62    
63            // TODO: remove dependency on gig engine
64            LinuxSampler::gig::EngineChannel* engineChannel =
65                (LinuxSampler::gig::EngineChannel*)pChannel->GetEngineChannel();
66            // TODO: pChannelLeft and pChannelRight are meant to be
67            // protected
68            engineChannel->pChannelLeft = new LinuxSampler::AudioChannel(0, 0, 0);
69            engineChannel->pChannelRight = new LinuxSampler::AudioChannel(1, 0, 0);
70        }
71    
72        PluginInstance::~PluginInstance() {
73            LinuxSampler::gig::EngineChannel* engineChannel =
74                (LinuxSampler::gig::EngineChannel*)pChannel->GetEngineChannel();
75            delete engineChannel->pChannelLeft;
76            delete engineChannel->pChannelRight;
77            LinuxSampler::MidiInputPort* port = engineChannel->pMidiInputPort;
78    
79            if (--plugin->RefCount == 0) {
80                delete plugin;
81                plugin = 0;
82            } else {
83                plugin->global->pSampler->RemoveSamplerChannel(pChannel);
84            }
85    
86      PluginDssi::~PluginDssi() {          LinuxSampler::MidiInputDevicePlugin::DeleteMidiPort(port);
87      }      }
88    
89      void PluginDssi::ConnectPort(unsigned long Port, LADSPA_Data* DataLocation) {      void PluginInstance::ConnectPort(unsigned long Port, LADSPA_Data* DataLocation) {
90          if (Port < 2) Out[Port] = DataLocation;          if (Port < 2) Out[Port] = DataLocation;
91      }      }
92    
93      char* PluginDssi::Configure(const char* Key, const char* Value) {      char* PluginInstance::Configure(const char* Key, const char* Value) {
94          dmsg(2, ("linuxsampler: configure Key=%s Value=%s\n", Key, Value));          dmsg(2, ("linuxsampler: configure Key=%s Value=%s\n", Key, Value));
95    
96          if (strcmp(Key, "instrument") == 0 && strcmp(Value, "") != 0) {          if (strcmp(Key, "instrument") == 0 && strcmp(Value, "") != 0) {
# Line 82  namespace { Line 118  namespace {
118          return 0;          return 0;
119      }      }
120    
121      inline void PluginDssi::RunSynth(unsigned long SampleCount,      inline void PluginInstance::RunMultipleSynths(unsigned long InstanceCount,
122                                       snd_seq_event_t* Events,                                                    LADSPA_Handle* Instances,
123                                       unsigned long EventCount) {                                                    unsigned long SampleCount,
124          LinuxSampler::MidiInputPort* port = pMidiDevice->Port();                                                    snd_seq_event_t** Events,
125                                                      unsigned long* EventCounts) {
126            if (InstanceCount == 0) return;
127    
128            LinuxSampler::AudioOutputDevicePlugin* audioDevice =
129                static_cast<PluginInstance*>(Instances[0])->plugin->pAudioDevice;
130    
131            unsigned eventPosArr[InstanceCount];
132            for (unsigned long i = 0 ; i < InstanceCount ; i++) eventPosArr[i] = 0;
133    
134          int samplePos = 0;          int samplePos = 0;
         unsigned eventPos = 0;  
135          while (SampleCount) {          while (SampleCount) {
136              int samples = std::min(SampleCount, 128UL);              int samples = std::min(SampleCount, 128UL);
137    
138              for ( ; eventPos < EventCount ; eventPos++) {              for (unsigned long i = 0 ; i < InstanceCount ; i++) {
139                  snd_seq_event_t* ev = &Events[eventPos];                  PluginInstance* instance = static_cast<PluginInstance*>(Instances[i]);
140                  int time = ev->time.tick - samplePos;                  LinuxSampler::EngineChannel* engineChannel =
141                  if (time >= samples) break;                      instance->pChannel->GetEngineChannel();
142                  switch (ev->type) {                  LinuxSampler::MidiInputPort* port = engineChannel->GetMidiInputPort();
143                  case SND_SEQ_EVENT_CONTROLLER:  
144                      port->DispatchControlChange(ev->data.control.param,                  snd_seq_event_t* events = Events[i];
145                                                  ev->data.control.value,                  unsigned& eventPos = eventPosArr[i];
                                                 ev->data.control.channel, time);  
                     break;  
146    
147                  case SND_SEQ_EVENT_CHANPRESS:                  for ( ; eventPos < EventCounts[i] ; eventPos++) {
148                      port->DispatchControlChange(128, ev->data.control.value,                      snd_seq_event_t* ev = &events[eventPos];
149                        int time = ev->time.tick - samplePos;
150                        if (time >= samples) break;
151                        switch (ev->type) {
152                        case SND_SEQ_EVENT_CONTROLLER:
153                            port->DispatchControlChange(ev->data.control.param,
154                                                        ev->data.control.value,
155                                                        ev->data.control.channel, time);
156                            break;
157    
158                        case SND_SEQ_EVENT_CHANPRESS:
159                            port->DispatchControlChange(128, ev->data.control.value,
160                                                        ev->data.control.channel, time);
161                            break;
162    
163                        case SND_SEQ_EVENT_PITCHBEND:
164                            port->DispatchPitchbend(ev->data.control.value,
165                                                  ev->data.control.channel, time);                                                  ev->data.control.channel, time);
166                      break;                          break;
167    
168                        case SND_SEQ_EVENT_NOTEON:
169                            port->DispatchNoteOn(ev->data.note.note,
170                                                 ev->data.note.velocity,
171                                                 ev->data.control.channel, time);
172                            break;
173    
174                        case SND_SEQ_EVENT_NOTEOFF:
175                            port->DispatchNoteOff(ev->data.note.note,
176                                                  ev->data.note.velocity,
177                                                  ev->data.control.channel, time);
178                            break;
179    
180                        case SND_SEQ_EVENT_SYSEX:
181                            port->DispatchSysex(ev->data.ext.ptr, ev->data.ext.len);
182                            break;
183                        }
184                    }
185    
186                  case SND_SEQ_EVENT_PITCHBEND:                  LinuxSampler::gig::EngineChannel* gigEngineChannel =
187                      port->DispatchPitchbend(ev->data.control.value,                      (LinuxSampler::gig::EngineChannel*)engineChannel;
188                                              ev->data.control.channel, time);                  gigEngineChannel->pChannelLeft->SetBuffer(instance->Out[0] + samplePos);
189                      break;                  gigEngineChannel->pChannelRight->SetBuffer(instance->Out[1] + samplePos);
190                    if (i) {
191                  case SND_SEQ_EVENT_NOTEON:                      gigEngineChannel->pChannelLeft->Clear(samples);
192                      port->DispatchNoteOn(ev->data.note.note,                      gigEngineChannel->pChannelRight->Clear(samples);
193                                           ev->data.note.velocity,                  } else {
194                                           ev->data.control.channel, time);                      // the buffer set in the audio device is cleared
195                      break;                      // by Render
196                        audioDevice->Channel(0)->SetBuffer(instance->Out[0] + samplePos);
197                  case SND_SEQ_EVENT_NOTEOFF:                      audioDevice->Channel(1)->SetBuffer(instance->Out[1] + samplePos);
                     port->DispatchNoteOff(ev->data.note.note,  
                                           ev->data.note.velocity,  
                                           ev->data.control.channel, time);  
                     break;  
   
                 case SND_SEQ_EVENT_SYSEX:  
                     port->DispatchSysex(ev->data.ext.ptr, ev->data.ext.len);  
                     break;  
198                  }                  }
199              }              }
200    
201              pAudioDevice->Channel(0)->SetBuffer(Out[0] + samplePos);              audioDevice->Render(samples);
             pAudioDevice->Channel(1)->SetBuffer(Out[1] + samplePos);  
             pAudioDevice->Render(samples);  
202    
203              samplePos += samples;              samplePos += samples;
204              SampleCount -= samples;              SampleCount -= samples;
205          }          }
206      }      }
207    
208      void PluginDssi::Activate() {      void PluginInstance::Activate() {
209          dmsg(2, ("linuxsampler: activate instance=%p\n", static_cast<void*>(this)));          dmsg(2, ("linuxsampler: activate instance=%p\n", static_cast<void*>(this)));
210          pMidiDevice->Port()->DispatchControlChange(123, 0, 0, 0); // all sound off          pChannel->GetEngineChannel()->GetMidiInputPort()->DispatchControlChange(123, 0, 0, 0); // all sound off
211      }      }
212    
213    
# Line 150  namespace { Line 216  namespace {
216    
217      LADSPA_Handle instantiate(const LADSPA_Descriptor* Descriptor,      LADSPA_Handle instantiate(const LADSPA_Descriptor* Descriptor,
218                                unsigned long SampleRate) {                                unsigned long SampleRate) {
219          return new PluginDssi(SampleRate);          return new PluginInstance(SampleRate);
220      }      }
221    
222      void cleanup(LADSPA_Handle Instance) {      void cleanup(LADSPA_Handle Instance) {
223          dmsg(2, ("linuxsampler: cleanup Instance=%p\n", static_cast<void*>(Instance)));          dmsg(2, ("linuxsampler: cleanup Instance=%p\n", static_cast<void*>(Instance)));
224          delete static_cast<PluginDssi*>(Instance);          delete static_cast<PluginInstance*>(Instance);
225      }      }
226    
227      void activate(LADSPA_Handle Instance) {      void activate(LADSPA_Handle Instance) {
228          static_cast<PluginDssi*>(Instance)->Activate();          static_cast<PluginInstance*>(Instance)->Activate();
229      }      }
230    
231      void connect_port(LADSPA_Handle Instance, unsigned long Port,      void connect_port(LADSPA_Handle Instance, unsigned long Port,
232                        LADSPA_Data* DataLocation) {                        LADSPA_Data* DataLocation) {
233          static_cast<PluginDssi*>(Instance)->ConnectPort(Port, DataLocation);          static_cast<PluginInstance*>(Instance)->ConnectPort(Port, DataLocation);
234      }      }
235    
236      void run(LADSPA_Handle Instance, unsigned long SampleCount) {      void run(LADSPA_Handle Instance, unsigned long SampleCount) {
237          static_cast<PluginDssi*>(Instance)->RunSynth(SampleCount, 0, 0);          return;
238      }      }
239    
240    
241  // *************** DSSI callback functions ***************  // *************** DSSI callback functions ***************
242  // *  // *
243    
     void run_synth(LADSPA_Handle Instance, unsigned long SampleCount,  
                    snd_seq_event_t* Events, unsigned long EventCount) {  
         static_cast<PluginDssi*>(Instance)->RunSynth(SampleCount, Events, EventCount);  
     }  
   
244      void run_multiple_synths(unsigned long InstanceCount,      void run_multiple_synths(unsigned long InstanceCount,
245                               LADSPA_Handle* Instances,                               LADSPA_Handle* Instances,
246                               unsigned long SampleCount,                               unsigned long SampleCount,
247                               snd_seq_event_t** Events,                               snd_seq_event_t** Events,
248                               unsigned long* EventCounts)                               unsigned long* EventCounts) {
249      {          PluginInstance::RunMultipleSynths(InstanceCount, Instances,
250          for (unsigned long i = 0 ; i < InstanceCount ; i++) {                                            SampleCount, Events,
251              static_cast<PluginDssi*>(Instances[i])->RunSynth(SampleCount, Events[i],                                            EventCounts);
                                                              EventCounts[i]);  
         }  
252      }      }
253    
254      char* configure(LADSPA_Handle Instance, const char* Key, const char* Value) {      char* configure(LADSPA_Handle Instance, const char* Key, const char* Value) {
255          return static_cast<PluginDssi*>(Instance)->Configure(Key, Value);          return static_cast<PluginInstance*>(Instance)->Configure(Key, Value);
256      }      }
257    
258    
# Line 209  namespace { Line 268  namespace {
268          Ladspa.Name = "LinuxSampler";          Ladspa.Name = "LinuxSampler";
269          Ladspa.Maker = "linuxsampler.org";          Ladspa.Maker = "linuxsampler.org";
270          Ladspa.Copyright = "(C) 2003,2004 Benno Senoner and Christian Schoenebeck, "          Ladspa.Copyright = "(C) 2003,2004 Benno Senoner and Christian Schoenebeck, "
271              "2005-2008 Christian Schoenebeck";              "2005-2009 Christian Schoenebeck";
272          Ladspa.PortCount = 2;          Ladspa.PortCount = 2;
273          Ladspa.ImplementationData = 0;          Ladspa.ImplementationData = 0;
274          Ladspa.PortDescriptors = PortDescriptors;          Ladspa.PortDescriptors = PortDescriptors;
# Line 238  namespace { Line 297  namespace {
297          Dssi.get_program = 0;          Dssi.get_program = 0;
298          Dssi.get_midi_controller_for_port = 0;          Dssi.get_midi_controller_for_port = 0;
299          Dssi.select_program = 0;          Dssi.select_program = 0;
300          Dssi.run_synth = run_synth;          Dssi.run_synth = 0;
301          Dssi.run_synth_adding = 0;          Dssi.run_synth_adding = 0;
302          Dssi.run_multiple_synths = run_multiple_synths;          Dssi.run_multiple_synths = run_multiple_synths;
303          Dssi.run_multiple_synths_adding = 0;          Dssi.run_multiple_synths_adding = 0;

Legend:
Removed from v.1857  
changed lines
  Added in v.1858

  ViewVC Help
Powered by ViewVC