简体   繁体   English

Web Audio API的音量控制和缓冲问题

[英]Volume controls and buffering issues with Web Audio API

I'm running into some issues writing an app using the Web Audio API. 我在使用Web Audio API编写应用程序时遇到了一些问题。

I'm trying to play multiple sounds with Web Audio API, each with an individual volume control and able to have multiple different sounds playing at once., but I can't figure out how to implement it. 我正在尝试使用Web Audio API播放多种声音,每种声音都有一个单独的音量控制,并且可以同时播放多种不同的声音。但我无法弄清楚如何实现它。

I can figure out how to implement a universal volume control, but would like to be able to increase/decrease individual sounds. 我可以弄清楚如何实现通用音量控制,但希望能够增加/减少单个声音。 I am also having the issue that when I have multiple sounds playing, I can't seem to stop them all.. one sounds seems to always get stuck somewhere. 我也有这样的问题,当我有多个声音播放时,我似乎无法阻止它们......一个声音似乎总是卡在某个地方。

Any advise on how to update the below code would be greatly appreciated. 任何有关如何更新以下代码的建议将不胜感激。

    <head> 
    <meta charset="UTF-8">
    <link rel="stylesheet" href="css/loopy_styles.css" />
    <script>
        context = new (window.AudioContext || window.webkitAudioContext)();

        //We set up an array of buffers to store our sounds in, with an extra entry as dummy '0' entry
        var soundBuffers = [null,null,null,null,null,null];

        //We load our sounds into the buffer when the page is opened.
        window.onload = function() {
          loadSound('sounds/fire_test1.wav', 1);
          loadSound('sounds/wind_test.wav', 2);
          loadSound('sounds/rain_test1.wav', 3);
          loadSound('sounds/stream.mp3', 4);
          loadSound('sounds/spring_test.wav', 5);
        };


        var currentlyPlayingSoundNum = 0;
        var currentlyPlayingSound = null;

        //Function to play sound, take in a number to represent each sound icon.
        function play_sound(num){
          if (num) {
            //Shows the paused version of button, hides the play version of the button.
            document.getElementById('playBtn'+num+'_play').style.display = 'none';
            document.getElementById('playBtn'+num+'_stop').style.display = 'block';
            //Sets the currently playing sound to the number supplied to the function.
            currentlyPlayingSoundNum = num;
            //Creates buffer for sound.
            currentlyPlayingSound = context.createBufferSource();
            //Sets the sound to loop continuously so we have seemless play-back.
            currentlyPlayingSound.looping = true;
            //Sends the sound at spot num in our buffer array to the buffer for our currently playing sound.
            currentlyPlayingSound.buffer = soundBuffers[num];
            currentlyPlayingSound.connect(context.destination);
            //Start playing the sound.
            currentlyPlayingSound.start(0);
          }
        }
        //Function to stop sound, take in a number to represent each sound icon.
        function stop_sound(num){
          if(num){
            document.getElementById('playBtn'+num+'_play').style.display = 'block';
            document.getElementById('playBtn'+num+'_stop').style.display = 'none';
          }
          if (currentlyPlayingSound) {
            //Shows the play version of button, hides the paused version of the button.
            document.getElementById('playBtn'+currentlyPlayingSoundNum+'_play').style.display = 'block';
            document.getElementById('playBtn'+currentlyPlayingSoundNum+'_stop').style.display = 'none';
            //Stops playing the currently playing sound.
            currentlyPlayingSound.stop(0);
            currentlyPlayingSound = null;
            currentlyPlayingSoundNumber = 0;
          }
        }
        function loadSound(url, bufferNum) {
          var request = new XMLHttpRequest();
          request.open('GET', url, true);
          request.responseType = 'arraybuffer';

          request.onload = function() {
            var successCallback = function(buffer) {
              soundBuffers[bufferNum] = buffer;
            }
            var errorCallback = function(e) {
              console.log(e);
            }
            context.decodeAudioData(request.response, successCallback, errorCallback);
          }
          request.send();
        }
    </script>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <title>Ambient Sound Generator</title>  
  </head>
<body>
<div class="background">
  <div id="intro-text">
    <h1 id="site-title">Ambient Sound Generator</h1>
    <p>Mix ambient sounds together to block out distractions and help you focus or relax</p>
    <p>Click the buttons below to begin</p>
  </div>
  <div id="button-container">
    <div id="btn1">
      <input type="image" class="pp_img" src="img/fire-pause.png" name="Fire" id="playBtn1_play" onclick="play_sound(1);"   />
      <input type="image" class="pp_img" src="img/fire-play.png" name="Fire" id="playBtn1_stop" onclick="stop_sound(1);" style="display:none"   />
      <p><input type="range" min="0" max="100" value="100" onchange="sample.changeVolume();">Volume</p>
    </div>
    <div id="btn2">
      <input type="image" class="pp_img" src="img/wind-pause.png" name="Wind" id="playBtn2_play" onclick="play_sound(2);"  />
      <input type="image" class="pp_img" src="img/wind-play.png" name="Wind" id="playBtn2_stop" onclick="stop_sound(2);" style="display:none" />
      <p><input type="range" min="0" max="100" value="100" onchange="sample.changeVolume();">Volume</p>
    </div>
    <div id="btn3">
      <input type="image" class="pp_img" src="img/rain-pause.png" name="Rain" id="playBtn3_play" onclick="play_sound(3);"/>
      <input type="image" class="pp_img" src="img/rain-play.png" name="Rain" id="playBtn3_stop" onclick="stop_sound(3);" style="display:none"/>
      <p><input type="range" min="0" max="100" value="100" onchange="sample.changeVolume();">Volume</p>
    </div>
    <div id="btn4">
      <input type="image" class="pp_img" src="img/stream-pause.png" name="Stream" id="playBtn4_play" onclick="play_sound(4);"/>
      <input type="image" class="pp_img" src="img/stream-play.png" name="Stream" id="playBtn4_stop" onclick="stop_sound(4);" style="display:none"/>
      <p><input type="range" min="0" max="100" value="100" onchange="sample.changeVolume();">Volume</p>
    </div>
    <div id="btn5">
      <input type="image" class="pp_img" src="img/forest-pause.png" name="Rain" id="playBtn5_play" onclick="play_sound(5);"/>
      <input type="image" class="pp_img" src="img/forest-play.png" name="Rain" id="playBtn5_stop" onclick="stop_sound(5);" style="display:none" />
      <p><input type="range" min="0" max="100" value="100" onchange="sample.changeVolume();">Volume</p>
    </div>
      </div>
    </div>
    </body>
    <script>
      function refreshData(){
        x = 1;  // x = seconds
        var d = new Date()
        var h = d.getHours();
        var m = d.getMinutes();
        var s = d.getSeconds();

        if (h<=9) {h = '0'+h};
        if (m<=9) {m = '0'+m};
        if (s<=9) {s = '0'+s};

        var color = '#'+h+m+s;

          $("div.background").css("background-color", color );
          $("p#hex").text(color);
          setTimeout(refreshData, x*1000);
      }
      refreshData(); // execute function
    </script>

Instead of 代替

currentlyPlayingSound.connect(context.destination);

You just need to create another GainNode and chain it in: 您只需要创建另一个GainNode并将其链接到:

var gain = context.createGain();
gain.gain.value = /*insert your gain variable here */;
currentlyPlayingSound.connect(gain);
gain.connect(context.destination);

You'll probably want to cache the gain node somewhere (so you can have a slider, etc.) 您可能希望在某处缓存增益节点(因此您可以使用滑块等)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM