首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设置提供程序块上带有AVAudioUnit崩溃的自定义AVAudioEngine

设置提供程序块上带有AVAudioUnit崩溃的自定义AVAudioEngine
EN

Stack Overflow用户
提问于 2017-03-14 23:15:27
回答 1查看 1.2K关注 0票数 5

下面的代码块应该创建一个产生正弦波的AVAudioNode,但是它在标记为-AUAudioUnitV2Bridge setOutputProvider::无法识别的选择器发送到实例的行上崩溃。

有什么可能是错的吗?

代码语言:javascript
复制
// TEST  
AudioComponentDescription mixerDesc;  
mixerDesc.componentType = kAudioUnitType_Generator;  
mixerDesc.componentSubType = kAudioUnitSubType_ScheduledSoundPlayer;  
mixerDesc.componentManufacturer = kAudioUnitManufacturer_Apple;  
mixerDesc.componentFlags = 0;  
mixerDesc.componentFlagsMask = 0;  

[AVAudioUnit instantiateWithComponentDescription:mixerDesc options:kAudioComponentInstantiation_LoadInProcess completionHandler:^(__kindof AVAudioUnit * _Nullable audioUnit, NSError * _Nullable error) {  
    NSLog(@"here");  

    // Crashes here  
    audioUnit.AUAudioUnit.outputProvider = ^AUAudioUnitStatus(AudioUnitRenderActionFlags *actionFlags, const AudioTimeStamp *timestamp, AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList *inputData)  
    {  
        const double amplitude = 0.2;  
        static double theta = 0.0;  
        double theta_increment = 2.0 * M_PI * 880.0 / 44100.0;  
        const int channel = 0;  
        Float32 *buffer = (Float32 *)inputData->mBuffers[channel].mData;  

        memset(inputData->mBuffers[channel].mData, 0, inputData->mBuffers[channel].mDataByteSize);  
        memset(inputData->mBuffers[1].mData, 0, inputData->mBuffers[1].mDataByteSize);  

        // Generate the samples  
        for (UInt32 frame = 0; frame < inputBusNumber; frame++)  
        {  
            buffer[frame] = sin(theta) * amplitude;  

            theta += theta_increment;  
            if (theta >= 2.0 * M_PI)  
            {  
                theta -= 2.0 * M_PI;  
            }  
        }  

        return noErr;  
    };  

}]; 

更新

这似乎是一种正确的方法,但是遗憾的是,状态会抛出错误,回调不会被调用。

代码语言:javascript
复制
    AVAudioUnitGenerator *unit = [[AVAudioUnitGenerator alloc] init];

// TEST
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Generator;
desc.componentSubType = kAudioUnitSubType_ScheduledSoundPlayer;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;

[AVAudioUnit instantiateWithComponentDescription:desc options:kAudioComponentInstantiation_LoadInProcess completionHandler:^(__kindof AVAudioUnit * _Nullable audioUnit, NSError * _Nullable error) {
    NSLog(@"here");

    self.audioNode = audioUnit;

    OSStatus status;
     AudioUnit *unit = audioUnit.audioUnit;

    UInt32 numBuses = 1;
    status = AudioUnitSetProperty(unit, kAudioUnitProperty_ElementCount, kAudioUnitScope_Output, 0, &numBuses, sizeof(UInt32));
    NSLog(@"status: %d", status);


    AURenderCallbackStruct rcbs;
    rcbs.inputProc = callback2;
    rcbs.inputProcRefCon = (__bridge void * _Nullable)(self);


    status = AudioUnitSetProperty(unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Output, 0, &rcbs, sizeof(rcbs));
    NSLog(@"status: %d", status);

}];
EN

回答 1

Stack Overflow用户

发布于 2017-03-18 19:05:10

错误信息到底说了什么。实例化所请求的audioUnit类型并确保AUAudioUnit不是零之后,以下代码将其显式化:

代码语言:javascript
复制
if (![audioUnit.AUAudioUnit respondsToSelector:@selector(outputProvider)]) {
        NSLog(@"selector method not found in this instance of an AUAudioUnit");
}

头文件并不声称绝对需要在所有音频单元中实现此方法。

后面添加:如果您只想让代码合成AVAudioUnit的示例,而不关心特定的API或代码结构,那么:获取AVAudioUnit实例的AudioUnit属性;创建AURenderCallback函数;使用这个C函数填充AURenderCallbackStruct;然后在AudioUnit上为kAudioUnitProperty_SetRenderCallback执行AudioUnitSetProperty。即使没有可用的outputProvider方法,这似乎也不会崩溃。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42798284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档