WavAudioFormatReader metadata not read correctly (no problem)


#1

I'm trying to read back a riff wave file that has metadata with the WavAudioFormatReader and there is an error in the reading back of sample loop points. The reader correctly parses the chunk, as it reports NumSampleLoops = 1 but then no other metadata information is set about the loop start and end points. The wavefile is correctly opened with loop points in other apps.

I've put a breakpoint here and it will exit from the loop early:

    struct SMPLChunk
    {
        ...

        void copyTo (StringPairArray& values, const int totalSize) const
        {
            setValue (values, "Manufacturer",      manufacturer);
            setValue (values, "Product",           product);
            setValue (values, "SamplePeriod",      samplePeriod);
            setValue (values, "MidiUnityNote",     midiUnityNote);
            setValue (values, "MidiPitchFraction", midiPitchFraction);
            setValue (values, "SmpteFormat",       smpteFormat);
            setValue (values, "SmpteOffset",       smpteOffset);
            setValue (values, "NumSampleLoops",    numSampleLoops);
            setValue (values, "SamplerData",       samplerData);

            for (int i = 0; i < (int) numSampleLoops; ++i)
            {
                if ((uint8*) (loops + (i + 1)) > ((uint8*) this) + totalSize)
>                   break;

                setValue (values, i, "Identifier", loops[i].identifier);
                setValue (values, i, "Type",       loops[i].type);
                setValue (values, i, "Start",      loops[i].start);
                setValue (values, i, "End",        loops[i].end);
                setValue (values, i, "Fraction",   loops[i].fraction);
                setValue (values, i, "PlayCount",  loops[i].playCount);
            }
        }

        ...

 


#2

Also, regarding this:


    struct SMPLChunk
    {
        ...
        SampleLoop loops[1];

But then there could be some buffer overflow when creating the wavefile from passed metadata:


    static MemoryBlock createFrom (const StringPairArray& values)
    {
        MemoryBlock data;
        const int numLoops = jmin (64, values.getValue ("NumSampleLoops", "0").getIntValue());
        if (numLoops > 0)
        {
            ...
            s->numSampleLoops    = ByteOrder::swapIfBigEndian ((uint32) numLoops);

            for (int i = 0; i < numLoops; ++i)
            {
>               SampleLoop& loop = s->loops[i];
                loop.identifier = getValue (values, i, "Identifier", "0");
                loop.type       = getValue (values, i, "Type", "0");
                loop.start      = getValue (values, i, "Start", "0");
                loop.end        = getValue (values, i, "End", "0");
                loop.fraction   = getValue (values, i, "Fraction", "0");
                loop.playCount  = getValue (values, i, "PlayCount", "0");
            }
        }
        return data;
    }

#3

-snips-


#4

This code looks completely correct to me - it will only break if it gets asked to read beyond the size of the chunk.. ?


#5

Ok regarding the save of data.

Regarding metadata not read correctly ? try reading this wave (rename as wav) with sample loopoints set. As i already said NumSampleLoops = 1 is set in metadata, but no LoopXvalue metadata found. Loop points in this wavefile get correctly restored in *ANY* application, sorry.


#6

All of the data containing the loop points lies beyond the end of the chunk - try it yourself and look at the memory addresses! The chunk size is only 36 bytes - it only contains the header info, and not the loop positions.

Is there some kind of implicit thing in the format specification that says that if no loop lengths are specified, then it should just loop the entire file? Or is this file just broken, and other readers are reading memory beyond the end of the chunk and not checking for errors?


#7

yeah my mistake. you always beat me to it :(

sorry for being a bit harsh, didn't want to put pressure on you ;)

 


#8

No problem! But do you mean that the file was broken, and other readers don't read it correctly?


#9

i generated that file programmatically, and after checking the difference with the same file exported from renoise i noticed the header size mistake. what bugged me was that opening that file in other applications i always saw the correct loop points, while opening it again with juce not... i thought there was something faulty with juce then !