当 ExtAudioFile 从 AudioFile 转换时,ExtAudioFileGetProperty 失败

Posted

技术标签:

【中文标题】当 ExtAudioFile 从 AudioFile 转换时,ExtAudioFileGetProperty 失败【英文标题】:ExtAudioFileGetProperty fails when ExtAudioFile is converted from AudioFile 【发布时间】:2016-11-24 14:51:48 【问题描述】:

我正在尝试将 MP3 文件加载到适用于 ios 的 OpenAL 缓冲区中,并且我已经从示例中复制了一些代码。

所以,使用这段代码:

    CFURLRef fileURL = nil;
    NSString* nsPath = [CDUtilities fullPathFromRelativePath:[NSString stringWithUTF8String:FilePath.c_str()]];

    if (nsPath) 
        fileURL = (CFURLRef)[[NSURL fileURLWithPath:nsPath] retain];
    

#if 0
    status = AudioFileOpenURL (fileURL, kAudioFileReadPermission, kAudioFileMP3Type, &AudioFileHandle );
    ExtAudioFileWrapAudioFileID ( AudioFileHandle, false, &ExtAudioFileHandle );

    // Close the AudioFile handle. It's no longer needed
    AudioFileClose ( AudioFileHandle );
    AudioFileHandle = nullptr;

#else
    status = ExtAudioFileOpenURL ( fileURL, &ExtAudioFileHandle );
#endif

    // Get the audio data format
    UInt32 PropertySize = sizeof ( InputDataFormat );
    status = ExtAudioFileGetProperty ( ExtAudioFileHandle, kExtAudioFileProperty_FileDataFormat, &PropertySize, &InputDataFormat);
    if (status != noErr)
    
        DecodeResult = false;
        goto function_exit;
    

    if ( InputDataFormat.mChannelsPerFrame > 2 )
    
        DecodeResult = false;
        goto function_exit;
    

    // Set the client format to 16 bit signed integer (native-endian) data
    // Maintain the channel count and sample rate of the original source format
    OutputDataFormat.mSampleRate = InputDataFormat.mSampleRate;
    OutputDataFormat.mChannelsPerFrame = InputDataFormat.mChannelsPerFrame;

    OutputDataFormat.mFormatID = kAudioFormatLinearPCM;
    OutputDataFormat.mBytesPerPacket = 2 * InputDataFormat.mChannelsPerFrame;
    OutputDataFormat.mFramesPerPacket = 1;
    OutputDataFormat.mBytesPerFrame = 2 * InputDataFormat.mChannelsPerFrame;
    OutputDataFormat.mBitsPerChannel = 16;
    OutputDataFormat.mFormatFlags = kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsSignedInteger;

    // Set the desired client (output) data format
    status = ExtAudioFileSetProperty ( ExtAudioFileHandle, kExtAudioFileProperty_ClientDataFormat, sizeof ( OutputDataFormat ), &OutputDataFormat );
    if (status != noErr)
    
        DecodeResult = false;
        goto function_exit;
    

    // Get the total frame count
    PropertySize = sizeof ( FrameCount );
    status = ExtAudioFileGetProperty ( ExtAudioFileHandle, kExtAudioFileProperty_FileLengthFrames, &PropertySize, &FrameCount );
    if (status != noErr)
    
        DecodeResult = false;
        goto function_exit;
    

在那个#if中,如果我将其切换为1,它将以AudioFile的形式打开mp3,然后将其转换为ExtAudioFile,否则,它将直接以ExtAudioFile的形式打开。

在第一种情况下,由于某种原因,稍后使用 kExtAudioFileProperty_FileLengthFrames 调用 ExtAudioFileGetProperty 失败并显示 0xffffffda。到那时还可以。如果我从一开始就将它作为 ExtAudioFile 打开,一切正常...

我需要将它作为 AudioFile 打开,因为我实际上是在使用 AudioFileOpenWithCallbacks 从缓冲区中读取数据(我已经有了另一种机制来将文件加载到缓冲区中)。如果有人知道从缓冲区获取 ExtAudioFile 甚至将 MP3 缓冲区转换为 PCM 的任何其他方法,请分享:)

为什么当我作为 AudioFile 打开并转换它时它会失败,而当我直接作为 ExtAudioFile 打开时却没有?

【问题讨论】:

【参考方案1】:

好的,所以我找到了答案。显然完全反对我在某些示例中看到的内容,您无法在将原始句柄转换为 ExtAudioFile 后释放它。我将那个 AudioFileClose 代码移到函数的末尾,突然一切正常。我只是想知道为什么其他所有东西都在使用关闭的句柄,但不是那个特定的属性,而是无论如何......苹果之谜:)

【讨论】:

以上是关于当 ExtAudioFile 从 AudioFile 转换时,ExtAudioFileGetProperty 失败的主要内容,如果未能解决你的问题,请参考以下文章

ExtAudioFile API 是不是曾经使用硬件来解码音频?

如何在 iOS 上使用 ExtAudioFile 进行 AAC 编码?

从 AudioUnit 格式转换为 ExtAudioFileWrite

如何修剪音频数据?

iOS 中的 ExtAudioFileWrite 失败,错误代码为 -66560

在 iOS 中将 ExtAudioFileRef 类型转换为 AudioFileID 类型