Audio Unit によるリアルタイム・タイムストレッチ(3. パラメータ設定)

本タイトルでは最後となる、タイムストレッチのパラメータ設定について説明していきます。
まず、前回説明した 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],
								 &paramInfo,
								 &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が用意している機能だけあって、リアルタイムでもスムーズにタイムストレッチをしてくれるので気持ちいいです。よかったら試してみてください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です