メモ用に最小の手順で書いています。
ここで書いた内容をクラス化すると使いやすいです。
"View-based Application"で"AUTest"としてプロジェクトを作成しAUTestViewControllerクラスへ直接コードを書いていく例です。
実行すると440Hz(ラ)の音が鳴るだけです。
AudioToolkitフレームワークの追加
AUTestViewController.h
AudioUnitの機能を使うために、"AudioUnit/AudioUnit.h"をインポートします。
クラス内で使う変数と、コールバック用のメソッドの宣言をします。
また、コールバック用のメソッド内で使う変数を@propertyで宣言します。
#import <UIKit/UIKit.h> #import <AudioUnit/AudioUnit.h> // 追加 @interface AUTestViewController : UIViewController { AudioUnit au; // AudioUnit double phase; // 位相の保存 Float64 SampleRate; // サンプリングレート UInt32 BitRate; // ビットレート Float64 frequency; // 再生する音程の周波数 } @property (nonatomic) double phase; @property (nonatomic) Float64 SampleRate; @property (nonatomic) Float64 frequency; static OSStatus renderer(void *inRef, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData); @end
AUTestViewController.m
コールバック用のメソッド内で使う変数を@synthesizeで宣言します。
@synthesize phase; @synthesize SampleRate; @synthesize frequency;
メモとして、viewDidLoadメソッドの中へ準備から再生開始までを一気に書いた例です。
- (void)viewDidLoad { [super viewDidLoad]; // サンプリングレートの設定 SampleRate = 44100.0f; // 44.1KHz // ビットレートの設定 BitRate = 8; // 8bit // 再生する音程の周波数 frequency = 440.0; // A(ラ) // AudioComponentのAudioComponentDescriptionを用意する AudioComponentDescription acd; acd.componentType = kAudioUnitType_Output; acd.componentSubType = kAudioUnitSubType_RemoteIO; acd.componentManufacturer = kAudioUnitManufacturer_Apple; acd.componentFlags = 0; acd.componentFlagsMask = 0; // AudioComponentの定義を取得 AudioComponent ac = AudioComponentFindNext(NULL, &acd); // AudioComponentをインスタンス化 AudioComponentInstanceNew(ac, &au); // AudioComponentを初期化 AudioUnitInitialize(au); // コールバックの設定 AURenderCallbackStruct CallbackStruct; CallbackStruct.inputProc = renderer; // ここでコールバック時に実行するメソッドを指定 CallbackStruct.inputProcRefCon = (__bridge void*)self; // コールバックの設定をAudioUnitへ設定 AudioUnitSetProperty(au, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &CallbackStruct, sizeof(AURenderCallbackStruct)); // AudioStreamBasicDescription(ASBD)の設定 AudioStreamBasicDescription asbd; asbd.mSampleRate = SampleRate; asbd.mFormatID = kAudioFormatLinearPCM; asbd.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical; asbd.mChannelsPerFrame = 2; asbd.mBytesPerPacket = sizeof(AudioUnitSampleType); asbd.mBytesPerFrame = sizeof(AudioUnitSampleType); asbd.mFramesPerPacket = 1; asbd.mBitsPerChannel = BitRate * sizeof(AudioUnitSampleType); asbd.mReserved = 0; // AudioUnitにASBDを設定 AudioUnitSetProperty(au, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &asbd, sizeof(asbd)); // 再生開始 AudioOutputUnitStart(au); }
コールバックで実行されるメソッドです。
サイン波を出力する処理を行っています。
static OSStatus renderer(void *inRef, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp* inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { // RenderOutputのインスタンスにキャストする AUTestViewController* def = (__bridge AUTestViewController*)inRef; // サイン波の計算に使う数値の用意 float freq = def.frequency * 2.0 * M_PI / def.SampleRate; // 値を書き込むポインタ AudioUnitSampleType *outL = ioData->mBuffers[0].mData; AudioUnitSampleType *outR = ioData->mBuffers[1].mData; for (int i = 0; i < inNumberFrames; i++) { // 周波数を計算 float wave = sin(def.phase); AudioUnitSampleType sample = wave * (1 << kAudioUnitSampleFractionBits); *outL++ = sample; *outR++ = sample; def.phase += freq; } return noErr; };
最後にメモリを使用した開放します。
viewDidUnloadに書いた例です
- (void)viewDidUnload { // 再生停止 AudioOutputUnitStop(au); // AudioUnitの解放 AudioUnitUninitialize(au); AudioComponentInstanceDispose(au); [super viewDidUnload]; }

- 作者: 永野哲久
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2009/11/12
- メディア: 大型本
- 購入: 6人 クリック: 114回
- この商品を含むブログ (25件) を見る