2012-11-09 40 views
7

मैं एक समस्या है के साथ खेलते हैं;)AUGraph रिकार्ड और RemoteIO और MultiChannelMixer

मैं माइक से ऑडियो रिकॉर्ड और यह विस्तारित ऑडियो फ़ाइल सेवाओं के साथ फ़ाइल के लिए लिखें और भी दर्ज की गई सामग्री खेलना चाहता हूँ। यदि मैं केवल दो कॉलबैक के साथ रिमोटियो का उपयोग करता हूं, तो इसे पढ़ने के लिए इसे पढ़ने के लिए एक काम करता है।

वॉल्यूम नियंत्रण के लिए मैं मल्टीचैनलमिक्सर और ऑग्राफ का उपयोग करना चाहता हूं। क्या यह संभव है कि आप प्लेबैक और उसी मिक्सर और रिमोटियो के साथ रिकॉर्डिंग का एहसास करें?

मुझे लगता है कि यह इस तरह दिखना चाहिए:

RemotIO Input ->  -> Write Callback 
        Mixer 
RemoteIO Output <-  <- Read Callback 

मैं दो AUNodes (RemoteIO और MultiChannelMixer) बनाने के लिए, मैं कैसे कॉलबैक और कनेक्शन है कि एक कॉलबैक माइक और एक दूसरे से AudioData देने सेट करना होगा एक फ़ाइल से डेटा पढ़ता है और दोनों पथ मिक्सर के माध्यम से जाते हैं?

पढ़ना और लेखन समस्या नहीं है, केवल नोड्स की कॉन्फ़िगरेशन है!

... और CAShow के उत्पादन:

OSStatus setupErr = noErr; 

AudioComponentDescription mixerDescription; 
AudioComponentDescription ioDescription; 

// the AUNodes 
AUNode mixerNode; 
AUNode ioNode; 

// the graph 
setupErr = NewAUGraph(&_graph); 
NSAssert(setupErr == noErr, @"Couldn't create graph"); 

// the mixer 
mixerDescription.componentFlags = 0; 
mixerDescription.componentFlagsMask = 0; 
mixerDescription.componentType = kAudioUnitType_Mixer; 
mixerDescription.componentSubType = kAudioUnitSubType_MultiChannelMixer; 
mixerDescription.componentManufacturer = kAudioUnitManufacturer_Apple; 

// the io 
ioDescription.componentFlags = 0; 
ioDescription.componentFlagsMask = 0; 
ioDescription.componentType = kAudioUnitType_Output; 
ioDescription.componentSubType = kAudioUnitSubType_RemoteIO; 
ioDescription.componentManufacturer = kAudioUnitManufacturer_Apple; 

// add mixer Node 
setupErr = AUGraphAddNode(self.graph, &mixerDescription, &mixerNode); 
NSAssert(setupErr == noErr, @"Couldn't create master mixer"); 

// add io Node 
setupErr = AUGraphAddNode(self.graph, &ioDescription, &ioNode); 
NSAssert(setupErr == noErr, @"Couldn't create io node"); 

// open Graph 
setupErr = AUGraphOpen(self.graph); 
NSAssert(setupErr == noErr, @"Couldn't open graph"); 

// get the mixer info 
setupErr = AUGraphNodeInfo(self.graph, mixerNode, &mixerDescription, &_mixer); 
NSAssert(setupErr == noErr, @"Couldn't get master mixer info"); 

// get the io info 
setupErr = AUGraphNodeInfo(self.graph, ioNode, &ioDescription, &_io); 
NSAssert(setupErr == noErr, @"Couldn't get io Node info"); 

// enable io input 
UInt32 enableFlag = 1; 
setupErr = AudioUnitSetProperty(self.io, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &enableFlag, sizeof(enableFlag)); 
NSAssert(setupErr == noErr, @"Couldn't enable io input"); 

// set up the mixers input callbacks 
AURenderCallbackStruct outputCallbackStruct; 
outputCallbackStruct.inputProc = outputCallback; 
outputCallbackStruct.inputProcRefCon = self; 

AURenderCallbackStruct inputCallbackStruct; 
inputCallbackStruct.inputProc = inputCallback; 
inputCallbackStruct.inputProcRefCon = self; 

setupErr = AUGraphConnectNodeInput(self.graph, mixerNode, 0, ioNode, 0); 
NSAssert(setupErr == noErr, @"Couldn't connect mixer output to io output"); 
setupErr = AUGraphConnectNodeInput(self.graph, ioNode, 1, mixerNode, 1); 
NSAssert(setupErr == noErr, @"Couldn't connect io input to mixer input"); 

// set output Callback 
setupErr = AUGraphSetNodeInputCallback(self.graph, ioNode, 1, &outputCallbackStruct); 
NSAssert(setupErr == noErr, @"Error setting io output callback"); 

// set input Callback 
setupErr = AUGraphSetNodeInputCallback(self.graph, mixerNode, 0, &inputCallbackStruct); 
NSAssert(setupErr == noErr, @"Error setting mixer input callback"); 

// describe format 
AudioStreamBasicDescription audioFormat = {0}; 
audioFormat.mSampleRate     = 44100.00; 
audioFormat.mFormatID     = kAudioFormatLinearPCM; 
audioFormat.mFormatFlags    = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 
audioFormat.mFramesPerPacket   = 1; 
audioFormat.mChannelsPerFrame   = 2; 
audioFormat.mBitsPerChannel    = 16; 
audioFormat.mBytesPerPacket    = 4; 
audioFormat.mBytesPerFrame    = 4; 

// set the rio input properties 
setupErr = AudioUnitSetProperty(self.io, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &audioFormat, sizeof(audioFormat)); 
NSAssert(setupErr == noErr, @"Error setting RIO input property"); 

// set the rio output properties 
setupErr = AudioUnitSetProperty(self.io, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &audioFormat, sizeof(audioFormat)); 
NSAssert(setupErr == noErr, @"Error setting RIO output property"); 

// set the master fader output properties 
setupErr = AudioUnitSetProperty(self.mixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Global, kOutputBus, &audioFormat, sizeof(audioFormat)); 
NSAssert(setupErr == noErr, @"Error setting master output property"); 

// set the master fader input properties 
setupErr = AudioUnitSetProperty(self.mixer, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Global, kOutputBus, &audioFormat, sizeof(audioFormat)); 
NSAssert(setupErr == noErr, @"Error setting master input1 property"); 

// initialize Graph 
setupErr = AUGraphInitialize(self.graph); 
NSAssert(setupErr == noErr, @"Error initializing graph - error code"); 

CAShow(self.graph); 

// start Graph 
setupErr = AUGraphStart(self.graph); 
NSAssert(setupErr == noErr, @"Error starting graph. - error code"); 

मैं आशा है कि आप मेरी समस्या :) धन्यवाद समझते हैं ..

अद्यतन:

AudioUnitGraph 0x8AEE000: 
    Member Nodes: 
    node 1: 'aumx' 'mcmx' 'appl', instance 0x865a510 O I 
    node 2: 'auou' 'rioc' 'appl', instance 0x865d0a0 O I 
    Connections: 
    node 1 bus 0 => node 2 bus 0 [ 2 ch, 44100 Hz, 'lpcm' (0x0000000C) 16-bit little-endian signed integer] 
    node 2 bus 1 => node 1 bus 1 [ 2 ch, 44100 Hz, 'lpcm' (0x0000000C) 16-bit little-endian signed integer] 
    Input Callbacks: 
    {0x4150, 0x7573340} => node 2 bus 1 [2 ch, 44100 Hz] 
    {0x4330, 0x7573340} => node 1 bus 0 [2 ch, 44100 Hz] 
    CurrentState: 
    mLastUpdateError=0, eventsToProcess=F, isRunning=F 
यहाँ

सेटअप कोड है: मेरी समस्या का वर्णन करने के लिए कुछ और सामग्री!

रिकॉर्डिंग: RemoteIO InputScope बस 0 -> मिक्सर इनपुट बस 0 -> मिक्सर आउटपुट बस 0 -> लिखें कॉलबैक -> फ़ाइल प्लेबैक: फ़ाइल -> पढ़ें कॉलबैक -> मिक्सर इनपुट बस 1 -> मिक्सर आउटपुट बस 0 - > RemoteIO OutputScope बस 1

Connection Plan

उत्तर

7

आप तीन नोड्स (यूनिट) के साथ AUGraph बनाने की जरूरत है:

  1. फ़ाइल प्लेयर (kAudioUnitSubType_AudioFilePlayer)
  2. RemoteIO
  3. मिक्सर

इस तरह से उन्हें कनेक्ट करें:

AUGraphConnectNodeInput(m_graph, m_player, 0, m_mixerNode, 0); // player -> mixer 
AUGraphConnectNodeInput(m_graph, m_mixerNode, 0, m_rioNode, 0); // mixer -> output 
AUGraphConnectNodeInput(m_graph, m_rioNode, 1, m_mixerNode, 1); // input -> mixer 

रियो पर इनपुट सक्षम करें:

UInt32 enable = 1; 
AudioUnitSetProperty(m_rioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enable, sizeof(UInt32)); 

मिक्सर उत्पादन प्रारूप प्राप्त करें और विस्तारित ऑडियो फ़ाइल के लिए ग्राहक प्रारूप के रूप में सेट:

AudioStreamBasicDescription mixerASBD; 
UInt32 prop = sizeof(mixerASBD); 
AudioUnitGetProperty(m_mixerUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &mixerASBD, &prop); 
ExtAudioFileSetProperty(extAudioFile, kExtAudioFileProperty_ClientDataFormat, sizeof(mixerASBD), &mixerASBD); 

परिभाषित प्रस्तुत करना कॉलबैक: मिक्सर से उत्पादन डेटा के लिए

static OSStatus mixerCallBack(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp * inTimeStamp, UInt32 inBusNumber,UInt32 inNumberFrames, AudioBufferList *ioData) { 
    if ((*ioActionFlags) & kAudioUnitRenderAction_PostRender) 
     return (ExtAudioFileWrite(extAudioFile, inNumberFrames, ioData)); 

    return noErr; 
} 

जोड़ें कॉलबैक:

AudioUnitAddRenderNotify(m_mixerUnit, mixerCallBack, NULL); 

सब है कि। खेलने के लिए आपको FilePlayer इकाई में ऑडियो फ़ाइलों को शेड्यूल करने की आवश्यकता है।