|  | @@ -1216,6 +1216,7 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
 | 
	
		
			
				|  |  |  			// console.log('si',si,i)
 | 
	
		
			
				|  |  |  			// console.log(note.sourceMeasure.MeasureNumberXML,note,svgElement, NoteRealValue, measureLength)
 | 
	
		
			
				|  |  |  			if (allNotes.length && allNotes[allNotes.length - 1].relativeTime === relativeTime) {
 | 
	
		
			
				|  |  | +				i++
 | 
	
		
			
				|  |  |  				continue;
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  			// console.log(iterator.currentMeasure)
 | 
	
	
		
			
				|  | @@ -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 ++
 | 
	
		
			
				|  |  | -					}
 | 
	
		
			
				|  |  | -					// 当最后音符就是没有打时间的休止小节,可能nextNoteTimes时间找不到,目前没有处理
 | 
	
		
			
				|  |  | +			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){ // 有可能_notes里面没有这个音符
 | 
	
		
			
				|  |  | +						nextNoteTimes = fliterNotesTime(_notes[nextI].note, preNoteTImes)
 | 
	
		
			
				|  |  |  					}
 | 
	
		
			
				|  |  | -					// 当没有找到preNoteTImes的时候 赋值为0 (当第一个音符就是没有打时间的休止小节会出现这种情况)
 | 
	
		
			
				|  |  | -					preNoteTImes || (preNoteTImes = 0)
 | 
	
		
			
				|  |  |  				}
 | 
	
		
			
				|  |  | +				// 当最后音符就是没有打时间的音符,可能nextNoteTimes时间找不到时候取上个音符的结束时间加上这个音符的时间
 | 
	
		
			
				|  |  | +				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 {
 | 
	
		
			
				|  |  | +	// 音符可能涉及多遍歌词,所以这里要找到对应的times
 | 
	
		
			
				|  |  | +	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  //差值在10毫秒之内
 | 
	
		
			
				|  |  | +		})
 | 
	
		
			
				|  |  | +		return timeObj?.begin*1000
 | 
	
		
			
				|  |  | +	}else{
 | 
	
		
			
				|  |  | +		return undefined
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  }
 |