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