tumtumtum / StreamingKit

A fast and extensible gapless AudioPlayer/AudioStreamer for OSX and iOS (iPhone, iPad)
Other
2.43k stars 525 forks source link

Retrieving Magic Cookie from MP3 files when writing stream to a file. #298

Open belakva opened 8 years ago

belakva commented 8 years ago

In STKAudioPlyer.m in -(void) createAudioConverter:(AudioStreamBasicDescription*)asbd there is an attempt to retrieve MagicCookie implemented.

However, while Apple Core Audio Format Specification states:

The Magic Cookie chunk contains supplementary (“magic cookie”) data required by certain audio data formats, such as MPEG-4 AAC, for decoding of the audio data.

STKAudioPlayer attempts to retrieve Magic Cookie from any file but AAC:

if (self->currentlyReadingEntry.dataSource.audioFileTypeHint != kAudioFileAAC_ADTSType)
    {
        status = AudioFileStreamGetPropertyInfo(audioFileStream, kAudioFileStreamProperty_MagicCookieData, &cookieSize, &writable);

        if (status)
        {
            return;
        }

        void* cookieData = alloca(cookieSize);

        status = AudioFileStreamGetProperty(audioFileStream, kAudioFileStreamProperty_MagicCookieData, &cookieSize, cookieData);

        if (status)
        {
            return;
        }

        status = AudioConverterSetProperty(audioConverterRef, kAudioConverterDecompressionMagicCookie, cookieSize, &cookieData);

        if (status)
        {
            [self unexpectedError:STKAudioPlayerErrorAudioSystemError];

            return;
        }
    }

Is this a mistake? Should there be (self->currentlyReadingEntry.dataSource.audioFileTypeHint == kAudioFileAAC_ADTSType) instead?

This was a commit by @danielgindi. @tumtumtum , I can make a pull request if necessary.

danielgindi commented 8 years ago

I don't think this was commited by me, but if I recall correctly- then this is correct. Because if we know the format already then it means we've read the magic cookie already.

Btw magic cookies are not unique to AAC.

belakva commented 8 years ago

@danielgindi thank you for reply!

I ment this commit and yes, my bad - I'm wrong, this code is not there. So sorry for interrupting.

However, thank you for joining the discussion. But there is still an issue with this code for me. I am trying to record a stream of MP3 file which is recognised fine and by the time described if is invoked,self->currentlyReadingEntry.dataSource.audioFileTypeHint is equal kAudioFileMP3Type. So we fall into if and the described method returns after AudioFileStreamGetPropertyInfo with status kAudioFileStreamError_DataUnavailable. Because MP3 files do not have magic cookies. The thing is if I comment out the whole if block described above, the file is recorded just fine.

Are you sure that if we know format it means we've read magic cookie? For sure it makes sense, but I do not see kAudioFileUnknownTypeor something like that in CF_ENUM(AudioFileTypeID). What value do you expect to be returned by self->currentlyReadingEntry.dataSource.audioFileTypeHint if magic cookie wasn't read?

Shall we then check self->currentlyReadingEntry.dataSource.audioFileTypeHint against every type in CF_ENUM(AudioFileTypeID) and only if does not match any of them fall into if block?

danielgindi commented 8 years ago

Well, as I've said it's been a long time :-) There needs to be some debugging and careful review of the code - as changes that might make sense for you might break other situations. In order to fully understand what's going on I'll need to dive back into this code, which I don't have the time for at the moment... maybe @tumtumtum can help here!

belakva commented 8 years ago

Ok, I see, it's just that I would not really expect @tumtumtum to show up soon. So could you just tell me 1 thing: are you sure that if we know format it means we've read magic cookie?

Thanks anyway :)