Search code examples
macososx-lionosx-mountain-lioncore-audio

Use of undeclared identifier 'kAudioUnitSubType_SpeechSynthesis...


I've been following the examples on Audio Units from Learning Core Audio book by Adamson and Avila. I'm getting the above error for some reason. I #include <CoreAudio/CoreAudio.h> even just to make sure I am importing the possible libraries for Audio, and made sure to configure the "Link Binary with Libraries" under the "Build Phases" part of target. I even changed the Base SDK to OSX 10.7 (as opposed to the default 10.8) to see what happens, but no cigar. And according to the documentation, the Speech Synthesis API is not fully deprecated in anyway -- some functions are, however. My MacBook is running 10.7.5. XCode is Version 4.6 (4H127.

Below I put a comment on where I got the error in CAPS. Any ideas?

//
//  main.c
//  CAsamplerSynthesisGraph
//
//  Created by Edderic Ugaddan on 6/25/13.
//  Copyright (c) 2013 Edderic Ugaddan. All rights reserved.
//

//#include <CoreFoundation/CoreFoundation.h>
#include <AudioUnit/AudioUnit.h>
#include <AudioToolbox/AudioToolbox.h>
#include <CoreAudio/CoreAudio.h>

// #define PART_II

#pragma mark user-data struct
// Insert Listing 7.19 here

typedef struct MyAUGraphPlayer {
    AUGraph graph;
    AudioUnit samplerAU;
} MyAUGraphPlayer;

#pragma mark utility functions
// Insert Listing 4.2 here

static void CheckError(OSStatus error, const char *operation) {
    if (error == noErr) return;

    char errorString[20];

    // See if it appears to be a 4-char-code.

    *(UInt32 *)*(errorString + 1) = CFSwapInt32HostToBig(error);
    if (isprint(errorString[1]) && isprint(errorString[2]) &&
        isprint(errorString[3]) && isprint(errorString[4])) {
        errorString[0] = errorString[5] = '\'';
        errorString[6] = '\0';
    }
    else {

        // No, format it as an integer.

        sprintf(errorString, "%d", (int) error);
        fprintf(stderr, "Error: %s (%s)\n", operation, errorString);
        exit(1);
    }
}


void CreateMyAUGraph(MyAUGraphPlayer *player) {
    // Insert Listing 7.21 here
    // Create a new graph
    CheckError(NewAUGraph(&player->graph),
               "NewAUGraph failed");

    // Generates a description that matches our output device (speakers)
    AudioComponentDescription outputcd = {0};
    outputcd.componentType = kAudioUnitType_Output;
    outputcd.componentSubType = kAudioUnitSubType_DefaultOutput;
    outputcd.componentManufacturer = kAudioUnitManufacturer_Apple;

    // Adds a node with above description to the graph
    AUNode outputNode;
    CheckError(AUGraphAddNode(player->graph,
                              &outputcd,
                              &outputNode),
               "AUGraphAddNode[kAudioUnitSubType_DefaultOutput] failed");

    // Generates a description that will match a generator AU
    // of type: sampler synthesizer
    AudioComponentDescription samplercd = {0};
    samplercd.componentType = kAudioUnitType_Generator;
    samplercd.componentSubType = kAudioUnitSubType_SpeechSynthesis; // I GET ERROR HERE
    samplercd.componentManufacturer = kAudioUnitManufacturer_Apple;

    // Adds a node with above description to the graph
    AUNode samplerNode;
    CheckError(AUGraphAddNode(player->graph,
                              &samplercd,
                              &samplerNode),
               "AUGraphAddNode[kAudioUnitSubType_samplerSynthesis] failed");

    // Opening the graph opens all contained audio units, but
    // does not allocate any resources yet
    CheckError(AUGraphOpen(player->graph),
               "AUGraphOpen failed");


    // Gets the reference to the AudioUnit object for the
    // sampler graph node
    CheckError(AUGraphNodeInfo(player->graph,
                               samplerNode,
                               NULL,
                               &player->samplerAU),
               "AUGraphNodeInfo failed");

#ifdef PART_II
    // Insert Listing 7.24 - 7.26 here
#else
    // Insert Listing 7.22 here
    // Connect the output source of the sampler synthesis AU
    // to the input source of the output node
    CheckError(AUGraphConnectNodeInput(player->graph,
                                       samplerNode,
                                       0,
                                       outputNode,
                                       0),
               "AUGraphConnectNodeInput failed");
#endif
}

// Replace with listing 7.23
void PrepareSamplerAU(MyAUGraphPlayer *player) {
//    Sampler

}

#pragma mark main function
// Replace with listing 7.20

int main(int argc, const char * argv[])
{

    MyAUGraphPlayer player = {0};

    // Build a basic sampler->speakers graph
    CreateMyAUGraph(&player);

    // Configure the sampler synthesizer
    PrepareSamplerAU(&player);

    // Start playing
    CheckError(AUGraphStart(player.graph),
               "AUGraphStart failed");

    // Sleep a while so the sampler can play out
    usleep ((int)(10 * 1000. * 1000.));

    // Cleanup
    AUGraphStop(player.graph);
    AUGraphUninitialize(player.graph);
    AUGraphClose(player.graph);

    return 0;
}

Solution

  • kAudioUnitSubType_SpeechSynthesis is declared in SpeechSynthesis.framework, which lives within the ApplicationServices.framework umbrella framework, so you should #import < ApplicationServices.framework>.