4

Since the way to instantiate an AVAudioUnit is this:

[AVAudioUnit instantiateWithComponentDescription:componentDescription options:0 completionHandler:^(__kindof AVAudioUnit * _Nullable audioUnit, NSError * _Nullable error) {
    }];

How am I supposed to subclass AVAudioUnit? I have tried this:

[MySubclassOfAVAudioUnit instantiateWithComponentDescription:componentDescription options:0 completionHandler:^(__kindof AVAudioUnit * _Nullable audioUnit, NSError * _Nullable error) {
    }];

But the audioUnit that is returned in the block is still of type AVAudioUnit and NOT MySubclassOfAVAudioUnit.


Per Rhythmic Fistman's response, I am registering my custom AUAudioUnit subclass with Apple's example code:

componentDescription.componentType = kAudioUnitType_Effect;
componentDescription.componentSubType = 0x666c7472; /*'fltr'*/
componentDescription.componentManufacturer = 0x44656d6f; /*'Demo'*/
componentDescription.componentFlags = 0;
componentDescription.componentFlagsMask = 0;

I want my AVAudioUnit subclass to always use my AUAudioUnit.

George Kagan
  • 5,913
  • 8
  • 46
  • 50
jeremywhuff
  • 2,911
  • 3
  • 29
  • 33
  • I realised my answer was wrong, you can only subclass `AUAudioUnit` & have it wrapped in the correct type of `AVAudioUnit` subclass. Please see my updated answer. – Rhythmic Fistman Nov 17 '16 at 04:14

1 Answers1

3

From instantiateWithComponentDescription:completionHandler:

The returned AVAudioUnit instance normally will be of a subclass (AVAudioUnitEffect, AVAudioUnitGenerator, AVAudioUnitMIDIInstrument, or AVAudioUnitTimeEffect), selected according to the component's type.

UPDATE I got this wrong - you can't instantiate your own AVAudioUnit subclass, you can only instantiate your AUAudioUnit, wrapped in the relevant built-in AVFoundation AVAudioUnit subclass (e.g. AVAudioUnitEffect, etc).

The following code causes MyAUAudioUnit, a subclass of AUAudioUnit to be instantiated:

#import <AVFoundation/AVFoundation.h>

@interface MyAUAudioUnit : AUAudioUnit {

}
@end

@implementation MyAUAudioUnit
    // implement it here
@end

// later
- (void)instantiateMyAUAudioUnitWrappedInAVAudioUnit {
    // register it (need only be done once)
    AudioComponentDescription desc;
    desc.componentType = kAudioUnitType_Effect;
    desc.componentSubType = 0x666c7472; /*'fltr'*/
    desc.componentManufacturer = 0x44656d6f; /*'Demo'*/
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;

    [AUAudioUnit registerSubclass:MyAUAudioUnit.class asComponentDescription:desc name:@"MyAU" version:1];

    // Instantiate as many times as you like:
    [AVAudioUnit instantiateWithComponentDescription:desc options:0 completionHandler:^(AVAudioUnit * audioUnit, NSError *error) {
        NSLog(@"AVAudioUnit: %@, error: %@", audioUnit, error);
    }];
}

WRONG BIT

So to have your AVAudioUnit subclass instantiated, you must first register it with the AUAudioUnit method:

+[AUAudioUnit registerSubclass:asComponentDescription:name:version:]

There is a code snippet and some possible gotchas in this devforum thread.

Rhythmic Fistman
  • 34,352
  • 5
  • 87
  • 159
  • Thanks for the quick response. I followed exactly that procedure, but instantiateWithComponentDescription will never return an instance of my subclass. The discussion thread doesn't seem to address this issue, unfortunately. I'll add a little more detail to the question. – jeremywhuff Nov 15 '16 at 18:18
  • can you show how you're calling `registerSubclass`? maybe show some of your `AUAudioUnit` subclass too? – Rhythmic Fistman Nov 16 '16 at 00:20
  • Just curious to know if the OP figured this out. I'm having the exact same issue. – GW.Rodriguez Nov 29 '17 at 00:14
  • There's code linked in @hotpaw2's answer here: https://stackoverflow.com/a/46775145/22147 – Rhythmic Fistman Nov 29 '17 at 05:47