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

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

コメントを残す

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