From e35ae165dd7096942e9641dfd9c6d6fc2a89f1c7 Mon Sep 17 00:00:00 2001 From: "Tim E. Real" Date: Thu, 5 May 2011 22:55:49 +0000 Subject: Fixed regression: Plugins would not restore saved control state when loading song. --- muse2/ChangeLog | 2 ++ muse2/muse/arranger/pcanvas.cpp | 10 +++++++--- muse2/muse/dssihost.cpp | 8 ++++++++ muse2/muse/plugin.cpp | 39 ++++++++++++++++++++++++++++++++++++--- muse2/muse/widgets/utils.cpp | 12 ++++++++++++ 5 files changed, 65 insertions(+), 6 deletions(-) diff --git a/muse2/ChangeLog b/muse2/ChangeLog index 43f1e73f..c38cf359 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,3 +1,5 @@ +05.05.2011: + - Fixed regression: Plugins would not restore saved control state when loading song. (Tim) 04.05.2011: - Fixed meter drawing for zero values in feedback parameters to plugin guis (rj) 02.05.2011: diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index c76e4421..35de93ee 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -3152,8 +3152,7 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t) ic++; int prevPosFrame=cvFirst.frame; prevVal = cvFirst.val; - - + ///bool discrete = cl->valueType() == VAL_BOOL || cl->mode() == CtrlList::DISCRETE; // Tim // prepare prevVal if (cl->valueType() == VAL_LOG ) { // use db scale for volume @@ -3195,7 +3194,12 @@ void PartCanvas::drawAutomation(QPainter& p, const QRect& r, AudioTrack *t) p.drawLine( leftX, (rr.bottom()-2)-prevVal*height, currentPixel, - (rr.bottom()-2)-nextVal*height); + (rr.bottom()-2)-nextVal*height); + ///(rr.bottom()-2)- (discrete?prevVal:nextVal)*height); // Tim + + ///if(discrete) + /// p.drawLine( currentPixel, (rr.bottom()-2)-prevVal*height, currentPixel, (rr.bottom()-2)-nextVal*height ); // Tim + firstRun=false; //printf("draw line: %d %f %d %f\n",tempomap.frame2tick(lastPos),rr.bottom()-lastVal*height,tempomap.frame2tick(cv.frame),rr.bottom()-curVal*height); prevPosFrame=cv.frame; diff --git a/muse2/muse/dssihost.cpp b/muse2/muse/dssihost.cpp index e5ccd628..cbb908e6 100644 --- a/muse2/muse/dssihost.cpp +++ b/muse2/muse/dssihost.cpp @@ -2402,6 +2402,14 @@ iMPEvent DssiSynthIF::getData(MidiPort* /*mp*/, MPEventList* el, iMPEvent i, uns // If the events happened even before current frame - n, make sure they are counted immediately as zero-frame. //evframe = (pos + frameOffset > v.frame + n) ? 0 : v.frame - pos - frameOffset + n; evframe = (syncFrame > v.frame + n) ? 0 : v.frame - syncFrame + n; + // Protection. Observed this condition. Why? Supposed to be linear timestamps. + if(found && evframe < frame) + { + printf("DssiSynthIF::getData *** Error: evframe:%lu < frame:%lu idx:%lu val:%f unique:%d\n", + evframe, v.frame, v.idx, v.value, v.unique); + // Just make it equal to the current frame so it gets processed right away. + evframe = frame; + } //printf("DssiSynthIF::getData ctrl dssi:%d idx:%lu frame:%lu val:%f unique:%d evframe:%lu\n", // synth->_isDssiVst, v.idx, v.frame, v.value, v.unique, evframe); // REMOVE Tim. diff --git a/muse2/muse/plugin.cpp b/muse2/muse/plugin.cpp index cc3977aa..76ebeb1b 100644 --- a/muse2/muse/plugin.cpp +++ b/muse2/muse/plugin.cpp @@ -1829,6 +1829,7 @@ void PluginI::setParam(unsigned long i, float val) // p4.0.23 timestamp() is circular, which is making it impossible to deal with 'modulo' events which // slip in 'under the wire' before processing the ring buffers. So try this linear timestamp instead: ce.frame = audio->curFrame(); + if(_controlFifo.put(ce)) { fprintf(stderr, "PluginI::setParameter: fifo overflow: in control number:%lu\n", i); @@ -2078,6 +2079,7 @@ void PluginI::activate() for (int i = 0; i < instances; ++i) _plugin->activate(handle[i]); if (initControlValues) { + //printf("PluginI::activate init:%d\n", initControlValues); //for (int i = 0; i < controlPorts; ++i) { for (unsigned long i = 0; i < controlPorts; ++i) { controls[i].val = controls[i].tmpVal; @@ -2087,6 +2089,7 @@ void PluginI::activate() // // get initial control values from plugin // + //printf("PluginI::activate init:%d\n", initControlValues); //for (int i = 0; i < controlPorts; ++i) { for (unsigned long i = 0; i < controlPorts; ++i) { controls[i].tmpVal = controls[i].val; @@ -2181,9 +2184,26 @@ bool PluginI::loadControl(Xml& xml) break; case Xml::TagEnd: if (tag == "control") { - if (setControl(name, val)) { - return false; - } + //if (setControl(name, val)) + // return false; + // p4.0.23 Special for loader - bypass the ring buffer and store directly, + // so that upon the 'gui = 1' tag (show the gui), the gui has immediate + // access to the values. + bool found = false; + for(unsigned long i = 0; i < controlPorts; ++i) + { + if(_plugin->portName(controls[i].idx) == name) + { + controls[i].val = controls[i].tmpVal = val; + found = true; + } + } + if(!found) + { + printf("PluginI:loadControl(%s, %f) controller not found\n", + name.toLatin1().constData(), val); + return false; + } initControlValues = true; } return true; @@ -2596,6 +2616,14 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float** // subsequent items which have the same frame. //printf("PluginI::apply control idx:%lu frame:%lu val:%f unique:%d evframe:%lu\n", // v.idx, v.frame, v.value, v.unique, evframe); // REMOVE Tim. + // Protection. Observed this condition. Why? Supposed to be linear timestamps. + if(found && evframe < frame) + { + printf("PluginI::apply *** Error: evframe:%lu < frame:%lu idx:%lu val:%f unique:%d\n", + evframe, v.frame, v.idx, v.value, v.unique); + // Just make it equal to the current frame so it gets processed right away. + evframe = 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)) @@ -2605,6 +2633,8 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float** //|| (found && v.frame != frame) //|| (!usefixedrate && found && !v.unique && v.frame != frame) || (found && !v.unique && evframe != frame) + // Protection. Observed this condition (dummy audio so far). Why? Supposed to be linear timestamps. + //|| (found && evframe < 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. @@ -2655,7 +2685,10 @@ void PluginI::apply(unsigned long n, unsigned long ports, float** bufIn, float** // Now update the actual values from the temporary values... for(unsigned long k = 0; k < controlPorts; ++k) + { + // printf("PluginI::apply updating port:%lu val:%f\n", k, controls[k].tmpVal); controls[k].val = controls[k].tmpVal; + } //if(found) if(found && !usefixedrate) diff --git a/muse2/muse/widgets/utils.cpp b/muse2/muse/widgets/utils.cpp index 38574d94..01a5249d 100644 --- a/muse2/muse/widgets/utils.cpp +++ b/muse2/muse/widgets/utils.cpp @@ -9,6 +9,7 @@ #include #include #include +//#include #include #include @@ -26,7 +27,18 @@ double curTime() { struct timeval t; gettimeofday(&t, 0); + //printf("%ld %ld\n", t.tv_sec, t.tv_usec); // Note I observed values coming out of order! Causing some problems. return (double)((double)t.tv_sec + (t.tv_usec / 1000000.0)); + /* + // Changed by Tim. p4.0.23 + struct timespec t; + //clock_gettime(CLOCK_MONOTONIC, &t); + //clock_gettime(CLOCK_MONOTONIC_RAW, &t); + //clock_gettime(CLOCK_REALTIME, &t); + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t); // Only this one works for me. Could be my older kernel... + printf("%ld %ld\n", t.tv_sec, t.tv_nsec); + return (double)((double)t.tv_sec + (t.tv_nsec / 1000000000.0)); + */ } //--------------------------------------------------------- -- cgit v1.2.3