2014-12-25 1 views
0

다음은 기본 코드입니다.웹 오디오 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 
} 
+0

코드를 표시하지 않으면 도움을 드릴 수 없습니다. 코드의 관련 부분을 게시하거나 jsfiddle 또는 유사하게 링크하십시오. –

+0

전체 코드를 추가했습니다. 당신이 도울 수 있기를 바랍니다. –

+0

두 개 이상의 오디오 컨텍스트가 필요하지 않습니다. 모든 오실레이터가 동일한 context.destination에 연결할 수 있도록 전역 범위에서 1 개의 오디오 컨텍스트를 정의해야합니다. 당신이 그것을 시도했지만 작동하지 않는다고 말했지만 많은 오디오 컨텍스트에서 작동하도록하기보다는 1 개의 오디오 컨텍스트를 사용하여 솔루션을 디버깅해야합니다. –

답변

0

좋아. 나는 그것을 알아.

오실레이터와 게인을 함수 외부의 변수로 정의하고 audioContext를 호출해야했습니다.

var osc, oscGain 

다음 함수.

function playIntervals() 

나는 또한 clunky 확인 창 대신 버튼을 사용하는 방법을 알아 냈습니다. 각 버튼은 자신의 기능이라고 부릅니다.

while (quit = o) 루프를 사용하고 있었지만 너무 많은 문제가 발생했습니다. 이제는 함수를 사용하여 모든 작업을 완료했습니다.

도움 주셔서 감사합니다.

관련 문제