2013-04-05 7 views
4

3 개의 MusicTrack이 포함 된 MusicSequence가있는 MusicPlayer가 있습니다. 나는 AUGraph를 3 개의 AUSampler 노드가있는 멀티 채널 믹서에 꽂아서 출력 노드에 연결했다.MusicPlayer 및 AUGraph를 사용하여 iOS에서 여러 악기를 설정할 수 없습니다.

나는 SoundFont를 사용하고 있으며, 나의 3 가지 다른 MusicTracks가 here으로 묘사 된 것처럼 3 가지 다른 악기에서 연주되기를 바랍니다. 그러나, 내가 가지고있는 코드는 작동하지 않습니다 - 대신, 그것은 부분 중 하나만 재생합니다. 다음

는 I는 AUGraph 만들기 :

NewAUGraph (&_processingGraph); 
AUNode samplerNode, samplerNodeTwo, samplerNodeThree, ioNode, mixerNode; 

AudioComponentDescription cd = {}; 
cd.componentManufacturer  = kAudioUnitManufacturer_Apple; 

//---------------------------------------- 
// Add 3 Sampler unit nodes to the graph 
//---------------------------------------- 
cd.componentType = kAudioUnitType_MusicDevice; 
cd.componentSubType = kAudioUnitSubType_Sampler; 

AUGraphAddNode (self.processingGraph, &cd, &samplerNode); 
AUGraphAddNode (self.processingGraph, &cd, &samplerNodeTwo); 
AUGraphAddNode (self.processingGraph, &cd, &samplerNodeThree); 

//----------------------------------- 
// 2. Add a Mixer unit node to the graph 
//----------------------------------- 
cd.componentType   = kAudioUnitType_Mixer; 
cd.componentSubType  = kAudioUnitSubType_MultiChannelMixer; 

AUGraphAddNode (self.processingGraph, &cd, &mixerNode); 

//-------------------------------------- 
// 3. Add the Output unit node to the graph 
//-------------------------------------- 
cd.componentType = kAudioUnitType_Output; 
cd.componentSubType = kAudioUnitSubType_RemoteIO; // Output to speakers 

AUGraphAddNode (self.processingGraph, &cd, &ioNode); 

//--------------- 
// Open the graph 
//--------------- 
AUGraphOpen (self.processingGraph); 

//----------------------------------------------------------- 
// Obtain the mixer unit instance from its corresponding node 
//----------------------------------------------------------- 
AUGraphNodeInfo (
          self.processingGraph, 
          mixerNode, 
          NULL, 
          &mixerUnit 
          ); 

//-------------------------------- 
// Set the bus count for the mixer 
//-------------------------------- 
UInt32 numBuses = 3; 
AudioUnitSetProperty(mixerUnit, 
           kAudioUnitProperty_ElementCount, 
           kAudioUnitScope_Input, 
           0, 
           &numBuses, 
           sizeof(numBuses)); 



//------------------ 
// Connect the nodes 
//------------------ 

AUGraphConnectNodeInput (self.processingGraph, samplerNode, 0, mixerNode, 0); 
AUGraphConnectNodeInput (self.processingGraph, samplerNodeTwo, 0, mixerNode, 1); 
AUGraphConnectNodeInput (self.processingGraph, samplerNodeThree, 0, mixerNode, 2); 

// Connect the mixer unit to the output unit 
AUGraphConnectNodeInput (self.processingGraph, mixerNode, 0, ioNode, 0); 

// Obtain references to all of the audio units from their nodes 
AUGraphNodeInfo (self.processingGraph, samplerNode, 0, &_samplerUnit); 
AUGraphNodeInfo (self.processingGraph, samplerNodeTwo, 0, &_samplerUnitTwo); 
AUGraphNodeInfo (self.processingGraph, samplerNodeThree, 0, &_samplerUnitThree); 
AUGraphNodeInfo (self.processingGraph, ioNode, 0, &_ioUnit); 

그때 사운드 폰트에서 3 개 악기로드 IDS (0, 1 및 사운드 폰트 2) 다음으로, 사운드 폰트의 'bankURL'전달 다음과 같이

// Load the first instrument 
AUSamplerBankPresetData bpdata; 
bpdata.bankURL = (__bridge CFURLRef) bankURL; 
bpdata.bankMSB = kAUSampler_DefaultMelodicBankMSB; 
bpdata.bankLSB = kAUSampler_DefaultBankLSB; 
bpdata.presetID = (UInt8) 0; 

AudioUnitSetProperty(self.samplerUnit, 
           kAUSamplerProperty_LoadPresetFromBank, 
           kAudioUnitScope_Global, 
           0, 
           &bpdata, 
           sizeof(bpdata)); 

// Load the second instrument 
AUSamplerBankPresetData bpdataTwo; 
bpdataTwo.bankURL = (__bridge CFURLRef) bankURL; 
bpdataTwo.bankMSB = kAUSampler_DefaultMelodicBankMSB; 
bpdataTwo.bankLSB = kAUSampler_DefaultBankLSB; 
bpdataTwo.presetID = (UInt8) 1; 

AudioUnitSetProperty(self.samplerUnitTwo, 
           kAUSamplerProperty_LoadPresetFromBank, 
           kAudioUnitScope_Global, 
           0, 
           &bpdataTwo, 
           sizeof(bpdataTwo)); 

// Load the third instrument 
AUSamplerBankPresetData bpdataThree; 
bpdataThree.bankURL = (__bridge CFURLRef) bankURL; 
bpdataThree.bankMSB = kAUSampler_DefaultMelodicBankMSB; 
bpdataThree.bankLSB = kAUSampler_DefaultBankLSB; 
bpdataThree.presetID = (UInt8) 2; 

AudioUnitSetProperty(self.samplerUnitThree, 
           kAUSamplerProperty_LoadPresetFromBank, 
           kAudioUnitScope_Global, 
           0, 
           &bpdataThree, 
           sizeof(bpdataThree)); 

마지막으로, 각 MusicTrack에 의해 사용되는 AUSampler 노드를 설정합니다

//------------------------------------------------- 
// Set the AUSampler nodes to be used by each track 
//------------------------------------------------- 
MusicTrack track, trackTwo, trackThree; 
MusicSequenceGetIndTrack(testSequence, 0, &track); 
MusicSequenceGetIndTrack(testSequence, 1, &trackTwo); 
MusicSequenceGetIndTrack(testSequence, 2, &trackThree); 

AUNode samplerNode, samplerNodeTwo, samplerNodeThree; 
AUGraphGetIndNode (self.processingGraph, 0, &samplerNode); 
AUGraphGetIndNode (self.processingGraph, 1, &samplerNodeTwo); 
AUGraphGetIndNode (self.processingGraph, 2, &samplerNodeThree); 

MusicTrackSetDestNode(track, samplerNode); 
MusicTrackSetDestNode(trackTwo, samplerNodeTwo); 
MusicTrackSetDestNode(trackThree, samplerNodeThree); 

그러나, 내가 MusicPlayer를 연주 할 때, 나는 오직 한 부분 만 연주하는 것을 듣습니다. 문제는 다른 악기를 사용하려고 할 때 발생합니다. 위의 경우처럼 AUGraph를 편집하는 대신 표준 MusicPlayer 설정으로 단일 악기를 사용하면 정상적으로 작동합니다.

내가 뭘 잘못하고 있는지 알 수있는 사람이 있습니까?

답변

4

해결책을 찾았습니다. 사운드 폰트의 악기를로드하기 전에, 다음 줄이 필요 : 다양한 MusicTracks이 AUSampler 노드를 할당하기 전에 악기의 사운드 폰트에서로드되기 전에

MusicSequenceSetAUGraph(testSequence, self.processingGraph); 

을만큼이 라인이 실행되는 시점으로 온다 , 그것은 작동하는 것처럼 보입니다 - 모든 파트는 원하는대로 다른 악기에서 연주됩니다. 관련 질문에 This answer이 나와 있습니다.

0

나는 당신과 똑같은 문제가있었습니다. 모든 트랙은 첫 번째 사운드 폰트 악기로 재생됩니다. 나는 당신의 해결책을 따라 갔지만 처음에는 효과가 없습니다. 마지막으로 문제를 해결합니다. 위에서 언급 한 것처럼 함수 호출 순서는 실제로 일치합니다. 예, 그렇습니다. 사실, 시퀀스 호출은 다음과 같아야합니다.

..... 
MusicSequenceSetAUGraph(s, _processingGraph); 
....... 
MusicTrackSetDestNode(track[i], samplerNodes[i]); 
...... 
[self loadFromDLSOrSoundFont]; 
...... 
MusicPlayerStart(p); 

이것은 내 프로젝트에서 작동합니다. 안녕하세요. 코드를 공유해 주셔서 감사합니다. 정말 도움 :