2013-04-22 11 views
0

Core Audio를 처음 사용하기 때문에 무언가가 분명하지 않을 수도 있습니다. 제 목표는 이전에 녹음 된 오디오 신호를 처리하는 것입니다. 그러나 이러한 신호는 먼저 필터링해야합니다. 나는 오디오를 재생할 필요가 없습니다. 나는 그것을 기록하고 처리해야합니다.코어 오디오 : non-remoteIO 장치의 kAudioOutputUnitProperty_SetInputCallback

내 그래프는 다음과 같습니다 -> HighPassFilter - RemoteIO> 콜백 (프로세스 오디오)

그리고 아래와 같이 설정

LBAudioDetectiveGetDefaultFormat(&detective->streamFormat); 

// Create new AUGraph 
OSStatus error = NewAUGraph(&detective->graph); 
LBErrorCheck(error); 

// Initialize AUNodes 
AudioComponentDescription rioCD = {0}; 
rioCD.componentType = kAudioUnitType_Output; 
rioCD.componentSubType = kAudioUnitSubType_RemoteIO; 
rioCD.componentManufacturer = kAudioUnitManufacturer_Apple; 

AUNode rioNode; 
error = AUGraphAddNode(detective->graph, &rioCD, &rioNode); 
LBErrorCheck(error); 

AudioComponentDescription filterCD = {0}; 
filterCD.componentType = kAudioUnitType_Effect; 
filterCD.componentSubType = kAudioUnitSubType_HighPassFilter; 
filterCD.componentManufacturer = kAudioUnitManufacturer_Apple; 

AUNode filterNode; 
error = AUGraphAddNode(detective->graph, &filterCD, &filterNode); 
LBErrorCheck(error); 

// Open the graph so I can modify the AudioUnits 
error = AUGraphOpen(detective->graph); 

// Adapt rioUnit 
error = AUGraphNodeInfo(detective->graph, rioNode, NULL, &detective->rioUnit); 
LBErrorCheck(error); 

UInt32 onFlag = 1; 
AudioUnitElement bus1 = 1; 
UInt32 propertySize = sizeof(UInt32);  
error = AudioUnitSetProperty(detective->rioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, bus1, &onFlag, propertySize); 
LBErrorCheck(error); 

propertySize = sizeof(AudioStreamBasicDescription); 
error = AudioUnitSetProperty(detective->rioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, bus1, &detective->streamFormat, propertySize); 
LBErrorCheck(error); 

// Adapt filterUnit 
error = AUGraphNodeInfo(detective->graph, filterNode, NULL, &detective->filterUnit); 
LBErrorCheck(error); 

AURenderCallbackStruct callback = {0}; 
callback.inputProc = _LBAudioDetectiveFilterOutput; 
callback.inputProcRefCon = detective; 
propertySize = sizeof(AURenderCallbackStruct); 
error = AudioUnitSetProperty(detective->filterUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &callback, propertySize); 
LBErrorCheck(error); 

// Connect the two units 
AudioUnitElement bus0 = 0; 
error = AUGraphConnectNodeInput(detective->graph, rioNode, bus1, filterNode, bus0); 
LBErrorCheck(error); 

AUGraphInitialize(detective->graph); 

내 코드가 오류와 함께 실패합니다 - 10879 콜백을 설정할 때. 필터 오디오 장치가이 속성을 지원하지 않는다고 가정합니다. 어떻게하면 녹음 된 사운드를 얻을 수 있습니까? 두 번째 일반 출력 단위는 내가 아는 한 허용되지 않습니다. RemoteIO 오디오 장치,하지만 RemoteIO 콜백에서 (대신 필터 유닛 또는 입력 버스의), 당기의 사전에 당신의 도움이

답변

2

구성 출력에 콜백 (버스 0)에 대한

감사 (렌더링) 필터 유닛으로부터. 그런 다음 필터 장치가 호출되어 RemoteIO 입력 (버스 1)에서 사용 가능한 데이터를 가져 와서 처리합니다.

소리를 내지 않으려면 출력 버퍼를 0으로 채 웁니다.

기본적으로 RemoteIO의 스피커 쪽은 스피커에서 소리를 내지 않으려는 경우에도 RemoteIO의 마이크쪽에있는 데이터에 대한 콜백 타이밍을 제공합니다. 이것은 전체 Audio Unit 체인이 풀 모델을 기반으로하기 때문에 (ADC에서 데이터를 API로 푸시 할 수있는 곳이 없음) 입력 및 출력의 하드웨어 샘플 속도가 동일하기 때문입니다. 따라서 출력은 오디오 유닛 체인이 마이크 입력 버퍼에서 가져 오기위한 정확한 시간에 호출됩니다.

+0

흠, 이것은 현명한 접근 방법이지만 입력 콜백을 더 이상 호출하지 않습니다. 정확히 어떤 버스를 연결해야합니까? rioUnit의 버스 1을 filterUnit의 버스 0에 연결했습니다. 콜백 구조체는 출력 범위의 rioUnit 버스 1에 구성되었습니다. 콜백이 호출되었지만 'ioData-> mBuffers [0] .mData'에 데이터가 없습니다. – lbrndnr