我正在尝试创建几种不同的乐器,每种乐器都有 1 个或多个小节,所有小节都包含 1 个或多个节拍。
乐器有自己的节奏,单位为 BPM(每分钟节拍)。因此,如果乐器播放其“歌曲”,则以 ms 为单位的长度/持续时间由numberOfMeasuresInInstrument*beatsInSingleMeasure/instrumentTempo*60.0*1000.0
beatsInSingleMeasure 计算,也可以称为 a signature
,因为音乐以 4/4 等单位定义。
我正在尝试循环播放“歌曲”。因此,如果我有多种持续时间不同的乐器,我希望它们同时开始,并演奏到自己的“成绩单”结束,然后等到所有乐器都完成(即最长的乐器持续时间)后再重新开始(这实际上是使每个“成绩单”的持续时间相等,并添加适当数量和速度的休止符以等于最长持续时间的乐器)。所以所有乐器都应该同时开始,并以它们的节奏间隔演奏它们的节拍,我认为这应该由另一个 setInterval() 管理。
这是一个小提琴来说明彼此之间的持续时间。假设第一个乐器演奏 2 秒,第二个演奏 1.6 秒,第三个演奏 1.5 秒。这将使第一个乐器的节拍每 0.66 秒播放一次,第二个乐器的节拍每 0.4 秒播放一次,第三个乐器的节拍每 0.25 秒播放一次。
我应该如何做到这一点?从概念上讲,嵌套间隔对我来说是有意义的,比如每 2 秒开始,并以适当的间隔播放你的节拍数(第一:每 0.66 秒三拍;第二:每 0.4 秒四拍;第三,每 0.25 秒六拍;)。这似乎比试图找出节拍持续时间的 LCD 并以这种方式播放它们更容易,因为我需要跟踪什么是节拍或休息,以及什么是填充物以确保它在 LCD 单元中,在在这种情况下,它是 .25、.4 和 .66 => .01666 秒的 LCD(也是 60Hz 或 1/60 秒)
目前我有以下内容:
//Which beat are we on? first ones are in the negative to allow the 'song'to buffer once through the 'song', required by HTML5 Audio buffer
var beatCounter = 0-(signature*measuresCount-1);
// How many measures?
var measureCounter = 0;
// Are we waiting on another instrument to play, because we haven't reached the maximum play duration
var waitCounter = false;
function calculateWaiting(){
if ( beatCounter*dur == currentInstrumentDuration && currentInstrumentDuration < maxDuration ){
waitCounter = true;
} else {
waitCounter = false;
}
};
//This is the instrument interval
this.animationIntervalID = setInterval((function(self) {
return function() {
//this is the beat interval
this.beatAnimationIntervalID = setInterval((function(self) {
return function() {
//if we have not yet played all the beats and are waiting on the
if (waitCounter == false){
// As long as we are still have beats to play, keep playing
if (beatCounter >= 0 && beatCounter < totalNumberOfBeats) {
//Get all the beats
var beats = $('#measure-rep-'+self.measureRepModel.cid).find('.audio-beat');
// If the beat is selected, ie not a rest....
var selected = self.parentMeasureModel.get('beats').models[beatCounter].get('selected');
//animate it
self.audioAnimate(beats.eq(beatCounter)[0], dur, selected);
}
//Increase the beatCounter until all of the beats have played, then reset the beatCounter
if (beatCounter < (totalNumberOfBeats-1)) {
beatCounter ++;
} else {
beatCounter = 0;
}
calculateWaiting();
} else {
// Waiting until the longest measure is complete
console.log('waiting until the longer instrument is done playing');
}
};
})(this), dur); //dur is the cycle at which every beat should be animating/lasting
};
})(this), maxDuration); //maxDuration is the cycle at which every instrument should be waiting for to repeat
所以这里是较短的版本:
//This is the instrument interval
this.animationIntervalID = setInterval((function(self) {
return function() {
//this is the beat interval
this.beatAnimationIntervalID = setInterval((function(self) {
return function() { ... };
})(this), dur); //dur is the cycle at which every beat should be animating/lasting
};
})(this), maxDuration); //maxDuration is the cycle at which every instrument should be waiting for to repeat
以及我想要完成的线性视觉效果:
//Scroll this window to see it linearly with time
// Let's assume that the first instrument plays for a duration of 2 seconds, the second
// plays for 1.6 s, and the third plays for 1.5 s. That would make the first instruments
// beats play at an interval of every .66s, the second instrument's beats play every
// .4 s, and the third instrument's beats play every .25s.
//
// The LCD of all instrument's beats is .01666s (60 Hz or 1/60th of a second), so it
// should look something like this: P meaning Play the beat, p, meaning the beat still
// being sustained, I meaning the LCD interval, and W meaning waiting
//
// 0s .5s 1s 1.5s 2s
// ^ ^ ^ ^ ^
// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
// 1: PpppppppppppppppppppppppppppppppppppppppPpppppppppppppppppppppppppppppppppppppppPppppppppppppppppppppppppppppppppppppppp
// 2: PpppppppppppppppppppppppPpppppppppppppppppppppppPpppppppppppppppppppppppPpppppppppppppppppppppppWWWWWWWWWWWWWWWWWWWWWWWW
// 3: PppppppppppppppPppppppppppppppPppppppppppppppPppppppppppppppPppppppppppppppPppppppppppppppWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW