문제

각각 고유한 사운드 글꼴 파일이 있는 2개 이상의 미디 파일을 혼합하는 방법을 찾고 있습니다.하나의 파일에 대해 다음 코드를 찾았고 여러 음악 플레이어를 시도했지만 올바른 접근 방식은 아닌 것 같습니다.또한 매초마다 이상한 팝 사운드가 들립니다.

그렇다면 musicplayer와 musicsequence 메서드 없이 au 단위만 사용하는 다른 방법이 있을까요?

다른 스레드에서 찾은 코드는 다음과 같습니다.

-(void) playMusic:(NSString*) name
{
NSString *presetURLPath = [[NSBundle mainBundle] pathForResource:@"GortsMiniPianoJ1" ofType:@"SF2"];
NSURL * presetURL = [NSURL fileURLWithPath:presetURLPath]; 
[self loadFromDLSOrSoundFont: (NSURL *)presetURL withPatch: (int)3];

NSString *midiFilePath = [[NSBundle mainBundle] pathForResource:name ofType:@"mid"];
NSURL * midiFileURL = [NSURL fileURLWithPath:midiFilePath];

NewMusicPlayer(&musicPlayer);

if (NewMusicSequence(&musicSequence) != noErr) 
{
    [NSException raise:@"play" format:@"Can't create MusicSequence"];  
}

if(MusicSequenceFileLoad(musicSequence, (CFURLRef)midiFileURL, 0, 0 != noErr)) 
{
    [NSException raise:@"play" format:@"Can't load MusicSequence"];
}

MusicPlayerSetSequence(musicPlayer, musicSequence);
MusicSequenceSetAUGraph(musicSequence, _processingGraph);
MusicPlayerPreroll(musicPlayer);
MusicPlayerStart(musicPlayer);
}
도움이 되었습니까?

해결책

여러 개의 MusicPlayer 인스턴스가 동기화를 유지하기에는 다소 어색한 것처럼 들리며 여러 개의 AUGraph가 작동할지 의심스럽습니다.나는 그것을 직접 시도하지 않았습니다.

단일 인스턴스를 사용하는 한 가지 접근 방식 MusicPlayer 각 미디 파일의 트랙을 '마스터' 시퀀스로 로드하는 것입니다.AUSampler 노드(고유한 soundFont 포함)를 각 트랙에 할당할 수 있습니다(MusicTrackSetDestNode) 그리고 이를 모두 통해 연결합니다. AUMixer.각 미디 파일의 템포를 관리해야 합니다(다음을 사용). MusicTrackNewExtendedTempoEvent) 관련 트랙에 파일 템포를 할당합니다.트랙 음소거 + 트랙 볼륨은 트랙 또는 믹서 수준에서 쉽게 처리됩니다.

작업 중인 미디 파일의 특성에 따라 많은 부분이 달라질 것 같습니다.Fwiw - 저는 iOS에서 미디 파일 재생에 대해 많은 연구를 했는데 MusicPlayer만큼 사용하기 쉬운 것은 없습니다.그러나, 그 베이스 라이브러리 MusicPlayer가 귀하에게 적합하지 않은 것으로 판명되면 살펴볼 가치가 있습니다.

믹서 입력 수 지정:

// set the bus count
UInt32 numBuses = BUS_COUNT; // a constant defined elsewhere
result = AudioUnitSetProperty(mixerUnit, 
                              kAudioUnitProperty_ElementCount, 
                              kAudioUnitScope_Input, 
                              0, 
                              &numBuses, 
                              sizeof(numBuses));

if (noErr != result) {[self printErrorMessage: @"Error setting Bus Count" withStatus: result]; return;}

다른 팁

나는 당신과 똑같은 문제가있었습니다.모든 트랙은 첫 번째 사운드 글꼴 악기로 재생됩니다.나는 당신의 솔루션을 따라 갔지만 처음에는 작동하지 않습니다.마지막으로 문제를 해결합니다.언급 한 것처럼, 호출하는 일련은 실제로 매숙합니다.네, 그렇습니다.사실, 순서 호출은 다음과 같아야합니다.

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

이 프로젝트에서 작동합니다.

그래서 각 트랙의 노드를 설정해 보았지만 아무 것도 바뀌지 않았습니다.사운드 폰트는 첫 번째에만 설정됩니다. samplerUnit.그래프를 설정하는 방법은 다음과 같습니다.

AudioComponentDescription MixerUnitDescription;
MixerUnitDescription.componentType          = kAudioUnitType_Mixer;
MixerUnitDescription.componentSubType       = kAudioUnitSubType_MultiChannelMixer;
MixerUnitDescription.componentManufacturer  = kAudioUnitManufacturer_Apple;
MixerUnitDescription.componentFlags         = 0;
MixerUnitDescription.componentFlagsMask     = 0;

AudioComponentDescription cd = {};
cd.componentManufacturer     = kAudioUnitManufacturer_Apple;
cd.componentType = kAudioUnitType_MusicDevice; // type - music device
cd.componentSubType = kAudioUnitSubType_Sampler; // sub type - sampler to convert our MIDI

result = NewAUGraph (&_processingGraph);
result = AUGraphAddNode(self.processingGraph, &MixerUnitDescription, &mixerNode);

result = AUGraphAddNode (self.processingGraph, &cd, &samplerNode);

result = AUGraphAddNode (self.processingGraph, &cd, &samplerNode2);

cd.componentType = kAudioUnitType_Output;  // Output
cd.componentSubType = kAudioUnitSubType_RemoteIO;  // Output to speakers

result = AUGraphAddNode (self.processingGraph, &cd, &ioNode);
result = AUGraphOpen (self.processingGraph);

result = AUGraphConnectNodeInput (self.processingGraph, samplerNode, 0, mixerNode, 0);
result = AUGraphConnectNodeInput (self.processingGraph, samplerNode2, 0, mixerNode, 1);

result = AUGraphConnectNodeInput (self.processingGraph, mixerNode, 0, ioNode, 0);
result = AUGraphNodeInfo (self.processingGraph, samplerNode, 0, &_samplerUnit);
result = AUGraphNodeInfo (self.processingGraph, samplerNode2, 0, &_samplerUnit2);
result = AUGraphNodeInfo (self.processingGraph, ioNode, 0, &_ioUnit);

이것은 특정 사운드 글꼴에 사운드 글꼴을 할당하기 위해 수정한 Apple 개발자 페이지의 예제 방법입니다. samplerUnit:

-(OSStatus) loadFromDLSOrSoundFont: (NSURL *)bankURL withPatch: (int)presetNumber withAudioUnit:(AudioUnit)auUnit{

OSStatus result = noErr;

// fill out a bank preset data structure
AUSamplerBankPresetData bpdata;
bpdata.bankURL  = (__bridge CFURLRef) bankURL;
bpdata.bankMSB  = kAUSampler_DefaultMelodicBankMSB;
bpdata.bankLSB  = kAUSampler_DefaultBankLSB;
bpdata.presetID = (UInt8) presetNumber;

// set the kAUSamplerProperty_LoadPresetFromBank property
result = AudioUnitSetProperty(auUnit,
                          kAUSamplerProperty_LoadPresetFromBank,
                          kAudioUnitScope_Global,
                          0,
                          &bpdata,
                          sizeof(bpdata));

// check for errors
NSCAssert (result == noErr,
       @"Unable to set the preset property on the Sampler. Error code:%d '%.4s'",
       (int) result,
       (const char *)&result);

return result;
}

그런 다음 각 트랙을 삽입하기 위해 이 작업을 두 번 수행했습니다. musicSequence:

if(MusicSequenceFileLoad(tmpSequence, (__bridge CFURLRef)midiFileURL, 0, 0 != noErr)) 
{
    [NSException raise:@"play" format:@"Can't load MusicSequence"];
}


MusicSequenceGetIndTrack(tmpSequence, 0, &tmpTrack);
MusicSequenceNewTrack(musicSequence, &track);
MusicTimeStamp trackLen = 0;
UInt32 trackLenLen = sizeof(trackLen);
MusicTrackGetProperty(tmpTrack, kSequenceTrackProperty_TrackLength, &trackLen, &trackLenLen);
MusicTrackCopyInsert(tmpTrack, 0, trackLenLen, track, 0);

그리고 마지막으로:

MusicTrackSetDestNode(track, samplerNode);
MusicTrackSetDestNode(track2, samplerNode2);

하지만 이렇게 하면 사운드 글꼴이 할당되지 않습니다. samplerUnit2:

[self loadFromDLSOrSoundFont: (NSURL *)presetURL2 withPatch: (int)0 withAudioUnit:self.samplerUnit2];

할당 대상 samplerUnit 잘 작동합니다.내가 여기서 무엇을 놓치고 있는지 어떤 아이디어가 있습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top