8

私は 10 バンドのイコライザーを作ろうとしていますが、kAudioUnitSubType_NBandEQオーディオ ユニットはうまくいっているようですが、Apple のドキュメントにはその設定方法や構成方法が記載されていません。

すでにノードを接続していますが、EQNode を iONode に接続しようとするとエラーになります (出力): https://gist.github.com/2295463

エフェクトを 10 バンドのイコライザーにするにはどうすればよいですか?

更新:ノボカイン を使用した実用的な DSP フォーミュラも解決策です。これらの DSP 式は非常に複雑です。

Update2:オーディオ ノードをプログラミングするよりもはるかにクリーンで小さいため、Novocaine で動作する DSP フォーミュラを好みます。

Update3: 「マルチタイプ EQ ユニット (サブタイプ kAudioUnitSubType_NBandEQ) は、「マルチタイプ EQ ユニット フィルター タイプ」 (68 ページ) で説明されているタイプのいずれかとして構成できるイコライザーを提供します。」ソース: http://developer.apple.com/library/ios/DOCUMENTATION/AudioUnit/Reference/AudioUnit_Framework/AudioUnit_Framework.pdf しかし、まだ例はありません。

重要な更新 (2005 年 17 月):私が github でリリースした私の DSP クラスを使用することを皆さんにお勧めします: https://github.com/bartolsthoorn/NVDSP これにより、n バンド イコライザーやあらゆる種類のオーディオ フィルターの開発が簡単になります。

4

2 に答える 2

3

私はNovocaineの作成者であり、vDSPを使用して200の奇妙なバンドEQを作成するためにそれを使用しました。

NBandEQオーディオユニットへの切り替えを検討していますが、vDSP_deq22を使用した実用的なソリューションがあります。

vDSP_deq22は、2次IIRフィルターを使用して、一度に1サンプルずつデータをフィルター処理します。2次バターワース係数はmusicdsp.orgで、またはより一般的にはグーグルで見つけることができます。コピーにアクセスできる場合は、Matlabもそれらを計算します。musicdsp.orgを使用しました。10個のvDSP_deq22フィルターを作成し、それぞれにオーディオを実行し、その帯域に指定されたゲインを掛けてから、フィルターバンク内のすべてのフィルターの出力を出力オーディオに合計します。

于 2012-04-19T21:07:13.667 に答える
2

10バンドイコライザーは以下のように構成できます

converterNode-> eqNode->converterNode->ioNode。

以下のサンプルコードを参照してください。ここではiPodEQユニットを使用しました。iPodEQunitのフォーマット仕様を10バンドイコライザーに置き換えます。

AUNode outputNode;
AUNode iPodTimeNode;
AUNode converterNode;
AUNode converterNode2;

AudioUnit converterAU;
AudioUnit converterAU2;

printf("create client format ASBD\n");

// client format audio going into the converter
mClientFormat.SetCanonical(1, false); 
mClientFormat.mSampleRate = kGraphSampleRate;
mClientFormat.Print();

printf("create output format ASBD\n");
CAStreamBasicDescription localOutput;
localOutput.SetAUCanonical(2, false);
localOutput.mSampleRate = kGraphSampleRate;

// output format
mOutputFormat.SetCanonical(1, false); 
mOutputFormat.mSampleRate = kGraphSampleRate;
mOutputFormat.Print();

OSStatus result = noErr;

printf("-----------\n");
printf("new AUGraph\n");

// create a new AUGraph
result = NewAUGraph(&mGraph);
if (result) { printf("NewAUGraph result %ld %08X %4.4s\n", result,
                     (unsigned int)result, (char*)&result); return; }

// create three CAComponentDescription for the AUs we want in the graph

// output unit
CAComponentDescription output_desc(kAudioUnitType_Output,
                                   kAudioUnitSubType_GenericOutput,
                                   kAudioUnitManufacturer_Apple);

// iPodTime unit
CAComponentDescription iPodTime_desc(kAudioUnitType_FormatConverter,
                                     kAudioUnitSubType_AUiPodTimeOther,
                                     kAudioUnitManufacturer_Apple);


// AU Converter
CAComponentDescription converter_desc(kAudioUnitType_FormatConverter,
                                      kAudioUnitSubType_AUConverter,
                                      kAudioUnitManufacturer_Apple);

printf("add nodes\n");

// create a node in the graph that is an AudioUnit, using the supplied
// AudioComponentDescription to find and open that unit
result = AUGraphAddNode(mGraph, &output_desc, &outputNode);

result = AUGraphAddNode(mGraph, &iPodTime_desc, &iPodTimeNode);

result = AUGraphAddNode(mGraph, &converter_desc, &converterNode);

result = AUGraphAddNode(mGraph, &converter_desc, &converterNode2);

// connect a node's output to a node's input
// converter -> iPodTime ->converter-> output

result = AUGraphConnectNodeInput(mGraph, converterNode2, 0, iPodTimeNode, 0);

result = AUGraphConnectNodeInput(mGraph, iPodTimeNode, 0, converterNode, 0);

result = AUGraphConnectNodeInput(mGraph, converterNode, 0, outputNode, 0);



// open the graph -- AudioUnits are open but not initialized
// (no resource allocation occurs here)
result = AUGraphOpen(mGraph);


// grab audio unit instances from the nodes
result = AUGraphNodeInfo(mGraph, converterNode, NULL, &converterAU);
result = AUGraphNodeInfo(mGraph, converterNode2, NULL, &converterAU2);
result = AUGraphNodeInfo(mGraph, iPodTimeNode, NULL, &mIPodTime);
result = AUGraphNodeInfo(mGraph, outputNode, NULL, &mOutputUnit);

//Get EQ unit format
UInt32 size ;
CAStreamBasicDescription eqDesc;
AudioUnitGetProperty(mIPodTime, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &eqDesc, &size);
eqDesc.Print();


// setup render callback struct
AURenderCallbackStruct rcbs;
rcbs.inputProc = &renderInput;
rcbs.inputProcRefCon = &mUserData;

printf("set AUGraphSetNodeInputCallback\n");

// set a callback for the specified node's specified input bus (bus 1)
result = AUGraphSetNodeInputCallback(mGraph, converterNode2, 0, &rcbs);

//SetFormat
result = AudioUnitSetProperty(converterAU2, kAudioUnitProperty_StreamFormat,
                              kAudioUnitScope_Input, 0, &mClientFormat, sizeof(mClientFormat));
result = AudioUnitSetProperty(converterAU2, kAudioUnitProperty_StreamFormat,
                              kAudioUnitScope_Output, 0, &eqDesc, sizeof(eqDesc));

printf("set converter input bus %d client kAudioUnitProperty_StreamFormat\n", 0);

// set the input stream format, this is the format of the audio
// for the converter input bus (bus 1)
result = AudioUnitSetProperty(converterAU, kAudioUnitProperty_StreamFormat,
                              kAudioUnitScope_Input, 0, &localOutput, sizeof(localOutput));


// in an au graph, each nodes output stream format (including sample rate)
// needs to be set explicitly this stream format is propagated to its
// destination's input stream format

printf("set converter output kAudioUnitProperty_StreamFormat\n");

// set the output stream format of the converter
result = AudioUnitSetProperty(converterAU, kAudioUnitProperty_StreamFormat,
                              kAudioUnitScope_Output, 0, &mOutputFormat, sizeof(mOutputFormat));

result = AudioUnitSetProperty(mOutputUnit, kAudioUnitProperty_StreamFormat,
                              kAudioUnitScope_Output, 0, &mOutputFormat, sizeof(mOutputFormat));

// set the output stream format of the iPodTime unit
result = AudioUnitSetProperty(mIPodTime, kAudioUnitProperty_StreamFormat,
                              kAudioUnitScope_Output, 0, &localOutput, sizeof(localOutput));


printf("AUGraphInitialize\n");
// add a render notification, this is a callback that the graph will call every time the graph renders
// the callback will be called once before the graph’s render operation, and once after the render operation is complete
于 2012-04-11T06:10:23.617 に答える