Audio Unit というのは, Core Audio のオーディオ処理の機能を持つ1つの単位のこと。Input, Effect, Output などが Audio Unit になります。 詳しい説明は, 各所ありますのでこれくらいです。
Mac OS X と, iOS ではプログラムの書き方が違います。
Mac OS Xでは, こちら のサンプルが完璧です。
これを参考にさせていただきながら, iOSとどのように違うのか, やってみました。
My Codex Leister さんでも言及のとおり, iOSでは, kAudioUnitType_Generatorつまり, 入力を発生させるような Audio Unit がないような気がします。
Output, Effect あたりはできそうな気がします。
コンポーネントの違い
Mac OS X AudioUnit.framework ComponentDescription
iOS AudioToolbox.framework AudioComponentDescripton
iOSでは,
struct AudioComponentDescription
{
OSType componentType;
OSType componentSubStype;
OSType componentManufacturer;
UInt32 componentFlags;
UInt32 componentFlagsMask;
};
typedef struct AudioComponentDescription AudioComponentDescription;
を使って, AudioComponent を取り出します。
その違い以外は, ほぼ Mac OS Xと同じコードです。
iOS で, Audio Unit で sin波を発生させて聞いてみるサンプルです。
重要そうなところは太字もしくは赤字にしてみました。
•AudioUnitViewController.h
#import "ViewController.h"
#import <AudioToolbox/AudioToolbox.h>
#define kRate 44100
#define kFreq 440
@interface AudioUnitViewController : ViewController
@property (nonatomic)AudioUnit unit;
@property (nonatomic)float phase;
- (IBAction)startClick:(id)sender;
- (IBAction)stopClick:(id)sender;
@end
•AudioUnitViewController.m
#import "AudioUnitViewController.h"
@interface AudioUnitViewController ()
@end
@implementation AudioUnitViewController
@synthesize unit;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
OSStatus AuRenderCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
//NSLog(@"inNumberFrames: %ld", inNumberFrames);
//NSLog(@"Bufs %ld", ioData->mNumberBuffers);
AudioUnitViewController *controller = (__bridge AudioUnitViewController *)inRefCon;
float *buf = ioData->mBuffers[0].mData;
float freq = kFreq * 2 * M_PI / kRate;
for ( int i=0; i < inNumberFrames; i++ )
{
float wave = sin(controller.phase);
*buf++ = wave;
controller.phase += freq;
}
return noErr;
}
-(void)audioUnit
{
OSStatus status;
AudioComponentDescription cd;
cd.componentType = kAudioUnitType_Output;
cd.componentSubType = kAudioUnitSubType_RemoteIO;
cd.componentManufacturer = kAudioUnitManufacturer_Apple;
cd.componentFlags = 0;
cd.componentFlagsMask = 0;
// Find compoent and create instance
AudioComponent comp = AudioComponentFindNext(NULL, &cd);
status = AudioComponentInstanceNew(comp, &unit);
// Set Callback
AURenderCallbackStruct input;
input.inputProc = AuRenderCallback;
input.inputProcRefCon = (__bridge void *)(self);
status = AudioUnitSetProperty(unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &input, sizeof(input));
status = AudioUnitInitialize(unit);
status = AudioOutputUnitStart(unit);
self.phase = 0;
}
-(void)stop
{
AudioOutputUnitStop(unit);
}
- (IBAction)startClick:(id)sender
{
[self audioUnit];
}
- (IBAction)stopClick:(id)sender
{
[self stop];
}
@end
0 件のコメント:
コメントを投稿