1

I have added the feature to control panning of sounds but I cannot get all sound into a single buffer channel. Now I found a project on github https://mdn.github.io/webaudio-examples/stereo-panner-node/ . The main problem int this github project is though it works on almost all devices it only play a single sound. I tried to modify it using queryselectorall for it to work on all noises throughout my website but no luck.

var audioCtx;
var myAudio = document.querySelectorAll("audio");
var panControl = document.querySelector('.panning-control');
var panValue = document.querySelector('.panning-value');

audioCtx = new window.AudioContext();
var panNode = audioCtx.createStereoPanner();
  
  for (var i = 0; i < myAudio.length; i++) 
{
  source = audioCtx.createMediaElementSource(myAudio[i]);
  source.connect(panNode);
}
  panNode.connect(audioCtx.destination);
 
panControl.oninput = function() {
    panNode.pan.value = panControl.value;
    
  }

The above code is my modified code. It pans all audio but it works only for a limited number of devices and especially not on phone. No sound comes from audio when I add the modified code on some devices. Help me add multiple sounds into a single buffer channel so I can add panning function to control all sounds through a single slider/seeker.

Your help would be appreciated.

PRAJ
  • 33
  • 7
  • I think part of the problem is that WebAudio isn't standardised across all browsers. I think the [p5 sound library](https://p5js.org/reference/#/libraries/p5.sound) is great for prototyping it might also be worth while trying out a few of the examples across different browsers to quickly see how implementations differ. – fdcpp Jan 05 '21 at 20:04
  • @fdcpp can you show me how to use p5 sound for my problem to select all sound on page for panning. I have absolutely no idea on this. Also why is the github code working across almost all devices if webaudio is the problem. Just wondering. My guess is queryselectorall is creating the problems bit I cannot find a way around it to select all sounds. – PRAJ Jan 06 '21 at 05:32
  • In all likelihood there will probably be a couple of problems. What I would recommend is splitting this into multiple questions.1. Try `queryselectorall` separate to the audio aspect of the question, does it work as intended. Check the compatibility https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll#browser_compatibility (looks okay so may be another aspect of the code. – fdcpp Jan 06 '21 at 09:56
  • 2. How do you play multiple sounds, either simultaneously or one after each other. Separate that from the panning and any DOM code on the page. – fdcpp Jan 06 '21 at 09:57
  • 3. How do you automate panning, just for a single sound. Separate from the DOM code again. Check how it works across browsers – fdcpp Jan 06 '21 at 09:58
  • 4. Finally join all of the above together. Make sure each individual part works before gluing it together. If a part doesn’t work, boil it down into as simple an example as possible and the. Post a question on SO – fdcpp Jan 06 '21 at 10:01
  • Also, if it doesn’t work on a device provide an is version and browser version. With adequate tagging you should get the right attention – fdcpp Jan 06 '21 at 10:02
  • @fdcpp for the1. I think it works across all browsers. For the 2. I use for loop to add all audio on the webpage using query selector and connect them to pan node and apply panning to all of them. For the 3. I have not made it automatic now for simplicity. Rather I am using the same seeker as in github code link i gave above. Still the problem occurs. Could you plz just take 3 audios for simplicity and connect them to pan node like in GitHub code using JavaScript or p5. I tried different sources across internet but couldn't find any answer. – PRAJ Jan 06 '21 at 10:57
  • Are you looking to have each sound having panning controlled independently of each other, or to have all sounds panned the same way by a single node? – fdcpp Jan 06 '21 at 12:25
  • all sounds in a single node as i tried to do it above in the code – PRAJ Jan 06 '21 at 12:26
  • Just to clarify, you have _n_ sounds which you wish to play simultaneously. You then wish to pan all sounds to the same channel (left or right) by a slider but then also automatically – fdcpp Jan 06 '21 at 12:27
  • right now for the sake of simplicity i am trying to do it via slider butlater when all sounds will start panning on all broswers then i will add a function to automatically move the slider. I just need a script to selct all sounds on a page and pan sounds from left to right or vice versa – PRAJ Jan 06 '21 at 12:30
  • Given that a [PannerNode](https://developer.mozilla.org/en-US/docs/Web/API/PannerNode) accepts only a single input, you have 2 problems to solve. **1.** _How do you sum multiple audio buffers into a single buffer?_ **2.** _How do you control panning of audio?_ You've solved the second part so your question is actually focussed around **1.** . Restate your question and strip out anything to do with panning as that is a separate problem, then you should hopefully receive more attention. – fdcpp Jan 06 '21 at 12:37
  • Also, here are some similar SO questions [merge multiple audio buffer sources](https://stackoverflow.com/questions/13709391/merge-multiple-audio-buffer-sources), [How to play multiple AudioBufferSourceNode synchronized?](https://stackoverflow.com/questions/19846107/how-to-play-multiple-audiobuffersourcenode-synchronized) , [How can I mix multiple stereo signals to one with WebAudio?](https://stackoverflow.com/questions/53684376/how-can-i-mix-multiple-stereo-signals-to-one-with-webaudio) – fdcpp Jan 06 '21 at 12:42
  • [Overlay two audio buffers into one buffer source](https://stackoverflow.com/questions/22135056/overlay-two-audio-buffers-into-one-buffer-source) – fdcpp Jan 06 '21 at 12:42
  • You could also connect multiple sources to the same destination, each source requiring it's own `PannerNode` with all `PannerNode` objects taking their parameters from the same input. Each is a perfectly valid approach – fdcpp Jan 06 '21 at 12:45
  • [Web Audio API: Layout to Achieve Panning for an Arbitrary Number of Sources](https://stackoverflow.com/questions/52152608/web-audio-api-layout-to-achieve-panning-for-an-arbitrary-number-of-sources) – fdcpp Jan 06 '21 at 12:47
  • Yeah i could do that but i have in total 49 sounds in my broswer and more can be added. Wouldn't it be tedious to have each sound have its own panner node. I was looking for a more direct approach. Also i updated the question. Also I loooked into your links i saw them earlier too but i couldn't understand much of how to apply them in my project. I am a little noob in web audio api :) – PRAJ Jan 06 '21 at 12:48
  • I don't see why you could not instantiate an array of PannerNode objects in a `for` loop which is of length `number_of_audio_sources` – fdcpp Jan 06 '21 at 12:50
  • Also, it is fine to be new to the material, but remember the focus of SO is to provide questions and answers that allows the community to help itself. We ideally should whittle this question down to multiple questions with a general application rather than a single question with a very specific application – fdcpp Jan 06 '21 at 12:52
  • Thanks for all the help buddy but i do not understand how to do that in array. Can you give a little demo of 5 such sounds (take any name) and attach them to panner node and createMediaElementSource for them as an **answer** – PRAJ Jan 06 '21 at 12:53
  • In that instance, your question is _how do I make an array in JavaScript_ then _how do I make an array of objects in Javascript_ Again, separate that out from the Audio aspect entirely – fdcpp Jan 06 '21 at 12:54

1 Answers1

1

Thanks for no help guys but just beating around the bush. Btw i found the answer to the question. Hope it helps some other person.

let audioCtx;
const myAudio = document.getElementsByClassName('allmusic');
const myScript = document.querySelector('script');
const panControl = document.querySelector('.panning-control');
const panValue = document.querySelector('.panning-value');


for(let i = 0; i<myAudio.length; i++){
   myAudio[i].addEventListener('play', () => {

  if(!audioCtx) {
    audioCtx = new window.AudioContext();
  }
  let source = audioCtx.createMediaElementSource(myAudio[i]);
  let panNode = audioCtx.createStereoPanner();
  panControl.oninput = function() {
    panNode.pan.value = panControl.value;
    panValue.innerHTML = panControl.value;
  }
  source.connect(panNode);
  panNode.connect(audioCtx.destination);
 });
}

For the panning control

<input class="panning-control" type="range" min="-1" max="1" step="0.1" value="0">

The audio selector will select all audios with class "allmusic". You can also use it as

const myAudio = document.querySelectorAll('audio');

I just added a different way to select all elements for click events Enjoy.

PRAJ
  • 33
  • 7
  • 1
    This is a solid answer. Only recommendation is to provide the accompanying html, maybe even a jsfiddle alongside – fdcpp Jan 06 '21 at 18:58