|
@@ -1216,6 +1216,7 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
|
|
|
|
|
|
|
|
|
if (allNotes.length && allNotes[allNotes.length - 1].relativeTime === relativeTime) {
|
|
|
+ i++
|
|
|
continue;
|
|
|
}
|
|
|
|
|
@@ -1286,39 +1287,55 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
|
|
|
|
|
|
* evxml的曲子,如果曲谱xml中带有times信息,则音符时值优先取times中的值
|
|
|
* 曲子:1795013295024062466(春暖花开),如果音符有times信息,休止符没有times信息,此种规则是认为休止符不参与时值计算的,需要过滤掉该休止符
|
|
|
- * TODO:需要考虑唱名怎么处理,唱名是xml有多少个音符,就需要唱多少个,不能剔除
|
|
|
*/
|
|
|
- if (state.isEvxml && note.isRestFlag && note?.noteTimeInfo?.length === 0 && state.xmlHasTimes ) {
|
|
|
- const idx = _notes.findIndex(item=>item.note === note);
|
|
|
- let nextNoteTimes = _notes[idx+1]?.note?.noteTimeInfo?.[0]?.begin*1000
|
|
|
- let preNoteTImes = _notes[idx-1]?.note?.noteTimeInfo?.[0]?.end*1000
|
|
|
-
|
|
|
- if(!nextNoteTimes && nextNoteTimes!==0){
|
|
|
- let nextIndex = idx + 2
|
|
|
- while(!nextNoteTimes && nextIndex<_notes.length){
|
|
|
- nextNoteTimes = _notes[nextIndex]?.note?.noteTimeInfo?.[0]?.begin*1000
|
|
|
- nextIndex ++
|
|
|
- }
|
|
|
-
|
|
|
+ let evNoteStartTime = 0, evNoteEndTime = 0;
|
|
|
+ if (state.isEvxml && note?.noteTimeInfo?.length === 0 && state.xmlHasTimes ) {
|
|
|
+
|
|
|
+ let preNoteTImes = allNotes[allNotes.length - 1]?.endtime*1000
|
|
|
+ if(!preNoteTImes){
|
|
|
+ preNoteTImes = Math.max(fixtime - noteLength, 0)*1000
|
|
|
}
|
|
|
- if(!preNoteTImes && preNoteTImes!==0){
|
|
|
- let preIndex = idx - 2
|
|
|
- while(!preNoteTImes && preIndex>-1){
|
|
|
- preNoteTImes = _notes[preIndex]?.note?.noteTimeInfo?.[0]?.end*1000
|
|
|
- preIndex --
|
|
|
+
|
|
|
+ let nextI = i
|
|
|
+ let nextNoteTimes
|
|
|
+
|
|
|
+ const notesRatio = []
|
|
|
+ while (!nextNoteTimes && nextI<_notes.length) {
|
|
|
+ notesRatio.push(_notes[nextI].note.length.realValue)
|
|
|
+ nextI++
|
|
|
+ if(_notes[nextI]?.note){
|
|
|
+ nextNoteTimes = fliterNotesTime(_notes[nextI].note, preNoteTImes)
|
|
|
}
|
|
|
-
|
|
|
- preNoteTImes || (preNoteTImes = 0)
|
|
|
}
|
|
|
+
|
|
|
+ if(!nextNoteTimes){
|
|
|
+ nextNoteTimes = preNoteTImes + noteLength*1000
|
|
|
+ }
|
|
|
+
|
|
|
const allowRange = Math.abs(nextNoteTimes - preNoteTImes)< 10;
|
|
|
if (allowRange) {
|
|
|
note.maxNoteNum = note.maxNoteNum - 1;
|
|
|
|
|
|
allNotes[allNotes.length - 1].noteLengthTime += noteLength
|
|
|
+ i++
|
|
|
continue;
|
|
|
+ }else{
|
|
|
+
|
|
|
+ if(notesRatio.length > 1){
|
|
|
+ const sum = notesRatio.reduce((acc:number, curr:number) => acc + curr, 0)
|
|
|
+ nextNoteTimes = (nextNoteTimes - preNoteTImes) * notesRatio[0] / sum + preNoteTImes
|
|
|
+ }
|
|
|
+ evNoteEndTime = nextNoteTimes/1000
|
|
|
+ evNoteStartTime = preNoteTImes/1000
|
|
|
+
|
|
|
+ if(evNoteEndTime - evNoteStartTime > noteLength){
|
|
|
+ evNoteEndTime = evNoteStartTime + noteLength
|
|
|
+ }
|
|
|
+ if (evNoteStartTime) {
|
|
|
+ relativeTime = evNoteStartTime - fixtime
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- let evNoteStartTime = 0, evNoteEndTime = 0;
|
|
|
if (state.isEvxml && note?.noteTimeInfo?.length ) {
|
|
|
let idx = noteIds.filter((item: any) => item === svgElement?.attrs.id)?.length || 0;
|
|
|
|
|
@@ -1745,4 +1762,18 @@ export const compatibleXmlPitchVoice = (xmlParse: any) => {
|
|
|
}
|
|
|
(window as any).xmlNeedAdjustVoice = xmlNeedAdjustVoice
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+function fliterNotesTime(note:any, preTime:number):undefined|number {
|
|
|
+
|
|
|
+ if(note?.noteTimeInfo?.length){
|
|
|
+ const timeObj = note?.noteTimeInfo.find((value:any) => {
|
|
|
+ const beginTime = value?.begin*1000 || 0
|
|
|
+ return beginTime > preTime || Math.abs(beginTime - preTime)< 10
|
|
|
+ })
|
|
|
+ return timeObj?.begin*1000
|
|
|
+ }else{
|
|
|
+ return undefined
|
|
|
+ }
|
|
|
}
|