OggWriter needs support for flush()


#1

It seems the only way currently to flush (or close) an OggWriter (subclass of AudioFormatWriter) is to delete it. However, if it writes to a MemoryOutputStream, that stream will be deleted in the destructor too, effectively discarding the output before it can be accessed!

Without properly flushing (closing) the Ogg stream, there is only incomplete data in the MemoryOutputStream, leaving to truncated samples.

OggWriter in its current state is fine for audio files, but less so for MemoryOutputStream, where the encoded data needs to be accessed immediately after (e.g. for storing in a database, soundbank file, etc).

Implementing flush() for OggWriter fixes this:

bool flush() override
{
    if (!ok)
        return false;
    writeSamples (0);
    output->flush();
    return true;
}

Any chance this will get included?


#2

Oh and by the way, it’s the same with FLACWriter:

bool flush() override
{
    if (!ok)
        return false;
    FlacNamespace::FLAC__stream_encoder_finish (encoder);
    output->flush();
    return true;
}

:smile:


#3

I wondered for a moment why I’d never hit that problem myself, but actually the pattern I’d recommend here would be to just use a temporary MemoryOutputStream to write a MemoryBlock, e.g.

MemoryBlock loadFile()
{
    MemoryBlock mb;
    auto* stream = new MemoryOutputStream (mb, false);
    ...save file, deleting stream....
    return mb;
}

#4

Yes, that works. Thanks for the tip.

On a side note, I always found it a bit strange that there’s no way to close a file other than deleting it (as is the case with many other Juce objects). On the other hand, a closed file is probably of little use anyway.

Ultimately, it forces you to be absolutely clear about the lifetime and scope of objects, which is a very good thing (unless for XP and agile development, where weak typing and garbage collection works better).