繁体   English   中英

iOS-从音频单元渲染回调访问生成的信号

[英]iOS - Accessing generated signal from Audio Unit render callback

我有一个iOS / Objective-C程序,当按下按钮时,该程序使用单个音频单元播放生成的信号。 我想添加以下功能:

a)第一次按下按钮时,会以某种数字数组的形式生成信号。

b)然后音频开始,渲染回调访问(并播放)生成的信号。

给定我当前的代码,我觉得这些增加只是几行,但是我在语法,使用哪种变量类型,如何跟踪当前样本等方面遇到麻烦。 我已经包含了相关代码,因为它是:


按钮按下:

- (IBAction)startPressed:(id)sender {
        [self setupAudioPlayer];
        [self createSignal];
        [self playAudio];
}

setupAudioPlayer中的一行:

input.inputProcRefCon=&mySignal; // mySignal is an instance var

音频创建:

-(void)createSignal{
    int beepLength=0.020*Fs; // Fs is sampling frequency
    float beepFrequency=440; // Hz

    // Declare some kind of numeric array "mySignal", which is an instance var.
    mySignal=...?

    // Generate audio signal (pure tone)
    for (int i=1; i<=beepLength; i++) {
        float t=i/Fs;
        mySignal[i]=sinf(2*M_PI*beepFrequency*t);
    }
}

渲染回调:

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

{
    const int channel1 = 0;
    Float32 *buffer = (Float32 *)ioData->mBuffers[channel1].mData;

    // This is where things get hazy
    Float32 *mySignal=(Float32 *)inRefCon;
    for (UInt32 frame = 0; frame < inNumberFrames; frame++)
    {
            buffer[frame]=mySignal[?]; 
    }

    return noErr;
}

因此,总结一下我的问题:应该如何定义mySignal? 如何从RenderTone访问此实例变量(我上面的“朦胧”代码只是一个猜测)? 如何在RenderTone中跟踪当前样本? 这种方法还有其他遗漏/奇怪的地方吗?

感谢您的阅读和任何帮助,非常感谢!

(我已经看到了示例代码,该示例代码将对视图控制器实例的引用传递到render回调中,然后以这种方式访问​​实例变量。但是,也许是错误地,我在其他地方读到,这不是好形式,因为它可能涉及太多计时要求如此严格的回调的计算开销。)

由于您是根据代数函数生成帧的,所以为什么不简单遵循Matt Gallagher的示例呢? 简而言之:只需将函数移到render回调内,并通过vc实例传递参数。

一般来说,您的选择仅限于将数据传递给具有预定义格式的回调。 我可能是在目标C中以良好形式提供建议的最后一个人,但是使用全局变量的方法是少数。

您可以将mySignal数组(或频率)作为全局mySignal传递。 不是最“优雅”的面向对象解决方案,而是一种可以避免所有OO麻烦开销的解决方案。 似乎仅适合使用基于C的解决方案,因为render回调基于C函数。

至于“跟踪”,不是很清楚您的意思,但是在我自己的生成音调的工作中,我已经用音调长度(以帧周期=长度为秒* FssampleRate初始化了一个remainingCycles周期)进行全局设置调用),并减少每次通过frame循环的次数; 当数字为零时,您将结束铃声。 (当然,您可以使用实例变量代替全局变量。)

也许这违反了面向对象编码的佳能,但是最终,您只需要完成工作即可。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM