AudioThumbnail low resolution issue

I have a problem with blockiness of the AudioThumbnail waveform I get when comparing two different methods.
If I generate the thumbnail like it was shown in the tutorials, the thumbnail looks fine and detailed:

audioThumbnail.setSource(new juce::FileInputSource(file));


But if I use AudioFormatReader to first read the audio data into AudioBuffer and from there generate the AudioThumbnail, the results look really low resolution and blocky:

auto reader = std::unique_ptrjuce::AudioFormatReader(audioFormatManager.createReaderFor(file));
auto audioBuffer = std::make_unique<juce::AudioBuffer>(reader->numChannels, reader->lengthInSamples);

reader->read(audioBuffer.get(), 0, (int) reader->lengthInSamples, 0, true, reader->numChannels > 1);

audioThumbnail.reset(reader->numChannels, reader->sampleRate, (int) reader->lengthInSamples);
audioThumbnail.addBlock(0, *audioBuffer, 0, (int) reader->lengthInSamples);


What am I doing wrong? In both cases the AudioThumbnail class construction is identical: both use 512 for sourceSamplesPerThumbnailSample constructor parameter. It looks like either addBlock() or setSource() changes the sourceSamplesPerThumbnailSample parameter given into the constructor, or something along those lines (even thought they don’t, I checked with debugger). I can’t explain otherwise how the second method gives much more blocky looking resutls that the setSource() does.

How to fix this issue? I need to visualize data contained in AudioBuffers.
To me it looks like using the tutorial’s method (setSource) somehow automatically adjusts the thumbnail’s resolution to match the one used when rendering the actual waveform on screen later on.

2 Likes

The AudioRecordingDemo updates a thumbnail by calling addBlock repeatedly. Does the thumbnail in that demo display correctly (i.e. not at a low resolution) for you? If the demo works, I’d recommend studying its code to look for differences between the demo’s use of the AudioThumbnail, and yours.

Is it possible that you’re using different values for startTimeSeconds and endTimeSeconds in the call to drawChannels when switching between audio data sources? I’d expect lower-resolution results when drawing shorter excerpts from the sample. It might be worth checking that you’re setting these values correctly when adding data using addBlock.

IIRC using setSource enables the thumbnail to open and read directly from the stream/file when you zoom in and essentially request a higher resolution that will have been cached.

This can lead to some surprising performance characteristics but means it can display at higher resolutions than using addBlock as that method can’t go back and re-read the block for the original data.

Rail

The AudioRecordingDemo thumbnail looks fine.

The start and end times for the thumbnail parameters are identical. It’s the exact same code without any modifications that’s displaying the thumbnail.

If you read my original message, that’s exactly what I’m doing and it’s causing the problem.

I didn’t know setSource() can access the file later to create different versions of the thumbnail. I think the optimal solution for me would be if I used setSource() so that it actually loads the audiodata from memory/AudioBuffer instead of file, whenever it decides to refresh the thumbnail resolution.

Is there ready made class for this in Juce?

Hmm, quick glance at the setSource() documentation reveals that I would only need to create my own InputSource and InputStream classes to get this done. I think that’s what I’m going to do. Then I have full control where I keep my original audio data and from where setSource() gets its data.

EDIT:
There already seems to be MemoryInputStream available. This leaves me only the InputSource to be implemented, which should be trivial.

EDIT2:
I’m starting to think this approach wasn’t so trivial after all. Does the setSource() assume that the InputSource/InputStream class returns WAV/AIFF file format data?

I was indicating that I’d found this issue before (with images to show the issue)

Rail