AudioThumbnail::drawChannels() question


#1

I'm trying to draw a vertical line denoting play position(scrubber?) on top of my waveform but the constant calls to drawChannels() are cranking up my CPU. 

        if (thumbnail->getTotalLength() > 0){
                    thumbnail->drawChannels (g, getLocalBounds(), startTime, endTime, 2.0f);
            }
        if(regionWidth>1){
                g.setColour(colour.contrasting(.5f).withAlpha(.7f));
                g.fillRect(timeToX(currentPlayPosition), 0.f, regionWidth, (float)getHeight());    
             }
        if(scrubberPosition>0){
                g.setColour(colour.contrasting(.8f));
                g.drawVerticalLine(timeToX(scrubberPosition), 0.f, getHeight());        
             }
        }

I also tried grabbing the waveform image first, and then calling Graphics::drawImage() in my paint routines but didn't help much at all. I could create a simple scrubber component and move it around on top of my waveform, but the underlying component Paint()'s method would still be called or?


#2

Almost certainly better to make your playhead a separate component and then set its bounds based on the playback time.

drawChannels shouldn't be too intensive as long as the zoom level is sufficient that it doesn't have to re-read from the source file and you are only repainting the area that needs to i.e. don't call repaint() which will re-draw the whole waveform.

If you use a separate component for the playhead only the area it covers will be repainted which is likely to only be a few pixels. Use JUCE_ENABLE_DEBUG_REPAINTING to be sure.


#3

Thanks Dave, that works a lot better, and I no longer constantly redraw the waveform. That was just silly on my part. One thing though, when you say only repaint() the areas I need to? How does I go about that? Pardon my ignorance. You can see the problem here:

The scrubber jumps a few samples each time, I know I should redraw whatever was under the scrubber and not the entire waveform. Any pointers as to how I go about that? Thanks again for the prompt reply. 


#4

Component::repaint (int x, int y, int width, int height), Ok, let me try it out..


#5

Perfect. Thanks Dave.


#6

If you actually follow Dave's advice and use a component for the playhead, then you don't need to worry about repainting anything manually, you just move the component and it'll all work.


#7

That's true. At present everything is housed in the one parent, so calling paint() on it, calls paint on its children. For now I'm happy to continue as is. Still can't believe I hadn't come across the paint only-part-of method before!


#8

And following your demo now, it all makes sense!