cpp,#includeint main() {, AudioDeviceID device = kAudioDeviceUnknown;, OSStatus status = AudioHardwareGetDefaultOutputDevice(device);, if (status != noErr) {, return -1;, }, // 获取设备名称, CFStringRef name;, UInt32 size = sizeof(name);, status = AudioDeviceGetProperty(device, kAudioDevicePropertyDeviceName, &size, &name);, if (status != noErr) {, return -1;, }, // 输出设备名称, CFShow(name);, CFRelease(name);, return 0;,},
“
CoreAudioAPI 是苹果公司为 macOS 和 iOS 平台提供的一套音频处理接口,它允许开发者进行音频的捕获、播放、混音以及各种音频效果的处理,下面将通过一个示例来展示如何使用 CoreAudioAPI 进行简单的音频播放。
示例:使用 CoreAudioAPI 播放音频文件
需要创建一个音频单元(Audio Unit),这是 CoreAudio 中用于音频处理的基本组件,在这个例子中,我们将使用一个远程音频单元来播放系统默认输出设备的声音。
AudioComponentDescription desc; desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_RemoteIO; desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.numberOfInputs = 0; desc.numberOfOutputs = 1; AudioComponent comp = AudioComponentFindNext(NULL, &desc); AudioUnit audioUnit; AudioComponentInstanceNew(comp, &audioUnit);
设置音频单元的流格式,在这个例子中,我们使用线性 PCM 格式,采样率为 44100 Hz,双声道,16 位深度。
AudioStreamBasicDescription streamFormat; streamFormat.mSampleRate = 44100.0; streamFormat.mFormatID = kAudioFormatLinearPCM; streamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; streamFormat.mChannelsPerFrame = 2; streamFormat.mBitsPerChannel = 16; streamFormat.mBytesPerFrame = streamFormat.mBitsPerChannel / 8 * streamFormat.mChannelsPerFrame; streamFormat.mFramesPerPacket = 1; streamFormat.mBytesPerPacket = streamFormat.mBytesPerFrame * streamFormat.mFramesPerPacket; AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &streamFormat, sizeof(streamFormat));
在播放音频之前,需要先加载音频数据,这里假设我们已经有一个音频文件的路径,并且已经将其读取到内存中。
// 假设 audioData 是一个指向音频数据的指针,dataSize 是音频数据的大小 UInt32 dataSize = ...; // 获取音频数据大小 void* audioData = ...; // 获取音频数据指针
为了能够持续播放音频,我们需要设置一个回调函数,当音频缓冲区即将耗尽时,该函数会被调用以填充新的音频数据。
AURenderCallbackStruct callbackStruct; callbackStruct.inputProc = MyRenderCallback; callbackStruct.inputProcRefCon = (void*)audioData; AudioUnitSetProperty(audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callbackStruct, sizeof(callbackStruct));
启动音频单元开始播放音频。
AudioUnitInitialize(audioUnit); AudioOutputUnitStart(audioUnit);
回调函数MyRenderCallback
需要从inputProcRefCon
中获取音频数据,并将其写入到输出缓冲区中。
static OSStatus MyRenderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumFrames, AudioBufferList *ioData) { void* audioData = (void*)inRefCon; // 将 audioData 中的数据复制到 ioData->mBuffers[0].mData 中 return noErr; }
Q1: 如果我想改变播放的音量,应该怎么做?
A1: 可以通过设置音频单元的音量属性来调整音量,使用AudioUnitSetParameter
函数设置kHALOutputParam_Volume
参数。
Q2: 如何处理多个音频输入源或输出设备?
A2: CoreAudioAPI 支持多输入和多输出设备的配置,你可以通过创建多个音频单元实例,或者使用kAudioSessionProperty_OverrideCategoryEnable_BluetoothLEOutput
等属性来管理不同的音频路径。
CoreAudioAPI 提供了强大的音频处理能力,但同时也伴随着一定的复杂性,对于初学者来说,理解和掌握这些 API 可能需要一些时间和实践,不过,一旦熟悉了这些基本概念和操作方法,你就能够开发出功能强大的音频应用程序,希望这个示例能够帮助你入门 CoreAudioAPI 的使用!