|
@@ -14,6 +14,8 @@ import {
|
|
|
OpenSheetMusicDisplay,
|
|
|
} from "/osmd-extended/src";
|
|
|
import { GradualChange, speedInfo } from "./calcSpeed";
|
|
|
+import { beatUnitTo, speedBeatTo } from "/src/helpers/beatConfig"
|
|
|
+
|
|
|
const browserInfo = browser();
|
|
|
dayjs.extend(duration);
|
|
|
|
|
@@ -686,11 +688,19 @@ export const formatXML = (xml: string, xmlUrl?: string): string => {
|
|
|
state.originSpeed = speeds[0] ? speeds[0] : 100;
|
|
|
state.speed = state.originSpeed;
|
|
|
}
|
|
|
+ // 赋值谱面速度节拍器,没有的时候 以后台传入的为准
|
|
|
+ const metronomeXml = xmlParse.getElementsByTagName('metronome')?.[0]
|
|
|
+ const beatUnit = metronomeXml?.getElementsByTagName('beat-unit')?.[0]?.textContent || ''
|
|
|
+ if(beatUnit){
|
|
|
+ const beatUnitDot = metronomeXml?.getElementsByTagName('beat-unit-dot')?.[0]
|
|
|
+ state.speedBeatUnit = beatUnitTo(beatUnit, !!beatUnitDot)
|
|
|
+ }
|
|
|
// 如果谱面和小节都没有打速度,osmd设置的小节速度默认取后台设置的速度
|
|
|
if (speeds.length === 0) {
|
|
|
;(window as any).baseMeasureSpeed = state.originSpeed
|
|
|
} else {
|
|
|
- state.originAudioPlayRate = speeds[0] / state.originSpeed
|
|
|
+ // 当前谱面的速度转为4分音符速度 因为我们速度比例转为4分音符了
|
|
|
+ state.originAudioPlayRate = speedBeatTo({unit:state.speedBeatUnit, speed:speeds[0]}, "1/4") / state.originSpeed
|
|
|
}
|
|
|
console.log('是否是变速的曲子:',hasVaryingSpeed,speeds)
|
|
|
|
|
@@ -853,6 +863,7 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
|
|
|
let preNoteEndTime = 0; // 上一个音符的结束时间
|
|
|
|
|
|
let preNoteMeasureNumber: any = null; // 上一个小节的number值
|
|
|
+ let currentRealTempo: any = {}; // 当前小节的速度与拍号信息
|
|
|
|
|
|
const _notes = [] as any[];
|
|
|
if (state.gradualTimes) {
|
|
@@ -966,13 +977,20 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
|
|
|
}
|
|
|
note.maxNoteNum = maxNoteNum;
|
|
|
note.trackIndex = minIndex;
|
|
|
+ currentRealTempo = iterator.currentMeasure.tempoExpressions.length ? iterator.currentMeasure.tempoExpressions.find((item: any) => item?.InstantaneousTempo?.isMetronomeMark)?.InstantaneousTempo || currentRealTempo : currentRealTempo;
|
|
|
+ const { beatUnit="quarter", dotted=false, tempoInBpm=state.originSpeed } = currentRealTempo
|
|
|
+ const speedBeatUnit = beatUnitTo(beatUnit, dotted)
|
|
|
_notes.push({
|
|
|
note,
|
|
|
iterator: { ...iterator },
|
|
|
currentTime,
|
|
|
isDouble,
|
|
|
isMutileSubject,
|
|
|
- measuresTempoInBPM: note?.sourceMeasure?.tempoInBPM
|
|
|
+ // measuresTempoInBPM: note?.sourceMeasure?.tempoInBPM,
|
|
|
+ // 转换成1/4拍的速度
|
|
|
+ measuresTempoInBPM: speedBeatTo({unit: speedBeatUnit || "1/4",speed: tempoInBpm || 0}, `1/4`),
|
|
|
+ speedBeatUnit, // 当前谱面小节的速度对应的是几分音符
|
|
|
+ currentRealTempo
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -990,7 +1008,7 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
|
|
|
console.log('变速曲子',hasVaryingSpeed, _notes)
|
|
|
let noteIds: any = [];
|
|
|
// let voicesBBox: any = null;
|
|
|
- for (let { note, iterator, currentTime, isDouble, isMutileSubject } of _notes) {
|
|
|
+ for (let { note, iterator, currentTime, isDouble, isMutileSubject, speedBeatUnit, measuresTempoInBPM } of _notes) {
|
|
|
if (note) {
|
|
|
if (preMeasureNumber != note?.sourceMeasure?.MeasureNumberXML) {
|
|
|
si = 0
|
|
@@ -999,14 +1017,14 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
|
|
|
preMeasureNumber = note?.sourceMeasure?.MeasureNumberXML
|
|
|
allMeasures.push(note.sourceMeasure);
|
|
|
}
|
|
|
- if (si === 0 && state.isSpecialBookCategory) {
|
|
|
- for (const expression of (note.sourceMeasure as SourceMeasure)?.TempoExpressions) {
|
|
|
- if (expression?.InstantaneousTempo?.beatUnit) {
|
|
|
- // 取最后一个有效的tempo
|
|
|
- beatUnit = expression.InstantaneousTempo.beatUnit;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ // if (si === 0 && state.isSpecialBookCategory) {
|
|
|
+ // for (const expression of (note.sourceMeasure as SourceMeasure)?.TempoExpressions) {
|
|
|
+ // if (expression?.InstantaneousTempo?.beatUnit) {
|
|
|
+ // // 取最后一个有效的tempo
|
|
|
+ // beatUnit = expression.InstantaneousTempo.beatUnit;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
// 判断是否是同一小节
|
|
|
if (staveIndex == note.sourceMeasure?.MeasureNumberXML && i !== 0) {
|
|
|
staveNoteIndex++
|
|
@@ -1098,12 +1116,15 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
|
|
|
|
|
|
let beatSpeed = 0;
|
|
|
// 速度不能为0 此处的速度应该是按照设置的速度而不是校准后的速度,否则mp3速度不对
|
|
|
- if (measureSpeed !== baseSpeed && !hasVaryingSpeed) {
|
|
|
- beatSpeed = baseSpeed || measureSpeed || 100
|
|
|
- } else {
|
|
|
- beatSpeed = (state.isSpecialBookCategory ? measureSpeed : baseSpeed) || 1;
|
|
|
- }
|
|
|
+ // if (measureSpeed !== baseSpeed && !hasVaryingSpeed) {
|
|
|
+ // beatSpeed = baseSpeed || measureSpeed || 100
|
|
|
+ // } else {
|
|
|
+ // beatSpeed = (state.isSpecialBookCategory ? measureSpeed : baseSpeed) || 1;
|
|
|
+ // }
|
|
|
+ // 计算音符时值,使用转换成1/4的速度计算
|
|
|
+ beatSpeed = measuresTempoInBPM;
|
|
|
// let beatSpeed = measureSpeed || baseSpeed
|
|
|
+ beatSpeed = beatSpeed / state.originAudioPlayRate;
|
|
|
// 如果有节拍器,需要将节拍器的时间算出来
|
|
|
if (i === 0) {
|
|
|
if(state.isOpenMetronome){
|
|
@@ -1116,7 +1137,7 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
|
|
|
}
|
|
|
// console.log(getTimeByBeatUnit(beatUnit, measureSpeed, iterator.currentMeasure.activeTimeSignature.Denominator))
|
|
|
let gradualLength = 0;
|
|
|
- let speed = (state.isSpecialBookCategory ? measureSpeed : baseSpeed) || 1;
|
|
|
+ let speed = measureSpeed ? measureSpeed : baseSpeed;
|
|
|
gradualChange = iterator.currentMeasure.speedInfo || gradualChange;
|
|
|
gradualSpeed = osmd.Sheet.SoundTempos?.get(note.sourceMeasure.measureListIndex) || gradualSpeed;
|
|
|
if (!gradualSpeed || gradualSpeed.length < 2) {
|
|
@@ -1411,7 +1432,8 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
|
|
|
firstVerticalMeasure: activeVerticalMeasureList[0],
|
|
|
noteLength: 1,
|
|
|
osdmContext: osmd,
|
|
|
- speedbeatUnit: beatUnit,
|
|
|
+ // speedbeatUnit: beatUnit,
|
|
|
+ speedBeatUnit,
|
|
|
multipleRestMeasures: multipleRestMeasures, // 当前合并小节的索引,从1开始到当前的totalMultipleRestMeasures结束,
|
|
|
totalMultipleRestMeasures, // 当前小节总的合并小节数
|
|
|
measureSpeed, // 小节速度
|