AudioThumbnail::getTotalLength() return 0 instead of the correct value

I need an audio waveform on screen, which shows what audio I’ve recorded so far. I.e. the final static waveform is drawn on screen as it fills the juce::AudioThumbnail. When more than 10 seconds has been recorded, the waveform is zoomed out so that the full waveform always fills the Component’s area on the screen.

The below code worked exactly like described until very recently, I suddenly noticed that it doesn’t zoom out anymore. For some reason juce::AudioThumbnail::getTotalLength() return 0, but still the next line where I actually draw the channels, draws the waveform perfectly, but obviously only the first 10 seconds of it. So something internal to the audioThumbnail has the right sample length for its own use, but I can’t get that same value out of getTotalLength().

How to fix this?

The code that used to work is below:

    const double end_time = std::max(10.0, mp_audio_thumbnail->getTotalLength());

                              juce::Rectangle<int>(0, 0, getWidth(), getHeight()),
                              0,                        // start time
                              end_time,                 // end time
                              1.0f);                    // vertical zoom

Did you set sample rate?

Yep. I just checked with a debugger, and audioThumbNail has 44100 as sample rate.

Do you fill the thumbnail from a reader or using addBlock?
If you are using an AudioFormatReader, you rely with getTotalLength() on the length in the reader, which is 0 until the writer was closed. The number is in the header but will only filled out once the file is finished.

Calling flush() on the Writer might be a quick fix, but is a bad idea, because it means you have concurrency issues from the writer thread and the GUI.

I think I would maintain a std::atomic<juce::int64> numSamples that you fill when writing the file and read to display it.

I’m using addBlock:

    // Create an AudioBuffer to wrap our incoming data.
    // Note that this does no allocations or copies, it simply references our input data
    AudioBuffer<float> buffer(const_cast<float**>(p_source_buffer_list), channel_count, sample_count);

    mp_thumbnail_to_update->addBlock(m_sample_counter, buffer, 0, sample_count);

The sample_count seems to be 1024 in my test, so no problems there at least.

I could do what you suggest: keep track how many samples has been saved so far and then use that value when needed.

Wait, I already have that value (m_sample_counter), so I could just use it instead of trying to get the same number directly in seconds from the thumbnail itself.

But’s it weird that this stopped working suddenly, after it had worked properly for awhile. I wonder if something changed in JUCE?