簡體   English   中英

iOS9 Beta和MusicTrackLoopInfo

[英]iOS9 Beta and MusicTrackLoopInfo

有沒有人能夠在IOS9 Beta上循環播放MIDI文件? 一旦我嘗試通過在MusicTrackLoopInfo中將numberOfLoops設置為0來循環,它會通過向播放器發送隨機MIDI來鎖定應用程序。 我已經報道了,但我想知道是否有人找到了解決方法。 所有其他iOS版本的代碼完全相同。

MusicTrackLoopInfo loopInfo;
loopInfo.loopDuration = loopLength;
loopInfo.numberOfLoops = 0;

好的,我剛才聽說iOS9會附帶這個bug。 可怕。

這是一個解決方法。

不要設置numberOfLoops,或者設置numberOfLoops = 1; //表示循環一次現在創建一個變量(即myVariableToKeepTrackOfAddedCopies)來跟蹤實際執行以下操作的次數:

在您的MIDIReadProc中,在音軌播放完畢之前的某個時刻,請執行以下操作:

// Copy the track to itself - effectively doubling the length
MusicTrack theTrack=nil;
MusicTrackGetProperty(theTrack, kSequenceTrackProperty_TrackLength,         &trackLen, &trackLenLen);
trackLen = 4.0; //<-- this is your real track length
MusicTrackCopyInsert(theTrack, 0, trackLen, theTrack, 0);
myVariableToKeepTrackOfAddedCopies++;

所以現在你的賽道在它結束之前是兩倍,賽道將繼續。 這將與循環相同,除非您占用更多內存,因為在每次迭代后使軌道長度更長。

停止序列/軌道時,將軌道剪切回原始大小。

MusicTrackCut(theTrack, 4.0, 4.0 +     (4.0*myVariableToKeepTrackOfAddedCopies));
MusicTrackGetProperty(theTrack, kSequenceTrackProperty_TrackLength,     &trackLen, &trackLenLen);

刺激,但它的工作原理。 我剛剛在iOS9 beta 5上驗證過。希望它有所幫助。

從iOS 9.2版開始修復此問題

奇怪的是,節奏軌道似乎沒有這個問題。 以下代碼不會鎖定我:

MusicTrack tempoTrack;
OSSTATUS = MusicSequenceGetTempoTrack(self.sequence, &tempoTrack);
SafeMusicTrackClear(tempoTrack); //calls into MusicTrackClear 

MusicTrackNewExtendedTempoEvent(tempoTrack, 0, self.tempo * self.tempoMultiplier);

MIDIMetaEvent timeSignatureMetaEvent;
timeSignatureMetaEvent.metaEventType = 0x58;
timeSignatureMetaEvent.dataLength = 4;
timeSignatureMetaEvent.data[0] = 1;
timeSignatureMetaEvent.data[1] = 4;
timeSignatureMetaEvent.data[2] = 0x18;
timeSignatureMetaEvent.data[3] = 0x08;

MusicTrackNewMetaEvent(tempoTrack, 0, &timeSignatureMetaEvent);

MusicTrackLoopInfo loopInfo;
loopInfo.loopDuration = 0.25f;
loopInfo.numberOfLoops = 0;

MusicTrackSetProperty(tempoTrack, kSequenceTrackProperty_LoopInfo, &loopInfo, sizeof(loopInfo));

不幸的是,節奏音軌似乎不能真正演奏音符。


更新:

經過幾個小時的挖掘並試圖找到問題的更好解決方案后,我決定通過在序列結束時發送用戶事件來手動循環。

我的序列是在方法中創建的......

-(void) loadPacketsForLoopingSequence {
    SafeMusicTrackClear(loopingTrack); //calls into MusicTrackClear

    // calculate timestampToPlaySequenceAt -- the starting point of the current sequence iteration, probably in the past, based on MusicPlayerGetTime and the length of the sequence -- here

    // calculate timestampToPlayNextSequenceAt -- the starting point of the next sequence iteration, based on MusicPlayerGetTime and the length of the sequence -- here

    // a single iteration of the notes get added to loopingTrack here, starting at timestampToPlaySequenceAt

    MusicEventUserData event;
    event.length = 1;
    event.data[0] = 0xab; //arbitrary designation

    // -0.5 to make sure we still have time to do the next step in the callback
    MusicTrackNewUserEvent(loopingTrack, timestampToPlayNextSequenceAt - 0.5, &event);
}

...在回調中再次調用:

void sequenceCallback(void* inClientData,
                      MusicSequence inSequence,
                      MusicTrack inTrack,
                      MusicTimeStamp inEventTime,
                      const MusicEventUserData* inEventData,
                      MusicTimeStamp inStartSliceBeat,
                      MusicTimeStamp inEndSliceBeat) {
    CSMidiMusicPlayer* musicPlayer = (CSMidiMusicPlayer*)inClientData;
    [musicPlayer loadPacketsForLoopingSequence];
}

必須在序列初始化期間使用MusicSequenceSetUserCallback注冊回調。

通過檢查sequenceCallback的參數並修改loadPacketsForLoopingSequence以接受參數,可以完全消除-0.5 loadPacketsForLoopingSequence ,但我還沒有那么遠。

我喜歡這個解決方案,因為它保持在MIDI時間,並且不會以意想不到的狀態方式修改MIDI文件。 (當你接近循環標記時,新注釋基本上會被流入。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM