/[svn]/gigedit/trunk/src/plugin/linuxsamplerplugin.cpp
ViewVC logotype

Diff of /gigedit/trunk/src/plugin/linuxsamplerplugin.cpp

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

revision 1853 by schoenebeck, Sun Mar 1 22:26:36 2009 UTC revision 3364 by schoenebeck, Tue Nov 14 18:07:25 2017 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2007, 2008 Andreas Persson   * Copyright (C) 2007 - 2017 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 19  Line 19 
19    
20  #include "linuxsamplerplugin.h"  #include "linuxsamplerplugin.h"
21    
22  #include <linuxsampler/plugins/InstrumentEditorFactory.h>  #ifdef LIBLINUXSAMPLER_HEADER_FILE
23    # include LIBLINUXSAMPLER_HEADER_FILE(plugins/InstrumentEditorFactory.h)
24    # include LIBLINUXSAMPLER_HEADER_FILE(engines/Engine.h)
25    # include LIBLINUXSAMPLER_HEADER_FILE(engines/EngineChannel.h)
26    #else
27    # include <linuxsampler/plugins/InstrumentEditorFactory.h>
28    # include <linuxsampler/engines/Engine.h>
29    # include <linuxsampler/engines/EngineChannel.h>
30    #endif
31    
32  #include "../gigedit/gigedit.h"  #include "../gigedit/gigedit.h"
33  #include "../gigedit/global.h"  #include "../gigedit/global.h"
34    
35  #include <iostream>  #include <iostream>
36  #include <sigc++/bind.h>  #ifdef SIGCPP_HEADER_FILE
37    # include SIGCPP_HEADER_FILE(bind.h)
38    #else
39    # include <sigc++/bind.h>
40    #endif
41  #include <glibmm/main.h>  #include <glibmm/main.h>
42    #include <set>
43    
44  REGISTER_INSTRUMENT_EDITOR(LinuxSamplerPlugin)  REGISTER_INSTRUMENT_EDITOR(LinuxSamplerPlugin)
45    
46    struct LSPluginPrivate {
47        std::set<gig::Region*> debounceRegionChange;
48        bool debounceRegionChangedScheduled;
49    
50        LSPluginPrivate() {
51            debounceRegionChangedScheduled = false;
52        }
53    };
54    
55  LinuxSamplerPlugin::LinuxSamplerPlugin() {  LinuxSamplerPlugin::LinuxSamplerPlugin() {
56      pApp = new GigEdit;      pApp = new GigEdit;
57        priv = new LSPluginPrivate;
58  }  }
59    
60  LinuxSamplerPlugin::~LinuxSamplerPlugin() {  LinuxSamplerPlugin::~LinuxSamplerPlugin() {
61      if (pApp) delete (GigEdit*) pApp;      if (pApp) delete static_cast<GigEdit*>(pApp);
62        if (priv) delete priv;
63    }
64    
65    int LinuxSamplerPlugin::Main(void* pInstrument, String sTypeName, String sTypeVersion, void* /*pUserData*/) {
66        return Main(pInstrument, sTypeName, sTypeVersion);
67  }  }
68    
69  int LinuxSamplerPlugin::Main(void* pInstrument, String sTypeName, String sTypeVersion) {  int LinuxSamplerPlugin::Main(void* pInstrument, String sTypeName, String sTypeVersion) {
70      std::cout << "Entered Gigedit Main() loop :)\n" << std::flush;      std::cout << "Entered Gigedit Main() loop :)\n" << std::flush;
71      gig::Instrument* pGigInstr = static_cast<gig::Instrument*>(pInstrument);      gig::Instrument* pGigInstr = static_cast<gig::Instrument*>(pInstrument);
72      GigEdit* app = (GigEdit*) pApp;      GigEdit* app = static_cast<GigEdit*>(pApp);
73    
74      // connect notification signals      // connect notification signals
75      app->signal_file_structure_to_be_changed().connect(      app->signal_file_structure_to_be_changed().connect(
# Line 82  int LinuxSamplerPlugin::Main(void* pInst Line 111  int LinuxSamplerPlugin::Main(void* pInst
111          )          )
112      );      );
113      app->signal_dimreg_to_be_changed().connect(      app->signal_dimreg_to_be_changed().connect(
114          sigc::bind(          // not connected directly anymore ...
115            /*sigc::bind(
116              sigc::mem_fun(              sigc::mem_fun(
117                  *this, &LinuxSamplerPlugin::NotifyDataStructureToBeChanged                  *this, &LinuxSamplerPlugin::NotifyDataStructureToBeChanged
118              ),              ),
119              "gig::DimensionRegion"              "gig::DimensionRegion"
120          )          )*/
121            // ... because we are doing some event debouncing here :
122            sigc::mem_fun(*this, &LinuxSamplerPlugin::__onDimRegionToBeChanged)
123      );      );
124      app->signal_dimreg_changed().connect(      app->signal_dimreg_changed().connect(
125          sigc::bind(          // not connected directly anymore ...
126            /*sigc::bind(
127              sigc::mem_fun(              sigc::mem_fun(
128                  *this, &LinuxSamplerPlugin::NotifyDataStructureChanged                  *this, &LinuxSamplerPlugin::NotifyDataStructureChanged
129              ),              ),
130              "gig::DimensionRegion"              "gig::DimensionRegion"
131          )          )*/
132            // ... because we are doing some event debouncing here :
133            sigc::mem_fun(*this, &LinuxSamplerPlugin::__onDimRegionChanged)
134      );      );
135      app->signal_sample_changed().connect(      app->signal_sample_changed().connect(
136          sigc::bind(          sigc::bind(
# Line 115  int LinuxSamplerPlugin::Main(void* pInst Line 150  int LinuxSamplerPlugin::Main(void* pInst
150      app->signal_keyboard_key_released().connect(      app->signal_keyboard_key_released().connect(
151          sigc::mem_fun(*this, &LinuxSamplerPlugin::__onVirtualKeyboardKeyReleased)          sigc::mem_fun(*this, &LinuxSamplerPlugin::__onVirtualKeyboardKeyReleased)
152      );      );
153        app->signal_switch_sampler_instrument().connect(
154            sigc::mem_fun(*this, &LinuxSamplerPlugin::__requestSamplerToSwitchInstrument)
155        );
156        app->signal_script_to_be_changed.connect(
157            sigc::bind(
158                sigc::mem_fun(
159                    *this, &LinuxSamplerPlugin::NotifyDataStructureToBeChanged
160                ),
161                "gig::Script"
162            )
163        );
164        app->signal_script_changed.connect(
165            sigc::bind(
166                sigc::mem_fun(
167                    *this, &LinuxSamplerPlugin::NotifyDataStructureChanged
168                ),
169                "gig::Script"
170            )
171        );
172    
173      // register a timeout job to gigedit's main loop, so we can poll the      // register a timeout job to gigedit's main loop, so we can poll the
174      // the sampler periodically for MIDI events (I HOPE it works on all      // the sampler periodically for MIDI events (I HOPE it works on all
# Line 131  int LinuxSamplerPlugin::Main(void* pInst Line 185  int LinuxSamplerPlugin::Main(void* pInst
185      return app->run(pGigInstr);      return app->run(pGigInstr);
186  }  }
187    
188    void LinuxSamplerPlugin::__onDimRegionToBeChanged(gig::DimensionRegion* pDimRgn) {
189        // instead of sending this signal per dimregion ...
190        //NotifyDataStructureToBeChanged(pDimRgn, "gig::DimensionRegion");
191    
192        // ... we are rather debouncing those dimregion to be changed events, and
193        // instead only send a region to be changed event, which is much faster when
194        // changing a very large amount of dimregions.
195        if (!pDimRgn) return;
196        gig::Region* pRegion = (gig::Region*) pDimRgn->GetParent();
197        const bool bIdle = priv->debounceRegionChange.empty();
198        bool bRegionLocked = priv->debounceRegionChange.count(pRegion);
199        if (!bRegionLocked) {
200            if (bIdle)
201                printf("DimRgn change event debounce BEGIN (%p)\n", pRegion);
202            priv->debounceRegionChange.insert(pRegion);
203            NotifyDataStructureToBeChanged(pRegion, "gig::Region");
204        }
205    }
206    
207    void LinuxSamplerPlugin::__onDimRegionChanged(gig::DimensionRegion* pDimRgn) {
208        // like above, not sending this ...
209        //NotifyDataStructureChanged(pDimRgn, "gig::DimensionRegion");
210    
211        // ... but rather aggressively debounce those dim region changed events and
212        // sending a debounced region changed event instead.
213        if (!pDimRgn) return;
214        if (!priv->debounceRegionChangedScheduled) {
215            priv->debounceRegionChangedScheduled = true;
216            Glib::signal_idle().connect_once(
217                sigc::mem_fun(*this, &LinuxSamplerPlugin::__onDimRegionChangedDebounced),
218                Glib::PRIORITY_HIGH_IDLE
219            );
220        }
221    }
222    
223    void LinuxSamplerPlugin::__onDimRegionChangedDebounced() {
224        // Note that we are really aggressively unlocking the region here: we are
225        // not even bothering whether the amount "changed" events match with the
226        // previously sent amount of "to be changed" events, because this handler
227        // here is only called when the app's event loop is already idle for a
228        // while, which is not the case if the app is still changing instrument
229        // parameters (except if the app is i.e. currently showing an error dialog
230        // to the user).
231        priv->debounceRegionChangedScheduled = false;
232        for (std::set<gig::Region*>::const_iterator it = priv->debounceRegionChange.begin();
233             it != priv->debounceRegionChange.end(); ++it)
234        {
235            gig::Region* pRegion = *it;
236            NotifyDataStructureChanged(pRegion, "gig::Region");
237        }
238        priv->debounceRegionChange.clear();
239        printf("DimRgn change event debounce END\n");
240    }
241    
242  bool LinuxSamplerPlugin::__onPollPeriod() {  bool LinuxSamplerPlugin::__onPollPeriod() {
243      #if HAVE_LINUXSAMPLER_VIRTUAL_MIDI_DEVICE      #if HAVE_LINUXSAMPLER_VIRTUAL_MIDI_DEVICE
244      GigEdit* app = (GigEdit*) pApp;      GigEdit* app = static_cast<GigEdit*>(pApp);
245      if (!NotesChanged()) return true;      if (!NotesChanged()) return true;
246      for (int iKey = 0; iKey < 128; iKey++)      for (int iKey = 0; iKey < 128; iKey++)
247          if (NoteChanged(iKey))          if (NoteChanged(iKey))
# Line 151  void LinuxSamplerPlugin::__onSamplesToBe Line 259  void LinuxSamplerPlugin::__onSamplesToBe
259      std::set<void*> samples;      std::set<void*> samples;
260      for (      for (
261          std::list<gig::Sample*>::iterator iter = lSamples.begin();          std::list<gig::Sample*>::iterator iter = lSamples.begin();
262          iter != lSamples.end(); iter++          iter != lSamples.end(); ++iter
263      ) samples.insert((void*)*iter);      ) samples.insert((void*)*iter);
264      // finally send notification to sampler      // finally send notification to sampler
265      NotifySamplesToBeRemoved(samples);      NotifySamplesToBeRemoved(samples);
# Line 169  void LinuxSamplerPlugin::__onVirtualKeyb Line 277  void LinuxSamplerPlugin::__onVirtualKeyb
277      #endif      #endif
278  }  }
279    
280    void LinuxSamplerPlugin::__requestSamplerToSwitchInstrument(gig::Instrument* pInstrument) {
281        if (!pInstrument) return;
282    
283        LinuxSampler::EngineChannel* pEngineChannel = GetEngineChannel();
284        if (!pEngineChannel) return;
285    
286        LinuxSampler::Engine* pEngine = pEngineChannel->GetEngine();
287        if (!pEngine) return;
288    
289        LinuxSampler::InstrumentManager* pInstrumentManager = pEngine->GetInstrumentManager();
290        if (!pInstrumentManager) return;
291    
292        gig::File* pFile = (gig::File*) pInstrument->GetParent();
293    
294        // resolve instrument's index number in its gig file
295        int index = -1;
296        for (int i = 0; pFile->GetInstrument(i); ++i) {
297            if (pFile->GetInstrument(i) == pInstrument) {
298                index = i;
299                break;
300            }
301        }
302        if (index < 0) return;
303    
304        LinuxSampler::InstrumentManager::instrument_id_t id;
305        id.FileName = pFile->GetFileName();
306        id.Index    = index;
307        pInstrumentManager->LoadInstrumentInBackground(id, pEngineChannel);
308    }
309    
310  bool LinuxSamplerPlugin::IsTypeSupported(String sTypeName, String sTypeVersion) {  bool LinuxSamplerPlugin::IsTypeSupported(String sTypeName, String sTypeVersion) {
311      return sTypeName == gig::libraryName() &&      return sTypeName == gig::libraryName() &&
312             sTypeVersion == gig::libraryVersion();             sTypeVersion == gig::libraryVersion();

Legend:
Removed from v.1853  
changed lines
  Added in v.3364

  ViewVC Help
Powered by ViewVC