2012-08-10 40 views
1

我正在通過MusicPlayer播放MIDI序列,這是從MIDI文件加載的,我希望在播放時將序列更改爲另一個序列。 當我試試這個:如何從一個音樂序列切換到另一個沒有時間延遲

MusicPlayerSetSequence(_player, sequence); 
MusicSequenceSetAUGraph(sequence, _processingGraph); 

停止播放。所以我再次啓動它回來,並設置與

MusicPlayerSetTime(_player, currentTime); 

所以它再次播放上序列停止的地方的時候,但有一點延遲。 我試圖將時間間隔添加到currentTime,我通過獲取停止前和重新開始後的時間來獲取時間間隔。但仍然有延遲。

我想知道是否有替代停止 - >改變序列 - >再次啓動。

+0

嘿 - 你是否放棄了合併曲目的方法?我終於找到了一些時間讓它工作。你的文件有點隱藏 - 不知道爲什麼。下面是一個關於你的MIDI文件/ sf2 +一個隨機midi/sf2的例子(我有過)(http://dl.dropbox.com/u/34715839/MusicPlayerTracksFromFiles.zip) - 乾杯 – 2012-08-10 04:31:54

+0

哦 - 這裏有個bug設置跟蹤循環時的文件:使用的trackLen值來自sourceTrack。在設置循環長度之前,應該從目標軌道重新計算此值。此外,發現最簡單的.mid文件的奇怪是由於它有2首曲目 - 第一首是空的 - 所以複製該曲目==沉默。 – 2012-08-10 07:54:41

+0

不,我沒有,我找到了自己的解決方案,並提出了另一個答案(http://stackoverflow.com/questions/11706042)。但感謝無論如何,我相信你的代碼將幫助我優化我的。我仍然試圖弄清楚你是如何循環序列的,因爲它沒有在正確的時間循環。我做 - '如果(時間> = trackLen)MusicPlayerSetTime(_player,0);' – chedda 2012-08-10 08:54:30

回答

1

因爲

MusicPlayerSetSequence(_player, sequence); 
MusicSequenceSetAUGraph(sequence, _processingGraph); 

仍然會導致播放器停止,仍然可以聽到稍微休息一下。 所以不是更新musicSequence,我說幹就幹,改變了軌道,而不是,這不會造成任何中斷的內容:

MusicTrack currentTrack; 
MusicTrack currentTrack2; 
MusicSequenceGetIndTrack(musicSequence, 0, &currentTrack); 
MusicSequenceGetIndTrack(musicSequence, 1, &currentTrack2); 
MusicTrackClear(currentTrack, 0, _trackLen); 
MusicTrackClear(currentTrack2, 0, _trackLen); 

MusicSequence tmpSequence; 
switch (number) { 
    case 0: 
     tmpSequence = musicSequence1; 
     break; 
    case 1: 
     tmpSequence = musicSequence2; 
     break; 
    case 2: 
     tmpSequence = musicSequence3; 
     break; 
    case 3: 
     tmpSequence = musicSequence4; 
     break; 

    default: 
     tmpSequence = musicSequence1; 
     break; 
} 

MusicTrack tmpTrack; 
MusicTrack tmpTrack2; 
MusicSequenceGetIndTrack(tmpSequence, 0, &tmpTrack); 
MusicSequenceGetIndTrack(tmpSequence, 1, &tmpTrack2); 
MusicTimeStamp trackLen = 0; 
UInt32 trackLenLenLen = sizeof(trackLen); 
MusicTrackGetProperty(tmpTrack, kSequenceTrackProperty_TrackLength, &trackLen, &trackLenLenLen); 
_trackLen = trackLen; 
MusicTrackCopyInsert(tmpTrack, 0, _trackLen, currentTrack, 0); 
MusicTrackCopyInsert(tmpTrack2, 0, _trackLen, currentTrack2, 0); 

節點沒有斷開,沒有更新的圖形,沒有停止播放。

2

如果您正在添加和移除軌道或切換序列,您肯定需要管理AUSamplers。處理AUSampler可能更清潔,爲每個新軌道創建一個新的軌道,但它也可以「回收」AUSamplers,但這意味着您需要跟蹤它們。

管理AUSamplers意味着當您不再使用某個實例時(例如,如果您刪除或替換MusicTrack),您需要將其與AUMixer實例斷開連接,將其從AUGraph實例中刪除,然後更新AUGraph。

有很多方法可以處理所有這些。爲了方便跟蹤AUSampler實例的總線數量,加載的聲音字體以及其他一些東西,我使用名爲SamplerAudioUnit的NSObject的子類來包含所有需要的屬性和方法。音樂曲目相同 - 我有一個Track類 - 但這可能不需要在您的項目中。

雖然是AUSamplers需要管理的性能和內存的要點。如果一個實例不再被使用,它應該被移除,並且AUMixer總線輸入被釋放。

順便說一句 - 我檢查文檔,顯然沒有技術限制混音器總線的數量 - 但數量確實需要指定。

// this is not cut and paste code - just an example of managing the AUSampler instance 

- (OSStatus)deleteTrack:(Track*) trackObj 
{ 
    OSStatus result = noErr; 

    // turn off MP if playing 
    BOOL MPstate = [self isPlaying]; 
    if (MPstate){ 
     MusicPlayerStop(player); 
    } 

    //-disconnect node from mixer + update list of mixer buses 
    SamplerAudioUnit * samplerObj = trackObj.sampler; 
    UInt32 busNumber = samplerObj.busNumber; 

    result = AUGraphDisconnectNodeInput(graph, mixerNode, busNumber); 
    if (result) {[self printErrorMessage: @"AUGraphDisconnectNodeInput" withStatus: result];} 

    [self clearMixerBusState: busNumber]; // routine that keeps track of available busses 

    result = MusicSequenceDisposeTrack(sequence, trackObj.track); 
    if (result) {[self printErrorMessage: @"MusicSequenceDisposeTrack" withStatus: result];} 

    // remove AUSampler node 
    result = AUGraphRemoveNode(graph, samplerObj.samplerNode); 
    if (result) {[self printErrorMessage: @"AUGraphRemoveNode" withStatus: result];} 

    result = AUGraphUpdate(graph, NULL); 
    if (result) {[self printErrorMessage: @"AUGraphUpdate" withStatus: result];} 
    samplerObj = nil; 
    trackObj = nil; 

    if (MPstate){ 
     MusicPlayerStart(player); 
    } 

    // CAShow(graph); 
    // CAShow(sequence); 

    return result; 
} 
+0

斷開連接,刪除和創建新節點解決了問題。非常感謝你。 – chedda 2012-08-13 01:35:48

相關問題