다음은 기본 코드입니다.웹 오디오 API 오실레이터를 6 번 이상 울리려면 어떻게해야합니까?
html에는 playInterval을 호출하는 버튼이 있습니다.
스크립트에서 나는 4 개의 발진기를 만들고 연결 한 playInterval 스크립트를 가지고 있고, 1 초 동안 2 개의 발진기를 함께 재생하고 0.5 초를 기다렸다가 1 초 동안 두 번째 발진기를 함께 재생합니다.
문제는 6 번 이상 재생할 간격 쌍을 얻을 수 없다는 것입니다. 나는 내가 생각할 수있는 모든 것을 수색하고 시도했다.
나는 함수에서 AudioContext를 가져서는 안된다는 것을 안다. 그래서 그 함수는 6 번 호출되지만, 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
}
코드를 표시하지 않으면 도움을 드릴 수 없습니다. 코드의 관련 부분을 게시하거나 jsfiddle 또는 유사하게 링크하십시오. –
전체 코드를 추가했습니다. 당신이 도울 수 있기를 바랍니다. –
두 개 이상의 오디오 컨텍스트가 필요하지 않습니다. 모든 오실레이터가 동일한 context.destination에 연결할 수 있도록 전역 범위에서 1 개의 오디오 컨텍스트를 정의해야합니다. 당신이 그것을 시도했지만 작동하지 않는다고 말했지만 많은 오디오 컨텍스트에서 작동하도록하기보다는 1 개의 오디오 컨텍스트를 사용하여 솔루션을 디버깅해야합니다. –