Audioformat no appropriate default constructor available

I’m new to Juce and am trying to read metadata from an mp3 file. I get the error that the juce::AudioFormat has no appropriate default constructor available. How do I fix this?

class PlaylistComponent  : public juce::Component,
                           public TableListBoxModel,
                           public Button::Listener,
                           public AudioSource,
                           public AudioFormat

Why are you trying to inherit from AudioFormat? That doesn’t seem appropriate at all for your class.

I’m not sure. I was following an example I saw. Should it be AudioFormatReader or something else?

Multiple inheritance might save a few characters typing, but best practice is to inherit as few as possible.

The rule is to prefer composition over inheritance

You don’t need inheritance at all to read audio file metadatas. In principle code like the following should work, but at least a random mp3 file I picked up from my drive didn’t produce any metadata keys/values…But looking at the file with Foobar2000, there definitely is metadata. The Juce mp3 metadata handling might be broken/limited in some manner.

juce::AudioFormatManager aman;
    aman.registerBasicFormats();
    juce::File f("D:\\foo.mp3");
    auto reader = aman.createReaderFor(f);
    if (reader)
    {
        auto keys = reader->metadataValues.getAllKeys();
        for (auto& k : keys)
        {
           DBG(k << reader->metadataValues.getValue(k,""));
        }
        delete reader;
    }
1 Like

If the file is in my Z:\WD\Music folder, do I set the file to

juce::File f(“Z:\WD\Music\1.mp3”);

Nothing is printed when I compile so I’m not sure if it can’t detect the file or it can’t detect the metadata.

On Windows you need to use \\ instead of \ for the file paths in source code. But in any case, it does look like Juce doesn’t actually even support the typical metadata stuff in mp3 files.

Ideally you assemble the path using

auto file = juce::File ("Z:").getChildFile ("WD").getChildFile ("foo.np3");
jassert (file.existsAsFile());

And even better is using the juce::File::getSpecialLocation (juce::File::userDesktopDirectory); to start with a path that definitely exists.

1 Like

I assembled the path like you said and still am not getting anything. Does this mean it can’t detect the metadata like xanekaios said

Did you add that jassert? If that didn’t stop (in debugger), you will know that you might not have opened the reader at all.

Make sure you know, if the reader was open or not, e.g. using DBG() in your code.
And always put a DBG in both branches:

if (reader)
{
    DBG ("reader opened: " << f.getFullPathName());
    // ...
}
else
{
    DBG ("reader not open: " << f.getFullPathName());
}

OK I added that and it does print out “reader opened: …” which means my reader is opened but it doesn’t seem to print out the metadata. And yes I added jassert

If you copy and pasted daniel’s code, you might have that “.np3” typo.

Also, stick a BP on the ‘auto keys… ’ line of xenakios’ code and see if it skips the for loop when stepping.

I always find it helpful to go on a jump to def spree on the things that aren’t working in this way.

  • Hopefully you’re changing that ‘foo’ bit anyway

What is BP? And yes, I changed the foo bit to match the file I was loading.

A breakpoint. Are you using VisualStudio?

I think if the reader is opened correctly and there is nothing in the metadataValues, then it seems JUCE is not reading the metadata or the mp3 has no metadata.

Yes

This is the code I’m using. The file path is Z:\WF\Music\example.mp3. I checked that the mp3 has metadata. Do you see anything wrong with the code? It only prints out reader opened but doesn’t print out the metadata.

    formatManager.registerBasicFormats();

    auto file = juce::File("Z:").getChildFile("WD").getChildFile("Music").getChildFile("example.mp3");
    jassert(file.existsAsFile());

    auto reader = formatManager.createReaderFor(file);
    if (reader)
    {
        DBG("reader opened: " << file.getFullPathName());
        for (auto& key : reader->metadataValues.getAllKeys())
        {
            DBG("Value: " + reader->metadataValues.getValue(key, ""));
        }
        delete reader;
    }
    else
    {
        DBG("reader not open: " << file.getFullPathName());
    }

I looked at the Juce mp3 code, and it just doesn’t support the metadata at all.

Would be lovely if somebody could have a look, since the legwork was already done by fellow @jrlanglois

I think he added mp3 to his PR in the course of the thread…