2010-11-27 6 views
0

私の質問はちょっと難しいですが、私は正確に経験していません(私はいくつかの言葉が間違っているかもしれません)ので、ここに行きます。 "Singer"というオブジェクトのインスタンスを宣言しています。インスタンスは "singer1"と呼ばれます。 「singer1」はオーディオ信号を生成する。iPhoneのライブ更新に関するヘルプ

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

//Singer *me = (Singer *)inRefCon; 

static int phase = 0; 

for(UInt32 i = 0; i < ioData->mNumberBuffers; i++) { 

    int samples = ioData->mBuffers[i].mDataByteSize/sizeof(SInt16); 

    SInt16 values[samples]; 

    float waves; 
    float volume=.5; 

    for(int j = 0; j < samples; j++) { 


     waves = 0; 


     waves += sin(kWaveform * 600 * phase)*volume; 
     waves += sin(kWaveform * 400 * phase)*volume; 
     waves += sin(kWaveform * 200 * phase)*volume; 
     waves += sin(kWaveform * 100 * phase)*volume;    

     waves *= 32500/4; // <--------- make sure to divide by how many waves you're stacking 

     values[j] = (SInt16)waves; 
     values[j] += values[j]<<16; 

     phase++; 

    } 

    memcpy(ioData->mBuffers[i].mData, values, samples * sizeof(SInt16)); 

} 

return noErr; 

}

本の

99%が借りたコードなので、私はそれがどのように動作するかの基本的な理解を持っている(I:さて、次は、オーディオ信号の仕様が決定されたコードですOSStatusのクラスやメソッド、あるいはそれが何であっても分かりませんが、600,400,200,100の4行が表示されていますか?それらは頻度を決定します。この変数は "fr1"と呼ばれ、 "fr1"はヘッダファイルで宣言されていますが、コンパイルしようとすると " fr1 "は宣言されていません。現在、私のこれを修正する手法は次のとおりです:right beコードがコンパイルされますと、私はそれを言うならばsinger1.fr1が実際に値を変更しますと、私はものを#IMPORTニースのは、私は、作品のこの種のラインに

fr1=0.0;//any number will work properly 

を追加します。 A)これがコンパイルされていて、指定されたトーンが再生されても(0.0はトーンなし)、「データ定義にタイプまたはストレージクラスがありません」および「Typeをintに宣言します」という警告が表示されます。 'fr1' "何らかの理由でヘッダーファイル(フロートとして)に以前の宣言が見当たらないからです。しかし、再度、この行を残すと、 "fr1は宣言されていない"ため、コードはコンパイルされません。 B)fr1の値を変更しても、singer1が "playbackcallback"変数内に格納されている値を更新したり、出力バッファの更新を担当しているとは限りません。おそらくこれは違ったコードで修正することができますか? C)これがうまくいっても、オーディオを一時停止/再生するときにはっきりとした「ギャップ」があります。これは削除する必要があります。これはコードの完全なオーバーホールを意味するので、何かを中断することなく新しい値を「動的に」挿入することができます。しかし、私が投稿しようとしているこのすべての努力は、このメソッドが私が欲しいものを正確に実行しているからです(私は数学的に値を計算することができ、DACにまっすぐ行くので、 、正方形などの波が容易に)。私はSinger.hと.mをpastebinにアップロードしてあなたの喜びを味わってくれました。申し訳ありませんが、2つのHTMLタグを投稿することはできませんので、完全なリンクです。 (http://pastebin.com/ewhKW2Tk) (http://pastebin.com/CNAT4gFv)

ので、TL; DRは、私が本当にやりたいすべてが現在の方程式/値を定義することが可能です4つの波のうちの1つを選択し、音に隙間なく頻繁に再定義します。おかげさまで (投稿が混乱していたり​​、トラックが外れてしまって申し訳ありませんが、私は確信しています)

答えて

1

私の理解では、バッファを再充填する必要があるたびにコールバック関数が呼び出されます。したがって、fr1..fr4を変更すると波形が変更されますが、バッファが更新されたときに限ります。変更を加えるには音を止めて再スタートする必要はありませんが、frの値を変更すると音色に急激な変化が見られます。音色の変化をスムーズにするには、時間の経過とともにfrの値をスムーズに変更するものを実装する必要があります。バッファーサイズを微調整することで、変化するfr値に対するサウンドの反応性をいくらかコントロールできます。

frが定義されていない問題は、コールバックがまっすぐなc関数であるためです。 fr変数は、Singerオブジェクトの一部としてobjective-cインスタンス変数として宣言されています。デフォルトではアクセスできません。

このプロジェクトを見て、彼がコールバック内からインスタンス変数へのアクセスをどのように実装しているかを見てください。基本的には、インスタンスへの参照をコールバック関数に渡し、それを介してインスタンス変数にアクセスします。

https://github.com/youpy/dowoscillator

予告:

Sinewave *sineObject = inRefCon; 
float freq = sineObject.frequency * 2 * M_PI/samplingRate; 

と:それは実際には一部ではないので

AURenderCallbackStruct input; 
input.inputProc = RenderCallback; 
input.inputProcRefCon = self; 

また、あなたは、あなたの@implementationブロックの外側でコールバック関数を移動したいと思いますあなたのシンガーオブジェクトの。

あなたはここにすべてのアクションでこれを見ることができます:https://github.com/coryalder/SineWaver

+0

をちょっとケニー、あなたの答えをありがとう。私は彼がやっていることを理解していると思います、目的のC変数をCコードがアクセスできるポインタに変えていますか? - >演算子は "。"に似ています。しかし、ポインタのために、右か?とにかく、@defs()はもう動作しません... Xcodeは "@defsは新しいabiでサポートされていません"と言います。代わりに私は何をすることができますか?また、バッファの更新頻度はどのくらいですか? singer1.fr1の値が変更されたことを確認したにもかかわらず、音の変化を聞いたことがないので(文字列に変換してUILabelに渡すことによって)また、コールバック関数をどこに移動する必要がありますか?どうもありがとうございます! – wyager

+0

私はそれをより正確に編集しました。全体的な@defsは、目的のCオブジェクトからc-structを作成しています...それを行う最良の方法ではありません。プロパティが設定されている場合は、客観的なcドット表記法を使用して値にアクセスすることができます。とにかく、私が煙を吹くだけではないことを確認するために、私はこれをすべて新しいプロジェクトに組み込んで、すべての機能を有効にしました。それをチェックしてくださいhttps://github.com/coryalder/SineWaver –

+0

私はデフォルトのバッファが1024バイトだと思う..私のSineWaverプロジェクトでスライダを速く動かすと、ポップアップが波形が突然変化するたびに - フィル。 –

関連する問題