setTimeout延迟,设置为0时约为100ms

问题描述 投票:1回答:1

作为一个个人项目,我正在尝试使用p5.js,Web Midi Api和Web Audio Font复制钢琴卷(如DAW中的钢琴卷)。在实现播放功能时,我首先使用while循环进行了播放,但是我意识到由于javascript是单线程,所以无法停止播放曲目。因此,我尝试使用此代码递归播放音符:

function playTrackRecursively(id) {
  var delay = 0;
  isTrackPlaying = true;
  playNote(mainTrack[id][0], 0);
  if (id < mainTrack.length - 1 && isTrackPlaying){
    delay = mainTrack[id + 1][1] - mainTrack[id][1];
    recursiveID = setTimeout(function() {
      playTrackRecursively(id + 1);
    }, delay * 1000);
  }
  isTrackPlaying = false;
}

它工作正常,但是当我尝试同时演奏多个音符时,它们彼此接连播放,大约延迟100毫秒。

我该怎么办?谢谢。

javascript web-audio-api p5.js
1个回答
2
投票

我在评论中通过@ user120242找到了解决方案。

所以这只是我的两种解决方案之间的混合。我以递归方式遍历曲目中的每个时间戳,并且每次以阵列的形式获取所有从此处开始的音符时,我都会一一播放(其速度足以使人产生同时感的幻觉)。所以尽管我读了什么,的确有可能。

这里是代码:

function playTrackRecursively(id) {
  var delay = 0;
  isTrackPlaying = true;
  var notesBatch = getNotesOfSameStartTime(mainTrack[id][1]);
  playNotesInBatch(notesBatch);
  if (id + notesBatch.length < mainTrack.length && isTrackPlaying){
    delay = mainTrack[id + notesBatch.length][1] - mainTrack[id][1];
    recursiveID = setTimeout(function() {
      playTrackRecursively(id + notesBatch.length);
    }, delay * 1000);
  }
}

function playNotesInBatch(notes) {
  for (var i = 0; i < notes.length; i++) {
    playNote(notes[i][0], notes[i][1]);
  }
}

function getNotesOfSameStartTime(startTime) {
  var indexArray = []
  for (var i = 0; i < mainTrack.length; i++) {
    if (mainTrack[i][1] == startTime) {
      indexArray.push(i);
    }
  }
  var batch = mainTrack.slice(indexArray[0], indexArray[indexArray.length - 1] + 1);
  return batch;
}
© www.soinside.com 2019 - 2024. All rights reserved.