Is it possible to draw to a buffer in memory, then copy that buffer to the panel?

Hello! I’m working on a sampler module that can switch between multiple samples. I’m contemplating adding a waveform display to the front panel.

I’ve found some nice code for rendering a waveform here: https://github.com/cfoulc/cf/blob/v1/src/PLAYER.cpp. However, that code appears to draw the waveform repeatedly, which seems like it would be CPU intensive. I could be wrong about this, but I think that it might be more efficient to draw the waveform to some off-screen buffer, then do some sort of “bitblt” (video memory copy) to the main panel. Is this possible, and if so, is there any sample code floating around which does this?

Thanks! Bret

You are looking for this:

1 Like

Fantastic! Thank you Ben!

Oh, I spoke too soon. @stoermelder The sample code that you linked to solves the problem of drawing something only when a value changes. That’s not really what I’m trying to achieve. My waveforms will never change, so I want to pre-render them in an off-screen buffer, then copy them into a section of the panel when the corresponding sample is selected via a CV input.

image

In the poorly drawn illustration above, either the red or the blue waveform will be visible on the front panel depending on which sample is selected.

Any help would be much appreciated!

I don’t get it. It sounds like you do want to re render every time it changes- it’s just that it will only change once. So just use the draw buffer, or if you insist read the code, learn how to do exactly what you want, and do it.

from your sample display you need just to subsample 200 points and cache them when rendered the first time and reuse them when needed.

If you want to present Maxima minima and RMS (like audiocity) you need to cache 600 points.

Drawing will cost only 1 moveto and 199 lineto, only with framebuffer dirty: you can cache the sampled points in cache files too if you want to avoid the first subsample computation.

FramebufferWidget has no concept of “when a value changes”. It simply redraws when dirty is set to true. It’s initialized to true, so if you only need to render once, you don’t ever need to set it to true.

1 Like

@synthi Yes, I have the “subsample” caching code already done and I’m storing the 200 values in a vector. It was the 1 moveto and 199 lineto commands that I was hoping to only do once per sample when that sample is first loaded.

What I’m trying to do would be something like this:

draw waveform for sample A into buffer A
draw waveform for sample B into buffer B

loop {
  if (Sample Select CV Input changes) {
    if(sample A is selected) {
      copy buffer A on to the front panel
    }
    if(sample B is selected) {
      copy buffer B on to the front panel
    }
  }
}

This is what I’m trying to avoid:

loop {
  if (Sample Select CV Input changes) {
    if(sample A is selected) {
      draw waveform for sample A on to the front panel
    }
    if(sample B is selected) {
      draw waveform for sample B on to the front panel
    }
  }
}

Now imagine that someone hooks up very fast LFO to the Sample Select CV Input. The waveform display will be flipping between different waveforms very quickly. This would require that the code constantly redraw the waveform display on the front panel unless I somehow draw the waveforms off-screen and copy/paste (using code) the rendered waveforms to the front panel.

Hopefully that clarifies things. Sorry if I’m still being confusing. I’m doing my best to explain it!

anyway you can’t redraw faster than the framerate so your worst case will be 60 dirty fb: peanuts

I can change display and sample in less than 1 msec in musicalbox (using for example an lfo), but the true limit is 17 msecs to arrive to the next video frame

That’s reassuring. If that’s my only option, I may take that route. Displaying the waveform is a “nice to have” for this module. I’ll have to think it over. I really appreciate the feedback @synthi!

@clone45 doesn’t really need to redraw the framebuffers, just hide/show them accordingly.

1 Like

You can use Squinky’s own DrawTimer.h to time the drawing performance of your module widget.

1 Like