如何将AudioFilePlayer AudioUnit连接到3DMixer?

我试图将AudioFilePlayer AudioUnit连接到AU3DMixerEmbedded Audio Unit,但我没有成功。

以下是我正在做的事情:

  • NewAUGraph()创建一个AUGraph

  • 打开图表

  • 初始化图形

  • 添加3个节点:

  • outputNode: kAudioUnitSubType_RemoteIO
  • mixerNode: kAudioUnitSubType_AU3DMixerEmbedded
  • filePlayerNode: kAudioUnitSubType_AudioFilePlayer
  • 连接节点:

  • filePlayerNode - > mixerNode
  • mixerNode - > outputNode
  • 配置filePlayer音频单元播放所需的文件

  • 开始图形

  • 这不起作用:它在AUGraphInitialize上出现错误10868(kAudioUnitErr_FormatNotSupported)。 我认为这个问题是由于filePlayer和调音台之间的音频格式不匹配造成的。 我认为这是因为: - 如果我注释掉将filePlayerNode连接到mixerNode( AUGraphConnectNodeInput(_graph, filePlayerNode, 0, mixerNode, 0) )并注释掉步骤6,则不报告错误。 - 如果替换第3步,将filePlayerNode直接连接到outputNode( AUGraphConnectNodeInput(_graph, filePlayerNode, 0, outputNode, 0) ),则会播放音频。

    在将filePlayerNode连接到mixerNode时缺少哪些步骤?

    这是完整的代码。 它基于苹果公司的示例代码和我从互联网上找到的其他样本。 ( 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;
    }
    

    我没有在代码中看到为音频单元设置适当的kAudioUnitProperty_StreamFormat。 您还必须检查错误结果代码,以确定您选择的流格式设置是否实际上由正在配置的音频设备支持。 如果不是,请尝试其他格式。


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

    尝试这样做,如果它可以帮助。只是为了信息左节点输入在正确的节点。 所以在第一行中,播放器节点被输入到混合器节点,现在混合器节点包含播放器和混合器,因此将混合器节点添加到输出节点。

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

    上一篇: How do I connect an AudioFilePlayer AudioUnit to a 3DMixer?

    下一篇: HMAC MD5 Validation with Node.js, Express and Trialpay