提前感谢您提供任何帮助。我正在玩一个家庭旋转程序生成的音乐应用程序,以便更熟悉JavaScript(我知道之前已经做过但我正在将其他方法弄黑,看看我是否可以开发自己的 )。
我目前正在通过范围滑块确定 beats/minute
,该滑块会触发一个函数来计算 1/16
的正确值, 1/8
, 1/4
, 1/2
和 1/1
备注加上演奏音符和下一个音符之间的间隔为20毫秒。
我有第二个递归函数,然后随机选择一个数组值,该值包含新计算的音符持续时间(以毫秒为单位)并播放确定持续时间的音符。我的问题是新的持续时间值没有动态传递到递归函数(即,更改滑块的值正确地改变音符持续时间变量,但它对正在播放的音符的长度没有影响。)
我传递的内容不正确吗?我错过了一些明显的东西吗?再次感谢您的任何见解。
<!-- BPM Slider -->
<input type="range" min="80" max="180" value="120" step="1" oninput="getBPM(this.value)" onchange="getBPM(this.value)">
</br>
<p id="bpm">120</p>
</br>
<!--- PLAY BUTTON -->
<button type="button" id="toggle" onclick="buttonFunc(), leadOneFunc()">PLAY</button>
<script>
var button = false;
var LeadOneLength = 333;
var quNote = (60000 / 120) - 20;
var eiNote = (60000 / (120 * 2)) - 20;
var siNote = (60000 / (120 * 4)) - 20;
var haNote = (60000 / (120 / 2)) - 20;
var whNote = (60000 / (120 / 4)) - 20;
var noteDur = [siNote, eiNote, quNote, haNote, whNote];
var lead1 = new Audio('tone1.ogg');
/* GET NOTE DURATIONS BSED ON BPM SLIDER INPUT */
function getBPM(bpmVal) {
document.getElementById("bpm").innerHTML = Number(bpmVal);
quNote = (60000 / Number(bpmVal)) - 20;
eiNote = (60000 / (Number(bpmVal) * 2)) - 20;
siNote = (60000 / (Number(bpmVal) * 4)) - 20;
haNote = (60000 / (Number(bpmVal) / 2)) - 20;
whNote = (60000 / (Number(bpmVal) / 2)) - 20;
bpmVal = Number(bpmVal);
}
/* LEAD INSTRUMENT RNG AND PLAY FUNCTION */
function leadOneFunc() {
/* RANDOMIZES DURATION OF SINGLE NOTE BASED ON TEMPO */
var leadOneDur = Math.floor(Math.random() * 5);
leadOneLength = noteDur[leadOneDur];
console.log(noteDur[leadOneDur]);
console.log(quNote);
lead1.pause();
/* IF TOGGLE IS SET TO PLAY, WILL PLAY NOTE FOR GENERATED DURATION AND PITCH AND RECURSE THROUGH FUNCTION RE-RANDOMIZING THE NEXT NOTE */
if(button === true) {
setTimeout(function() {lead1.currentTime = 0; lead1.play();}, 20);
setTimeout(leadOneFunc, leadOneLength);
}
/* IF TOGGLE IS SET TO STOP, WILL PAUSE ALL AUDIO */
else {
lead1.pause();
}
}
/* TOGGLE BUTTON VARIABLE DEFINITION & BUTTON DISPLAY CHANGE*/
function buttonFunc() {
if(button === false) {
button = true;
document.getElementById('toggle').innerHTML = 'STOP';
}
else {
button = false; document.getElementById('toggle').innerHTML = 'PLAY';
}
}
</script>
答案 0 :(得分:0)
问题是函数 getBPM 根本没有改变数组 noteDur 。它设置全局变量,如 quNote ,但更改它们对 noteDur 没有影响。相反,您应该重新填充 noteDur 数组。
通过一些额外的改进,您可以使用此功能:
function getNoteDurations(bpm) {
arr = [];
for (var factor = 4; factor >= 0.25; factor /= 2) {
arr.push((60000 / (bpm * factor)) - 20);
}
return arr;
}
在主脚本中使用如下:
var noteDur = getNoteDurations(120);
并在 getBPM 中调用它:
function getBPM(bpmVal) {
document.getElementById("bpm").textContent = bpmVal;
noteDur = getNoteDurations(+bpmVal);
}