0
$\begingroup$

I am working with audio on a data preparation algorithm that detects specific points in an audio file, and making a tool for myself to help me go through a couple hundred files quickly enough to find good heuristics, before having it churn half a million of similar files. I am having a few problems with dynamic computations either missing updates or making the interface choppy.

So I have a Graphics with an AudioPlot and a few ListLinePlots and other stuff over it. I need to examine some interesting ranges on the plots. I am placing an inset into the graphics when the mouse goes down, and highlight the range as mouse moves, to show a few interesting figures about the selection in the inset box. When the mouse is released, both the highlight and the box are removed. This is so far so good while I show simple things like the range length and endpoints, but the CPU time it takes to get the really interesting numbers is in the range of 30-120ms. What I want is smooth response to mouse movement, with the values that take longer to compute showing a placeholder $\infty$ until the mouse is held still long enough. As it moves, I am fine with seeing a waiting indicator, but I do want the highlighted selection edge move smoothly with the mouse. This is critical, as positioning on the graph must be quite precise. I am trying to queue calculations on the main link, freeing the preemptive link for responsiveness, but that gives me strange results.

I am exposing a very similar (possibly the same) problem here with regular dynamic sliders. First, this works smoothly, but the updated value is not that where the mouse sits.

slowIdentity[x_] := (Pause[.5]; x);
DynamicModule[{pos = 0, res = \[Infinity]},
 {
  Slider[Dynamic[pos, TrackedSymbols :> {pos}]],
  Dynamic[pos, TrackedSymbols :> {pos}],
  Dynamic[res = \[Infinity]; res = slowIdentity[pos]; (* on the main link *)
   Dynamic[res, TrackedSymbols :> {res}], (* on the preemptive link *)
   TrackedSymbols :> {pos},
   SynchronousUpdating -> False]
  }
 ]
 (* E. g., {-------------|--,0.912,0.267} *)

slowIdentity just returns its argument after having spent some time "computing" it. The $\infty$ is to indicate waiting for the results. The slider is smooth, but the two values displayed do not match. If you hold mouse down and drag the slider smoothly then stop (not releasing the button), the value apparently reflects the first tick noted by the FE (e. g., from .25 move smoothly to .9 and stop; the second, "computed" value shows as 0.26). In every case, this is the value close to where the slider was the last time the result res was refreshed from the $\infty$ to a number.

Amazingly, while the Dynamic documentation says “Dynamic[expr] is equivalent to Dynamic[expr,(expr=#)&]”, explicitly specifying the updating function changes a lot. Now the slider becomes choppy, although the eventual update, as soon as I hold the mouse still, is correct.

slowIdentity[x_] := (Pause[.5]; x);
DynamicModule[{pos = 0, res = \[Infinity]},
 {
  Slider[Dynamic[pos, (pos = #1) &, TrackedSymbols :> {pos}]], (* The only change is here! *)
  Dynamic[pos, TrackedSymbols :> {pos}],
  Dynamic[res = \[Infinity]; res = slowIdentity[pos];
   Dynamic[res, TrackedSymbols :> {res}],
   TrackedSymbols :> {pos},
   SynchronousUpdating -> False]
  }
 ]

The choppiness is not as noticeable on my faster work machine, but very prominent on the slower home computer. Also, it does not seem to get worse (or gets a bit smoother even!) if I increase the Pause argument in this sample.

  1. Am I doing anything wrong? I honestly tried all the things a trained monkey would do, to no avail.

  2. Bonus question. When the whole expression is first evaluated, a gray box is displayed. Is there any way to avoid that and display the $\infty$ right away? This is the same thing I see the first time I press the mouse over my graph. I would not mind a gray box of a smaller size too, if that is possible. Currently, it blows up my inset which slows things even more (and looks too ugly, if that counts as a problem, given those I already have).

I'm ok with undocumented functions and features, as long as they get my job done. This tool is for my own use.

$\endgroup$
  • $\begingroup$ Did you take a look at ControlActive? $\endgroup$ – Lukas Lang Jul 21 '18 at 8:38
  • $\begingroup$ @LukasLang, yes, I monkeyed with it too. But my case is not a control. I am hooking to mouse down/up/move events in my code. Come think of it, I do not seem to have written a good question. I am seeing a similar behavior, but am now not sure it is actually same. $\endgroup$ – kkm Jul 21 '18 at 19:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.