|
@@ -30,6 +30,7 @@ type TCriteria = "frequency" | "amplitude" | "decibels";
|
|
|
* 阶段评测时,判断是否从第一小节开始,并且曲子本身含有节拍器,需要传节拍器时长,否则传0
|
|
|
*/
|
|
|
let actualBeatLength = 0
|
|
|
+let calculateInfo: any = {}
|
|
|
|
|
|
export default defineComponent({
|
|
|
name: "evaluat-model",
|
|
@@ -107,25 +108,46 @@ export default defineComponent({
|
|
|
|
|
|
/** 生成评测曲谱数据 */
|
|
|
const formatTimes = () => {
|
|
|
+ let starTime = 0
|
|
|
let ListenMode = false;
|
|
|
let dontEvaluatingMode = false;
|
|
|
let skip = false;
|
|
|
const datas = [];
|
|
|
let selectTimes = state.times
|
|
|
+ let unitTestIdx = 0
|
|
|
+ let preTime = 0
|
|
|
+ let preTimes = []
|
|
|
+ // 系统节拍器时长
|
|
|
actualBeatLength = Math.round(state.times[0].fixtime * 1000 / 1)
|
|
|
// 如果是阶段评测,选取该阶段的times
|
|
|
if (state.isSelectMeasureMode && state.section.length) {
|
|
|
const startIndex = state.times.findIndex(
|
|
|
(n: any) => n.noteId == state.section[0].noteId
|
|
|
)
|
|
|
- const endIndex = state.times.findIndex(
|
|
|
+ let endIndex = state.times.findIndex(
|
|
|
(n: any) => n.noteId == state.section[1].noteId
|
|
|
)
|
|
|
- actualBeatLength = startIndex == 0 && !state.needTick ? actualBeatLength : 0
|
|
|
+ endIndex = endIndex < state.section[1].i ? state.section[1].i : endIndex
|
|
|
+ if (startIndex > 1) {
|
|
|
+ // firstNoteTime应该取预备小节的第一个音符的开始播放的时间
|
|
|
+ const idx = startIndex - 1 - (state.times[startIndex-1].si)
|
|
|
+ preTime = state.times[idx] ? state.times[idx].time * 1000 : 0
|
|
|
+ }
|
|
|
+ actualBeatLength = startIndex == 0 && !state.needTick ? actualBeatLength : 0
|
|
|
selectTimes = state.times.filter((n: any, index: number) => {
|
|
|
return index >= startIndex && index <= endIndex
|
|
|
})
|
|
|
+ preTimes = state.times.filter((n: any, index: number) => {
|
|
|
+ return index < startIndex
|
|
|
+ })
|
|
|
+ unitTestIdx = startIndex
|
|
|
+ starTime = selectTimes[0].sourceRelativeTime || selectTimes[0].relativeTime
|
|
|
}
|
|
|
+ // 阶段评测beatLength需要加上预备小节的持续时长
|
|
|
+ actualBeatLength = preTimes.length ? actualBeatLength + preTimes[preTimes.length - 1].relaMeasureLength * 1000 : actualBeatLength
|
|
|
+ let firstNoteTime = unitTestIdx > 1 ? preTime : 0
|
|
|
+ let measureIndex = -1
|
|
|
+ let recordMeasure = -1
|
|
|
|
|
|
for (let index = 0; index < selectTimes.length; index++) {
|
|
|
const item = selectTimes[index];
|
|
@@ -134,8 +156,8 @@ export default defineComponent({
|
|
|
// const rate = state.speed / state.originSpeed;
|
|
|
const rate = 1;
|
|
|
const difftime = item.difftime;
|
|
|
- const start = difftime + (item.sourceRelativeTime || item.relativeTime);
|
|
|
- const end = difftime + (item.sourceRelaEndtime || item.relaEndtime);
|
|
|
+ const start = difftime + (item.sourceRelativeTime || item.relativeTime) - starTime;
|
|
|
+ const end = difftime + (item.sourceRelaEndtime || item.relaEndtime) - starTime;
|
|
|
const isStaccato = note.noteElement.voiceEntry.isStaccato();
|
|
|
const noteRate = isStaccato ? 0.5 : 1;
|
|
|
if (note.formatLyricsEntries.contains("Play") || note.formatLyricsEntries.contains("Play...")) {
|
|
@@ -161,6 +183,10 @@ export default defineComponent({
|
|
|
// console.log(note.measureOpenIndex, item.measureOpenIndex, note);
|
|
|
// console.log("skip", skip)
|
|
|
// console.log(end,start,rate,noteRate, '评测')
|
|
|
+ if (note.measureOpenIndex != recordMeasure) {
|
|
|
+ measureIndex++
|
|
|
+ recordMeasure = note.measureOpenIndex
|
|
|
+ }
|
|
|
const data = {
|
|
|
timeStamp: (start * 1000) / rate,
|
|
|
duration: ((end * 1000) / rate - (start * 1000) / rate) * noteRate,
|
|
@@ -168,23 +194,27 @@ export default defineComponent({
|
|
|
nextFrequency: item.nextFrequency,
|
|
|
prevFrequency: item.prevFrequency,
|
|
|
// 重复的情况index会自然累加,render的index是谱面渲染的index
|
|
|
- measureIndex: note.measureOpenIndex,
|
|
|
+ measureIndex: measureIndex,
|
|
|
measureRenderIndex: item.measureListIndex,
|
|
|
dontEvaluating: ListenMode || dontEvaluatingMode || item.skipMode,
|
|
|
- musicalNotesIndex: item.i,
|
|
|
+ musicalNotesIndex: index,
|
|
|
denominator: note.noteElement?.Length.denominator,
|
|
|
isOrnament: !!note?.voiceEntry?.ornamentContainer,
|
|
|
};
|
|
|
datas.push(data);
|
|
|
}
|
|
|
- return datas;
|
|
|
+ return {
|
|
|
+ datas,
|
|
|
+ firstNoteTime
|
|
|
+ }
|
|
|
};
|
|
|
/** 连接websocket */
|
|
|
const handleConnect = async () => {
|
|
|
const behaviorId = localStorage.getItem("behaviorId") || undefined;
|
|
|
const rate = state.speed / state.originSpeed;
|
|
|
+ calculateInfo = formatTimes()
|
|
|
const content = {
|
|
|
- musicXmlInfos: formatTimes(),
|
|
|
+ musicXmlInfos: calculateInfo.datas,
|
|
|
subjectId: state.subjectId,
|
|
|
detailId: state.detailId,
|
|
|
examSongId: state.examSongId,
|
|
@@ -231,7 +261,7 @@ export default defineComponent({
|
|
|
handleStartEvaluat();
|
|
|
} else if (type === "tryagain") {
|
|
|
// 再来一次
|
|
|
- handleStartBegin();
|
|
|
+ startBtnHandle()
|
|
|
}
|
|
|
evaluatingData.resulstMode = false;
|
|
|
};
|
|
@@ -270,7 +300,7 @@ export default defineComponent({
|
|
|
|
|
|
const startBtnHandle = () => {
|
|
|
handleConnect();
|
|
|
- handleStartBegin();
|
|
|
+ handleStartBegin(calculateInfo.firstNoteTime);
|
|
|
}
|
|
|
onMounted(() => {
|
|
|
evaluatingData.isDisabledPlayMusic = true;
|