如何使用AudioUnit(iOS)播放信号?

时间:2016-10-26 08:59:41

标签: ios objective-c iphone core-audio audiounit

我需要生成一个信号并用iPhone的扬声器或耳机播放。

为此,我生成交错信号。然后我需要使用下一个信息实例化一个AudioUnit继承的类对象:2个通道,44100 kHz采样率,一些缓冲区大小来存储几帧。

然后我需要编写一个回调方法,它将接收我的信号并将其插入iPhone的输出缓冲区。

问题是我不知道如何编写AudioUnit继承类。我无法理解Apple关于它的文档,我可以找到的所有示例都是从文件中读取并使用大量延迟或使用已编译的构造。

我开始认为我是愚蠢的东西。请帮忙......

1 个答案:

答案 0 :(得分:2)

要使用AudioUnit向iPhone的硬件播放音频,您不会从AudioUnit派生出来,因为CoreAudio是交流框架 - 而是给它一个渲染回调,您可以在其中为设备提供信息音频样本。以下代码示例向您展示了如何操作。您需要使用真正的错误处理替换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;
}