如何使用 AudioUnit (iOS) 播放信号?
How to play a signal with AudioUnit (iOS)?
我需要生成信号并用 iPhone 的扬声器或耳机播放。
为此,我生成了一个交错信号。然后我需要用下一个信息实例化一个 AudioUnit 继承的 class 对象:2 个通道、44100 kHz 采样率、一些缓冲区大小来存储几帧。
然后我需要编写一个回调方法,该方法将接收我的信号并将其放入 iPhone 的输出缓冲区。
问题是我不知道如何编写继承的 AudioUnit class。我无法理解 Apple 的有关它的文档,我能找到的所有示例要么从文件中读取并以巨大的延迟播放,要么使用 depricated 结构。
我开始觉得自己很蠢什么的。请帮助...
要使用 AudioUnit
向 iPhone 的硬件播放音频,您不能从 AudioUnit
派生,因为 CoreAudio 是一个 c 框架 - 而是给它一个渲染向设备提供音频样本的回调。以下代码示例向您展示了如何操作。您需要将 assert
替换为真正的错误处理,并且您可能希望使用 kAudioUnitProperty_StreamFormat
选择器更改或至少检查音频单元的样本格式。我的格式恰好是 48kHz 浮点交错立体声。
static OSStatus
renderCallback(
void* inRefCon,
AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList* ioData)
{
// inRefCon contains your cookie
// write inNumberFrames to ioData->mBuffers[i].mData here
return noErr;
}
AudioUnit
createAudioUnit() {
AudioUnit au;
OSStatus err;
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
assert(0 != comp);
err = AudioComponentInstanceNew(comp, &au);
assert(0 == err);
AURenderCallbackStruct input;
input.inputProc = renderCallback;
input.inputProcRefCon = 0; // put your cookie here
err = AudioUnitSetProperty(au, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &input, sizeof(input));
assert(0 == err);
err = AudioUnitInitialize(au);
assert(0 == err);
err = AudioOutputUnitStart(au);
assert(0 == err);
return au;
}
我需要生成信号并用 iPhone 的扬声器或耳机播放。
为此,我生成了一个交错信号。然后我需要用下一个信息实例化一个 AudioUnit 继承的 class 对象:2 个通道、44100 kHz 采样率、一些缓冲区大小来存储几帧。
然后我需要编写一个回调方法,该方法将接收我的信号并将其放入 iPhone 的输出缓冲区。
问题是我不知道如何编写继承的 AudioUnit class。我无法理解 Apple 的有关它的文档,我能找到的所有示例要么从文件中读取并以巨大的延迟播放,要么使用 depricated 结构。
我开始觉得自己很蠢什么的。请帮助...
要使用 AudioUnit
向 iPhone 的硬件播放音频,您不能从 AudioUnit
派生,因为 CoreAudio 是一个 c 框架 - 而是给它一个渲染向设备提供音频样本的回调。以下代码示例向您展示了如何操作。您需要将 assert
替换为真正的错误处理,并且您可能希望使用 kAudioUnitProperty_StreamFormat
选择器更改或至少检查音频单元的样本格式。我的格式恰好是 48kHz 浮点交错立体声。
static OSStatus
renderCallback(
void* inRefCon,
AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList* ioData)
{
// inRefCon contains your cookie
// write inNumberFrames to ioData->mBuffers[i].mData here
return noErr;
}
AudioUnit
createAudioUnit() {
AudioUnit au;
OSStatus err;
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
assert(0 != comp);
err = AudioComponentInstanceNew(comp, &au);
assert(0 == err);
AURenderCallbackStruct input;
input.inputProc = renderCallback;
input.inputProcRefCon = 0; // put your cookie here
err = AudioUnitSetProperty(au, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &input, sizeof(input));
assert(0 == err);
err = AudioUnitInitialize(au);
assert(0 == err);
err = AudioOutputUnitStart(au);
assert(0 == err);
return au;
}