gpt4 book ai didi

cocoa - 在 Cocoa 中加载 OpenAL 的 .wav 文件

转载 作者:行者123 更新时间:2023-12-03 16:17:45 24 4
gpt4 key购买 nike

我需要将声音文件加载到基于 Cocoa 的 OpenAL 应用程序。

进展:

  • OpenAL 实用程序函数 alutLoadWAVFile 已被弃用; Mac OS X SDK 中不再包含 alut header 。根据技术说明,实际代码仍然存在,以实现二进制兼容性。但是,如果我尝试添加该函数的声明,代码将编译,但链接器将中止,并提示找不到 alutLoadWAVFile 的符号。 (我正在链接到 OpenAL.framework)。

  • 但是,Apple OpenAL 示例代码仍然使用此符号。当我清理示例代码项目时,它可以正常编译和链接。但没有找到该函数的声明。 (附带问题:那么它如何构建和链接?)

所以,我找到了 Apple 的 George Warner 的一些代码,其中包含 alutCreateBufferFromFile 和 alutLoadMemoryFromFile 的替换函数。尽管能够直接从大多数任何类型的音频文件创建 OpenAL 缓冲区,但该代码似乎仅支持 8 位单声道声音文件。 16 位立体声或单声道 44khz 文件会产生令人讨厌的嘶嘶声和削波。 (文件没问题;Quicktime 可以正常播放。)

因此,我的问题是:有人可以向我指出一些适合与 OpenAL 缓冲区一起使用的 Cocoa/Carbon 的 .wav 加载代码/帮助吗?谢谢。

最佳答案

我确信您已经解决了这个问题,但是对于通过 Google 找到此问题的人来说,这里有一些几乎没有经过测试的 WAV 加载代码。它可以工作,但在用于实际用途之前,您最好仔细检查内存泄漏等问题。

static bool LoadWAVFile(const char* filename, ALenum* format, ALvoid** data, ALsizei* size, ALsizei* freq, Float64* estimatedDurationOut)
{
CFStringRef filenameStr = CFStringCreateWithCString( NULL, filename, kCFStringEncodingUTF8 );
CFURLRef url = CFURLCreateWithFileSystemPath( NULL, filenameStr, kCFURLPOSIXPathStyle, false );
CFRelease( filenameStr );

AudioFileID audioFile;
OSStatus error = AudioFileOpenURL( url, kAudioFileReadPermission, kAudioFileWAVEType, &audioFile );
CFRelease( url );

if ( error != noErr )
{
fprintf( stderr, "Error opening audio file. %d\n", error );
return false;
}

AudioStreamBasicDescription basicDescription;
UInt32 propertySize = sizeof(basicDescription);
error = AudioFileGetProperty( audioFile, kAudioFilePropertyDataFormat, &propertySize, &basicDescription );

if ( error != noErr )
{
fprintf( stderr, "Error reading audio file basic description. %d\n", error );
AudioFileClose( audioFile );
return false;
}

if ( basicDescription.mFormatID != kAudioFormatLinearPCM )
{
// Need PCM for Open AL. WAVs are (I believe) by definition PCM, so this check isn't necessary. It's just here
// in case I ever use this with another audio format.
fprintf( stderr, "Audio file is not linear-PCM. %d\n", basicDescription.mFormatID );
AudioFileClose( audioFile );
return false;
}

UInt64 audioDataByteCount = 0;
propertySize = sizeof(audioDataByteCount);
error = AudioFileGetProperty( audioFile, kAudioFilePropertyAudioDataByteCount, &propertySize, &audioDataByteCount );
if ( error != noErr )
{
fprintf( stderr, "Error reading audio file byte count. %d\n", error );
AudioFileClose( audioFile );
return false;
}

Float64 estimatedDuration = 0;
propertySize = sizeof(estimatedDuration);
error = AudioFileGetProperty( audioFile, kAudioFilePropertyEstimatedDuration, &propertySize, &estimatedDuration );
if ( error != noErr )
{
fprintf( stderr, "Error reading estimated duration of audio file. %d\n", error );
AudioFileClose( audioFile );
return false;
}

ALenum alFormat = 0;

if ( basicDescription.mChannelsPerFrame == 1 )
{
if ( basicDescription.mBitsPerChannel == 8 )
alFormat = AL_FORMAT_MONO8;
else if ( basicDescription.mBitsPerChannel == 16 )
alFormat = AL_FORMAT_MONO16;
else
{
fprintf( stderr, "Expected 8 or 16 bits for the mono channel but got %d\n", basicDescription.mBitsPerChannel );
AudioFileClose( audioFile );
return false;
}

}
else if ( basicDescription.mChannelsPerFrame == 2 )
{
if ( basicDescription.mBitsPerChannel == 8 )
alFormat = AL_FORMAT_STEREO8;
else if ( basicDescription.mBitsPerChannel == 16 )
alFormat = AL_FORMAT_STEREO16;
else
{
fprintf( stderr, "Expected 8 or 16 bits per channel but got %d\n", basicDescription.mBitsPerChannel );
AudioFileClose( audioFile );
return false;
}
}
else
{
fprintf( stderr, "Expected 1 or 2 channels in audio file but got %d\n", basicDescription.mChannelsPerFrame );
AudioFileClose( audioFile );
return false;
}

UInt32 numBytesToRead = audioDataByteCount;
void* buffer = malloc( numBytesToRead );

if ( buffer == NULL )
{
fprintf( stderr, "Error allocating buffer for audio data of size %u\n", numBytesToRead );
return false;
}

error = AudioFileReadBytes( audioFile, false, 0, &numBytesToRead, buffer );
AudioFileClose( audioFile );

if ( error != noErr )
{
fprintf( stderr, "Error reading audio bytes. %d\n", error );
free(buffer);
return false;
}

if ( numBytesToRead != audioDataByteCount )
{
fprintf( stderr, "Tried to read %lld bytes from the audio file but only got %d bytes\n", audioDataByteCount, numBytesToRead );
free(buffer);
return false;
}

*freq = basicDescription.mSampleRate;
*size = audioDataByteCount;
*format = alFormat;
*data = buffer;
*estimatedDurationOut = estimatedDuration;

return true;
}

关于cocoa - 在 Cocoa 中加载 OpenAL 的 .wav 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/805454/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com