7

AudioFilePlayer AudioUnit を AU3DMixerEmbedded Audio Unit に接続しようとしていますが、うまくいきません。

これが私がやっていることです:

  1. AUGraphで作成NewAUGraph()

  2. グラフを開く

  3. グラフを初期化する

  4. 3 つのノードを追加します。

    • 出力ノード:kAudioUnitSubType_RemoteIO
    • ミキサーノード:kAudioUnitSubType_AU3DMixerEmbedded
    • filePlayerNode:kAudioUnitSubType_AudioFilePlayer
  5. ノードを接続します。

    • filePlayerNode -> ミキサーノード
    • ミキサー ノード -> 出力ノード
  6. 必要なファイルを再生するように filePlayer Audio Unit を構成する

  7. グラフを開始

これは機能しません: AUGraphInitialize でエラー 10868 (kAudioUnitErr_FormatNotSupported) で停止します。問題は、filePlayer とミキサーの間のオーディオ形式の不一致によるものだと思います。これは次の理由からだと思いますAUGraphConnectNodeInput(_graph, filePlayerNode, 0, mixerNode, 0)。- ステップ 3 を filePlayerNode を outputNode ( AUGraphConnectNodeInput(_graph, filePlayerNode, 0, outputNode, 0)) に直接接続するように置き換えると、オーディオが再生されます。

filePlayerNode を MixerNode に接続する際に欠けている手順は何ですか?

これが完全なコードです。これは、Apple のサンプル コードと、インターウェブから見つけた他のサンプルに基づいています。(AUGraphStartは後者と呼ばれます):

- (id)init
{
    self = [super init];
    if (self != nil)
    {
        {
            //create a new AUGraph
            CheckError(NewAUGraph(&_graph), "NewAUGraph failed");        
            // opening the graph opens all contained audio units but does not allocate any resources yet            
            CheckError(AUGraphOpen(_graph), "AUGraphOpen failed");                
            // now initialize the graph (causes resources to be allocated) 
            CheckError(AUGraphInitialize(_graph), "AUGraphInitialize failed");                    
        }

        AUNode outputNode;
        {
            AudioComponentDescription outputAudioDesc = {0};
            outputAudioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;            
            outputAudioDesc.componentType = kAudioUnitType_Output;
            outputAudioDesc.componentSubType = kAudioUnitSubType_RemoteIO;
            // adds a node with above description to the graph
            CheckError(AUGraphAddNode(_graph, &outputAudioDesc, &outputNode), "AUGraphAddNode[kAudioUnitSubType_DefaultOutput] failed");
        }

        AUNode mixerNode;
        {
            AudioComponentDescription mixerAudioDesc = {0};
            mixerAudioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;                                
            mixerAudioDesc.componentType = kAudioUnitType_Mixer;
            mixerAudioDesc.componentSubType = kAudioUnitSubType_AU3DMixerEmbedded;
            mixerAudioDesc.componentFlags = 0;
            mixerAudioDesc.componentFlagsMask = 0;
            // adds a node with above description to the graph
            CheckError(AUGraphAddNode(_graph, &mixerAudioDesc, &mixerNode), "AUGraphAddNode[kAudioUnitSubType_AU3DMixerEmbedded] failed");            
        }

        AUNode filePlayerNode;            
        {
            AudioComponentDescription fileplayerAudioDesc = {0};            
            fileplayerAudioDesc.componentType = kAudioUnitType_Generator;
            fileplayerAudioDesc.componentSubType = kAudioUnitSubType_AudioFilePlayer;
            fileplayerAudioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
            // adds a node with above description to the graph
            CheckError(AUGraphAddNode(_graph, &fileplayerAudioDesc, &filePlayerNode), "AUGraphAddNode[kAudioUnitSubType_AudioFilePlayer] failed");
        }

        //Connect the nodes
        {
            // connect the output source of the file player AU to the input source of the output node            
//            CheckError(AUGraphConnectNodeInput(_graph, filePlayerNode, 0, outputNode, 0), "AUGraphConnectNodeInput");                        

            CheckError(AUGraphConnectNodeInput(_graph, filePlayerNode, 0, mixerNode, 0), "AUGraphConnectNodeInput");
            CheckError(AUGraphConnectNodeInput(_graph, mixerNode, 0, outputNode, 0), "AUGraphConnectNodeInput");                                    
        }



        // configure the file player
        // tell the file player unit to load the file we want to play
        {
            //?????
            AudioStreamBasicDescription inputFormat; // input file's data stream description
            AudioFileID inputFile; // reference to your input file            

            // open the input audio file and store the AU ref in _player
            CFURLRef songURL = (__bridge CFURLRef)[[NSBundle mainBundle] URLForResource:@"monoVoice" withExtension:@"aif"];
            CheckError(AudioFileOpenURL(songURL, kAudioFileReadPermission, 0, &inputFile), "AudioFileOpenURL failed");

            //create an empty MyAUGraphPlayer struct
            AudioUnit fileAU;

            // get the reference to the AudioUnit object for the file player graph node
            CheckError(AUGraphNodeInfo(_graph, filePlayerNode, NULL, &fileAU), "AUGraphNodeInfo failed");

            // get and store the audio data format from the file
            UInt32 propSize = sizeof(inputFormat);
            CheckError(AudioFileGetProperty(inputFile, kAudioFilePropertyDataFormat, &propSize, &inputFormat), "couldn't get file's data format");            

            CheckError(AudioUnitSetProperty(fileAU, kAudioUnitProperty_ScheduledFileIDs, kAudioUnitScope_Global, 0, &(inputFile), sizeof((inputFile))), "AudioUnitSetProperty[kAudioUnitProperty_ScheduledFileIDs] failed");

            UInt64 nPackets;
            UInt32 propsize = sizeof(nPackets);
            CheckError(AudioFileGetProperty(inputFile, kAudioFilePropertyAudioDataPacketCount, &propsize, &nPackets), "AudioFileGetProperty[kAudioFilePropertyAudioDataPacketCount] failed");

            // tell the file player AU to play the entire file
            ScheduledAudioFileRegion rgn;
            memset (&rgn.mTimeStamp, 0, sizeof(rgn.mTimeStamp));
            rgn.mTimeStamp.mFlags = kAudioTimeStampSampleTimeValid;
            rgn.mTimeStamp.mSampleTime = 0;
            rgn.mCompletionProc = NULL;
            rgn.mCompletionProcUserData = NULL;
            rgn.mAudioFile = inputFile;
            rgn.mLoopCount = 1;
            rgn.mStartFrame = 0;
            rgn.mFramesToPlay = nPackets * inputFormat.mFramesPerPacket;

            CheckError(AudioUnitSetProperty(fileAU, kAudioUnitProperty_ScheduledFileRegion, kAudioUnitScope_Global, 0,&rgn, sizeof(rgn)), "AudioUnitSetProperty[kAudioUnitProperty_ScheduledFileRegion] failed");

            // prime the file player AU with default values
            UInt32 defaultVal = 0;
            CheckError(AudioUnitSetProperty(fileAU, kAudioUnitProperty_ScheduledFilePrime, kAudioUnitScope_Global, 0, &defaultVal, sizeof(defaultVal)), "AudioUnitSetProperty[kAudioUnitProperty_ScheduledFilePrime] failed");

            // tell the file player AU when to start playing (-1 sample time means next render cycle)
            AudioTimeStamp startTime;
            memset (&startTime, 0, sizeof(startTime));
            startTime.mFlags = kAudioTimeStampSampleTimeValid;
            startTime.mSampleTime = -1;
            CheckError(AudioUnitSetProperty(fileAU, kAudioUnitProperty_ScheduleStartTimeStamp, kAudioUnitScope_Global, 0, &startTime, sizeof(startTime)), "AudioUnitSetProperty[kAudioUnitProperty_ScheduleStartTimeStamp]");

            // file duration
            //double duration = (nPackets * _player.inputFormat.mFramesPerPacket) / _player.inputFormat.mSampleRate;
        }            


    }
    return self;
}
4

2 に答える 2

3

オーディオ ユニットに適切な kAudioUnitProperty_StreamFormat を設定するコードがわかりません。また、エラー結果コードをチェックして、選択したストリーム形式設定が構成中のオーディオ ユニットで実際にサポートされているかどうかを確認する必要があります。そうでない場合は、別の形式を試してください。

于 2012-04-24T18:52:22.997 に答える
0

(AUGraphConnectNodeInput(_graph、filePlayerNode、0、mixerNode、0))(AUGraphConnectNodeInput(_graph、mixerNode、0、outputNode、0))

役立つ場合は、この方法を試してください。参考までに、左側のノードが右側のノードに入力されています。したがって、最初の行でプレーヤーノードがミキサーノードに入力され、ミキサーノードにプレーヤーとミキサーの両方が含まれるようになり、ミキサーノードを出力ノードに追加します。

于 2013-01-04T07:03:18.070 に答える