Reputation: 3
I'm trying to display the length of audio files in a Playlist component for an application. I've not used Juce or C++ before, and I can't understand how to do that from Juce documentation. I want to make a function that takes an audio file's URL and returns the length in seconds of that audio without playing that file or doing anything else with that file. I've tried a lot of things, and all of them didn't work, and this is the last thing I've tried:
void PlaylistComponent::trackStats(URL audioURL)
{
AudioFormatManager formatManager;
std::unique_ptr<AudioFormatReaderSource> readerSource;
AudioTransportSource transportSource;
auto* reader = formatManager.createReaderFor(audioURL.createInputStream(false));
if (reader != nullptr)
{
std::unique_ptr<AudioFormatReaderSource> newSource(new AudioFormatReaderSource(reader, true));
transportSource.setSource(newSource.get(), 0, nullptr, reader->sampleRate);
readerSource.reset(newSource.release());
DBG("PlaylistComponent::trackStats(URL audioURL): " << transportSource.getLengthInSeconds());
}
else
{
DBG("Something went wrong loading the file");
}
}
And this is the PlaylistComponent header file:
class PlaylistComponent : public juce::Component,
public juce::TableListBoxModel,
public Button::Listener,
public FileDragAndDropTarget
{
...
}
Upvotes: 0
Views: 1130
Reputation: 1007
You can do this very early on in the audio file opening procedure. You only need an AudioFormatReader instance (no need to create an AudioFormatReaderSource):
// create juce::File from a path juce::String (from a drag & drop event etc).
File file{filePath};
// make sure it is a file and not a directory, etc.
if (!file.existsAsFile()) return;
// create the AudioFormatReader that contains the data
AudioFormatReader *reader = formatManagerInstance.createReaderFor(file);
// make sure a valid reader can be created (not an unsupported file)
if (reader == nullptr) return;
// log the length in seconds
std::cout << reader->lengthInSamples / reader->sampleRate << "\n";
Note: for this to work you will need to
IMPORTANT: if successful the createReaderFor() method uses new to create a new AudioFormatReaderInstance, so make sure to use delete on it when you are finished using it to avoid memory leaks
Upvotes: 0
Reputation: 1025
juce::AudioFormatReaderSource has a method called getTotalLength()
which returns the total amount of samples.
Divide that by the sample rate of the file and you have the total length in seconds. Something like this:
if (auto* reader = audioFormatReaderSource->getAudioFormatReader())
double lengthInSeconds = static_cast<double> (audioFormatReaderSource->getTotalLength()) / reader->sampleRate;
Upvotes: 1