簡體   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