Mac MP3 import issue with QTAudioFormatReader


I’m working on importing QuickTime supported formats, rendering them to uncompressed PCM. I’ve had 100% success importing files containing PCM and AAC (.mp4/.m4a) encoded audio tracks. However, with MP3 I end up with gaps in the audio, and the file length is always truncated to 1/2 or 1/4 the input length (BTW this is on the Mac). I’m reading from a QTAudioReader (returned by QuickTimeAudioFormat::createReaderFor()) and writing to a PCM format writer (using WAV for my example below).

My code basically looks like this (assume we pass in a valid qtFile and reader created by an AudioFormatManager that has properly registered QuickTimeAudioFormat):

void importQuickTimeFile(const File &qtFile, AudioFormatReader &reader)
    WavAudioFormat wavFormat;
    File wavFile(qtFile.withFileExtension("wav"));
    FileOutputStream *outStream = wavFile.createOutputStream();
    if (outStream)
        AudioFormatWriter *writer = wavFormat.createWriterFor( outStream,
                                                               StringPairArray(), 0 );
        if (writer)
            int numSamples = 32768;
            int samplesRead = 0;
            while (samplesRead < reader.lengthInSamples)
                writer->writeFromAudioReader(reader, samplesRead, numSamples);
                samplesRead += numSamples;

                // get the last remaining samples
                if (reader.lengthInSamples - samplesRead < numSamples)
                    numSamples = (int)reader.lengthInSamples - samplesRead;
            delete writer;

Anyone had this problem? Anything I’m doing wrong? I did notice that QTAudioReader makes heavy use of the QuickTime 7 API, and wondering if that has something to do with it. The JUCE code I’m using is very close to the 1.51 release (I diffed the juce_QuickTimeAudioFormat source and it is functionally identical).


Your loop looks a bit dodgy - instead of a loop, try just calling writeFromAudioReader to tell it to write all of the samples, and see if that helps…

Actually, I’d already tried setting numSamples to the max i[/i] and got identical results. To rule out the loop altogether, I just now tried replacing the loop code with

and… again, same results.

The loop is there because the real code is being run from a ThreadWithProgressWindow and I need to update the progress. As I say it’s only MP3 encoded tracks that exhibit this behavior. Other encodings behave properly.

If the ThreadWithProgressWindow rings alarm bells, I’ve already tried this from the main thread and got the same results. (I had previously triggered the assert where the comment said QuickTime objects had to be created on the main thread. That’s the reason the reader is pre-created and passed in as a reference argument.)

Ah yes, QT has all sorts of stupid problems when you use threads - whenever I’ve used it, I’ve had to run it on the main message thread.



Update: This problem appears to only affect the Mac. MP3 import works fine on Windows. Any advice getting this working on Mac is appreciated.

Source of one problem found: file truncation occurs when importing an MP3 that is on an encrypted volume (e.g. user account with FileVault turned on).

Still getting gaps in the audio though, on unencrypted volumes with writer reading reader.lengthInSamples all at once. This is happening with the System install of QuickTime.framework on both Leopard and Snow Leopard.

FWIW, just want to add: AudioFormatWriter::writeFromAudioReader() (which my code calls) employs a loop similar to mine. In fact, that loop uses a temp buffer that throttles the number of samples to read down to 16384 or less. My loop was feeding in 32768, so it’s not surprising that bumping that up to read the entire length in samples doesn’t make any difference. I’ve also tried setting numSamples in my code to 16384 and still get gaps.