Технические вопросы и ответы QA1717

Используя iPodTime аудиоустройство для игры аудиокниг

Q: Какие свойства могут быть установлены для AUiPodTime и как я конфигурирую его?

A: Какие свойства могут быть установлены для AUiPodTime и как я конфигурирую его?

AUiPodTime является растягивающим во времени аудиоустройством, которое в состоянии выполнять изменения уровня от 0.5x до 2x. Этот модуль разработан, чтобы использоваться с аудиокнигами и речевыми записями, такими как зарегистрированная лекция, позволяющая изменения скорости воспроизведения, не влияя на подачу.

Аудиоустройство AUiPodTime описано kAudioUnitType_FormatConverter введите и kAudioUnitSubType_AUiPodTime подтип. Потоковый формат ввода и вывода должен быть каноническим форматом данных аудиоустройства и может содержать один или два канала. Оба формата должны иметь то же число каналов и ту же частоту дискретизации; поддерживаются все общие частоты дискретизации.

При использовании этого аудиоустройства в графике аудиоустройства не забудьте устанавливать формат потока вывода - каждый формат потока вывода узлов (включая частоту дискретизации) должен быть установлен явно. Этот потоковый формат тогда распространен к входному потоковому формату его места назначения.

Перечисление 1  Типичный пример установки графика аудиоустройства.

- (void)initializeAUGraph:(Float64)inSampleRate
{
    printf("initializeAUGraph\n");

    AUNode outputNode;
    AUNode iPodTimeNode;
    AUNode mixerNode;
    AUNode converterNode;
    AudioUnit converterAU;

    printf("create client format ASBD\n");

    // client format audio going into the converter
    mClientFormat.SetCanonical(2, true); 
    mClientFormat.mSampleRate = 22050.0;
    mClientFormat.Print();

    printf("create output format ASBD\n");

    // output format
    mOutputFormat.SetAUCanonical(2, false); 
    mOutputFormat.mSampleRate = inSampleRate;
    mOutputFormat.Print();

    OSStatus result = noErr;

    printf("-----------\n");
    printf("new AUGraph\n");

    // create a new AUGraph
    result = NewAUGraph(&mGraph);
    if (result) { printf("NewAUGraph result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    // create three CAComponentDescription for the AUs we want in the graph

    // output unit
    CAComponentDescription output_desc(kAudioUnitType_Output,
                                       kAudioUnitSubType_RemoteIO,
                                       kAudioUnitManufacturer_Apple);

    // iPodTime unit
    CAComponentDescription iPodTime_desc(kAudioUnitType_FormatConverter,
                                         kAudioUnitSubType_AUiPodTime,
                                         kAudioUnitManufacturer_Apple);

    // multichannel mixer unit
    CAComponentDescription mixer_desc(kAudioUnitType_Mixer,
                                      kAudioUnitSubType_MultiChannelMixer,
                                      kAudioUnitManufacturer_Apple);

    // AU Converter
    CAComponentDescription converter_desc(kAudioUnitType_FormatConverter,
                                          kAudioUnitSubType_AUConverter,
                                          kAudioUnitManufacturer_Apple);

    printf("add nodes\n");

    // create a node in the graph that is an AudioUnit, using the supplied
    // AudioComponentDescription to find and open that unit
    result = AUGraphAddNode(mGraph, &output_desc, &outputNode);
    if (result) { printf("AUGraphNewNode 1 result %lu %4.4s\n", result, (char*)&result);
                    return; }

    result = AUGraphAddNode(mGraph, &iPodTime_desc, &iPodTimeNode);
    if (result) { printf("AUGraphNewNode 2 result %lu %4.4s\n", result, (char*)&result);
                    return; }

    result = AUGraphAddNode(mGraph, &mixer_desc, &mixerNode);
    if (result) { printf("AUGraphNewNode 3 result %lu %4.4s\n", result, (char*)&result);
                    return; }

    result = AUGraphAddNode(mGraph, &converter_desc, &converterNode);
    if (result) { printf("AUGraphNewNode 3 result %lu %4.4s\n", result, (char*)&result);
                    return; }

    // connect a node's output to a node's input
    // converter -> mixer -> iPodTime -> output

    result = AUGraphConnectNodeInput(mGraph, converterNode, 0, mixerNode, 0);
    if (result) { printf("AUGraphConnectNodeInput result %lu %4.4s\n", result,
                    (char*)&result); return; }

    result = AUGraphConnectNodeInput(mGraph, mixerNode, 0, iPodTimeNode, 0);
    if (result) { printf("AUGraphConnectNodeInput result %lu %4.4s\n", result,
                    (char*)&result); return; }

    result = AUGraphConnectNodeInput(mGraph, iPodTimeNode, 0, outputNode, 0);
    if (result) { printf("AUGraphConnectNodeInput result %lu %4.4s\n", result,
                    (char*)&result); return; }

    // open the graph -- AudioUnits are open but not initialized
    // (no resource allocation occurs here)
    result = AUGraphOpen(mGraph);
    if (result) { printf("AUGraphOpen result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    // grab audio unit instances from the nodes
    result = AUGraphNodeInfo(mGraph, converterNode, NULL, &converterAU);
    if (result) { printf("AUGraphNodeInfo result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    result = AUGraphNodeInfo(mGraph, mixerNode, NULL, &mMixer);
    if (result) { printf("AUGraphNodeInfo result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    result = AUGraphNodeInfo(mGraph, iPodTimeNode, NULL, &mIPodTime);
    if (result) { printf("AUGraphNodeInfo result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    // set bus count
    UInt32 numbuses = 1;

    printf("set input bus count %lu\n", numbuses);

    result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_ElementCount,
                    kAudioUnitScope_Input, 0, &numbuses, sizeof(numbuses));
    if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    // setup render callback struct
    AURenderCallbackStruct rcbs;
    rcbs.inputProc = &renderInput;
    rcbs.inputProcRefCon = &mUserData;

    printf("set AUGraphSetNodeInputCallback\n");

    // set a callback for the specified node's specified input bus (bus 1)
    result = AUGraphSetNodeInputCallback(mGraph, converterNode, 0, &rcbs);
    if (result) { printf("AUGraphSetNodeInputCallback result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    printf("set converter input bus %d client kAudioUnitProperty_StreamFormat\n", 0);

    // set the input stream format, this is the format of the audio
    // for the converter input bus (bus 1)
    result = AudioUnitSetProperty(converterAU, kAudioUnitProperty_StreamFormat,
                kAudioUnitScope_Input, 0, &mClientFormat, sizeof(mClientFormat));
    if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    // in an au graph, each nodes output stream format (including sample rate)
    // needs to be set explicitly this stream format is propagated to its
    // destination's input stream format

    printf("set converter output kAudioUnitProperty_StreamFormat\n");

    // set the output stream format of the converter
    result = AudioUnitSetProperty(converterAU, kAudioUnitProperty_StreamFormat,
                kAudioUnitScope_Output, 0, &mOutputFormat, sizeof(mOutputFormat));
    if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    printf("set mixer output kAudioUnitProperty_StreamFormat\n");

    // set the output stream format of the mixer
    result = AudioUnitSetProperty(mMixer, kAudioUnitProperty_StreamFormat,
                kAudioUnitScope_Output, 0, &mOutputFormat, sizeof(mOutputFormat));
    if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    printf("set iPodTime output kAudioUnitProperty_StreamFormat\n");

    // set the output stream format of the iPodTime unit
    result = AudioUnitSetProperty(mIPodTime, kAudioUnitProperty_StreamFormat,
                kAudioUnitScope_Output, 0, &mOutputFormat, sizeof(mOutputFormat));
    if (result) { printf("AudioUnitSetProperty result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    printf("AUGraphInitialize\n");

    // now that we've set everything up we can initialize the graph, this will also
    // validate the connections
    result = AUGraphInitialize(mGraph);
    if (result) { printf("AUGraphInitialize result %ld %08X %4.4s\n", result,
                    (unsigned int)result, (char*)&result); return; }

    CAShow(mGraph);
}

kTimePitchParam_Rate параметр, объявленный в AudioUnitParameters.h используется для управления уровнем воспроизведения аудио от 0.5x до 2.0x скорость. AudioUnitParameterValue a Float32 округленный модулем к тому, какой бы ни из следующего является самым близким: 0.5, 0.66667, 0.8, 1.0, 1.25, 1.5, 2. Скорость воспроизведения 1,0 является значением по умолчанию.

  Установка Listing 2 Method уровень AUiPodTime.

// sets the rate of the iPodTime Audio Unit
- (void)setIPodTimeRate:(AudioUnitParameterValue)value
{
    OSStatus result = AudioUnitSetParameter(mIPodTime,
            kTimePitchParam_Rate, kAudioUnitScope_Global, 0, value, 0);
    if (result) { printf("AudioUnitSetParameter kTimePitchParam_Rate
     Global result %ld %08X %4.4s\n", result, (unsigned int)result, (char*)&result); return; }
}


История версии документа


ДатаПримечания
03.09.2010

Новый документ, описывающий использование модуля AUiPodTime, который полезен при воспроизведении аудиокниг на различных уровнях, не изменяя подачу.