3

我一直在尝试通过将 AURenderCallbackStruct 附加到音频单元的输入来操纵由 kAudioUnitType_Generator 音频单元生成的样本,但没有成功。我设法使用以下简单图表在 OS X 上运行:

(input callback) -> multichannel mixer -> (intput callback) -> default output

但是我在以下(甚至更简单的)图表中失败了,这些图表以发电机单元开头:

speech synthesis -> (intput callback) -> default output           | fails in render callback with kAudioUnitErr_Uninitialized
audiofile player -> (intput callback) -> default output           | fails when scheduling file region with kAudioUnitErr_Uninitialized

从设置 ASBD 格式到采样率,我几乎尝试了所有我能想到的方法,但我总是遇到这些错误。有谁知道如何设置一个图表,我们可以在其中操作来自这些不错的生成器单元的样本?

下面是使用语音合成的尝试失败的渲染回调函数和图形实例化方法。音频文件播放器对此几乎相同,当然,除了设置文件播放。如果我删除回调并在其中添加一个 AUGraphConnectNodeInput ,这两种设置都可以工作......

static OSStatus RenderCallback(void *inRefCon,
                                    AudioUnitRenderActionFlags *ioActionFlags,
                                    const AudioTimeStamp *inTimeStamp,
                                    UInt32 inBusNumber,
                                    UInt32 inNumberFrames,
                                    AudioBufferList *ioData) {

    AppDelegate *app = (AppDelegate *)inRefCon;
    AudioUnit inputUnit = app->_speechUnit;
    OSStatus status = noErr;

    status = AudioUnitRender(inputUnit, ioActionFlags, inTimeStamp, 0, inNumberFrames, ioData);
    // *** ERROR *** kAudioUnitErr_Uninitialized, code: -10867

    // ... insert processing code here...

    return status;
}

- (int)createSynthGraph {
    AUGRAPH_CHECK( NewAUGraph( &_graph ) );

    AUNode speechNode, outputNode;

    // speech synthesizer
    AudioComponentDescription speechCD = {0};
    speechCD.componentType = kAudioUnitType_Generator;
    speechCD.componentSubType = kAudioUnitSubType_SpeechSynthesis;
    speechCD.componentManufacturer = kAudioUnitManufacturer_Apple;

    // output device (speakers)
    AudioComponentDescription outputCD = {0};
    outputCD.componentType = kAudioUnitType_Output;
    outputCD.componentSubType = kAudioUnitSubType_DefaultOutput;
    outputCD.componentManufacturer = kAudioUnitManufacturer_Apple;

    AUGRAPH_CHECK( AUGraphAddNode( _graph, &outputCD, &outputNode ) );
    AUGRAPH_CHECK( AUGraphAddNode( _graph, &speechCD, &speechNode ) );

    AUGRAPH_CHECK( AUGraphOpen( _graph ) );
    AUGRAPH_CHECK( AUGraphNodeInfo( _graph, outputNode, NULL, &_outputUnit ) );
    AUGRAPH_CHECK( AUGraphNodeInfo( _graph, speechNode, NULL, &_speechUnit ) );

    // setup stream formats:
    AudioStreamBasicDescription streamFormat = [self streamFormat];
    AU_CHECK( AudioUnitSetProperty( _speechUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &streamFormat, sizeof(streamFormat) ) );

    // setup callback:
    AURenderCallbackStruct callback;
    callback.inputProc = RenderCallback;
    callback.inputProcRefCon = self;
    AUGRAPH_CHECK( AUGraphSetNodeInputCallback ( _graph, outputNode, 0, &callback ) );

    // init and start
    AUGRAPH_CHECK( AUGraphInitialize( _graph ) );
    AUGRAPH_CHECK( AUGraphStart( _graph ) );
    return 0;
}
4

2 回答 2

1

您必须使用 将这些节点连接在一起AUGraphConnectNodeInput除非它们已连接,否则不会在其中AUGraph初始化 AudioUnit 。图中未连接到其他单元的单元将不会被初始化。

您也可以在开始图表之前尝试手动初始化它们。

于 2013-02-27T20:32:52.420 回答
1

当您的音频单元未初始化时,会出现 kAudioUnitErr_Uninitialized 错误。只需在设置问题属性之前初始化您的图表。这将初始化图中所有打开的音频单元。来自 AUGraph.h 中的 AUGraphInitialize 讨论:

在交互中涉及的每个打开的节点/AudioUnit(准备渲染)和 SubGraph 上调用 AudioUnitInitialize()。

于 2015-01-29T10:30:24.370 回答