以下是基本代码:
在html中我有一个调用playInterval的按钮。
在脚本中我有playInterval脚本,它创建并连接四个振荡器,然后一起播放两个振荡器1秒,等待0.5秒,并将第二个两个振荡器一起播放1秒。
问题是,我不能让间隔对发挥超过6次。我搜索并尝试了我能想到的一切。我知道我不应该在函数中使用AudioContext - 这就是为什么它被调用六次+,但是如果我从函数中取出AudioContext声明它就不起作用。
我知道必须有一个简单的解决方案。任何帮助将不胜感激。
以下代码适用于前两个级别。 此外,我不得不在确认窗口中伪造一个按钮选项,因为我无法弄清楚如何使用常规按钮。
注意:这是在Chrome中测试的。
HTML:
<table border="1" cellspacing ="10" align = "left">
<tr align = "right">
<td>Testing Beat Speed Difference Sensitivity (BSDS) of:</td>
<td align = "left" id ="beatSpeedDifference"></td>
</tr>
<tr align = "right">
<td>Current level (out of 13 levels):</td>
<td align = "left" id ="currentLevel"></td>
</tr>
<tr align = "right">
<td>Consecutive correct answers at this BSDS:</td>
<td align = "left" id ="curConCorrect"></td>
</tr>
</table>
SCRIPT:
// define and assign variables
var faster = [447.5, 447, 446.5, 446, 445.75, 445.63, 445.5, 445.4, 445.3, 445.25, 445.2, 445.15, 445.1];
var slower = [436.67, 436.43, 436.15, 435.83, 435.65, 435.56, 435.45, 435.37, 435.28, 435.24, 435.19, 435.15, 435.1];
var bsd = [0.5, 0.4, 0.3, 0.2, 0.15, 0.13, 0.1, 0.08, 0.06, 0.05, 0.04, 0.03, 0.02];
var passed = [0,0,0,0,0,0,0,0,0,0,0,0,0];
var conCorrect = 0; //concurrent correct answers
var level = 0;
var setup = 0;
var quit = 0;
var playing = 0;
var pitch;
var choice = "empty";
moveableA440 = 440;
document.getElementById("beatSpeedDifference").innerHTML = bsd[level]*100 + "%";
document.getElementById("currentLevel").innerHTML = level + 1;
document.getElementById("curConCorrect").innerHTML = conCorrect;
alert("BEAT SPEED DIFFERENCE SENSIVITY TEST. \n\
You will hear two beat speeds. \n\
The first one will be beating at 5bps. \n\
The second one will be beating faster or slower. \n\
Click OK to accept if the 2nd beat speed is faster.\n\
Click CANCEL if the 2nd beat speed is not faster than the first.");
while (quit === 0) {
//setup chooses a new beat speed if first or previous has been answered
if (setup === 0) {
pitch = getPitch();
if (pitch < 445) { // to elliminate slower BSD sounding flatter
pitch = pitch + 5;
moveableA440 = moveableA440 + 5;
}
setup = 1;
}
//playing plays the two beat speeds once
if (playing === 0) {
playInterval();
playing = 1;
}
//Enter user choice if no choice has been made
if (choice === "empty") {
var r = confirm("OK = Sped Up\n\Cancel = Slowed Down");
if (r === true) {
choice = "faster";
} else {
choice = "slower";
}
}
//Once choice has been made
if (choice !== "empty") { //reset everything for next beat speed
setup = 0; //reset for a new beat speed
playing = 0; //reset to play new beat speed
//Do if correct choice
if (choice === "faster" && pitch > 445 || choice === "slower" && pitch < 445) {
// Stop beats if user selects ok before beats finish
constRef.stop();
moveablePitch.stop();
conCorrect = conCorrect + 1; //Advance and display concurrent correct choices
document.getElementById("curConCorrect").innerHTML = conCorrect;
//Do if three correct answers
if (conCorrect > 2) {
if (passed[level] === 1) { // Do if three correct and has passed this level already
alert("Your Beat Speed Sensitivity is " + bsd[level]*100 + "%");
quit = 1; //stop script
}
// Do if three correct but not passed level yet
conCorrect = 0; //Reset concurrent correct choices
passed[level] = 1;//record level passed
level = level + 1; //advance and display level
document.getElementById("currentLevel").innerHTML = level + 1;
document.getElementById("beatSpeedDifference").innerHTML = bsd[level]*100 + "%";
conCorrect = 0; //reset and display conCorrect
document.getElementById("curConCorrect").innerHTML = conCorrect;
if (level > 12) {// No more levels
alert("Your Beat Speed Sensitivity is " + bsd[12]*100 + "%");
quit = 1;
}
};
} else { //Do if choice is wrong
// Stop beats if user selects ok before beats finish
constRef.stop();
moveablePitch.stop();
level = level - 1;
if (level < 0) {
alert("Your Beat Speed Sensitivity is " + bsd[0]*100 + "%");
quit = 1;
}
document.getElementById("currentLevel").innerHTML = level + 1;
document.getElementById("beatSpeedDifference").innerHTML = bsd[level]*100 + "%";
conCorrect = 0; //reset and display conCorrect
document.getElementById("curConCorrect").innerHTML = conCorrect;
}
choice = "empty" //reset choice
}
}
var r = confirm("Play Again?");
if (r === true) {
window.location.reload()
} else {
alert("Thanks for playing.\n\Please subscribe to howtotunepianos.com");
}
//Functions
function getPitch() {
var coin = Math.random();
if (coin > 0.5) {
return faster[level];
} else {
return slower[level];
}
}
function playInterval() {
context = new webkitAudioContext();
// Create oscillators
constRef = context.createOscillator();
moveablePitch = context.createOscillator();
a440 = context.createOscillator();
a445 = context.createOscillator();
// Connect to output
constRef.connect(context.destination);
moveablePitch.connect(context.destination);
a440.connect(context.destination);
a445.connect(context.destination);
// Define values for oscillators
constRef.type = "sine";
constRef.frequency.value = moveableA440;
moveablePitch.type = "sine";
moveablePitch.frequency.value = pitch;
a440.type = "sine";
a440.frequency.value = 440;
a445.type = "sine";
a445.frequency.value = 445;
// Play
a440.start(0);
a445.start(0);
a440.stop(1);
a445.stop(1);
constRef.start(1);
moveablePitch.start(1);
constRef.stop(2);
moveablePitch.stop(2);
moveableA440 = 440;// reset
}
答案 0 :(得分:0)
确定。我想到了。
我必须将振荡器和增益定义为函数外部的变量,并调用audioContext。
var osc, oscGain
然后是功能。
function playIntervals()
我还想出了如何使用按钮代替笨重的确认窗口;每个按钮都会调用它自己的功能。
我正在使用while(quit = o)循环,但这会产生太多问题。现在整个事情都是用函数完成的。
感谢您的帮助。