- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我需要将声音文件加载到基于 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/
我正在开发一个需要能够平均三个数字的 Facebook 应用程序。但是,它总是返回 0 作为答案。这是我的代码: $y = 100; $n = 250; $m = 300; $number = ($y
我只是无法弄清楚这一点,也找不到任何对我来说有意义的类似问题。我的问题:我从数据库中提取记录,并在我的网页上以每个面板 12 条的倍数显示它们。因此,我需要知道有多少个面板可以使用 JavaScrip
我是一名优秀的程序员,十分优秀!