当 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