如何让网络音频api振荡器发出超过6次的声音

时间:2014-12-25 04:27:01

标签: audio

以下是基本代码:

在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
}

1 个答案:

答案 0 :(得分:0)

确定。我想到了。

我必须将振荡器和增益定义为函数外部的变量,并调用audioContext。

var osc, oscGain

然后是功能。

function playIntervals()

我还想出了如何使用按钮代替笨重的确认窗口;每个按钮都会调用它自己的功能。

我正在使用while(quit = o)循环,但这会产生太多问题。现在整个事情都是用函数完成的。

感谢您的帮助。