本タイトルでは最後となる、タイムストレッチのパラメータ設定について説明していきます。
まず、前回説明した prepareAUGraph 関数内でコメントにしていた箇所を有効にします。
1 2 3 4 5 6 7 8 9 10 11 12 | - (OSStatus)prepareAUGraph { // (略) // 6. AUiPodTimeOtherへ設定するためのプロキシオブジェクトを作成 _aUiPodTimeProxy = [[AUiPodTimeProxy alloc] initWithReverbUnit:_aUiPodTimeUnit]; // (略) } |
上記で生成している AUiPodTimeProxy クラスでタイムストレッチのパラメータ設定を行います。
まず、AUiPodTimeProxy クラスの定義を示します。
初期化関数として、AudioUnit のパラメータを引数として必要とするため、自作の initWithAudioUnit 関数を用意しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @interface AUiPodTimeProxy : NSObject { AudioUnit _aUiPodTimeUnit; Float32 _playbackRate; AudioUnitParameterID _paramId; } @property(atomic) Float32 playbackRate; - (id)initWithAudioUnit:(AudioUnit)aUiPodTimeUnit; @end |
実装部分は以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | @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が用意している機能だけあって、リアルタイムでもスムーズにタイムストレッチをしてくれるので気持ちいいです。よかったら試してみてください。