| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- import { reactive } from 'vue';
- import tockAndTick from './tockAndTick.json';
- import { Howl } from 'howler';
- import { initSelectScorePart, initSelectScorePartModal, setting, setting_modal } from './setting';
- import { beatDesc } from './beat-desc';
- const tickData = reactive({
- list: [] as number[],
- len: 0, // 有几拍
- afterBeat: 0, // 一小节里面有几拍
- tickEnd: false,
- /** 节拍器时间 */
- beatLengthInMilliseconds: 0,
- state: '',
- source1: '' as any,
- source2: '' as any,
- index: 0,
- show: false
- });
- // console.log(setting, 'setting')
- let defaultSetting = {
- // playState: setting.playState,
- // speed: setting.speed,
- // scorePart: setting.scorePart
- } as any
- let diffTime = 0; // 每一次节拍时间差
- const handlePlay = (i: number, source: any) => {
- let payBeatTime = new Date().getTime();
- return new Promise(resolve => {
- if (tickData.tickEnd) {
- resolve(i);
- return;
- }
- let timeSppedEnum = 16.7;
- const proofTime = () => {
- if (defaultSetting.playState !== 'play') {
- return;
- }
- setTimeout(() => {
- if (tickData.tickEnd) {
- resolve(i);
- return;
- }
- const currentTime = new Date().getTime();
- // 两次定时任务时间间隔
- const diffTime = currentTime - payBeatTime;
- if (diffTime >= tickData.beatLengthInMilliseconds) {
- tickData.index++;
- if (source) source.play();
- resolve(i);
- payBeatTime = currentTime;
- } else {
- if (
- Math.abs(diffTime - tickData.beatLengthInMilliseconds) <=
- timeSppedEnum
- ) {
- // 为了处理最后循环时间,用循环耗时
- for (let index = 0; index < 500000; index++) {
- let forTime = new Date().getTime();
- if (
- Math.abs(forTime - payBeatTime) >=
- tickData.beatLengthInMilliseconds
- ) {
- tickData.index++;
- if (source) source.play();
- resolve(i);
- payBeatTime = forTime;
- break;
- }
- }
- } else {
- proofTime();
- }
- }
- }, timeSppedEnum);
- };
- proofTime();
- });
- };
- /** 设置节拍器
- * @param beatLengthInMilliseconds 节拍间隔时间
- * @param beat 节拍数
- */
- export const handleInitTick = (
- beatLengthInMilliseconds: number,
- beat: number,
- afterBeat: number
- ) => {
- tickData.state = '';
- tickData.beatLengthInMilliseconds = beatLengthInMilliseconds;
- tickData.len = beat;
- tickData.afterBeat = afterBeat;
- };
- /** 开始节拍器
- * @param {boolean} 是否开启了设置
- */
- export const handleStartTick = async (settingStatus = false) => {
- const tempSetting = settingStatus ? setting_modal : setting
- defaultSetting = {
- playState: tempSetting.playState,
- speed: tempSetting.speed,
- scorePart: tempSetting.scorePart
- }
- tickData.show = true;
- tickData.tickEnd = false;
- if (tickData.state !== 'ok') {
- tickData.source1 = new Howl({
- src: tockAndTick.tick
- });
- tickData.source2 = new Howl({
- src: tockAndTick.tock
- });
- tickData.state = 'ok';
- }
- tickData.index = 0;
- tickData.beatLengthInMilliseconds = (60 / defaultSetting.speed) * 1000;
- if (tickData.afterBeat === 8) {
- tickData.beatLengthInMilliseconds = tickData.beatLengthInMilliseconds * 0.5;
- }
- for (let i = 0; i < defaultSetting.scorePart.length; i++) {
- if (tickData.tickEnd) return false;
- const temp = defaultSetting.scorePart[i];
- let len = temp.length;
- if (tickData.afterBeat === 8) {
- len = tickData.len;
- }
- for (let j = 0; j < len; j++) {
- // 提前结束, 直接放回false
- if (tickData.tickEnd) return false;
- const source =
- j === 0 ? tickData.source1 : j === len ? null : tickData.source2;
- await handlePlay(j, source);
- const tempJ = tickData.afterBeat === 8 ? Math.floor((j <= 0 ? 1 : j) / 3) : j
- if (settingStatus) {
- initSelectScorePartModal(i, tempJ)
- } else {
- initSelectScorePart(i, tempJ);
- }
- defaultSetting.playState = settingStatus ? setting_modal.playState : setting.playState
- if (defaultSetting.playState !== 'play') {
- hendleEndTick(settingStatus)
- }
- }
- }
- // console.log(+new Date() - startTime);
- tickData.show = false;
- handleStartTick(settingStatus);
- return true;
- };
- /** 节拍器暂停
- * @param {boolean} 是否开启了设置
- */
- export const hendleEndTick = (settingStatus = false) => {
- tickData.tickEnd = true;
- // 添加延期是因为播放时定时任务播放最多有16.7毫秒的延迟
- if (settingStatus) {
- initSelectScorePartModal()
- } else {
- initSelectScorePart();
- }
- };
|