|
@@ -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
|
|
|
+ }
|
|
|
}
|