Ver código fonte

节拍器弱起补时间为负时候从歌词开始播起;遇到首位不相连的,现在主动连接起来

黄琪勇 11 meses atrás
pai
commit
846ddf83ec
1 arquivos alterados com 38 adições e 4 exclusões
  1. 38 4
      src/helpers/metronome.ts

+ 38 - 4
src/helpers/metronome.ts

@@ -277,27 +277,61 @@ class Metronome {
 		// 1.统计有多少小节
 		const measures: any[] = [];
 		let xmlNumber = -1;
+		let isDiff = false //弱起时间不够补的时候
 		for (let i = 0; i < times.length; i++) {
 			const note = times[i];
-			const measureNumberXML = note?.noteElement?.sourceMeasure?.MeasureNumberXML;
+			const measureNumberXML = note.MeasureNumberXML;
 			// console.log("🚀 ~ note?.noteElement?.sourceMeasure", note?.noteElement?.sourceMeasure)
 			// console.log("🚀 ~ measureNumberXML", measureNumberXML, note)
 			// console.log("🚀 ~ measureNumberXML", note)
-			const measureListIndex = note?.noteElement?.sourceMeasure?.measureListIndex;
+			const measureListIndex = measureNumberXML - 1;
 			if (measureNumberXML > -1) {
 				if (measureNumberXML != xmlNumber) {
 					// 弱起的时候 根据音符结尾时间减去音符开头时间,得到的不是正常小节的时间,然后平均分配节拍之后,当前节拍间隔会非常短 这里弱起取整个小节的时间
+					// 当小节时间 减去音符时间,前奏没有预留时间时候,从歌词开始唱的那里开始响节拍器
 					let startTime = note.measures[0].time
 					if(i === 0 && note.measures[0].difftime>0){
 						startTime = note.measures[note.measures.length - 1].endtime - note.measures[0].measureLength
+						if(startTime < 0){
+							isDiff = true
+						}
+					}
+					if(isDiff) {
+						// 当前小节有歌词,开放弱起节拍器
+						let isLyric = false
+						let noteIndex = 0
+						while(!isLyric && noteIndex<note.measures.length){
+							isLyric = !!note.measures[noteIndex]?.formatLyricsEntries?.length
+							noteIndex ++
+						}
+						isDiff = !isLyric
+					}
+					if(isDiff){
+						xmlNumber = measureNumberXML;
+						continue
+					}
+					// 最后一小节的时间 有可能和下一小节开始时间接不上
+					const { time, endtime, noteLengthTime } = note.measures[note.measures.length - 1]
+					let nextNoteStartTime = times[note.measures[note.measures.length - 1].i + 1]?.time
+					let noteEndTime = 0
+					if(!nextNoteStartTime){
+						noteEndTime = time + noteLengthTime
+					}else{
+						if(Math.abs(nextNoteStartTime - endtime)*1000< 10){
+							// 当首位本来就是相连的
+							noteEndTime = endtime
+						}else{
+							// 当首位不相连,差值大于这个音符的持续时间的时候取这个音符的时间(防止有间奏的连起来时间太长),否则直接取后一个音符的开始时间
+							noteEndTime = nextNoteStartTime - time > noteLengthTime ? time + noteLengthTime : nextNoteStartTime
+						}	
 					}
 					const m = {
 						measureNumberXML: measureNumberXML,
 						measureNumberIndex: measureListIndex,
 						numerator: note?.noteElement?.sourceMeasure?.ActiveTimeSignature?.numerator || 0,
 						start: startTime,
-						end: note.measures[note.measures.length - 1].endtime,
-						time: note.measures[note.measures.length - 1].endtime - startTime,
+						end: noteEndTime,
+						time: noteEndTime - startTime,
 						stave_x: note?.noteElement?.sourceMeasure?.verticalMeasureList?.[0]?.stave?.x || 0,
 						end_x: note?.stave?.end_x || 0 || 0,
 						stepList: [] as number[],