diff options
| author | Florian Jung <flo@windfisch.org> | 2011-04-27 16:57:12 +0000 | 
|---|---|---|
| committer | Florian Jung <flo@windfisch.org> | 2011-04-27 16:57:12 +0000 | 
| commit | 0f7a7ab47a2a7742fba2ea6af980ee5d950b8c37 (patch) | |
| tree | 34ce8136927d4ba5627df7dc40defdbc59e5d885 /muse2/muse | |
| parent | 928081edaa0752e14577c36b6b595ab38079224a (diff) | |
| parent | 499ccec21dd2ac636fb019c98a902c351b4ec165 (diff) | |
32-notes are now fully supported (also 32-rests are supported now)
corrected a bug
updated AUTHORS
merged with trunk
Diffstat (limited to 'muse2/muse')
| -rw-r--r-- | muse2/muse/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | muse2/muse/app.cpp | 2 | ||||
| -rw-r--r-- | muse2/muse/audiotrack.cpp | 6 | ||||
| -rw-r--r-- | muse2/muse/controlfifo.cpp | 75 | ||||
| -rw-r--r-- | muse2/muse/controlfifo.h | 64 | ||||
| -rw-r--r-- | muse2/muse/ctrl.h | 3 | ||||
| -rw-r--r-- | muse2/muse/driver/alsamidi.h | 2 | ||||
| -rw-r--r-- | muse2/muse/driver/audiodev.h | 2 | ||||
| -rw-r--r-- | muse2/muse/driver/dummyaudio.cpp | 2 | ||||
| -rw-r--r-- | muse2/muse/driver/jackaudio.h | 2 | ||||
| -rw-r--r-- | muse2/muse/driver/jackmidi.h | 2 | ||||
| -rw-r--r-- | muse2/muse/dssihost.cpp | 430 | ||||
| -rw-r--r-- | muse2/muse/dssihost.h | 29 | ||||
| -rw-r--r-- | muse2/muse/mididev.h | 2 | ||||
| -rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 42 | ||||
| -rw-r--r-- | muse2/muse/midiedit/scoreedit.h | 2 | ||||
| -rw-r--r-- | muse2/muse/mixer/astrip.cpp | 28 | ||||
| -rw-r--r-- | muse2/muse/mixer/panknob.cpp | 5 | ||||
| -rw-r--r-- | muse2/muse/osc.cpp | 43 | ||||
| -rw-r--r-- | muse2/muse/osc.h | 6 | ||||
| -rw-r--r-- | muse2/muse/plugin.cpp | 704 | ||||
| -rw-r--r-- | muse2/muse/plugin.h | 140 | ||||
| -rw-r--r-- | muse2/muse/song.cpp | 1 | ||||
| -rw-r--r-- | muse2/muse/synth.cpp | 5 | ||||
| -rw-r--r-- | muse2/muse/synth.h | 6 | 
25 files changed, 1282 insertions, 322 deletions
| diff --git a/muse2/muse/CMakeLists.txt b/muse2/muse/CMakeLists.txt index 2a630f84..2d2a9fe3 100644 --- a/muse2/muse/CMakeLists.txt +++ b/muse2/muse/CMakeLists.txt @@ -83,6 +83,7 @@ file (GLOB core_source_files        cobject.cpp        conf.cpp        confmport.cpp +      controlfifo.cpp        ctrl.cpp        dssihost.cpp         event.cpp diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index 80a7b7ef..8def91ec 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -4952,7 +4952,7 @@ again:                    }              }        microSleep(100000); -      song->clear(false, clear_all); +      song->clear(true, clear_all);        microSleep(100000);        return false;        } diff --git a/muse2/muse/audiotrack.cpp b/muse2/muse/audiotrack.cpp index 98e74331..c427a55c 100644 --- a/muse2/muse/audiotrack.cpp +++ b/muse2/muse/audiotrack.cpp @@ -989,7 +989,8 @@ bool AudioTrack::readProperties(Xml& xml, const QString& tag)              //PluginI* p = 0;              PluginIBase* p = 0;                   bool ctlfound = false; -            int m = l->id() & AC_PLUGIN_CTL_ID_MASK; +            //int m = l->id() & AC_PLUGIN_CTL_ID_MASK; +            unsigned m = l->id() & AC_PLUGIN_CTL_ID_MASK;       // p4.0.21              int n = (l->id() >> AC_PLUGIN_CTL_BASE_POW) - 1;              if(n >= 0 && n < PipelineDepth)              { @@ -1163,7 +1164,8 @@ void AudioTrack::mapRackPluginsToControllers()        // Ignore volume, pan, mute etc.        if(id < AC_PLUGIN_CTL_BASE)          continue; -      int param = id & AC_PLUGIN_CTL_ID_MASK; +      //int param = id & AC_PLUGIN_CTL_ID_MASK; +      unsigned param = id & AC_PLUGIN_CTL_ID_MASK;    // p4.0.21        int idx = (id >> AC_PLUGIN_CTL_BASE_POW) - 1;        //PluginI* p = (*_efxPipe)[idx]; diff --git a/muse2/muse/controlfifo.cpp b/muse2/muse/controlfifo.cpp new file mode 100644 index 00000000..526e88c7 --- /dev/null +++ b/muse2/muse/controlfifo.cpp @@ -0,0 +1,75 @@ +//============================================================================= +//  MusE +//  Linux Music Editor +// +//  Copyright (C) 1999-2010 by Werner Schweer and others +// +//  This program is free software; you can redistribute it and/or modify +//  it under the terms of the GNU General Public License version 2. +// +//  This program is distributed in the hope that it will be useful, +//  but WITHOUT ANY WARRANTY; without even the implied warranty of +//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +//  GNU General Public License for more details. +// +//  You should have received a copy of the GNU General Public License +//  along with this program; if not, write to the Free Software +//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "controlfifo.h" + +//--------------------------------------------------------- +//   ControlFifo +//    put +//    return true on fifo overflow +//--------------------------------------------------------- + +bool ControlFifo::put(const ControlEvent& event) +      { +      if (size < CONTROL_FIFO_SIZE) { +            fifo[wIndex] = event; +            wIndex = (wIndex + 1) % CONTROL_FIFO_SIZE; +            // q_atomic_increment(&size); +            ++size; +            return false; +            } +      return true; +      } + +//--------------------------------------------------------- +//   get +//--------------------------------------------------------- + +ControlEvent ControlFifo::get() +      { +      ControlEvent event(fifo[rIndex]); +      rIndex = (rIndex + 1) % CONTROL_FIFO_SIZE; +      // q_atomic_decrement(&size); +      --size; +      return event; +      } + +//--------------------------------------------------------- +//   peek +//--------------------------------------------------------- + +const ControlEvent& ControlFifo::peek(int n) +      { +      int idx = (rIndex + n) % CONTROL_FIFO_SIZE; +      return fifo[idx]; +      } + +//--------------------------------------------------------- +//   remove +//--------------------------------------------------------- + +void ControlFifo::remove() +      { +      rIndex = (rIndex + 1) % CONTROL_FIFO_SIZE; +      // q_atomic_decrement(&size); +      --size; +      } + + + diff --git a/muse2/muse/controlfifo.h b/muse2/muse/controlfifo.h new file mode 100644 index 00000000..a0b6bfd0 --- /dev/null +++ b/muse2/muse/controlfifo.h @@ -0,0 +1,64 @@ +//============================================================================= +//  MusE +//  Linux Music Editor +// +//  Copyright (C) 1999-2010 by Werner Schweer and others +// +//  This program is free software; you can redistribute it and/or modify +//  it under the terms of the GNU General Public License version 2. +// +//  This program is distributed in the hope that it will be useful, +//  but WITHOUT ANY WARRANTY; without even the implied warranty of +//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +//  GNU General Public License for more details. +// +//  You should have received a copy of the GNU General Public License +//  along with this program; if not, write to the Free Software +//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __CONTROLFIFO_H__ +#define __CONTROLFIFO_H__ + +#define CONTROL_FIFO_SIZE 8192 + +//--------------------------------------------------------- +//  ControlEvent +//  Item struct for ControlFifo.  +//--------------------------------------------------------- + +struct ControlEvent +{ +  // Unique: Whether the item must not be skipped, even if it has the same  +  //  (possibly rounded) frame and index as the previous item. This is mainly for  +  //  dssi-vst guis, they require acknowledgment of every message. +  bool unique;  +  unsigned idx; +  float value; +  unsigned frame;     +}; + +//--------------------------------------------------------- +//  ControlFifo +//--------------------------------------------------------- + +class ControlFifo +{ +      ControlEvent fifo[CONTROL_FIFO_SIZE]; +      volatile int size; +      int wIndex; +      int rIndex; + +   public: +      ControlFifo()  { clear(); } +      bool put(const ControlEvent& event);   // returns true on fifo overflow +      ControlEvent get(); +      const ControlEvent& peek(int n = 0); +      void remove(); +      bool isEmpty() const { return size == 0; } +      void clear()         { size = 0, wIndex = 0, rIndex = 0; } +      int getSize() const  { return size; } +}; + + +#endif
\ No newline at end of file diff --git a/muse2/muse/ctrl.h b/muse2/muse/ctrl.h index 4d864b9f..955fd01f 100644 --- a/muse2/muse/ctrl.h +++ b/muse2/muse/ctrl.h @@ -23,7 +23,8 @@ const int AC_MUTE   = 2;  #define AC_PLUGIN_CTL_BASE_POW     12  #define AC_PLUGIN_CTL_ID_MASK      0xFFF -inline int genACnum(int plugin, int ctrl) { return (plugin + 1) * AC_PLUGIN_CTL_BASE + ctrl; } +//inline int genACnum(int plugin, int ctrl) { return (plugin + 1) * AC_PLUGIN_CTL_BASE + ctrl; } +inline unsigned genACnum(unsigned plugin, unsigned ctrl) { return (plugin + 1) * AC_PLUGIN_CTL_BASE + ctrl; }  class Xml; diff --git a/muse2/muse/driver/alsamidi.h b/muse2/muse/driver/alsamidi.h index 455ab1df..a2480c5c 100644 --- a/muse2/muse/driver/alsamidi.h +++ b/muse2/muse/driver/alsamidi.h @@ -44,7 +44,7 @@ class MidiAlsaDevice : public MidiDevice {        virtual void* outClientPort() { return (void*)&adr; }    // That is, ALSA midi client ports can be both r/w.        virtual void writeRouting(int, Xml&) const; -      virtual inline int deviceType() { return ALSA_MIDI; }  +      virtual inline int deviceType() const { return ALSA_MIDI; }         };  extern bool initMidiAlsa(); diff --git a/muse2/muse/driver/audiodev.h b/muse2/muse/driver/audiodev.h index af53d7de..4685b89a 100644 --- a/muse2/muse/driver/audiodev.h +++ b/muse2/muse/driver/audiodev.h @@ -28,7 +28,7 @@ class AudioDevice {        AudioDevice() {}        virtual ~AudioDevice() {} -      virtual int deviceType() = 0;  // p3.3.52 +      virtual int deviceType() const = 0;  // p3.3.52        //virtual void start() = 0;        virtual void start(int priority) = 0; diff --git a/muse2/muse/driver/dummyaudio.cpp b/muse2/muse/driver/dummyaudio.cpp index 597ecf2b..55f091c2 100644 --- a/muse2/muse/driver/dummyaudio.cpp +++ b/muse2/muse/driver/dummyaudio.cpp @@ -66,7 +66,7 @@ class DummyAudioDevice : public AudioDevice {          free(buffer);         } -      virtual inline int deviceType() { return DUMMY_AUDIO; } // p3.3.52 +      virtual inline int deviceType() const { return DUMMY_AUDIO; } // p3.3.52        //virtual void start();        virtual void start(int); diff --git a/muse2/muse/driver/jackaudio.h b/muse2/muse/driver/jackaudio.h index d3132efe..5be0797f 100644 --- a/muse2/muse/driver/jackaudio.h +++ b/muse2/muse/driver/jackaudio.h @@ -38,7 +38,7 @@ class JackAudioDevice : public AudioDevice {        virtual ~JackAudioDevice();        virtual void nullify_client() { _client = 0; } -      virtual inline int deviceType() { return JACK_AUDIO; }   // p3.3.52 +      virtual inline int deviceType() const { return JACK_AUDIO; }   // p3.3.52        void scanMidiPorts(); diff --git a/muse2/muse/driver/jackmidi.h b/muse2/muse/driver/jackmidi.h index 842cbc2d..2dcf2fbb 100644 --- a/muse2/muse/driver/jackmidi.h +++ b/muse2/muse/driver/jackmidi.h @@ -129,7 +129,7 @@ class MidiJackDevice : public MidiDevice {        //static MidiDevice* createJackMidiDevice(QString /*name*/, int /*rwflags*/); // 1:Writable 2: Readable. Do not mix.        static MidiDevice* createJackMidiDevice(QString name = "", int rwflags = 3); // p3.3.55 1:Writable 2: Readable 3: Writable + Readable -      virtual inline int deviceType() { return JACK_MIDI; }  +      virtual inline int deviceType() const { return JACK_MIDI; }         virtual void setName(const QString&); diff --git a/muse2/muse/dssihost.cpp b/muse2/muse/dssihost.cpp index f2e94dae..b91000be 100644 --- a/muse2/muse/dssihost.cpp +++ b/muse2/muse/dssihost.cpp @@ -48,6 +48,7 @@  #include "midiport.h"  #include "stringparam.h"  #include "plugin.h" +#include "controlfifo.h"  //#include "al/al.h"  //#include "al/xml.h"  #include "xml.h" @@ -550,8 +551,10 @@ DssiSynth::DssiSynth(QFileInfo& fi, const DSSI_Descriptor* d) : // ddskrjo remov    _inPlaceCapable = !LADSPA_IS_INPLACE_BROKEN(descr->Properties); -  // Blacklist vst plugins in-place configurable for now.  -  if ((_inports != _outports) || (fi.completeBaseName() == QString("dssi-vst") && !config.vstInPlace)) +  // Hack: Special flag required for example for control processing. +  _isDssiVst = fi.completeBaseName() == QString("dssi-vst"); +  // Hack: Blacklist vst plugins in-place, configurable for now.  +  if ((_inports != _outports) || (_isDssiVst && !config.vstInPlace))          _inPlaceCapable = false;  } @@ -677,8 +680,10 @@ SynthIF* DssiSynth::createSIF(SynthI* synti)            }            _inPlaceCapable = !LADSPA_IS_INPLACE_BROKEN(descr->Properties); -          // Blacklist vst plugins in-place configurable for now.  -          if((_inports != _outports) || (info.completeBaseName() == QString("dssi-vst") && !config.vstInPlace)) +          // Hack: Special flag required for example for control processing. +          _isDssiVst = info.completeBaseName() == QString("dssi-vst"); +          // Hack: Blacklist vst plugins in-place, configurable for now.  +          if((_inports != _outports) || (_isDssiVst && !config.vstInPlace))              _inPlaceCapable = false;          }          }   @@ -1374,10 +1379,22 @@ void DssiSynthIF::setParameter(unsigned long n, float v)      return;    } -  if(!controls) -    return; -   -  controls[n].val = v; +  //if(!controls) +  //  return; +  //controls[n].val = v; +  // p4.0.21 +  ControlEvent ce; +  ce.unique = false; +  ce.idx = n; +  ce.value = v; +  // Time-stamp the event. This does a possibly slightly slow call to gettimeofday via timestamp(). +  //  timestamp() is more or less an estimate of the current frame. (This is exactly how ALSA events  +  //  are treated when they arrive in our ALSA driver.)  +  ce.frame = audio->timestamp();   +  if(_controlFifo.put(ce)) +  { +    fprintf(stderr, "DssiSynthIF::setParameter: fifo overflow: in control number:%ld\n", n); +  }    // Notify that changes are to be sent upon heartbeat.    // TODO: No, at least not for now. So far, setParameter is only called during loading of stored params, @@ -1579,7 +1596,7 @@ bool DssiSynthIF::processEvent(const MidiPlayEvent& e, snd_seq_event_t* event)    len += 2;    //snd_seq_event_t* event = &events[nevents]; -  event->queue = SND_SEQ_QUEUE_DIRECT; +  //event->queue = SND_SEQ_QUEUE_DIRECT;    #ifdef DSSI_DEBUG     fprintf(stderr, "DssiSynthIF::processEvent midi event type:%d chn:%d a:%d b:%d\n", e.type(), chn, a, b); @@ -1592,12 +1609,16 @@ bool DssiSynthIF::processEvent(const MidiPlayEvent& e, snd_seq_event_t* event)        fprintf(stderr, "DssiSynthIF::processEvent midi event is ME_NOTEON\n");        #endif +      snd_seq_ev_clear(event);  +      event->queue = SND_SEQ_QUEUE_DIRECT;        if(b)          snd_seq_ev_set_noteon(event, chn, a, b);        else          snd_seq_ev_set_noteoff(event, chn, a, 0);      break;      case ME_NOTEOFF: +      snd_seq_ev_clear(event);  +      event->queue = SND_SEQ_QUEUE_DIRECT;        snd_seq_ev_set_noteoff(event, chn, a, 0);      break;      case ME_PROGRAM: @@ -1665,6 +1686,8 @@ bool DssiSynthIF::processEvent(const MidiPlayEvent& e, snd_seq_event_t* event)          #endif          b &= 0x3fff; +        snd_seq_ev_clear(event);  +        event->queue = SND_SEQ_QUEUE_DIRECT;          snd_seq_ev_set_pitchbend(event, chn, b);          // Event pointer filled. Return true.          return true; @@ -1697,7 +1720,7 @@ bool DssiSynthIF::processEvent(const MidiPlayEvent& e, snd_seq_event_t* event)          int ctlnum = a;          //switch(midiControllerType(a))          if(midiControllerType(a) != MidiController::Controller7) -          return false; +          return false;   // Event pointer not filled. Return false.          else            {            /* @@ -1782,6 +1805,8 @@ bool DssiSynthIF::processEvent(const MidiPlayEvent& e, snd_seq_event_t* event)          #ifdef DSSI_DEBUG           printf("DssiSynthIF::processEvent non-ladspa filling midi event chn:%d dataA:%d dataB:%d\n", chn, a, b);          #endif +        snd_seq_ev_clear(event);  +        event->queue = SND_SEQ_QUEUE_DIRECT;          snd_seq_ev_set_controller(event, chn, a, b);          return true;        } @@ -1867,9 +1892,13 @@ bool DssiSynthIF::processEvent(const MidiPlayEvent& e, snd_seq_event_t* event)      }      break;      case ME_PITCHBEND: +      snd_seq_ev_clear(event);  +      event->queue = SND_SEQ_QUEUE_DIRECT;        snd_seq_ev_set_pitchbend(event, chn, a);      break;      case ME_AFTERTOUCH: +      snd_seq_ev_clear(event);  +      event->queue = SND_SEQ_QUEUE_DIRECT;        snd_seq_ev_set_chanpress(event, chn, a);      break;      case ME_SYSEX: @@ -1948,6 +1977,8 @@ bool DssiSynthIF::processEvent(const MidiPlayEvent& e, snd_seq_event_t* event)          // "DssiSynthIF::processEvent midi event is ME_SYSEX"          // "WARNING: MIDI event of type ? decoded to 367 bytes, discarding"          // That might be ALSA doing that. +        snd_seq_ev_clear(event);  +        event->queue = SND_SEQ_QUEUE_DIRECT;          snd_seq_ev_set_sysex(event, len,            //(unsigned char*)ba.data());            (unsigned char*)ca); @@ -1964,6 +1995,8 @@ bool DssiSynthIF::processEvent(const MidiPlayEvent& e, snd_seq_event_t* event)    return true;  } +#if 0 +  //---------------------------------------------------------  //   getData  //--------------------------------------------------------- @@ -2241,6 +2274,331 @@ iMPEvent DssiSynthIF::getData(MidiPort* /*mp*/, MPEventList* el, iMPEvent i, uns    return i;  } +#else + +//--------------------------------------------------------- +//   getData +//--------------------------------------------------------- + +//void DssiSynthIF::getData(MidiEventList* el, unsigned pos, int ch, unsigned samples, float** data) +iMPEvent DssiSynthIF::getData(MidiPort* /*mp*/, MPEventList* el, iMPEvent i, unsigned pos, int ports, unsigned n, float** buffer) +{ +  //#ifdef DSSI_DEBUG  +  //  fprintf(stderr, "DssiSynthIF::getData elsize:%d pos:%d ports:%d samples:%d processed already?:%d\n", el->size(), pos, ports, n, synti->processed()); +  //#endif +   +  // Grab the control ring buffer size now. +  //const int cbsz = _controlFifo.getSize();  +   +  // We may not be using nevents all at once - this will be just the maximum.  +  unsigned long nevents = el->size() + synti->eventFifo.getSize();  +  snd_seq_event_t events[nevents]; +  // No, do this in processEvent. +  //memset(events, 0, sizeof(events));  +   +  //nevents = 0; + +  unsigned endPos = pos + n; +  int frameOffset = audio->getFrameOffset(); +   +  // All ports must be connected to something! +  unsigned long nop, k; +  // First, copy the given input buffers to our local input buffers. +  //np = portsin > synth->_inports ? synth->_inports : portsin; +  //for(k = 0; k < np; ++k) +  //  memcpy(audioInBuffers[k], inbuffer[k], sizeof(float) * n); +  //for(; k < portsin; ++k) +  //  memset(audioInBuffers[k], 0, sizeof(float) * n); +   +  // Watch our limits. +  //willyfoobar-2011-02-13 +  //old code//np = ports > synth->_outports ? synth->_outports : ports; +  nop = ((unsigned long) ports) > synth->_outports ? synth->_outports : ((unsigned long) ports); +  // TODO Number of inports requested? +  //nip = ((unsigned long) iports) > synth->_inports ? synth->_inports : ((unsigned long) iports); +   +  const DSSI_Descriptor* dssi = synth->dssi; +  const LADSPA_Descriptor* descr = dssi->LADSPA_Plugin; +  unsigned sample = 0; +  int loopcount = 0;      // REMOVE Tim. +   +  // NOTE Tested: Variable run-lengths worked superbly for LADSPA and DSSI synths. But DSSI-VST definitely  +  //  does NOT like changing sample run length. It crashes the plugin and Wine (but MusE keeps running!).  +  // Furthermore, it resizes the shared memory (mmap, remap) upon each run length DIFFERENT from the last.  +  // And all of this done through client-server communications. It doesn't seem designed for this technique. +  // +  // So we could support an alternate technique: A fixed control processing rate, in number of samples.  +  // +  // Allow user to choose either a fixed rate or these 'packets' for LADSPA and DSSI plugins/synths,  +  //  but make fixed-rate MANDATORY for DSSI-VST plugins and synths. +  //  +  // Or K.I.S.S - Just use fixed rates only, but allow it to be changed. I'm worried about libraries and +  //  plugins other than DSSI-VST. What if they need the fixed-rate, too? +  // How to tell, and manage it all...? +  // But this 'packet' method sure seems to work nicely so far, so we'll throw it in... +  // +  // Must make this detectable for dssi vst synths, just like the plugins' in-place blacklist. +  //const bool usefixedrate = true;       +  const bool usefixedrate = synth->_isDssiVst;  // Try this. +  // TODO Make this number a global setting. +  // Note for dssi-vst this MUST equal audio period. It doesn't like broken-up runs (it stutters),  +  //  even with fixed sizes. Could be a Wine + Jack thing, wanting a full Jack buffer's length. +  //unsigned fixedsize = 2048;    +  unsigned fixedsize = n;      +   +  // For now, the fixed size is clamped to the audio buffer size. +  // TODO: We could later add slower processing over several cycles - +  //  so that users can select a small audio period but a larger control period.  +  if(fixedsize > n) +    fixedsize = n; +   +  while(sample < n) +  { +    //unsigned nsamp = n; +    //unsigned nsamp = n - sample; +    unsigned nsamp = usefixedrate ? fixedsize : n - sample; +    bool found = false; +    unsigned frame = 0;  +    unsigned index = 0; +    // Get all control ring buffer items valid for this time period... +    //for(int m = 0; m < cbsz; ++m) +    while(!_controlFifo.isEmpty()) +    { +      //ControlValue v = _controlFifo.get();  +      ControlEvent v = _controlFifo.peek();  +      //printf("DssiSynthIF::getData control idx:%d frame:%d val:%f\n", v.idx, v.frame, v.value);   // REMOVE Tim. +      // Process only items in this time period. Make sure to process all +      //  subsequent items which have the same frame.  +      //if(v.frame >= (endPos + frameOffset) || (found && v.frame != frame))   +      //if(v.frame < sample || v.frame >= (sample + nsamp) || (found && v.frame != frame))   +      //if(v.frame < sample || v.frame >= (endPos + frameOffset) || (found && v.frame != frame))   +      if(v.frame < sample || v.frame >= (endPos + frameOffset)   +         //|| (found && v.frame != frame)   +         //|| (!usefixedrate && found && !v.unique && v.frame != frame)   +         || (found && !v.unique && v.frame != frame)   +         // dssi-vst needs them serialized and accounted for, no matter what. This works with fixed rate  +         //  because nsamp is constant. But with packets, we need to guarantee at least one-frame spacing.  +         // Although we likely won't be using packets with dssi-vst, so it's OK for now. +         //|| (found && v.idx == index))   +         //|| (usefixedrate && found && v.idx == index))  // Try this. +         || (usefixedrate && found && v.unique && v.idx == index))  //  +        break; +      _controlFifo.remove();               // Done with the ring buffer's item. Remove it. +      if(v.idx >= synth->_controlInPorts) // Sanity check. +        break; +      found = true; +      frame = v.frame; +      index = v.idx; +      // Set the ladspa control port value. +      controls[v.idx].val = v.value; +    } +     +    //if(found) +    if(found && !usefixedrate) +      //nsamp = frame - sample + 1; +      nsamp = frame - sample; +    if(sample + nsamp >= n)         // Safety check. +      nsamp = n - sample;  +     +    //printf("DssiSynthIF::getData n:%d frame:%d sample:%d nsamp:%d pos:%d fOffset:%d loopcount:%d\n",  +    //       n, frame, sample, nsamp, pos, frameOffset, loopcount);   // REMOVE Tim. +     +    // TODO: TESTING: Don't allow zero-length runs. This could/should be checked in the control loop instead. +    // Note this means it is still possible to get stuck in the top loop (at least for a while). +    if(nsamp == 0) +      continue; +       +    nevents = 0; +    // Process event list events... +    for(; i != el->end(); ++i)  +    { +      //if(i->time() >= (endPos + frameOffset))  // NOTE: frameOffset? Tested, examined printouts of times: Seems OK for playback. +      if(i->time() >= (pos + sample + nsamp + frameOffset))  // frameOffset? Test again... +        break; +         +      #ifdef DSSI_DEBUG  +      fprintf(stderr, "DssiSynthIF::getData eventlist event time:%d\n", i->time()); +      #endif +       +      // p3.3.39 Update hardware state so knobs and boxes are updated. Optimize to avoid re-setting existing values. +      // Same code as in MidiPort::sendEvent() +      if(synti->midiPort() != -1) +      { +        MidiPort* mp = &midiPorts[synti->midiPort()]; +        if(i->type() == ME_CONTROLLER)  +        { +          int da = i->dataA(); +          int db = i->dataB(); +          db = mp->limitValToInstrCtlRange(da, db); +          if(!mp->setHwCtrlState(i->channel(), da, db)) +            continue; +          //mp->setHwCtrlState(i->channel(), da, db); +        } +        else +        if(i->type() == ME_PITCHBEND)  +        { +          int da = mp->limitValToInstrCtlRange(CTRL_PITCH, i->dataA()); +          if(!mp->setHwCtrlState(i->channel(), CTRL_PITCH, da)) +            continue; +          //mp->setHwCtrlState(i->channel(), CTRL_PITCH, da); +        } +        else +        if(i->type() == ME_PROGRAM)  +        { +          if(!mp->setHwCtrlState(i->channel(), CTRL_PROGRAM, i->dataA())) +            continue; +          //mp->setHwCtrlState(i->channel(), CTRL_PROGRAM, i->dataA()); +        } +      } +           +      // Returns false if the event was not filled. It was handled, but some other way. +      if(processEvent(*i, &events[nevents])) +      { +        // Time-stamp the event.   p4.0.15 Tim. +        int ft = i->time() - frameOffset - pos; +        if(ft < 0) +          ft = 0; +        //if (ft >= (int)segmentSize)  +        if (ft >= int(sample + nsamp))  +        { +          //printf("DssiSynthIF::getData: eventlist event time:%d out of range. pos:%d offset:%d ft:%d (seg=%d)\n", i->time(), pos, frameOffset, ft, segmentSize); +          printf("DssiSynthIF::getData: eventlist event time:%d out of range. pos:%d offset:%d ft:%d sample:%d nsamp:%d\n", i->time(), pos, frameOffset, ft, sample, nsamp); +          ///if (ft > (int)segmentSize) +            //ft = segmentSize - 1; +            ft = sample + nsamp - 1; +        } +        // "Each event is timestamped relative to the start of the block, (mis)using the ALSA "tick time" field as a frame count.  +        //  The host is responsible for ensuring that events with differing timestamps are already ordered by time."  -  From dssi.h +        events[nevents].time.tick = ft; +         +        ++nevents; +      }   +    } +     +    // Now process putEvent events... +    while(!synti->eventFifo.isEmpty())  +    { +      //MidiPlayEvent e = synti->eventFifo.get();   +      MidiPlayEvent e = synti->eventFifo.peek();   +       +      #ifdef DSSI_DEBUG  +      fprintf(stderr, "DssiSynthIF::getData eventFifo event time:%d\n", e.time()); +      #endif +       +      //if(e.time() >= (endPos + frameOffset))   +      if(e.time() >= (pos + sample + nsamp + frameOffset))   +        break; +       +      synti->eventFifo.remove();    // Done with ring buffer's event. Remove it. +      // Returns false if the event was not filled. It was handled, but some other way. +      if(processEvent(e, &events[nevents])) +      { +        // Time-stamp the event.   p4.0.15 Tim. +        int ft = e.time() - frameOffset - pos; +        if(ft < 0) +          ft = 0; +        //if (ft >= (int)segmentSize)  +        if (ft >= int(sample + nsamp))  +        { +          //printf("DssiSynthIF::getData: eventFifo event time:%d out of range. pos:%d offset:%d ft:%d (seg=%d)\n", e.time(), pos, frameOffset, ft, segmentSize); +          printf("DssiSynthIF::getData: eventFifo event time:%d out of range. pos:%d offset:%d ft:%d sample:%d nsamp:%d\n", e.time(), pos, frameOffset, ft, sample, nsamp); +          ///if (ft > (int)segmentSize) +            //ft = segmentSize - 1; +            ft = sample + nsamp - 1; +        } +        // "Each event is timestamped relative to the start of the block, (mis)using the ALSA "tick time" field as a frame count.  +        //  The host is responsible for ensuring that events with differing timestamps are already ordered by time."  -  From dssi.h +        events[nevents].time.tick = ft; +         +        ++nevents; +      }   +    } +     +    /* +    // +    // p3.3.39 Handle inputs... +    // +    //if((song->bounceTrack != this) && !noInRoute())  +    if(!((AudioTrack*)synti)->noInRoute())  +    { +      RouteList* irl = ((AudioTrack*)synti)->inRoutes(); +      iRoute i = irl->begin(); +      if(!i->track->isMidiTrack()) +      { +        //if(debugMsg) +          printf("DssiSynthIF::getData: Error: First route is a midi track route!\n"); +      } +      else +      { +        int ch     = i->channel       == -1 ? 0 : i->channel; +        int remch  = i->remoteChannel == -1 ? 0 : i->remoteChannel; +        int chs    = i->channels      == -1 ? 0 : i->channels; +         +        // TODO: +        //if(ch >= synth->_inports) +        //iUsedIdx[ch] = true; +        //if(chs == 2) +        //  iUsedIdx[ch + 1] = true; +         +        //((AudioTrack*)i->track)->copyData(framePos, channels, nframe, bp); +        ((AudioTrack*)i->track)->copyData(pos, ports,  +                                        //(i->track->type() == Track::AUDIO_SOFTSYNTH && i->channel != -1) ? i->channel : 0,  +                                        i->channel,  +                                        i->channels, +                                        n, bp); +      } +       +      //unsigned pos, int ports, unsigned n, float** buffer     +       +      ++i; +      for(; i != irl->end(); ++i) +      { +        if(i->track->isMidiTrack()) +        { +          //if(debugMsg) +            printf("DssiSynthIF::getData: Error: Route is a midi track route!\n"); +          continue; +        } +        //((AudioTrack*)i->track)->addData(framePos, channels, nframe, bp); +        ((AudioTrack*)i->track)->addData(framePos, channels,  +                                          //(i->track->type() == Track::AUDIO_SOFTSYNTH && i->channel != -1) ? i->channel : 0,  +                                          i->channel,  +                                          i->channels, +                                          nframe, bp); +      } +    }   +    */   +       +    k = 0; +    // Connect the given buffers directly to the ports, up to a max of synth ports. +    for(; k < nop; ++k) +      descr->connect_port(handle, synth->oIdx[k], buffer[k] + sample); +    // Connect the remaining ports to some local buffers (not used yet). +    for(; k < synth->_outports; ++k) +      descr->connect_port(handle, synth->oIdx[k], audioOutBuffers[k] + sample); +    // Just connect all inputs to some local buffers (not used yet). TODO: Support inputs.  +    for(k = 0; k < synth->_inports; ++k) +      descr->connect_port(handle, synth->iIdx[k], audioInBuffers[k] + sample); +     +    // Run the synth for a period of time. This processes events and gets/fills our local buffers... +    if(synth->dssi->run_synth) +    { +      synth->dssi->run_synth(handle, nsamp, events, nevents); +    }   +    else if (synth->dssi->run_multiple_synths)  +    { +      snd_seq_event_t* ev = events; +      synth->dssi->run_multiple_synths(1, &handle, nsamp, &ev, &nevents); +    } +     +    sample += nsamp; +    loopcount++;       // REMOVE Tim. +  } +   +  return i; +} +#endif +  //---------------------------------------------------------  //   putEvent  //--------------------------------------------------------- @@ -2607,7 +2965,7 @@ int DssiSynthIF::oscControl(unsigned long port, float value)    //LADSPA_Data value = argv[1]->f;    #ifdef DSSI_DEBUG  -  printf("DssiSynthIF::oscControl received oscControl port:%ld val:%f\n", port, value); +  printf("DssiSynthIF::oscControl received oscControl port:%ld val:%f\n", port, value);      #endif    //int controlPorts = synth->_controlInPorts; @@ -2641,19 +2999,17 @@ int DssiSynthIF::oscControl(unsigned long port, float value)    //  because dssi-vst is WAITING FOR A RESPONSE. (A CHANGE in the control port value).     // It will output something like "...4 events expected..." and count that number down as 4 actual control port value CHANGES    //  are done here in response. Normally it says "...0 events expected..." when MusE is the one doing the DSSI control changes. -  // TODO: (Done) May need FIFOs on each control(!) so that the control changes get sent one per process cycle.  -  // Observed countdown not actually going to zero upon string of changes.    //    // NOTE: NOTE: This line in RemoteVSTServer::setParameter(int p, float v) in dssi-vst-server.cpp :    //    //  " if (tv.tv_sec > m_lastGuiComms.tv_sec + 10) "    //    //  explains an observation that after ten seconds, the server automatically clears the expected number to 0. -  // TODO: Now MusE should forget about all the VST fifo events past ten+ (?) seconds. Add event timestamps...    // You can't send any 'new' values until either you a): send all the expected events or b): wait ten seconds.    // (Because the server simply ignores the 'expected' messages.)    //    // Well, at least here are the fifos. Try this ... +  /*    OscControlFifo* cfifo = _oscif.oscFifo(cport);     if(cfifo)    { @@ -2669,6 +3025,21 @@ int DssiSynthIF::oscControl(unsigned long port, float value)        fprintf(stderr, "DssiSynthIF::oscControl: fifo overflow: in control number:%ld\n", cport);      }    } +  */ +  // p4.0.21 +  ControlEvent ce; +  ce.unique = synth->_isDssiVst;    // Special for messages from vst gui to host - requires processing every message. +  ce.idx = cport; +  ce.value = value; +  // Time-stamp the event. This does a possibly slightly slow call to gettimeofday via timestamp(). +  //  timestamp() is more or less an estimate of the current frame. (This is exactly how ALSA events  +  //  are treated when they arrive in our ALSA driver.)  +  ce.frame = audio->timestamp();   +  if(_controlFifo.put(ce)) +  { +    fprintf(stderr, "DssiSynthIF::oscControl: fifo overflow: in control number:%ld\n", cport); +  } +      //const DSSI_Descriptor* dssi = synth->dssi;    //const LADSPA_Descriptor* ld = dssi->LADSPA_Plugin; @@ -2976,7 +3347,8 @@ int DssiSynthIF::getControllerInfo(int id, const char** name, int* ctrl, int* mi    ///int i = synth->pIdx[id];    //int i = synth->pIdx[k]; -  int i = controls[id].idx; +  //int i = controls[id].idx; +  unsigned i = controls[id].idx;   // p4.0.21    //ladspaDefaultValue(ld, i, &controls[id].val); @@ -3103,7 +3475,8 @@ int DssiSynthIF::totalInChannels() const  bool DssiSynthIF::on() const                                 { return true; }  // Synth is not part of a rack plugin chain. Always on.  void DssiSynthIF::setOn(bool /*val*/)                        { }    -int DssiSynthIF::pluginID()                                  { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->UniqueID : 0; }  +//int DssiSynthIF::pluginID()                                  { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->UniqueID : 0; }  +unsigned DssiSynthIF::pluginID()                             { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->UniqueID : 0; }     //int DssiSynthIF::id()                                        { return 0; } // Synth is not part of a rack plugin chain. Always 0.  int DssiSynthIF::id()                                        { return MAX_PLUGINS; } // Set for special block reserved for dssi synth. p4.0.20  QString DssiSynthIF::pluginLabel() const                     { return (synth && synth->dssi) ? QString(synth->dssi->LADSPA_Plugin->Label) : QString(); }  @@ -3112,18 +3485,27 @@ QString DssiSynthIF::lib() const                             { return synth ? sy  QString DssiSynthIF::dirPath() const                         { return synth ? synth->absolutePath() : QString(); }  QString DssiSynthIF::fileName() const                        { return synth ? synth->fileName() : QString(); }  AudioTrack* DssiSynthIF::track()                             { return (AudioTrack*)synti; } -void DssiSynthIF::enableController(int i, bool v)            { controls[i].enCtrl = v; }  -bool DssiSynthIF::controllerEnabled(int i) const             { return controls[i].enCtrl; }   -bool DssiSynthIF::controllerEnabled2(int i) const            { return controls[i].en2Ctrl; }    +//void DssiSynthIF::enableController(int i, bool v)            { controls[i].enCtrl = v; }  +//bool DssiSynthIF::controllerEnabled(int i) const             { return controls[i].enCtrl; }   +//bool DssiSynthIF::controllerEnabled2(int i) const            { return controls[i].en2Ctrl; }    +void DssiSynthIF::enableController(unsigned i, bool v)       { controls[i].enCtrl = v; }  +bool DssiSynthIF::controllerEnabled(unsigned i) const        { return controls[i].enCtrl; }   +bool DssiSynthIF::controllerEnabled2(unsigned i) const       { return controls[i].en2Ctrl; }     void DssiSynthIF::updateControllers()                        { }  void DssiSynthIF::writeConfiguration(int /*level*/, Xml& /*xml*/)        { }  bool DssiSynthIF::readConfiguration(Xml& /*xml*/, bool /*readPreset*/) { return false; } -int DssiSynthIF::parameters() const                          { return synth ? synth->_controlInPorts : 0; } -void DssiSynthIF::setParam(int i, double val)                { setParameter(i, val); } -double DssiSynthIF::param(int i) const                       { return getParameter(i); } -const char* DssiSynthIF::paramName(int i)                    { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortNames[controls[i].idx] : 0; } +//int DssiSynthIF::parameters() const                          { return synth ? synth->_controlInPorts : 0; } +//void DssiSynthIF::setParam(int i, double val)                { setParameter(i, val); } +//double DssiSynthIF::param(int i) const                       { return getParameter(i); } +//const char* DssiSynthIF::paramName(int i)                    { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortNames[controls[i].idx] : 0; }  //LADSPA_PortRangeHint DssiSynthIF::range(int i)               { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortRangeHints[i] : 0; } -LADSPA_PortRangeHint DssiSynthIF::range(int i)               { return synth->dssi->LADSPA_Plugin->PortRangeHints[controls[i].idx]; } +//LADSPA_PortRangeHint DssiSynthIF::range(int i)               { return synth->dssi->LADSPA_Plugin->PortRangeHints[controls[i].idx]; } +unsigned DssiSynthIF::parameters() const                     { return synth ? synth->_controlInPorts : 0; } +void DssiSynthIF::setParam(unsigned i, float val)            { setParameter(i, val); } +float DssiSynthIF::param(unsigned i) const                   { return getParameter(i); } +const char* DssiSynthIF::paramName(unsigned i)               { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortNames[controls[i].idx] : 0; } +//LADSPA_PortRangeHint DssiSynthIF::range(unsigned i)          { return (synth && synth->dssi) ? synth->dssi->LADSPA_Plugin->PortRangeHints[i] : 0; } +LADSPA_PortRangeHint DssiSynthIF::range(unsigned i)          { return synth->dssi->LADSPA_Plugin->PortRangeHints[controls[i].idx]; }  #else //DSSI_SUPPORT diff --git a/muse2/muse/dssihost.h b/muse2/muse/dssihost.h index a98cfd87..27c0eae4 100644 --- a/muse2/muse/dssihost.h +++ b/muse2/muse/dssihost.h @@ -75,6 +75,8 @@ class DssiSynth : public Synth {        MidiCtl2LadspaPortMap port2MidiCtlMap;   // Maps DSSI port numbers to midi controller numbers.        bool _hasGui;        bool _inPlaceCapable; +      // Hack: Special flag required. +      bool _isDssiVst;     public:        //DssiSynth(const QFileInfo* fi, QString l) : Synth(fi, l) { @@ -236,7 +238,8 @@ class DssiSynthIF : public SynthIF, public PluginIBase        //-------------------------        bool on() const;               void setOn(bool /*val*/);    -      int pluginID(); +      //int pluginID(); +      unsigned pluginID();        // p4.0.21        int id();        QString pluginLabel() const;          QString name() const; @@ -244,17 +247,25 @@ class DssiSynthIF : public SynthIF, public PluginIBase        QString dirPath() const;        QString fileName() const;        AudioTrack* track();           -      void enableController(int /*i*/, bool v = true);  -      bool controllerEnabled(int /*i*/) const;           -      bool controllerEnabled2(int /*i*/) const;           +      //void enableController(int /*i*/, bool v = true);  +      //bool controllerEnabled(int /*i*/) const;           +      //bool controllerEnabled2(int /*i*/) const;           +      void enableController(unsigned /*i*/, bool v = true);      // p4.0.21 +      bool controllerEnabled(unsigned /*i*/) const;           +      bool controllerEnabled2(unsigned /*i*/) const;                  void updateControllers();        void writeConfiguration(int /*level*/, Xml& /*xml*/);        bool readConfiguration(Xml& /*xml*/, bool readPreset=false); -      int parameters() const;           -      void setParam(int /*i*/, double /*val*/);  -      double param(int /*i*/) const;         -      const char* paramName(int /*i*/);      -      LADSPA_PortRangeHint range(int /*i*/);  +      //int parameters() const;           +      //void setParam(int /*i*/, double /*val*/);  +      //double param(int /*i*/) const;         +      //const char* paramName(int /*i*/);      +      //LADSPA_PortRangeHint range(int /*i*/);  +      unsigned parameters() const;                            // p4.0.21 +      void setParam(unsigned /*i*/, float /*val*/);  +      float param(unsigned /*i*/) const;         +      const char* paramName(unsigned /*i*/);      +      LADSPA_PortRangeHint range(unsigned /*i*/);         friend class DssiSynth;        }; diff --git a/muse2/muse/mididev.h b/muse2/muse/mididev.h index 6ac93729..275bd014 100644 --- a/muse2/muse/mididev.h +++ b/muse2/muse/mididev.h @@ -77,7 +77,7 @@ class MidiDevice {        MidiDevice(const QString& name);        virtual ~MidiDevice() {} -      virtual int deviceType() = 0; +      virtual int deviceType() const = 0;        //virtual void* clientPort() { return 0; }        // p3.3.55 diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index de397c30..cbe9c20a 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -2,7 +2,7 @@  //  MusE  //  Linux Music Editor  //  scoreedit.cpp -//  (C) Copyright 2011 Florian Jung (florian.a.jung@web.de) +//  (C) Copyright 2011 Florian Jung (flo93@users.sourceforge.net)  //========================================================= @@ -129,7 +129,7 @@ QString create_random_string(int len=8)  QPixmap *pix_whole, *pix_half, *pix_quarter; // arrays [NUM_MYCOLORS]  QPixmap *pix_dot, *pix_b, *pix_sharp, *pix_noacc; // arrays [NUM_MYCOLORS] -QPixmap *pix_r1, *pix_r2, *pix_r4, *pix_r8, *pix_r16; // pointers +QPixmap *pix_r1, *pix_r2, *pix_r4, *pix_r8, *pix_r16, *pix_r32; // pointers  QPixmap *pix_flag_up, *pix_flag_down; // arrays [4]  QPixmap *pix_num; // array [10]  QPixmap *pix_clef_violin, *pix_clef_bass; //pointers @@ -287,7 +287,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos)  	quant_toolbar->addWidget(new QLabel(tr("Pixels per whole:"), quant_toolbar));  	QSpinBox* px_per_whole_spinbox = new QSpinBox(this); -	px_per_whole_spinbox->setRange(10, 1000); +	px_per_whole_spinbox->setRange(10, 1200);  	px_per_whole_spinbox->setSingleStep(50);  	connect(px_per_whole_spinbox, SIGNAL(valueChanged(int)), score_canvas, SLOT(set_pixels_per_whole(int)));  	connect(score_canvas, SIGNAL(pixels_per_whole_changed(int)), px_per_whole_spinbox, SLOT(setValue(int))); @@ -835,6 +835,7 @@ void ScoreCanvas::init_pixmaps()  		pix_r4=new QPixmap;  		pix_r8=new QPixmap;  		pix_r16=new QPixmap; +		pix_r32=new QPixmap;  		pix_clef_violin=new QPixmap;  		pix_clef_bass=new QPixmap; @@ -858,6 +859,7 @@ void ScoreCanvas::init_pixmaps()  		pix_r4->load(museGlobalShare + "/scoreglyphs/rest4.png");  		pix_r8->load(museGlobalShare + "/scoreglyphs/rest8.png");  		pix_r16->load(museGlobalShare + "/scoreglyphs/rest16.png"); +		pix_r32->load(museGlobalShare + "/scoreglyphs/rest32.png");  		pix_flag_up[0].load(museGlobalShare + "/scoreglyphs/flags8u.png");  		pix_flag_up[1].load(museGlobalShare + "/scoreglyphs/flags16u.png");  		pix_flag_up[2].load(museGlobalShare + "/scoreglyphs/flags32u.png"); @@ -905,13 +907,11 @@ bool operator< (const note_pos_t& a, const note_pos_t& b)  int flo_quantize(int tick, int quant_ticks)  { -	//TODO quantizing must be done with the proper functions!  	return int(nearbyint((float)tick / quant_ticks))*quant_ticks;  }  int flo_quantize_floor(int tick, int quant_ticks)  { -	//TODO quantizing must be done with the proper functions, see above  	return int(tick / quant_ticks) * quant_ticks;  } @@ -2071,6 +2071,7 @@ void staff_t::calc_item_pos()  					case 2: it->pix=pix_r4; break;  					case 3: it->pix=pix_r8; break;  					case 4: it->pix=pix_r16; break; +					case 5: it->pix=pix_r32; break;  				}  				it->x+=parent->note_x_indent() + (it->ausweich ? REST_AUSWEICH_X : 0); //AUSWEICH_X @@ -2754,7 +2755,6 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event)  	int y=event->y() + y_pos - staff_it->y_draw;  	int x=event->x()+x_pos-x_left;  	int tick=flo_quantize_floor(x_to_tick(x), quant_ticks()); -						//TODO quantizing must (maybe?) be done with the proper functions  	if (staff_it!=staves.end())  	{ @@ -2790,9 +2790,26 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event)  			{  				mouse_down_pos=event->pos();  				mouse_operation=NO_OP; + +				int t=tick; + +				set<FloItem, floComp>::iterator found; +				do +				{ +					found=itemlist[t].find(FloItem(FloItem::NOTE, set_it->pos)); +					if (found == itemlist[t].end()) +					{ +						cerr << "ERROR: THIS SHOULD NEVER HAPPEN: could not find the note's tie-destination" << endl; +						break; +					} +					else +					{ +						t+=calc_len(found->len, found->dots); +					} +				} while (found->tied);  				int total_begin=set_it->begin_tick; -				int total_end=tick; +				int total_end=t;  				int this_begin=tick;  				int this_end=this_begin+calc_len(set_it->len, set_it->dots); @@ -2819,7 +2836,7 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event)  				}  				if (debugMsg) -					cout << "you clicked at a note with begin at "<<set_it->begin_tick<<" and end at "<<tick<<endl +					cout << "you clicked at a note with begin at "<<set_it->begin_tick<<" and end at "<<t<<endl  							 << "x-drag-operation will be "<<mouse_x_drag_operation<<endl  							 << "pointer to part is "<<set_it->source_part << endl; @@ -3466,12 +3483,13 @@ set<Part*> staff_t::parts_at_tick(unsigned tick)   *   o clean up code (find TODOs)   *    * IMPORTANT TODO - *   x nothing atm - * - * less important stuff - *   o deal with expanding parts or clip (expanding is better) + *   o save and restore window settings, automatically reopen windows + *     after loading file etc   *   o offer functions like in the pianoroll: quantize etc.   *   o support selections + * + * less important stuff + *   o deal with expanding parts   *   o do all the song_changed(SC_EVENT_INSERTED) properly   *   o add tracks in correct order to score   *   o draw measure numbers diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index 255e09d5..b68b637a 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -2,7 +2,7 @@  //  MusE  //  Linux Music Editor  //  scoreedit.h -//  (C) Copyright 2011 Florian Jung (florian.a.jung@web.de) +//  (C) Copyright 2011 Florian Jung (flo93@users.sourceforge.net)  //=========================================================  #ifndef __SCOREEDIT_H__ diff --git a/muse2/muse/mixer/astrip.cpp b/muse2/muse/mixer/astrip.cpp index 2f1a2262..265061ad 100644 --- a/muse2/muse/mixer/astrip.cpp +++ b/muse2/muse/mixer/astrip.cpp @@ -430,7 +430,10 @@ void AudioStrip::volumeChanged(double val)        else              vol = pow(10.0, val/20.0);        volume = vol; -      audio->msgSetVolume((AudioTrack*)track, vol); +      //audio->msgSetVolume((AudioTrack*)track, vol); +      // p4.0.21 audio->msgXXX waits. Do we really need to? +      ((AudioTrack*)track)->setVolume(vol); +              ((AudioTrack*)track)->recordAutomation(AC_VOLUME, vol);        song->update(SC_TRACK_MODIFIED); // for graphical automation update @@ -455,7 +458,10 @@ void AudioStrip::volumePressed()        else              vol = pow(10.0, val/20.0);        volume = vol; -      audio->msgSetVolume((AudioTrack*)track, volume); +      //audio->msgSetVolume((AudioTrack*)track, volume); +      // p4.0.21 audio->msgXXX waits. Do we really need to? +      ((AudioTrack*)track)->setVolume(volume); +              ((AudioTrack*)track)->startAutoRecord(AC_VOLUME, volume);        } @@ -498,7 +504,10 @@ void AudioStrip::volLabelChanged(double val)              vol = pow(10.0, val/20.0);        volume = vol;        slider->setValue(val); -      audio->msgSetVolume((AudioTrack*)track, vol); +      //audio->msgSetVolume((AudioTrack*)track, vol); +      // p4.0.21 audio->msgXXX waits. Do we really need to? +      ((AudioTrack*)track)->setVolume(vol); +              ((AudioTrack*)track)->startAutoRecord(AC_VOLUME, vol);        } @@ -513,7 +522,10 @@ void AudioStrip::panChanged(double val)          track->enablePanController(false);        panVal = val;   -      audio->msgSetPan(((AudioTrack*)track), val); +      //audio->msgSetPan(((AudioTrack*)track), val); +      // p4.0.21 audio->msgXXX waits. Do we really need to? +      ((AudioTrack*)track)->setPan(val); +              ((AudioTrack*)track)->recordAutomation(AC_PAN, val);        } @@ -528,7 +540,9 @@ void AudioStrip::panPressed()          track->enablePanController(false);        panVal = pan->value();   -      audio->msgSetPan(((AudioTrack*)track), panVal); +      //audio->msgSetPan(((AudioTrack*)track), panVal); +      // p4.0.21 audio->msgXXX waits. Do we really need to? +      ((AudioTrack*)track)->setPan(panVal);        ((AudioTrack*)track)->startAutoRecord(AC_PAN, panVal);        } @@ -563,7 +577,9 @@ void AudioStrip::panLabelChanged(double val)        panVal = val;        pan->setValue(val); -      audio->msgSetPan((AudioTrack*)track, val); +      //audio->msgSetPan((AudioTrack*)track, val); +      // p4.0.21 audio->msgXXX waits. Do we really need to? +      ((AudioTrack*)track)->setPan(val);        ((AudioTrack*)track)->startAutoRecord(AC_PAN, val);        } diff --git a/muse2/muse/mixer/panknob.cpp b/muse2/muse/mixer/panknob.cpp index 065c1bd1..c99f0bd5 100644 --- a/muse2/muse/mixer/panknob.cpp +++ b/muse2/muse/mixer/panknob.cpp @@ -8,6 +8,7 @@  #include "../audio.h"  #include "panknob.h" +#include "track.h"  //---------------------------------------------------------  //   PanKnob @@ -26,7 +27,9 @@ PanKnob::PanKnob(QWidget* parent, AudioTrack* s)  void PanKnob::valueChanged(double val)        { -      audio->msgSetPan(src, val); +      //audio->msgSetPan(src, val); +      // p4.0.21 audio->msgXXX waits. Do we really need to? +      src->setPan(val);        } diff --git a/muse2/muse/osc.cpp b/muse2/muse/osc.cpp index edaede1f..9f9a5531 100644 --- a/muse2/muse/osc.cpp +++ b/muse2/muse/osc.cpp @@ -405,6 +405,7 @@ void stopOSC() +/*  //---------------------------------------------------------  //   OscControlFifo  //    put @@ -456,7 +457,7 @@ void OscControlFifo::remove()        // q_atomic_decrement(&size);        --size;        } - +*/  //--------------------------------------------------------- @@ -483,7 +484,7 @@ OscIF::OscIF()    _oscGuiQProc = 0;    _oscGuiVisible = false; -  _oscControlFifos = 0; +  //_oscControlFifos = 0;  }  OscIF::~OscIF() @@ -530,10 +531,11 @@ OscIF::~OscIF()    if(_uiOscPath)      free(_uiOscPath); -  if(_oscControlFifos) -    delete[] _oscControlFifos; +  //if(_oscControlFifos) +  //  delete[] _oscControlFifos;  } +/*  //---------------------------------------------------------  //   oscFifo  //--------------------------------------------------------- @@ -544,6 +546,7 @@ OscControlFifo* OscIF::oscFifo(unsigned long i) const      return 0;    return &_oscControlFifos[i];  } +*/  //---------------------------------------------------------  //   oscUpdate @@ -1135,15 +1138,15 @@ bool OscIF::oscGuiVisible() const  void OscDssiIF::oscSetSynthIF(DssiSynthIF* s)  {     _oscSynthIF = s; -  if(_oscControlFifos) -    delete[] _oscControlFifos; -  _oscControlFifos = 0; +  //if(_oscControlFifos) +  //  delete[] _oscControlFifos; +  //_oscControlFifos = 0; -  if(_oscSynthIF && _oscSynthIF->dssiSynth()) -  { -    unsigned long ports = _oscSynthIF->dssiSynth()->inControls(); -    _oscControlFifos = new OscControlFifo[ports];   -  }   +  //if(_oscSynthIF && _oscSynthIF->dssiSynth()) +  //{ +  //  unsigned long ports = _oscSynthIF->dssiSynth()->inControls(); +  //  _oscControlFifos = new OscControlFifo[ports];   +  //}    }  //--------------------------------------------------------- @@ -1327,15 +1330,15 @@ bool OscDssiIF::oscInitGui()  void OscEffectIF::oscSetPluginI(PluginI* s)  {     _oscPluginI = s;  -  if(_oscControlFifos) -    delete[] _oscControlFifos; -  _oscControlFifos = 0; +  //if(_oscControlFifos) +  //  delete[] _oscControlFifos; +  //_oscControlFifos = 0; -  if(_oscPluginI && _oscPluginI->plugin()) -  { -    unsigned long ports = _oscPluginI->plugin()->controlInPorts(); -    _oscControlFifos = new OscControlFifo[ports];   -  }   +  //if(_oscPluginI && _oscPluginI->plugin()) +  //{ +  //  unsigned long ports = _oscPluginI->plugin()->controlInPorts(); +  //  _oscControlFifos = new OscControlFifo[ports];   +  //}    }  //--------------------------------------------------------- diff --git a/muse2/muse/osc.h b/muse2/muse/osc.h index ea94451b..02c30de4 100644 --- a/muse2/muse/osc.h +++ b/muse2/muse/osc.h @@ -34,6 +34,7 @@ class QString;  class PluginI;  class OscIF; +/*  // Keep the OSC fifo small. There may be thousands of controls, and each control needs a fifo.  // Oops, no, if the user keeps adjusting a slider without releasing the mouse button, then all of the   //  events are sent at once upon releasing the button, meaning there might be thousands of events at once. @@ -73,6 +74,7 @@ class OscControlFifo        void clear()         { size = 0, wIndex = 0, rIndex = 0; }        int getSize() const  { return size; }  }; +*/  //---------------------------------------------------------  //  OscIF @@ -137,7 +139,7 @@ class OscIF        char* _uiOscShowPath;        bool _oscGuiVisible; -      OscControlFifo* _oscControlFifos; +      //OscControlFifo* _oscControlFifos;        virtual bool oscInitGui(const QString& /*typ*/, const QString& /*baseName*/, const QString& /*name*/,                          const QString& /*label*/, const QString& /*filePath*/, const QString& /*guiPath*/); @@ -146,7 +148,7 @@ class OscIF        OscIF();        virtual ~OscIF(); -      OscControlFifo* oscFifo(unsigned long) const; +      //OscControlFifo* oscFifo(unsigned long) const;        virtual int oscUpdate(lo_arg**);            virtual int oscProgram(lo_arg**)   { return 0; }    diff --git a/muse2/muse/plugin.cpp b/muse2/muse/plugin.cpp index 06e72e4e..7dd2486f 100644 --- a/muse2/muse/plugin.cpp +++ b/muse2/muse/plugin.cpp @@ -44,6 +44,7 @@  #include "slider.h"  #include "midictrl.h"  #include "plugin.h" +#include "controlfifo.h"  #include "xml.h"  #include "icons.h"  #include "song.h" @@ -84,7 +85,8 @@ QStringList PluginDialog::sortItems = QStringList();  //   ladspa2MidiControlValues  //--------------------------------------------------------- -bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, int port, int ctlnum, int* min, int* max, int* def) +//bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, int port, int ctlnum, int* min, int* max, int* def) +bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, unsigned port, int ctlnum, int* min, int* max, int* def)  {    LADSPA_PortRangeHint range = plugin->PortRangeHints[port];    LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor; @@ -274,7 +276,8 @@ bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, int port, int ctl  //   midi2LadspaValue  //--------------------------------------------------------- -float midi2LadspaValue(const LADSPA_Descriptor* plugin, int port, int ctlnum, int val) +//float midi2LadspaValue(const LADSPA_Descriptor* plugin, int port, int ctlnum, int val) +float midi2LadspaValue(const LADSPA_Descriptor* plugin, unsigned port, int ctlnum, int val)  {    LADSPA_PortRangeHint range = plugin->PortRangeHints[port];    LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor; @@ -448,7 +451,8 @@ float midi2LadspaValue(const LADSPA_Descriptor* plugin, int port, int ctlnum, in  //   ladspa2MidiController  //--------------------------------------------------------- -MidiController* ladspa2MidiController(const LADSPA_Descriptor* plugin, int port, int ctlnum) +//MidiController* ladspa2MidiController(const LADSPA_Descriptor* plugin, int port, int ctlnum) +MidiController* ladspa2MidiController(const LADSPA_Descriptor* plugin, unsigned port, int ctlnum)  {    int min, max, def; @@ -467,85 +471,96 @@ MidiController* ladspa2MidiController(const LADSPA_Descriptor* plugin, int port,  //---------------------------------------------------------------------------------  //float ladspaDefaultValue(const LADSPA_Descriptor* plugin, int k) -bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, int port, float* val) +//bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, int port, float* val) +bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, unsigned port, float* val)  { -      LADSPA_PortRangeHint range = plugin->PortRangeHints[port]; -      LADSPA_PortRangeHintDescriptor rh = range.HintDescriptor; -//      bool isLog = LADSPA_IS_HINT_LOGARITHMIC(rh); -      //double val = 1.0; -      float m = (rh & LADSPA_HINT_SAMPLE_RATE) ? float(sampleRate) : 1.0f; -      if (LADSPA_IS_HINT_DEFAULT_MINIMUM(rh))  +      if(port < plugin->PortCount)         { -        *val = range.LowerBound * m; -        return true; -      } -      else if (LADSPA_IS_HINT_DEFAULT_LOW(rh))  -      { -            if (LADSPA_IS_HINT_LOGARITHMIC(rh)) -            { -              *val = exp(fast_log10(range.LowerBound * m) * .75 + -                     log(range.UpperBound * m) * .25); -              return true; -            }          -            else -            { -              *val = range.LowerBound*.75*m + range.UpperBound*.25*m; +        LADSPA_PortRangeHint range = plugin->PortRangeHints[port]; +        LADSPA_PortRangeHintDescriptor rh = range.HintDescriptor; +  //      bool isLog = LADSPA_IS_HINT_LOGARITHMIC(rh); +        //double val = 1.0; +        float m = (rh & LADSPA_HINT_SAMPLE_RATE) ? float(sampleRate) : 1.0f; +        if (LADSPA_IS_HINT_DEFAULT_MINIMUM(rh))  +        { +          *val = range.LowerBound * m; +          return true; +        } +        else if (LADSPA_IS_HINT_DEFAULT_LOW(rh))  +        { +              if (LADSPA_IS_HINT_LOGARITHMIC(rh)) +              { +                //*val = exp(fast_log10(range.LowerBound * m) * .75 + +                //       log(range.UpperBound * m) * .25); +                // p4.0.21 And below... +                *val = expf(fast_log10(range.LowerBound * m) * .75 +  // Why fast_log10? +                      logf(range.UpperBound * m) * .25); +                return true; +              }          +              else +              { +                *val = range.LowerBound*.75*m + range.UpperBound*.25*m; +                return true; +              }       +        } +        else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(rh))  +        { +              if (LADSPA_IS_HINT_LOGARITHMIC(rh)) +              { +                //*val = exp(log(range.LowerBound * m) * .5 + +                //       log10(range.UpperBound * m) * .5); +                *val = expf(logf(range.LowerBound * m) * .5 + +                      log10f(range.UpperBound * m) * .5);     // Why log10? +                return true; +              }          +              else +              { +                *val = range.LowerBound*.5*m + range.UpperBound*.5*m; +                return true; +              }       +        } +        else if (LADSPA_IS_HINT_DEFAULT_HIGH(rh))  +        { +              if (LADSPA_IS_HINT_LOGARITHMIC(rh)) +              { +                //*val = exp(log(range.LowerBound * m) * .25 + +                //       log(range.UpperBound * m) * .75); +                *val = expf(logf(range.LowerBound * m) * .25 + +                      logf(range.UpperBound * m) * .75); +                return true; +              }          +              else +              { +                *val = range.LowerBound*.25*m + range.UpperBound*.75*m; +                return true; +              }       +        } +        else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(rh))  +        { +              *val = range.UpperBound*m;                return true; -            }       -      } -      else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(rh))  -      { -            if (LADSPA_IS_HINT_LOGARITHMIC(rh)) -            { -              *val = exp(log(range.LowerBound * m) * .5 + -                     log10(range.UpperBound * m) * .5); +        } +        else if (LADSPA_IS_HINT_DEFAULT_0(rh)) +        { +              *val = 0.0;                return true; -            }          -            else -            { -              *val = range.LowerBound*.5*m + range.UpperBound*.5*m; +        }       +        else if (LADSPA_IS_HINT_DEFAULT_1(rh)) +        { +              *val = 1.0;                return true; -            }       -      } -      else if (LADSPA_IS_HINT_DEFAULT_HIGH(rh))  -      { -            if (LADSPA_IS_HINT_LOGARITHMIC(rh)) -            { -              *val = exp(log(range.LowerBound * m) * .25 + -                     log(range.UpperBound * m) * .75); +        }       +        else if (LADSPA_IS_HINT_DEFAULT_100(rh)) +        { +              *val = 100.0;                return true; -            }          -            else -            { -              *val = range.LowerBound*.25*m + range.UpperBound*.75*m; +        }       +        else if (LADSPA_IS_HINT_DEFAULT_440(rh)) +        { +              *val = 440.0;                return true; -            }       -      } -      else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(rh))  -      { -            *val = range.UpperBound*m; -            return true; +        }         } -      else if (LADSPA_IS_HINT_DEFAULT_0(rh)) -      { -            *val = 0.0; -            return true; -      }       -      else if (LADSPA_IS_HINT_DEFAULT_1(rh)) -      { -            *val = 1.0; -            return true; -      }       -      else if (LADSPA_IS_HINT_DEFAULT_100(rh)) -      { -            *val = 100.0; -            return true; -      }       -      else if (LADSPA_IS_HINT_DEFAULT_440(rh)) -      { -            *val = 440.0; -            return true; -      }              // No default found. Set return value to 1.0, but return false.        *val = 1.0; @@ -556,9 +571,10 @@ bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, int port, float* val)  //   ladspaControlRange  //--------------------------------------------------------- -void ladspaControlRange(const LADSPA_Descriptor* plugin, int i, float* min, float* max)  +//void ladspaControlRange(const LADSPA_Descriptor* plugin, int i, float* min, float* max)  +void ladspaControlRange(const LADSPA_Descriptor* plugin, unsigned port, float* min, float* max)         { -      LADSPA_PortRangeHint range = plugin->PortRangeHints[i]; +      LADSPA_PortRangeHint range = plugin->PortRangeHints[port];        LADSPA_PortRangeHintDescriptor desc = range.HintDescriptor;        if (desc & LADSPA_HINT_TOGGLED) {              *min = 0.0; @@ -690,7 +706,10 @@ Plugin::Plugin(QFileInfo* f, const LADSPA_Descriptor* d, bool isDssi)    //  EnsembleLite (EnsLite VST) has the flag set, but it is a vst synth and is not involved here!    // Yet many (all?) ladspa vst effect plugins exhibit this problem.      // Changed by Tim. p3.3.14 -  if ((_inports != _outports) || (fi.completeBaseName() == QString("dssi-vst") && !config.vstInPlace)) +  // Hack: Special Flag required for example for control processing. +  _isDssiVst = fi.completeBaseName() == QString("dssi-vst"); +  // Hack: Blacklist vst plugins in-place, configurable for now.  +  if ((_inports != _outports) || (_isDssiVst && !config.vstInPlace))          _inPlaceCapable = false;  } @@ -756,7 +775,8 @@ int Plugin::incReferences(int val)      if(dssi)      {        const DSSI_Descriptor* descr; -      for(int i = 0;; ++i)  +      //for(int i = 0;; ++i)  +      for(unsigned i = 0;; ++i)     // p4.0.21        {          descr = dssi(i);          if(descr == NULL) @@ -787,7 +807,8 @@ int Plugin::incReferences(int val)        if(ladspadf)        {          const LADSPA_Descriptor* descr; -        for(int i = 0;; ++i)  +        //for(int i = 0;; ++i)  +        for(unsigned i = 0;; ++i)       // p4.0.21          {            descr = ladspadf(i);            if(descr == NULL) @@ -863,8 +884,10 @@ int Plugin::incReferences(int val)        _inPlaceCapable = !LADSPA_IS_INPLACE_BROKEN(plugin->Properties); -      // Blacklist vst plugins in-place configurable for now.  -      if ((_inports != _outports) || (fi.completeBaseName() == QString("dssi-vst") && !config.vstInPlace)) +      // Hack: Special flag required for example for control processing. +      _isDssiVst = fi.completeBaseName() == QString("dssi-vst"); +      // Hack: Blacklist vst plugins in-place, configurable for now.  +      if ((_inports != _outports) || (_isDssiVst && !config.vstInPlace))              _inPlaceCapable = false;      }    }       @@ -921,32 +944,46 @@ void Plugin::range(unsigned long i, float* min, float* max) const  //   defaultValue  //--------------------------------------------------------- -double Plugin::defaultValue(unsigned long port) const +//double Plugin::defaultValue(unsigned long port) const +float Plugin::defaultValue(unsigned long port) const  { +    // p4.0.21 +    float val; +    ladspaDefaultValue(plugin, port, &val); +    return val; +     +    /*      if(port >= plugin->PortCount)         return 0.0;      LADSPA_PortRangeHint range = plugin->PortRangeHints[port];      LADSPA_PortRangeHintDescriptor rh = range.HintDescriptor; -    double val = 1.0; +    //double val = 1.0; +    float val = 1.0;       if (LADSPA_IS_HINT_DEFAULT_MINIMUM(rh))            val = range.LowerBound;      else if (LADSPA_IS_HINT_DEFAULT_LOW(rh))            if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor)) -                val = exp(fast_log10(range.LowerBound) * .75 + -                    log(range.UpperBound) * .25); +                //val = exp(fast_log10(range.LowerBound) * .75 + +                //    log(range.UpperBound) * .25); +                val = expf(fast_log10(range.LowerBound) * .75 + +                    logf(range.UpperBound) * .25);            else                  val = range.LowerBound*.75 + range.UpperBound*.25;      else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(rh))            if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor)) -                val = exp(log(range.LowerBound) * .5 + -                    log(range.UpperBound) * .5); +                //val = exp(log(range.LowerBound) * .5 + +                //    log(range.UpperBound) * .5); +                val = expf(logf(range.LowerBound) * .5 + +                    logf(range.UpperBound) * .5);            else                  val = range.LowerBound*.5 + range.UpperBound*.5;      else if (LADSPA_IS_HINT_DEFAULT_HIGH(rh))            if (LADSPA_IS_HINT_LOGARITHMIC(range.HintDescriptor)) -                val = exp(log(range.LowerBound) * .25 + -                    log(range.UpperBound) * .75); +                //val = exp(log(range.LowerBound) * .25 + +                //    log(range.UpperBound) * .75); +                val = expf(logf(range.LowerBound) * .25 + +                    logf(range.UpperBound) * .75);            else                  val = range.LowerBound*.25 + range.UpperBound*.75;      else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(rh)) @@ -961,6 +998,7 @@ double Plugin::defaultValue(unsigned long port) const            val = 440.0;      return val;       +    */  }  //--------------------------------------------------------- @@ -981,7 +1019,8 @@ static void loadPluginLib(QFileInfo* fi)    if(dssi)    {      const DSSI_Descriptor* descr; -    for (int i = 0;; ++i)  +    //for (int i = 0;; ++i)  +    for (unsigned i = 0;; ++i)  // p4.0.21      {        descr = dssi(i);        if (descr == 0) @@ -1033,7 +1072,8 @@ static void loadPluginLib(QFileInfo* fi)      }      const LADSPA_Descriptor* descr; -    for (int i = 0;; ++i)  +    //for (int i = 0;; ++i)  +    for (unsigned i = 0;; ++i)       // p4.0.21      {        descr = ladspa(i);        if (descr == NULL) @@ -1444,7 +1484,8 @@ bool Pipeline::nativeGuiVisible(int idx)  //   apply  //--------------------------------------------------------- -void Pipeline::apply(int ports, unsigned long nframes, float** buffer1) +//void Pipeline::apply(int ports, unsigned long nframes, float** buffer1) +void Pipeline::apply(unsigned ports, unsigned nframes, float** buffer1)  {        // prepare a second set of buffers in case a plugin is not        // capable of inPlace processing @@ -1467,26 +1508,31 @@ void Pipeline::apply(int ports, unsigned long nframes, float** buffer1)                    {                          if (swap)                                //p->connect(ports, buffer2, buffer2); -                              p->connect(ports, buffer, buffer); +                              //p->connect(ports, buffer, buffer); +                              p->apply(nframes, ports, buffer, buffer);     // p4.0.21                          else -                              p->connect(ports, buffer1, buffer1); +                              //p->connect(ports, buffer1, buffer1); +                              p->apply(nframes, ports, buffer1, buffer1);   //                    }                    else                     {                          if (swap)                                //p->connect(ports, buffer2, buffer1); -                              p->connect(ports, buffer, buffer1); +                              //p->connect(ports, buffer, buffer1); +                              p->apply(nframes, ports, buffer, buffer1);    //                          else                                //p->connect(ports, buffer1, buffer2); -                              p->connect(ports, buffer1, buffer); +                              //p->connect(ports, buffer1, buffer); +                              p->apply(nframes, ports, buffer1, buffer);    //                          swap = !swap;                    } -                  p->apply(nframes); +                  //p->apply(nframes);                                      // Rem. p4.0.21                    }              }        if (swap)         { -            for (int i = 0; i < ports; ++i) +            //for (int i = 0; i < ports; ++i) +            for (unsigned i = 0; i < ports; ++i)    // p4.0.21                    //memcpy(buffer1[i], buffer2[i], sizeof(float) * nframes);                    //memcpy(buffer1[i], buffer[i], sizeof(float) * nframes);                    AL::dsp->cpy(buffer1[i], buffer[i], nframes); @@ -1648,10 +1694,13 @@ void PluginI::updateControllers()    if(!_track)      return; -  for(int i = 0; i < controlPorts; ++i)  +  //for(int i = 0; i < controlPorts; ++i)  +  for(unsigned i = 0; i < controlPorts; ++i)       //audio->msgSetPluginCtrlVal(this, genACnum(_id, i), controls[i].val);      // p3.3.43 -    audio->msgSetPluginCtrlVal(_track, genACnum(_id, i), controls[i].val); +    //audio->msgSetPluginCtrlVal(_track, genACnum(_id, i), controls[i].val); +    // p4.0.21 audio->msgXXX waits. Do we really need to? +    _track->setPluginCtrlVal(genACnum(_id, i), controls[i].val);  }  //--------------------------------------------------------- @@ -1722,8 +1771,10 @@ void PluginI::setChannels(int c)                    }              } -      int curPort = 0; -      int curOutPort = 0; +      //int curPort = 0; +      //int curOutPort = 0; +      unsigned long curPort = 0;      // p4.0.21 +      unsigned long curOutPort = 0;        unsigned long ports   = _plugin->ports();        for (unsigned long k = 0; k < ports; ++k)         { @@ -1752,13 +1803,47 @@ void PluginI::setChannels(int c)  }  //--------------------------------------------------------- +//   setParam +//--------------------------------------------------------- + +void PluginI::setParam(unsigned i, float val)  +{  +  //controls[i].tmpVal = val;  +   +  // p4.0.21 +  if(i >= _plugin->_controlInPorts) +  //if(i >= controlPorts) +  { +    printf("PluginI::setParameter param number %u out of range of ports:%ld\n", i, _plugin->_controlInPorts); +    return; +  } +  ControlEvent ce; +  ce.unique = false; +  ce.idx = i; +  ce.value = val; +  // Time-stamp the event. This does a possibly slightly slow call to gettimeofday via timestamp(). +  //  timestamp() is more or less an estimate of the current frame. (This is exactly how ALSA events  +  //  are treated when they arrive in our ALSA driver.)  +  ce.frame = audio->timestamp();   +  if(_controlFifo.put(ce)) +  { +    fprintf(stderr, "PluginI::setParameter: fifo overflow: in control number:%u\n", i); +  } +   +  // Notify that changes are to be sent upon heartbeat. +  // TODO: No, at least not for now. So far, setParameter is only called during loading of stored params, +  //  and we don't want this interfering with oscUpdate which also sends the values. +  //synti->_guiUpdateControls[n] = true; +}      + +//---------------------------------------------------------  //   defaultValue  //--------------------------------------------------------- -double PluginI::defaultValue(unsigned int param) const +//double PluginI::defaultValue(unsigned int param) const +float PluginI::defaultValue(unsigned param) const  { -//#warning controlPorts should really be unsigned -  if(param >= (unsigned)controlPorts) +  if(param >= controlPorts)      return 0.0;    return _plugin->defaultValue(controls[param].idx); @@ -1872,8 +1957,10 @@ bool PluginI::initPluginInstance(Plugin* plug, int c)        controls    = new Port[controlPorts];        controlsOut = new Port[controlOutPorts]; -      int i  = 0; -      int ii = 0; +      //int i  = 0; +      //int ii = 0; +      unsigned long curPort = 0; +      unsigned long curOutPort = 0;        for(unsigned long k = 0; k < ports; ++k)         {          LADSPA_PortDescriptor pd = _plugin->portd(k); @@ -1881,27 +1968,31 @@ bool PluginI::initPluginInstance(Plugin* plug, int c)          {            if(pd & LADSPA_PORT_INPUT)            { -            double val = _plugin->defaultValue(k); -            controls[i].val    = val; -            controls[i].tmpVal = val; -            controls[i].enCtrl  = true; -            controls[i].en2Ctrl = true; -            ++i; +            //double val = _plugin->defaultValue(k); +            float val = _plugin->defaultValue(k);    // p4.0.21 +            controls[curPort].val    = val; +            controls[curPort].tmpVal = val; +            controls[curPort].enCtrl  = true; +            controls[curPort].en2Ctrl = true; +            ++curPort;            }            else            if(pd & LADSPA_PORT_OUTPUT)            {              //double val = _plugin->defaultValue(k); -            controlsOut[ii].val     = 0.0; -            controlsOut[ii].tmpVal  = 0.0; -            controlsOut[ii].enCtrl  = false; -            controlsOut[ii].en2Ctrl = false; -            ++ii; +            //float val = _plugin->defaultValue(k); +            controlsOut[curOutPort].val     = 0.0; +            controlsOut[curOutPort].tmpVal  = 0.0; +            controlsOut[curOutPort].enCtrl  = false; +            controlsOut[curOutPort].en2Ctrl = false; +            ++curOutPort;            }          }        } -      unsigned long curPort = 0; -      unsigned long curOutPort = 0; +      //unsigned long curPort = 0; +      //unsigned long curOutPort = 0; +      curPort = 0; +      curOutPort = 0;        for(unsigned long k = 0; k < ports; ++k)         {          LADSPA_PortDescriptor pd = _plugin->portd(k); @@ -1932,13 +2023,16 @@ bool PluginI::initPluginInstance(Plugin* plug, int c)  //   connect  //--------------------------------------------------------- -void PluginI::connect(int ports, float** src, float** dst) +//void PluginI::connect(int ports, float** src, float** dst) +void PluginI::connect(unsigned ports, unsigned offset, float** src, float** dst)        { -      int port = 0; +      //int port = 0; +      unsigned port = 0;  // p4.0.21        for (int i = 0; i < instances; ++i) {              for (unsigned long k = 0; k < _plugin->ports(); ++k) {                    if (isAudioIn(k)) { -                        _plugin->connectPort(handle[i], k, src[port]); +                        //_plugin->connectPort(handle[i], k, src[port]); +                        _plugin->connectPort(handle[i], k, src[port] + offset);     // p4.0.21                          port = (port + 1) % ports;                          }                    } @@ -1947,7 +2041,8 @@ void PluginI::connect(int ports, float** src, float** dst)        for (int i = 0; i < instances; ++i) {              for (unsigned long k = 0; k < _plugin->ports(); ++k) {                    if (isAudioOut(k)) { -                        _plugin->connectPort(handle[i], k, dst[port]); + //                       _plugin->connectPort(handle[i], k, dst[port]); +                        _plugin->connectPort(handle[i], k, dst[port] + offset);     // p4.0.21                          port = (port + 1) % ports;  // overwrite output?  //                        ++port;  //                        if (port >= ports) { @@ -1979,7 +2074,8 @@ void PluginI::activate()        for (int i = 0; i < instances; ++i)              _plugin->activate(handle[i]);        if (initControlValues) { -            for (int i = 0; i < controlPorts; ++i) { +            //for (int i = 0; i < controlPorts; ++i) { +            for (unsigned i = 0; i < controlPorts; ++i) {                    controls[i].val = controls[i].tmpVal;                    }              } @@ -1987,7 +2083,8 @@ void PluginI::activate()              //              // get initial control values from plugin              // -            for (int i = 0; i < controlPorts; ++i) { +            //for (int i = 0; i < controlPorts; ++i) { +            for (unsigned i = 0; i < controlPorts; ++i) {                    controls[i].tmpVal = controls[i].val;                    }              } @@ -1998,11 +2095,14 @@ void PluginI::activate()  //    set plugin instance controller value by name  //--------------------------------------------------------- -bool PluginI::setControl(const QString& s, double val) +//bool PluginI::setControl(const QString& s, double val) +bool PluginI::setControl(const QString& s, float val)        { -      for (int i = 0; i < controlPorts; ++i) { +      //for (int i = 0; i < controlPorts; ++i) { +      for (unsigned i = 0; i < controlPorts; ++i) {              if (_plugin->portName(controls[i].idx) == s) { -                  controls[i].val = controls[i].tmpVal = val; +                  //controls[i].val = controls[i].tmpVal = val; +                  setParam(i, val);     // p4.0.21                    return false;                    }              } @@ -2023,8 +2123,10 @@ void PluginI::writeConfiguration(int level, Xml& xml)           //_plugin->lib().toLatin1().constData(), _plugin->label().toLatin1().constData(), channel);           Xml::xmlString(_plugin->lib()).toLatin1().constData(), Xml::xmlString(_plugin->label()).toLatin1().constData(), channel); -      for (int i = 0; i < controlPorts; ++i) { -            int idx = controls[i].idx; +      //for (int i = 0; i < controlPorts; ++i) { +            //int idx = controls[i].idx; +      for (unsigned i = 0; i < controlPorts; ++i) {          // p4.0.21 +            unsigned idx = controls[i].idx;                  //              QString s("control name=\"%1\" val=\"%2\" /");              //xml.tag(level, s.arg(_plugin->portName(idx)).arg(controls[i].tmpVal).toLatin1().constData());              xml.tag(level, s.arg(Xml::xmlString(_plugin->portName(idx)).toLatin1().constData()).arg(controls[i].tmpVal).toLatin1().constData()); @@ -2052,7 +2154,8 @@ bool PluginI::loadControl(Xml& xml)        QString file;        QString label;        QString name("mops"); -      double val = 0.0; +      //double val = 0.0; +      float val = 0.0;     // p4.0.21        for (;;) {              Xml::Token token = xml.parse(); @@ -2069,7 +2172,8 @@ bool PluginI::loadControl(Xml& xml)                          if (tag == "name")                                name = xml.s2();                          else if (tag == "val") -                              val = xml.s2().toDouble(); +                              //val = xml.s2().toDouble(); +                              val = xml.s2().toFloat();     // p4.0.21                          break;                    case Xml::TagEnd:                          if (tag == "control") { @@ -2307,7 +2411,8 @@ void PluginIBase::deleteGui()  void PluginI::enableAllControllers(bool v)  { -  for(int i = 0; i < controlPorts; ++i)  +  //for(int i = 0; i < controlPorts; ++i)  +  for(unsigned i = 0; i < controlPorts; ++i)       controls[i].enCtrl = v;  } @@ -2317,7 +2422,8 @@ void PluginI::enableAllControllers(bool v)  void PluginI::enable2AllControllers(bool v)  { -  for(int i = 0; i < controlPorts; ++i)  +  //for(int i = 0; i < controlPorts; ++i)  +  for(unsigned i = 0; i < controlPorts; ++i)       controls[i].en2Ctrl = v;  } @@ -2325,7 +2431,9 @@ void PluginI::enable2AllControllers(bool v)  //   apply  //--------------------------------------------------------- -void PluginI::apply(int n) +/* +//void PluginI::apply(int n) +void PluginI::apply(unsigned n)  {        // Process control value changes.        //if(automation && _track && _track->automationType() != AUTO_OFF && _id != -1) @@ -2412,6 +2520,156 @@ void PluginI::apply(int n)              _plugin->apply(handle[i], n);        }              } +*/ +       +#if 1 +// p4.0.21 +void PluginI::apply(unsigned n, unsigned ports, float** bufIn, float** bufOut) +{ +      // Process control value changes. +      //if(automation && _track && _track->automationType() != AUTO_OFF && _id != -1) +      //{ +      //  for(int i = 0; i < controlPorts; ++i) +      //  { +      //    if( controls[i].enCtrl && controls[i].en2Ctrl ) +      //      controls[i].tmpVal = _track->pluginCtrlVal(genACnum(_id, i)); +      //  }   +      //}       +       +      //unsigned endPos = pos + n; +      int frameOffset = audio->getFrameOffset(); +       +      unsigned sample = 0; +      int loopcount = 0;      // REMOVE Tim. +       +      // Must make this detectable for dssi vst effects. +      //const bool usefixedrate = true;       +      const bool usefixedrate = _plugin->_isDssiVst;  // Try this. +      // TODO Make this number a global setting. +      // Note for dssi-vst this MUST equal audio period. It doesn't like broken-up runs (it stutters),  +      //  even with fixed sizes. Could be a Wine + Jack thing, wanting a full Jack buffer's length. +      //unsigned fixedsize = 2048;    +      unsigned fixedsize = n;      +       +      // For now, the fixed size is clamped to the audio buffer size. +      // TODO: We could later add slower processing over several cycles - +      //  so that users can select a small audio period but a larger control period.  +      if(fixedsize > n) +        fixedsize = n; +       +      // Process automation control values now. +      // TODO: This needs to be respect frame resolution. Put this inside the sample loop below. +      for(unsigned long k = 0; k < controlPorts; ++k) +      { +        if(automation && _track && _track->automationType() != AUTO_OFF && _id != -1) +        { +          if(controls[k].enCtrl && controls[k].en2Ctrl ) +            controls[k].tmpVal = _track->pluginCtrlVal(genACnum(_id, k)); +        }       +      } +         +      while(sample < n) +      { +        //unsigned nsamp = n; +        //unsigned nsamp = n - sample; +        unsigned nsamp = usefixedrate ? fixedsize : n - sample; +        bool found = false; +        unsigned frame = 0;  +        unsigned index = 0; +        // Get all control ring buffer items valid for this time period... +        //for(int m = 0; m < cbsz; ++m) +        while(!_controlFifo.isEmpty()) +        { +          //ControlValue v = _controlFifo.get();  +          ControlEvent v = _controlFifo.peek();  +          //printf("PluginI::apply control idx:%d frame:%d val:%f\n", v.idx, v.frame, v.value);   // REMOVE Tim. +          // Process only items in this time period. Make sure to process all +          //  subsequent items which have the same frame.  +          //if(v.frame >= (endPos + frameOffset) || (found && v.frame != frame))   +          //if(v.frame < sample || v.frame >= (sample + nsamp) || (found && v.frame != frame))   +          //if(v.frame < sample || v.frame >= (endPos + frameOffset) || (found && v.frame != frame))   +          //if(v.frame < sample || v.frame >= (endPos + frameOffset)   +          if(v.frame < sample || v.frame >= frameOffset   +              //|| (found && v.frame != frame)   +              //|| (!usefixedrate && found && !v.unique && v.frame != frame)   +              || (found && !v.unique && v.frame != frame)   +              // dssi-vst needs them serialized and accounted for, no matter what. This works with fixed rate  +              //  because nsamp is constant. But with packets, we need to guarantee at least one-frame spacing.  +              // Although we likely won't be using packets with dssi-vst, so it's OK for now. +              //|| (found && v.idx == index))   +              //|| (usefixedrate && found && v.idx == index))  // Try this. +              || (usefixedrate && found && v.unique && v.idx == index))  //  +            break; +          _controlFifo.remove();               // Done with the ring buffer's item. Remove it. +          //if(v.idx >= controlPorts)            // Sanity check. +          if(v.idx >= _plugin->_controlInPorts)  +            break; +          found = true; +          frame = v.frame; +          index = v.idx; +          // Set the ladspa control port value. +          //controls[v.idx].val = v.value; +          controls[v.idx].tmpVal = v.value; +           +          // Need to update the automation value, otherwise it overwrites later with the last automation value. +          if(_track && _id != -1) +          { +            // Since we are now in the audio thread context, there's no need to send a message, +            //  just modify directly. +            //audio->msgSetPluginCtrlVal(this, genACnum(_id, k), controls[k].val); +            // p3.3.43 +            //audio->msgSetPluginCtrlVal(_track, genACnum(_id, k), controls[k].val); +            _track->setPluginCtrlVal(genACnum(_id, v.idx), v.value); +             +            // Record automation. +            // NO! Take care of this immediately in the OSC control handler, because we don't want  +            //  any delay. +            // OTOH Since this is the actual place and time where the control ports values +            //  are set, best to reflect what happens here to automation. +            // However for dssi-vst it might be best to handle it that way. +             +            //AutomationType at = _track->automationType(); +            // TODO: Taken from our native gui control handlers.  +            // This may need modification or may cause problems -  +            //  we don't have the luxury of access to the dssi gui controls ! +            //if(at == AUTO_WRITE || (audio->isPlaying() && at == AUTO_TOUCH)) +            //  enableController(k, false); +            //_track->recordAutomation(id, v.value); +          }   +        } + +        // Now update the actual values from the temporary values... +        for(unsigned long k = 0; k < controlPorts; ++k) +          controls[k].val = controls[k].tmpVal; +         +        //if(found) +        if(found && !usefixedrate) +          //nsamp = frame - sample + 1; +          nsamp = frame - sample; +        if(sample + nsamp >= n)         // Safety check. +          nsamp = n - sample;  +         +        //printf("PluginI::apply ports:%d n:%d frame:%d sample:%d nsamp:%d fOffset:%d loopcount:%d\n",  +        //      ports, n, frame, sample, nsamp, frameOffset, loopcount);   // REMOVE Tim. +         +        // TODO: TESTING: Don't allow zero-length runs. This could/should be checked in the control loop instead. +        // Note this means it is still possible to get stuck in the top loop (at least for a while). +        if(nsamp == 0) +          continue; +           +        connect(ports, sample, bufIn, bufOut); +         +        for(int i = 0; i < instances; ++i) +        { +          //fprintf(stderr, "PluginI::apply handle %d\n", i); +          _plugin->apply(handle[i], nsamp); +        }       +       +        sample += nsamp; +        loopcount++;       // REMOVE Tim. +      } +} +#endif  //---------------------------------------------------------  //   oscConfigure @@ -2544,7 +2802,8 @@ int PluginI::oscUpdate()        // Send current control values.        //unsigned long ports = controlPorts; -      for(int i = 0; i < controlPorts; ++i)  +      //for(int i = 0; i < controlPorts; ++i)  +      for(unsigned i = 0; i < controlPorts; ++i)         {          //unsigned long k = synth->pIdx(i);          //_oscIF.oscSendControl(k, controls[i]); @@ -2576,15 +2835,15 @@ int PluginI::oscControl(unsigned long port, float value)    //if(port >= controlPorts)    //if(port < 0 || port >= _plugin->rpIdx.size()) -  //{ -    //fprintf(stderr, "DssiSynthIF::oscControl: port number:%d is out of range of number of ports:%d\n", port, controlPorts); -  //  fprintf(stderr, "PluginI::oscControl: port number:%d is out of range of index list size:%d\n", port, _plugin->rpIdx.size()); -  //  return 0; -  //} +  if(port >= _plugin->rpIdx.size()) +  { +    fprintf(stderr, "PluginI::oscControl: port number:%ld is out of range of index list size:%d\n", port, _plugin->rpIdx.size()); +    return 0; +  }    // Convert from DSSI port number to control input port index. -  //unsigned long cport = _plugin->rpIdx[port]; -  unsigned long cport = _plugin->port2InCtrl(port); +  unsigned long cport = _plugin->rpIdx[port]; +  //unsigned long cport = _plugin->port2InCtrl(port);    if((int)cport == -1)    { @@ -2607,6 +2866,7 @@ int PluginI::oscControl(unsigned long port, float value)    // TODO: May need FIFOs on each control(!) so that the control changes get sent one per process cycle!     // Observed countdown not actually going to zero upon string of changes.    // Try this ... +  /*    OscControlFifo* cfifo = _oscif.oscFifo(cport);     if(cfifo)    { @@ -2622,16 +2882,32 @@ int PluginI::oscControl(unsigned long port, float value)        fprintf(stderr, "PluginI::oscControl: fifo overflow: in control number:%ld\n", cport);      }    } +  */ +  // p4.0.21 +  ControlEvent ce; +  ce.unique = _plugin->_isDssiVst;   // Special for messages from vst gui to host - requires processing every message. +  ce.idx = cport; +  ce.value = value; +  // Time-stamp the event. This does a possibly slightly slow call to gettimeofday via timestamp(). +  //  timestamp() is more or less an estimate of the current frame. (This is exactly how ALSA events  +  //  are treated when they arrive in our ALSA driver.)  +  ce.frame = audio->timestamp();   +  if(_controlFifo.put(ce)) +  { +    fprintf(stderr, "PluginI::oscControl: fifo overflow: in control number:%ld\n", cport); +  } +      // Record automation:    // Take care of this immediately, because we don't want the silly delay associated with     //  processing the fifo one-at-a-time in the apply(). -  // NOTE: Ahh crap! We don't receive control events until the user RELEASES a control ! +  // NOTE: With some vsts we don't receive control events until the user RELEASES a control.     // So the events all arrive at once when the user releases a control.    // That makes this pretty useless... But what the heck...    if(_track && _id != -1)    { -    int id = genACnum(_id, cport); +    //int id = genACnum(_id, cport); +    unsigned id = genACnum(_id, cport);      AutomationType at = _track->automationType();      // TODO: Taken from our native gui control handlers.  @@ -2880,10 +3156,14 @@ void PluginDialog::fillPlugs(int nbr)  {      pList->clear();      for (iPlugin i = plugins.begin(); i != plugins.end(); ++i) { -          int ai = i->inports(); -          int ao = i->outports(); -          int ci = i->controlInPorts(); -          int co = i->controlOutPorts(); +          //int ai = i->inports(); +          //int ao = i->outports(); +          //int ci = i->controlInPorts(); +          //int co = i->controlOutPorts(); +          unsigned ai = i->inports();       // p4.0.21 +          unsigned ao = i->outports(); +          unsigned ci = i->controlInPorts(); +          unsigned co = i->controlOutPorts();            bool addFlag = false;            switch (nbr) {                  case SEL_SM: // stereo & mono @@ -2928,10 +3208,14 @@ void PluginDialog::fillPlugs(const QString &sortValue)  {      pList->clear();      for (iPlugin i = plugins.begin(); i != plugins.end(); ++i) { -          int ai = i->inports(); -          int ao = i->outports(); -          int ci = i->controlInPorts(); -          int co = i->controlOutPorts(); +          //int ai = i->inports(); +          //int ao = i->outports(); +          //int ci = i->controlInPorts(); +          //int co = i->controlOutPorts(); +          unsigned ai = i->inports();          // p4.0.21 +          unsigned ao = i->outports(); +          unsigned ci = i->controlInPorts(); +          unsigned co = i->controlOutPorts();            bool addFlag = false; @@ -3045,16 +3329,24 @@ PluginGui::PluginGui(PluginIBase* p)                    const char* name = ba.constData();                    if (*name !='P')                          continue; -                  int parameter = -1; -                  sscanf(name, "P%d", ¶meter); -                  if (parameter == -1) -                        continue; +                  //int parameter = -1; +                  //sscanf(name, "P%d", ¶meter); +                  //if (parameter == -1) +                  //      continue; +                  unsigned parameter;                        // p4.0.21 +                  int rv = sscanf(name, "P%u", ¶meter); +                  if(rv != 1) +                    continue;                    ++nobj;                    }              it = l.begin();              gw   = new GuiWidgets[nobj];              nobj = 0;              QSignalMapper* mapper = new QSignalMapper(this); +             +            // FIXME: There's no unsigned for gui params. We would need to limit nobj to MAXINT.    // p4.0.21 +            // FIXME: Our Slider class uses doubles for values, giving some problems with float conversion.    // p4.0.21 +                          connect(mapper, SIGNAL(mapped(int)), SLOT(guiParamChanged(int)));              QSignalMapper* mapperPressed = new QSignalMapper(this); @@ -3068,10 +3360,14 @@ PluginGui::PluginGui(PluginIBase* p)                    const char* name = ba.constData();                    if (*name !='P')                          continue; -                  int parameter = -1; -                  sscanf(name, "P%d", ¶meter); -                  if (parameter == -1) -                        continue; +                  //int parameter = -1; +                  //sscanf(name, "P%d", ¶meter); +                  //if (parameter == -1) +                  //      continue; +                  unsigned parameter;                         // p4.0.21 +                  int rv = sscanf(name, "P%u", ¶meter); +                  if(rv != 1) +                    continue;                    mapper->setMapping(obj, nobj);                    mapperPressed->setMapping(obj, nobj); @@ -3085,7 +3381,8 @@ PluginGui::PluginGui(PluginIBase* p)                          gw[nobj].type = GuiWidgets::SLIDER;                          ((Slider*)obj)->setId(nobj);                          ((Slider*)obj)->setCursorHoming(true); -                        for(int i = 0; i < nobj; i++) +                        //for(int i = 0; i < nobj; i++) +                        for(unsigned i = 0; i < nobj; i++)             // p4.0.21                          {                            if(gw[i].type == GuiWidgets::DOUBLE_LABEL && gw[i].param == parameter)                              ((DoubleLabel*)gw[i].widget)->setSlider((Slider*)obj); @@ -3098,7 +3395,8 @@ PluginGui::PluginGui(PluginIBase* p)                    else if (strcmp(obj->metaObject()->className(), "DoubleLabel") == 0) {                          gw[nobj].type = GuiWidgets::DOUBLE_LABEL;                          ((DoubleLabel*)obj)->setId(nobj); -                        for(int i = 0; i < nobj; i++) +                        //for(int i = 0; i < nobj; i++) +                        for(unsigned i = 0; i < nobj; i++)                          {                            if(gw[i].type == GuiWidgets::SLIDER && gw[i].param == parameter)                            { @@ -3141,7 +3439,8 @@ PluginGui::PluginGui(PluginIBase* p)              mw->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); -            int n  = plugin->parameters(); +            //int n  = plugin->parameters(); +            unsigned n  = plugin->parameters();   // p4.0.21              params = new GuiParam[n];              // Changed p3.3.43 @@ -3155,7 +3454,8 @@ PluginGui::PluginGui(PluginIBase* p)              QFontMetrics fm = fontMetrics();              int h           = fm.height() + 4; -            for (int i = 0; i < n; ++i) { +            //for (int i = 0; i < n; ++i) { +            for (unsigned i = 0; i < n; ++i) {       // p4.0.21                    QLabel* label = 0;                    LADSPA_PortRangeHint range = plugin->range(i);                    double lower = 0.0;     // default values @@ -3301,7 +3601,7 @@ void PluginGui::ctrlPressed(int param)        if(params[param].type == GuiParam::GUI_SLIDER)        { -        double val = ((Slider*)params[param].actuator)->value(); +        double val = ((Slider*)params[param].actuator)->value();            if (LADSPA_IS_HINT_LOGARITHMIC(params[param].hint))                val = pow(10.0, val/20.0);          else if (LADSPA_IS_HINT_INTEGER(params[param].hint)) @@ -3315,14 +3615,17 @@ void PluginGui::ctrlPressed(int param)          if(track)          {            // p3.3.43 -          audio->msgSetPluginCtrlVal(track, id, val); +          //audio->msgSetPluginCtrlVal(track, id, val); +          // p4.0.21 audio->msgXXX waits. Do we really need to? +          track->setPluginCtrlVal(id, val);            track->startAutoRecord(id, val);          }          }               else if(params[param].type == GuiParam::GUI_SWITCH)        { -        double val = (double)((CheckBox*)params[param].actuator)->isChecked(); +        //double val = (double)((CheckBox*)params[param].actuator)->isChecked(); +        float val = (float)((CheckBox*)params[param].actuator)->isChecked();      // p4.0.21          plugin->setParam(param, val);          // p3.3.43 @@ -3331,7 +3634,9 @@ void PluginGui::ctrlPressed(int param)          if(track)          {            // p3.3.43 -          audio->msgSetPluginCtrlVal(track, id, val); +          //audio->msgSetPluginCtrlVal(track, id, val); +          // p4.0.21 audio->msgXXX waits. Do we really need to? +          track->setPluginCtrlVal(id, val);            track->startAutoRecord(id, val);          }   @@ -3423,7 +3728,9 @@ void PluginGui::sliderChanged(double val, int param)        if(track)        {          // p3.3.43 -        audio->msgSetPluginCtrlVal(track, id, val); +        //audio->msgSetPluginCtrlVal(track, id, val); +        // p4.0.21 audio->msgXXX waits. Do we really need to? +        track->setPluginCtrlVal(id, val);          track->recordAutomation(id, val);        }   @@ -3465,7 +3772,9 @@ void PluginGui::labelChanged(double val, int param)        if(track)        {          // p3.3.43 -        audio->msgSetPluginCtrlVal(track, id, val); +        //audio->msgSetPluginCtrlVal(track, id, val); +        // p4.0.21 audio->msgXXX waits. Do we really need to? +        track->setPluginCtrlVal(id, val);          track->startAutoRecord(id, val);        }   @@ -3596,7 +3905,8 @@ void PluginGui::setOn(bool val)  void PluginGui::updateValues()        {        if (params) { -            for (int i = 0; i < plugin->parameters(); ++i) { +            //for (int i = 0; i < plugin->parameters(); ++i) { +            for (unsigned i = 0; i < plugin->parameters(); ++i) {       // p4.0.21                    GuiParam* gp = ¶ms[i];                    if (gp->type == GuiParam::GUI_SLIDER) {                          double lv = plugin->param(i); @@ -3617,17 +3927,20 @@ void PluginGui::updateValues()                    }              }        else if (gw) { -            for (int i = 0; i < nobj; ++i) { +            //for (int i = 0; i < nobj; ++i) { +            for (unsigned i = 0; i < nobj; ++i) {      // p4.0.21                    QWidget* widget = gw[i].widget;                    int type = gw[i].type; -                  int param = gw[i].param; -                  double val = plugin->param(param); +                  //int param = gw[i].param; +                  //double val = plugin->param(param); +                  unsigned param = gw[i].param;        // p4.0.21 +                  float val = plugin->param(param);                    switch(type) {                          case GuiWidgets::SLIDER: -                              ((Slider*)widget)->setValue(val); +                              ((Slider*)widget)->setValue(val);    // Note conversion to double                                break;                          case GuiWidgets::DOUBLE_LABEL: -                              ((DoubleLabel*)widget)->setValue(val); +                              ((DoubleLabel*)widget)->setValue(val);   // Note conversion to double                                break;                          case GuiWidgets::QCHECKBOX:                                ((QCheckBox*)widget)->setChecked(int(val)); @@ -3652,7 +3965,8 @@ void PluginGui::updateControls()        if(at == AUTO_OFF)          return;        if (params) { -            for (int i = 0; i < plugin->parameters(); ++i) { +            //for (int i = 0; i < plugin->parameters(); ++i) { +            for (unsigned i = 0; i < plugin->parameters(); ++i) {      // p4.0.21                    GuiParam* gp = ¶ms[i];                    if (gp->type == GuiParam::GUI_SLIDER) {                          if( plugin->controllerEnabled(i) && plugin->controllerEnabled2(i) ) @@ -3698,10 +4012,12 @@ void PluginGui::updateControls()                    }              }        else if (gw) { -            for (int i = 0; i < nobj; ++i) { +            //for (int i = 0; i < nobj; ++i) { +            for (unsigned i = 0; i < nobj; ++i) {    // p4.0.21                    QWidget* widget = gw[i].widget;                    int type = gw[i].type; -                  int param = gw[i].param; +                  //int param = gw[i].param; +                  unsigned param = gw[i].param;      // p4.0.21                    switch(type) {                          case GuiWidgets::SLIDER:                                if( plugin->controllerEnabled(param) && plugin->controllerEnabled2(param) ) @@ -3771,7 +4087,8 @@ void PluginGui::updateControls()  void PluginGui::guiParamChanged(int idx)  {        QWidget* w = gw[idx].widget; -      int param  = gw[idx].param; +      //int param  = gw[idx].param; +      unsigned param  = gw[idx].param;    // p4.0.21        int type   = gw[idx].type;        AutomationType at = AUTO_OFF; @@ -3798,7 +4115,8 @@ void PluginGui::guiParamChanged(int idx)                    break;              } -      for (int i = 0; i < nobj; ++i) { +      //for (int i = 0; i < nobj; ++i) { +      for (unsigned i = 0; i < nobj; ++i) {      // p4.0.21              QWidget* widget = gw[i].widget;              if (widget == w || param != gw[i].param)                    continue; @@ -3830,7 +4148,9 @@ void PluginGui::guiParamChanged(int idx)            //if(track)            //{              // p3.3.43 -            audio->msgSetPluginCtrlVal(track, id, val); +            //audio->msgSetPluginCtrlVal(track, id, val); +            // p4.0.21 audio->msgXXX waits. Do we really need to? +            track->setPluginCtrlVal(id, val);              switch(type)               { @@ -3853,7 +4173,8 @@ void PluginGui::guiParamChanged(int idx)  void PluginGui::guiParamPressed(int idx)        { -      int param  = gw[idx].param; +      //int param  = gw[idx].param; +      unsigned param  = gw[idx].param;     // p4.0.21        AutomationType at = AUTO_OFF;        AudioTrack* track = plugin->track(); @@ -3893,7 +4214,8 @@ void PluginGui::guiParamPressed(int idx)  void PluginGui::guiParamReleased(int idx)        { -      int param  = gw[idx].param; +      //int param  = gw[idx].param; +      unsigned param  = gw[idx].param;    // p4.0.21        int type   = gw[idx].type;        AutomationType at = AUTO_OFF; @@ -3938,7 +4260,8 @@ void PluginGui::guiParamReleased(int idx)  void PluginGui::guiSliderPressed(int idx)        { -      int param  = gw[idx].param; +      //int param  = gw[idx].param; +      unsigned param  = gw[idx].param;    // p4.0.21        QWidget *w = gw[idx].widget;        AutomationType at = AUTO_OFF; @@ -3961,12 +4284,15 @@ void PluginGui::guiSliderPressed(int idx)        //audio->msgSetPluginCtrlVal(((PluginI*)plugin), id, val);        // p3.3.43 -      audio->msgSetPluginCtrlVal(track, id, val); +      //audio->msgSetPluginCtrlVal(track, id, val); +      // p4.0.21 audio->msgXXX waits. Do we really need to? +      track->setPluginCtrlVal(id, val);        track->startAutoRecord(id, val);        // Needed so that paging a slider updates a label or other buddy control. -      for (int i = 0; i < nobj; ++i) { +      //for (int i = 0; i < nobj; ++i) { +      for (unsigned i = 0; i < nobj; ++i) {           // p4.0.21              QWidget* widget = gw[i].widget;              if (widget == w || param != gw[i].param)                    continue; diff --git a/muse2/muse/plugin.h b/muse2/muse/plugin.h index 41da1bfb..2d78a335 100644 --- a/muse2/muse/plugin.h +++ b/muse2/muse/plugin.h @@ -22,6 +22,7 @@  #include "globals.h"  #include "globaldefs.h"  #include "ctrl.h" +#include "controlfifo.h"  //#include "stringparam.h" @@ -78,7 +79,10 @@ class PluginBase  //---------------------------------------------------------  class Plugin { +        protected: +   friend class PluginI; +              void* _handle;        int _references;        int _instNo; @@ -92,6 +96,9 @@ class Plugin {        QString _copyright;        bool _isDssi; +      // Hack: Special flag required. +      bool _isDssiVst; +              #ifdef DSSI_SUPPORT        const DSSI_Descriptor* dssi_descr;        #endif @@ -138,11 +145,13 @@ class Plugin {              if (plugin && plugin->cleanup)                    plugin->cleanup(handle);              } -      void connectPort(LADSPA_Handle handle, int port, float* value) { +      //void connectPort(LADSPA_Handle handle, int port, float* value) { +      void connectPort(LADSPA_Handle handle, unsigned port, float* value) {     // p4.0.21              if(plugin)                plugin->connect_port(handle, port, value);              } -      void apply(LADSPA_Handle handle, int n) { +      //void apply(LADSPA_Handle handle, int n) { +      void apply(LADSPA_Handle handle, unsigned n) {                            // p4.0.21              if(plugin)                plugin->run(handle, n);              } @@ -165,7 +174,8 @@ class Plugin {              return plugin->PortRangeHints[i];              } -      double defaultValue(unsigned long port) const; +      //double defaultValue(unsigned long port) const; +      float defaultValue(unsigned long port) const; // p4.0.21             void range(unsigned long i, float*, float*) const;        const char* portName(unsigned long i) { @@ -173,7 +183,7 @@ class Plugin {              }        // Returns (int)-1 if not an input control.    -      unsigned long port2InCtrl(unsigned long p) { return p >= rpIdx.size() ? (unsigned long)-1 : rpIdx[p]; }    +      //unsigned long port2InCtrl(unsigned long p) { return p >= rpIdx.size() ? (unsigned long)-1 : rpIdx[p]; }           unsigned long inports() const         { return _inports; }        unsigned long outports() const        { return _outports; } @@ -218,7 +228,8 @@ class PluginList : public std::list<Plugin> {  //---------------------------------------------------------  struct Port { -      int idx; +      //int idx; +      unsigned idx;        float val;        float tmpVal; @@ -251,7 +262,8 @@ struct GuiWidgets {              };        QWidget* widget;        int type; -      int param; +      //int param; +      unsigned param;   // p4.0.21        };  class PluginI; @@ -296,6 +308,7 @@ class PluginBase  class PluginIBase   {     protected: +      ControlFifo _controlFifo;        PluginGui* _gui;        void makeGui(); @@ -305,7 +318,8 @@ class PluginIBase        ~PluginIBase();         virtual bool on() const = 0;               virtual void setOn(bool /*val*/) = 0;    -      virtual int pluginID() = 0; +      //virtual int pluginID() = 0; +      virtual unsigned pluginID() = 0;        // p4.0.21        virtual int id() = 0;        virtual QString pluginLabel() const = 0;          virtual QString name() const = 0; @@ -315,19 +329,27 @@ class PluginIBase        virtual AudioTrack* track() = 0;           -      virtual void enableController(int /*i*/, bool /*v*/ = true) = 0;  -      virtual bool controllerEnabled(int /*i*/) const = 0;           -      virtual bool controllerEnabled2(int /*i*/) const = 0;           +      //virtual void enableController(int /*i*/, bool /*v*/ = true) = 0;  +      //virtual bool controllerEnabled(int /*i*/) const = 0;           +      //virtual bool controllerEnabled2(int /*i*/) const = 0;           +      virtual void enableController(unsigned /*i*/, bool /*v*/ = true) = 0;   // p4.0.21 +      virtual bool controllerEnabled(unsigned /*i*/) const = 0;           +      virtual bool controllerEnabled2(unsigned /*i*/) const = 0;                  virtual void updateControllers() = 0;        virtual void writeConfiguration(int /*level*/, Xml& /*xml*/) = 0;        virtual bool readConfiguration(Xml& /*xml*/, bool /*readPreset*/=false) = 0; -      virtual int parameters() const = 0;           -      virtual void setParam(int /*i*/, double /*val*/) = 0;  -      virtual double param(int /*i*/) const = 0;         -      virtual const char* paramName(int /*i*/) = 0;      -      virtual LADSPA_PortRangeHint range(int /*i*/) = 0;  +      //virtual int parameters() const = 0;           +      //virtual void setParam(int /*i*/, double /*val*/) = 0;  +      //virtual double param(int /*i*/) const = 0;         +      //virtual const char* paramName(int /*i*/) = 0;      +      //virtual LADSPA_PortRangeHint range(int /*i*/) = 0;  +      virtual unsigned parameters() const = 0;                  // p4.0.21 +      virtual void setParam(unsigned /*i*/, float /*val*/) = 0;   +      virtual float param(unsigned /*i*/) const = 0;             +      virtual const char* paramName(unsigned /*i*/) = 0;         +      virtual LADSPA_PortRangeHint range(unsigned /*i*/) = 0;           QString dssi_ui_filename() const;        //virtual void showGui(bool) = 0;         // p4.0.20 @@ -347,7 +369,8 @@ class PluginGui : public QMainWindow {        PluginIBase* plugin;        // plugin instance        GuiParam* params; -      int nobj;               // number of widgets in gw +      //int nobj;                +      unsigned nobj;             // number of widgets in gw      // p4.0.21        GuiWidgets* gw;        QAction* onOff; @@ -404,8 +427,11 @@ class PluginI : public PluginIBase {        Port* controls;        Port* controlsOut; -      int controlPorts; -      int controlOutPorts; +      //int controlPorts; +      //int controlOutPorts; +      unsigned controlPorts;      // p4.0.21 +      unsigned controlOutPorts;   //  +              ///PluginGui* _gui;        bool _on;        bool initControlValues; @@ -436,20 +462,29 @@ class PluginI : public PluginIBase {        void setTrack(AudioTrack* t)  { _track = t; }        AudioTrack* track()           { return _track; } -      int pluginID()                { return _plugin->id(); } +      //int pluginID()                { return _plugin->id(); } +      unsigned pluginID()           { return _plugin->id(); }    // p4.0.21        void setID(int i);        int id()                      { return _id; }        void updateControllers();        bool initPluginInstance(Plugin*, int channels);        void setChannels(int); -      void connect(int ports, float** src, float** dst); -      void apply(int n); - -      void enableController(int i, bool v = true)   { controls[i].enCtrl = v; } -      bool controllerEnabled(int i) const           { return controls[i].enCtrl; } -      void enable2Controller(int i, bool v = true)  { controls[i].en2Ctrl = v; } -      bool controllerEnabled2(int i) const          { return controls[i].en2Ctrl; } +      //void connect(int ports, float** src, float** dst); +      //void apply(int n); +      //void connect(unsigned ports, float** src, float** dst);    +      //void apply(unsigned n);    +      void connect(unsigned ports, unsigned offset, float** src, float** dst); // p4.0.21 +      void apply(unsigned n, unsigned ports, float** bufIn, float** bufOut);   //  + +      //void enableController(int i, bool v = true)   { controls[i].enCtrl = v; } +      //bool controllerEnabled(int i) const           { return controls[i].enCtrl; } +      //void enable2Controller(int i, bool v = true)  { controls[i].en2Ctrl = v; } +      //bool controllerEnabled2(int i) const          { return controls[i].en2Ctrl; } +      void enableController(unsigned i, bool v = true)   { controls[i].enCtrl = v; }      // p4.0.21 +      bool controllerEnabled(unsigned i) const           { return controls[i].enCtrl; }    +      void enable2Controller(unsigned i, bool v = true)  { controls[i].en2Ctrl = v; }      +      bool controllerEnabled2(unsigned i) const          { return controls[i].en2Ctrl; }          void enableAllControllers(bool v = true);        void enable2AllControllers(bool v = true); @@ -481,7 +516,8 @@ class PluginI : public PluginIBase {        void writeConfiguration(int level, Xml& xml);        bool readConfiguration(Xml& xml, bool readPreset=false);        bool loadControl(Xml& xml); -      bool setControl(const QString& s, double val); +      //bool setControl(const QString& s, double val); +      bool setControl(const QString& s, float val);    // p4.0.21        void showGui();        void showGui(bool);        bool isDssiPlugin() const { return _plugin->isDssiPlugin(); }   @@ -490,17 +526,29 @@ class PluginI : public PluginIBase {        bool isShowNativeGuiPending() { return _showNativeGuiPending; }        bool guiVisible();        bool nativeGuiVisible(); -      int parameters() const           { return controlPorts; } -      void setParam(int i, double val) { controls[i].tmpVal = val; } -      double param(int i) const        { return controls[i].val; } -      double defaultValue(unsigned int param) const; -      const char* paramName(int i)     { return _plugin->portName(controls[i].idx); } -      LADSPA_PortDescriptor portd(int i) const { return _plugin->portd(controls[i].idx); } -      void range(int i, float* min, float* max) const { _plugin->range(controls[i].idx, min, max); } -      bool isAudioIn(int k) { return (_plugin->portd(k) & AUDIO_IN) == AUDIO_IN; } -      bool isAudioOut(int k) { return (_plugin->portd(k) & AUDIO_OUT) == AUDIO_OUT; } +      //int parameters() const           { return controlPorts; } +      //void setParam(int i, double val) { controls[i].tmpVal = val; } +      //double param(int i) const        { return controls[i].val; } +      //double defaultValue(unsigned int param) const; +      //const char* paramName(int i)     { return _plugin->portName(controls[i].idx); } +      //LADSPA_PortDescriptor portd(int i) const { return _plugin->portd(controls[i].idx); } +      //void range(int i, float* min, float* max) const { _plugin->range(controls[i].idx, min, max); } +      //bool isAudioIn(int k) { return (_plugin->portd(k) & AUDIO_IN) == AUDIO_IN; } +      //bool isAudioOut(int k) { return (_plugin->portd(k) & AUDIO_OUT) == AUDIO_OUT; } +      //LADSPA_PortRangeHint range(int i) { return _plugin->range(controls[i].idx); } +      // p4.0.21 +      unsigned parameters() const           { return controlPorts; }     +      //void setParam(unsigned i, float val) { controls[i].tmpVal = val; }      +      void setParam(unsigned i, float val);   +      float param(unsigned i) const        { return controls[i].val; }        +      float defaultValue(unsigned param) const;                      +      const char* paramName(unsigned i)     { return _plugin->portName(controls[i].idx); } +      LADSPA_PortDescriptor portd(unsigned i) const { return _plugin->portd(controls[i].idx); } +      void range(unsigned i, float* min, float* max) const { _plugin->range(controls[i].idx, min, max); } +      bool isAudioIn(unsigned k) { return (_plugin->portd(k) & AUDIO_IN) == AUDIO_IN; } +      bool isAudioOut(unsigned k) { return (_plugin->portd(k) & AUDIO_OUT) == AUDIO_OUT; } +      LADSPA_PortRangeHint range(unsigned i) { return _plugin->range(controls[i].idx); }        bool inPlaceCapable() const { return _plugin->inPlaceCapable(); } -      LADSPA_PortRangeHint range(int i) { return _plugin->range(controls[i].idx); }        };  //--------------------------------------------------------- @@ -533,7 +581,8 @@ class Pipeline : public std::vector<PluginI*> {        void deleteAllGuis();        bool guiVisible(int);        bool nativeGuiVisible(int); -      void apply(int ports, unsigned long nframes, float** buffer); +      //void apply(int ports, unsigned long nframes, float** buffer); +      void apply(unsigned ports, unsigned nframes, float** buffer);  // p4.0.21        void move(int idx, bool up);        bool empty(int idx) const;        void setChannels(int); @@ -581,11 +630,16 @@ class PluginDialog : public QDialog {  extern void initPlugins();  extern PluginList plugins; -extern bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, int port, float* val); -extern void ladspaControlRange(const LADSPA_Descriptor* plugin, int i, float* min, float* max); -extern bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, int port, int ctlnum, int* min, int* max, int* def); -//extern MidiController* ladspa2MidiController(const LADSPA_Descriptor* plugin, int port, int ctlnum); -extern float midi2LadspaValue(const LADSPA_Descriptor* plugin, int port, int ctlnum, int val); +//extern bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, int port, float* val); +//extern void ladspaControlRange(const LADSPA_Descriptor* plugin, int i, float* min, float* max); +//extern bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, int port, int ctlnum, int* min, int* max, int* def); +//extern float midi2LadspaValue(const LADSPA_Descriptor* plugin, int port, int ctlnum, int val); +// p4.0.21 +extern bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, unsigned port, float* val); +extern void ladspaControlRange(const LADSPA_Descriptor* plugin, unsigned port, float* min, float* max); +extern bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, unsigned port, int ctlnum, int* min, int* max, int* def); +extern float midi2LadspaValue(const LADSPA_Descriptor* plugin, unsigned port, int ctlnum, int val); +//extern MidiController* ladspa2MidiController(const LADSPA_Descriptor* plugin, unsigned port, int ctlnum);  #endif diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index ad6de83d..cf040348 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -2161,6 +2161,7 @@ void Song::clear(bool signal, bool /*clear_all*/)        if (signal) {              emit loopChanged(false);              recordChanged(false); +            emit songChanged(-1);              }        } diff --git a/muse2/muse/synth.cpp b/muse2/muse/synth.cpp index 6212340f..521c7d63 100644 --- a/muse2/muse/synth.cpp +++ b/muse2/muse/synth.cpp @@ -917,8 +917,9 @@ void SynthI::preProcessAlways()      // Clear any accumulated play events.      playEvents()->clear();      // Eat up any fifo events. -    while(!eventFifo.isEmpty())  -      eventFifo.get();   +    //while(!eventFifo.isEmpty())  +    //  eventFifo.get();   +    eventFifo.clear();  // p4.0.21 Duh, clear is the same but faster AND safer, right?    }      } diff --git a/muse2/muse/synth.h b/muse2/muse/synth.h index 100d7bd6..b11ea2d9 100644 --- a/muse2/muse/synth.h +++ b/muse2/muse/synth.h @@ -149,8 +149,8 @@ class SynthIF {        virtual const char* getPatchName(int, int, MType, bool) = 0;        virtual void populatePatchPopup(QMenu*, int, MType, bool) = 0;        virtual void write(int level, Xml& xml) const = 0; -      virtual float getParameter(unsigned long idx) const = 0; -      virtual void setParameter(unsigned long idx, float value) = 0; +      virtual float getParameter(unsigned long idx) const = 0;         +      virtual void setParameter(unsigned long idx, float value) = 0;          virtual int getControllerInfo(int id, const char** name, int* ctrl, int* min, int* max, int* initval) = 0;        }; @@ -211,7 +211,7 @@ class SynthI : public AudioTrack, public MidiDevice,        //SynthI* clone() const { return new SynthI(*this); }        SynthI* clone(bool /*cloneParts*/) const { return new SynthI(*this); } -      virtual inline int deviceType() { return SYNTH_MIDI; }  +      virtual inline int deviceType() const { return SYNTH_MIDI; }         SynthIF* sif() const { return _sif; }        bool initInstance(Synth* s, const QString& instanceName); | 
