本タイトルでは最後となる、タイムストレッチのパラメータ設定について説明していきます。
まず、前回説明した prepareAUGraph 関数内でコメントにしていた箇所を有効にします。
- (OSStatus)prepareAUGraph { // (略) // 6. AUiPodTimeOtherへ設定するためのプロキシオブジェクトを作成 _aUiPodTimeProxy = [[AUiPodTimeProxy alloc] initWithReverbUnit:_aUiPodTimeUnit]; // (略) }
上記で生成している AUiPodTimeProxy クラスでタイムストレッチのパラメータ設定を行います。
まず、AUiPodTimeProxy クラスの定義を示します。
初期化関数として、AudioUnit のパラメータを引数として必要とするため、自作の initWithAudioUnit 関数を用意しています。
@interface AUiPodTimeProxy : NSObject { AudioUnit _aUiPodTimeUnit; Float32 _playbackRate; AudioUnitParameterID _paramId; } @property(atomic) Float32 playbackRate; - (id)initWithAudioUnit:(AudioUnit)aUiPodTimeUnit; @end
実装部分は以下のようになります。
@implementation AUiPodTimeProxy @synthesize playbackRate = _playbackRate; - (id)initWithAudioUnit:(AudioUnit)aUiPodTimeUnit { self = [super init]; if (self) { _aUiPodTimeUnit = aUiPodTimeUnit; _playbackRate = self.playbackRate; UInt32 size = sizeof(UInt32); AudioUnitGetPropertyInfo(_aUiPodTimeUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, 0, &size, NULL); int numOfParams = size / sizeof(AudioUnitParameterID); AudioUnitParameterID paramList[numOfParams]; AudioUnitGetProperty(_aUiPodTimeUnit, kAudioUnitProperty_ParameterList, kAudioUnitScope_Global, 0, paramList, &size); for (int i = 0; i < numOfParams; i++) { _paramId = paramList[i]; AudioUnitParameterInfo paramInfo; size = sizeof(paramInfo); AudioUnitGetProperty(_aUiPodTimeUnit, kAudioUnitProperty_ParameterInfo, kAudioUnitScope_Global, paramList[i], ¶mInfo, &size); AudioUnitSetParameter(_aUiPodTimeUnit, paramList[i], kAudioUnitScope_Global, 0, _playbackRate, 0); } } return self; } - (Float32)playbackRate { Float32 value = 0.0f; OSStatus ret = AudioUnitGetParameter(_aUiPodTimeUnit, _paramId, kAudioUnitScope_Global, 0, &value); if (ret != noErr) { NSLog(@"Error getting parameter(%d)", parameter); } return value; } - (void)setPlaybackRate:(Float32)value { // AUiPodTimeOther の場合 int parameter = 0; Float32 min = 0.5f; Float32 max = 2.0f; if (value < min || value > max) { NSLog(@"Invalid value(%f)<%f - %f> for parameter(%d). Ignored.", value, min, max, parameter); return; } OSStatus ret = AudioUnitSetParameter(_aUiPodTimeUnit, parameter, kAudioUnitScope_Global, 0, value, 0); if (ret != noErr) { NSLog(@"Error setting parameter(%d)", parameter); } } @end
initWithAudioUnit 関数について説明します。
AudioUnitGetPropertyInfo で、AudioUnitGetProperty で取得する paramList のサイズを取得します。
次の AudioUnitGetProperty(第2引数を kAudioUnitProperty_ParameterList)で paramList の各IDを取得します。
for文内の AudioUnitGetProperty(第2引数を kAudioUnitProperty_ParameterInfo)で各IDのパラメータが取得できます。
タイムストレッチ(AUiPodTimeOther)の場合、取得する値は以下のようになります。
numOfParams = 1
paramList[0] = 0
paramInfo.name = rate
paramInfo.minValue = 0.5
paramInfo.maxValue = 2.0
paramInfo.defaultValue = 1.0
最後の AudioUnitSetParameter で、上記の値を設定します。
playbackRate プロパティを用いて、タイムストレッチの値を取得/設定することができます。
スライダー(UISlider)などを用いてコントロールすると良いと思います。
さすがAppleが用意している機能だけあって、リアルタイムでもスムーズにタイムストレッチをしてくれるので気持ちいいです。よかったら試してみてください。