Have you ever wanted to pan your sounds in p5.sound.js
through a multichannel speaker environment. Well now you can! 🔈🔈🔈🔈
p5.spatial.js is not meant to replace the p5.3DPanner
class in p5.sound.js
(which is great for creating virtual headphone environments), but rather to allow users of p5.js
to create spatialized sound works using multichannel speaker systems in a web browser.
Combine this library with your p5.js
and p5.sound.js
sketches to create moving and interactive spatialized sound objects with the included p5.AudioSource
class. Connect your sketch to quadraphonic and other non-traditional speaker setups!
Include the library using the CDN link after p5.sound.js
<script src="https://cdn.jsdelivr.net/gh/ogbabydiesal/p5.spatial.js@latest/dist/p5.spatial.js"></script>
Below is a simple example that uses the multichannel audio class, p5.AudioSource
, from p5.spatial.js. A live example can be found here.
Note how the audio node graph follows the same pattern found in p5.sound.js
, where source nodes can be chained to the spatial p5.AudioSource
class using the connect()
method. Calling p5.AudioSource())
with no arguments initializes a quadraphonic panner (with speakers in a clockwise layout). Custom speaker layouts can be defined using a JSON
object that describes the position of each speaker in the system. An example of how these layouts should be formatted is illustrated in the General Usage section below. Calling the move(x, y)
method on the p5.AudioSource
object updates the position of the audio source and evaluates the gain relative to each channel in the speaker layout.
let osc;
let spatSource;
let pos, speed;
function setup() {
createCanvas(100, 100);
pos = createVector(0, 0);
speed = createVector(1, 1.3);
osc = new p5.Oscillator('sine');
osc.disconnect();
/*
Creates a multichannel audio node and connects a sound source to it!
*/
spatSource = new p5.AudioSource();
osc.connect(spatSource);
textAlign(CENTER);
textWrap(WORD);
textSize(10);
}
function draw() {
background(220);
pos.x += speed.x;
pos.y += speed.y;
if (pos.x < 0 || pos.x > width) {
speed.x *= -1;
}
if (pos.y < 0 || pos.y > height) {
speed.y *= -1;
}
//Draw a moving rectangle and attach a sound source to it
rect(pos.x, pos.y, 10, 10);
spatSource.move(pos.x, pos.y);
text('click to start the sound', 0, 20, 100);
}
function mousePressed() {
osc.start();
}
For more examples of the library in use see the p5 editor examples here. Additionally, the dist
folder in this repo contains an example you can start with.
- Configure a multichannel interface as the default system audio output device. (i.e in your Mac or Windows system preferences.)
- Add the
p5.spatial.js
library after thep5.sound.js
andp5.js
core library - (optional) Create a
JSON Object
containing the positions of the virtual speakers in the top of your sketch usingcanvas
coordinates. A standard quad setup in a clockwise channel configuration might look like this for example:
let speakers = {
out_1 : {
x: 0,
y: 0,
w: 10,
h: 10
},
out_2 : {
x: width,
y: 0,
w: 10,
h: 10
},
out_3 : {
x: width,
y: height,
w: 10,
h: 10
},
out_4 : {
x: 0,
y: height,
w: 10,
h: 10
}
}
You don't need to specifiy the widths or heights (w, h) for the speakers but it may be helpful if you are visualizing the sources with rect(x,y,w,h)
for example. By default p5.AudioSource()
defaults to this quad configuration. The custom speaker JSON
object should be defined in the p5 setup function, after createCanvas()
.
- Create a
p5.sound.js
audio node graph and calldisconnect()
on the final node in the chain. We'll connect it to our spatial audio source class in just a moment. - Create a
new p5.AudioSource()
class and optionally, a speaker layout 'object.' The pickup radius of the speakers is determined by the second argument. Your code might look something likeaudioSource_1 = new p5.AudioSource(speakers, 100)
. Additionally you maybe specify a built-in layout. Currently there are three,'quad'
,'octophonic'
. and'5.1'
. Create an octophonic multichannel layout like this:p5.AudioSource('octophonic', 45)
, where 45 adjusts the speaker's pickup radius. - Connect the
p5.sound.js
audio node graph to thep5.AudioSource
oject using the regularconnect()
method. - Call the
move()
method on thep5.AudioSource
object and pass in thex
andy
coordinate of the sound source.p5.AudioSource()
will automatically calculate the loudnesses of your sound source in each speaker based on the proximity of the source to the virtual speakers. - Make sure to call
start()
on any sound making objects in your sketch! - To visualize the speaker layout call the
renderLayout()
andrenderPickup()
methods. See this example for more info.
Do you want to extend or add to the library?
- Clone the repo and run
npm install
to download the dependencies. - Create a new class like the
AudioSource.js
file in thesrc
folder. - Add that exported class to the
app.js
file. - In the root directory use the
npm run build
command to build the library. - The built library will appear in the
dist
folder.
- Separate source and ouput logic so you can treat output channels with indepent effects.
- Allow movement of speaker positions post-setup.
- Create more examples with common speaker setups (8-channel cube, ring, etc...).
- Make 3D examples using the
WebGL
property ofcanvas
. - Create flocking examples 🐥.
- Allow the renderLayout and renderPickup methods to accept rgb values.
- Create method to report positions of speakers for custom layout drawing.
- Create method to draw speaker output numbers
- Signals can modulate source positions
- stereo fall back example