Varispeed audiounit to AUGraph in iOS6

I'm studying AudioUnits in iOS and trying to implement such graph:

    -------------------       -----------------
   |                   |     |                 |
-->|  FormatConverter  | --->| bus 0           |
   |      (Varispeed)  |     |                 |
   --------------------      |    Multichannel |
   --------------------      |    Mixer Unit   |
   |                   |     |                 |      --------------------
-->|  FormatConverter  | --->| bus 1           |     |                    |
   |   (Varispeed)     |     |                 | --->|      Remote IO     | ----->
   --------------------      |                 |     |       Unit         |
   --------------------      |                 |     |                    |
  |                    |     |                 |      --------------------
->| FormatConverter    | --->| bus 2           |
  | (Varispeed)        |     |                 |
  ---------------------      |                 |         
                              -----------------

Firstly I tried to work with AudioUnits without kAudioUnitSubType_Varispeed Unit. It worked correctly, sounds played. But now I want to realize pitch for every sound (separately), that is why I've decided to add Varispeed Unit to control pitch for each sound.

I'm using the following code:

OSStatus result = noErr;

    //............................................................................
    // Specify the audio unit component descriptions for the audio units to be
    //    added to the graph.

    // I/O unit
    AudioComponentDescription iOUnitDescription;
    iOUnitDescription.componentType          = kAudioUnitType_Output;
    iOUnitDescription.componentSubType       = kAudioUnitSubType_RemoteIO;
    iOUnitDescription.componentManufacturer  = kAudioUnitManufacturer_Apple;
    iOUnitDescription.componentFlags         = 0;
    iOUnitDescription.componentFlagsMask     = 0;

    // Multichannel mixer unit
    AudioComponentDescription MixerUnitDescription;
    MixerUnitDescription.componentType          = kAudioUnitType_Mixer;
    MixerUnitDescription.componentSubType       = kAudioUnitSubType_MultiChannelMixer;
    MixerUnitDescription.componentManufacturer  = kAudioUnitManufacturer_Apple;
    MixerUnitDescription.componentFlags         = 0;
    MixerUnitDescription.componentFlagsMask     = 0;

    // Varispeed unit
    AudioComponentDescription varispeedUnitDescription;
    MixerUnitDescription.componentType          = kAudioUnitType_FormatConverter;
    MixerUnitDescription.componentSubType       = kAudioUnitSubType_Varispeed;
    MixerUnitDescription.componentManufacturer  = kAudioUnitManufacturer_Apple;
    MixerUnitDescription.componentFlags         = 0;
    MixerUnitDescription.componentFlagsMask     = 0;

    //............................................................................
    // Add nodes to the audio processing graph.
    NSLog (@"Adding nodes to audio processing graph");

    AUNode iONode;         // node for I/O unit
    AUNode mixerNode;      // node for Multichannel Mixer unit
    AUNode varispeedNode0;
    AUNode varispeedNode1;
    AUNode varispeedNode2;

    //............................................................................
    // Create a new audio processing graph.
    result = NewAUGraph(&processingGraph);

    if (noErr != result) {[self printErrorMessage: @"NewAUGraph" withStatus: result]; return;}

    //............................................................................
    // Open the audio processing graph
    result = AUGraphOpen(processingGraph);

    if (noErr != result) {
        [self printErrorMessage: @"AUGraphOpen" withStatus: result];
        return;
    }

    //............................................................................
    // Add the nodes to the audio processing graph
    result = AUGraphAddNode(
                             processingGraph,
                             &varispeedUnitDescription,
                             &varispeedNode0);

    if (noErr != result) {
        [self printErrorMessage: @"AUGraphNewNode failed for varispeedNode0 unit" withStatus: result];
        return;
    }

    result = AUGraphAddNode (
                             processingGraph,
                             &varispeedUnitDescription,
                             &varispeedNode1);

    if (noErr != result) {
        [self printErrorMessage: @"AUGraphNewNode failed for varispeedNode1 unit" withStatus: result];
        return;
    }

    result = AUGraphAddNode (
                             processingGraph,
                             &varispeedUnitDescription,
                             &varispeedNode2);

    if (noErr != result) {
        [self printErrorMessage: @"AUGraphNewNode failed for varispeedNode2 unit" withStatus: result];
        return;
    }

    result = AUGraphAddNode (
                             processingGraph,
                             &iOUnitDescription,
                             &iONode);

    if (noErr != result) {
        [self printErrorMessage: @"AUGraphNewNode failed for I/O unit" withStatus: result];
        return;
    }

    result = AUGraphAddNode (
                             processingGraph,
                             &MixerUnitDescription,
                             &mixerNode);

    if (noErr != result) {
        [self printErrorMessage: @"AUGraphNewNode failed for Mixer unit" withStatus: result];
        return;
    }

When I run app I've got the following error:

2013-04-24 21:44:59.335 Drumpads[327:c07] *** AUGraphNewNode failed for varispeedNode0 unit error: ˇˇ¯+
2013-04-24 21:44:59.338 Drumpads[327:c07] Error.domain = NSOSStatusErrorDomain, code=-2005, descr =Error Domain=NSOSStatusErrorDomain Code=-2005 "The operation couldn’t be completed. (OSStatus error -2005.)"

According to MacErrors.h -2005 means 'badComponentType'.

So it seems that Varispeed Unit cannot be even added to AUGraph. Everything seems to be correctly, so I don't know why adding Varispeed Node causes error.

I've used sample code from developers.apple.com code as a reference (I know, it's for OSx, but Varispeed is now available for iOS5 and 6, so I've decided that I can use this code as a reference).

I need to control pitch shift for every sound. I've choosen Varispeed, but I've also read about NewTimePitch Nodes. I've tried NewTimePitch (in the same graph) but also with no success.

Does anybody know what is wrong in my code and why adding Varispeed Node causes error?

Thanks in advance!


After another day of research and trying to find more information about FormatConverter and Varispeed and reading a lot of information I've finally found the answer.

Of course it was very hard to fix it but lucky me! LOL

This is my previous code:

AudioComponentDescription varispeedUnitDescription;
MixerUnitDescription.componentType          = kAudioUnitType_FormatConverter;
MixerUnitDescription.componentSubType       = kAudioUnitSubType_Varispeed;
MixerUnitDescription.componentManufacturer  = kAudioUnitManufacturer_Apple;
MixerUnitDescription.componentFlags         = 0;
MixerUnitDescription.componentFlagsMask     = 0;

And here is the new one:

AudioComponentDescription varispeedUnitDescription;
varispeedUnitDescription.componentType          = kAudioUnitType_FormatConverter;
varispeedUnitDescription.componentSubType       = kAudioUnitSubType_Varispeed;
varispeedUnitDescription.componentManufacturer  = kAudioUnitManufacturer_Apple;
varispeedUnitDescription.componentFlags         = 0;
varispeedUnitDescription.componentFlagsMask     = 0;

So... It was really bad component type (-2005) since varispeedUnitDescription was not actually described correctly.

链接地址: http://www.djcxy.com/p/62308.html

上一篇: 使用AUGraph与音频单元之间的直接连接通过GCD队列

下一篇: 在iOS6中使用Arisraph的Varispeed audiounit