20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/pause_soundfile/sketch.js:
--------------------------------------------------------------------------------
1 | // // ====================
2 | // // DEMO: pause sound when the user presses a key, resume on release
3 | // // ====================
4 |
5 | // var soundFile;
6 |
7 | // function preload() {
8 | // // create a SoundFile
9 | // soundFormats('ogg', 'mp3');
10 | // soundFile = loadSound('../_files/Damscray_02');
11 | // }
12 |
13 | // function setup() {
14 | // createCanvas(400, 400);
15 | // background(0, 255, 0);
16 |
17 | // soundFile.loop();
18 | // createP('Press any key to pause. Resume when the key is released');
19 | // }
20 |
21 | // function keyTyped() {
22 | // soundFile.pause();
23 | // background(255, 0, 0);
24 | // }
25 |
26 | // function keyReleased() {
27 | // soundFile.play();
28 | // background(0, 255, 0);
29 | // }
30 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/oscillatorSecondsFromNow/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: change amplitude with fadeTime, and schedule the change to happen in the future.
3 | // */
4 |
5 | // function setup() {
6 | // osc = new p5sound.TriOsc();
7 | // osc.freq(260);
8 | // createP('mousePressed: set amplitude to .7 over the course of .2 seconds');
9 | // createP(
10 | // 'mouseReleased: 1 second fade to 0. Start the fade 0.5 seconds from now'
11 | // );
12 | // }
13 |
14 | // function mousePressed() {
15 | // osc.start();
16 | // // fade amplitude to .7 over the course of .2 seconds
17 | // osc.amp(0.7, 0.002);
18 | // }
19 |
20 | // function mouseReleased() {
21 | // // fade amplitude to zero over the course of 1 second. Start the fade after .5 seconds.
22 | // osc.amp(0, 0.2, 0.5);
23 | // }
24 |
--------------------------------------------------------------------------------
/test/unit/core/version.js:
--------------------------------------------------------------------------------
1 | // suite('Version', function() {
2 | // var myp5sound;
3 |
4 | // setup(function(done) {
5 | // new p5sound(function(p) {
6 | // p.setup = function() {
7 | // myp5sound = p;
8 | // done();
9 | // };
10 | // });
11 | // });
12 |
13 | // teardown(function() {
14 | // myp5sound.remove();
15 | // });
16 |
17 | // test('exists on p5sound object', function() {
18 | // assert.isString(p5sound.VERSION);
19 | // // ensure the string isn't empty
20 | // assert.isTrue(p5sound.VERSION.length > 0);
21 | // });
22 |
23 | // test('exists on instance of p5sound sketch', function() {
24 | // assert.isString(myp5sound.VERSION);
25 | // // ensure the string isn't empty
26 | // assert.isTrue(myp5sound.VERSION.length > 0);
27 | // });
28 | // });
29 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/Reverb_basic/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: Reverb
3 | // */
4 |
5 | // var sound, reverb;
6 |
7 | // function preload() {
8 | // soundFormats('mp3', 'ogg');
9 | // soundFile = loadSound('../_files/Damscray_02');
10 |
11 | // // disconnect the default connection
12 | // // so that we only hear the sound via the reverb.process
13 | // soundFile.disconnect();
14 | // }
15 |
16 | // function setup() {
17 | // createCanvas(720, 100);
18 | // background(0);
19 |
20 | // reverb = new p5sound.Reverb();
21 |
22 | // // sonnects soundFile to reverb with a
23 | // // reverbTime of 6 seconds, decayRate of 0.2%
24 | // reverb.process(soundFile, 6, 0.2);
25 |
26 | // reverb.amp(3); // turn it up!
27 | // }
28 |
29 | // function mousePressed() {
30 | // soundFile.play();
31 | // }
32 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/play_soundfile/sketch.js:
--------------------------------------------------------------------------------
1 | // // ====================
2 | // // DEMO: play a sound when the user presses a key
3 | // // ====================
4 |
5 | // // create a variable for the sound file
6 | // var soundFile;
7 |
8 | // function preload() {
9 | // // create a SoundFile
10 | // soundFile = loadSound(['../_files/beatbox.ogg', '../_files/beatbox.mp3']);
11 | // }
12 |
13 | // function setup() {
14 | // createCanvas(400, 400);
15 | // background(0);
16 |
17 | // createP('Press any key to play the sound');
18 | // }
19 |
20 | // // when a key is pressed...
21 | // function keyPressed() {
22 | // // play the sound file
23 | // soundFile.play();
24 |
25 | // // also make the background yellow
26 | // background(255, 255, 0);
27 | // }
28 |
29 | // function keyReleased() {
30 | // // make the background black again when the key is released
31 | // background(0);
32 | // }
33 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/loadSound_preload/sketch.js:
--------------------------------------------------------------------------------
1 | // // Sound samples from Damscray - "Dancing Tiger",
2 | // // Creative Commons BY-NC-SA
3 |
4 | // function preload() {
5 | // soundFormats('ogg', 'mp3');
6 | // soundFile = loadSound('../_files/Damscray_01');
7 | // }
8 |
9 | // function setup() {
10 | // createCanvas(400, 200);
11 |
12 | // text('File is ready! Click to pause / play.', 50, 10);
13 |
14 | // soundFile.rate(0.8);
15 | // soundFile.reverseBuffer();
16 | // soundFile.loop();
17 |
18 | // peaks = soundFile.getPeaks();
19 | // beginShape();
20 | // for (i = 0; i < peaks.length; i++) {
21 | // vertex(map(i, 0, peaks.length, 0, width), map(peaks[i], -1, 1, height, 0));
22 | // }
23 | // endShape();
24 | // }
25 |
26 | // function mousePressed() {
27 | // if (soundFile.isPlaying()) {
28 | // soundFile.pause();
29 | // } else {
30 | // soundFile.play();
31 | // }
32 | // }
33 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/loadSound_callback/sketch.js:
--------------------------------------------------------------------------------
1 | // // Sound samples from Damscray - "Dancing Tiger",
2 | // // Creative Commons BY-NC-SA
3 |
4 | // function preload() {
5 | // soundFile = loadSound('../_files/Damscray_01', soundReady);
6 | // }
7 |
8 | // function setup() {
9 | // createCanvas(400, 200);
10 | // soundFormats('ogg', 'mp3');
11 | // }
12 |
13 | // function soundReady() {
14 | // soundFile.rate(1.75);
15 | // soundFile.loop();
16 |
17 | // text('File is ready! Click to pause / unpause', 50, 10);
18 |
19 | // // draw the waveform
20 | // peaks = soundFile.getPeaks();
21 | // beginShape();
22 | // for (i = 0; i < peaks.length; i++) {
23 | // vertex(map(i, 0, peaks.length, 0, width), map(peaks[i], -1, 1, height, 0));
24 | // }
25 | // endShape();
26 | // }
27 |
28 | // function mousePressed() {
29 | // if (soundFile.isPlaying()) {
30 | // soundFile.pause();
31 | // } else {
32 | // soundFile.play();
33 | // }
34 | // }
35 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/peakDetect_basic/sketch.js:
--------------------------------------------------------------------------------
1 | // var cnv, soundFile, fft, peakDetect;
2 | // var ellipseWidth = 10;
3 |
4 | // function preload() {
5 | // soundFile = loadSound('../_files/beat.mp3');
6 | // }
7 |
8 | // function setup() {
9 | // cnv = createCanvas(100, 100);
10 |
11 | // fft = new p5sound.FFT();
12 | // peakDetect = new p5sound.PeakDetect();
13 |
14 | // setupSound();
15 | // }
16 |
17 | // function draw() {
18 | // background(0);
19 |
20 | // fft.analyze();
21 | // peakDetect.update(fft);
22 |
23 | // if (peakDetect.isDetected) {
24 | // ellipseWidth = 50;
25 | // } else {
26 | // ellipseWidth *= 0.95;
27 | // }
28 |
29 | // ellipse(width / 2, height / 2, ellipseWidth, ellipseWidth);
30 | // }
31 |
32 | // function setupSound() {
33 | // cnv.mouseClicked(function() {
34 | // if (soundFile.isPlaying()) {
35 | // soundFile.stop();
36 | // } else {
37 | // soundFile.play();
38 | // }
39 | // });
40 | // }
41 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/soundFormats/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * There is no single audio format that is supported by all
3 | // * popular web browsers. Most web browsers support MP3, but
4 | // * some (Firefox, Opera) do not because it is a patented codec.
5 | // *
6 | // * You can ensure file format compatability by including multiple
7 | // * file extensions. Both MP3 and OGG are recommended.
8 | // */
9 |
10 | // var soundFile;
11 |
12 | // function preload() {
13 | // // set the extensions we have included
14 | // soundFormats('mp3', 'ogg');
15 |
16 | // // load either beatbox.mp3 or beatbox.ogg, depending on the browser
17 | // soundFile = loadSound('../_files/beatbox.mp3');
18 | // }
19 |
20 | // function setup() {
21 | // createCanvas(400, 400);
22 | // background(0);
23 | // }
24 |
25 | // function keyPressed() {
26 | // soundFile.play();
27 | // background(255, 255, 0);
28 | // }
29 |
30 | // function keyReleased() {
31 | // background(0);
32 | // }
33 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/oscillator_FMSynth/sketch.js:
--------------------------------------------------------------------------------
1 | // var carrier, modulator;
2 |
3 | // // carrier frequency signal, a p5.Signal
4 | // var carrierFreq;
5 |
6 | // // modulator frequency signal, a p5.Signal
7 | // var modFreq;
8 |
9 | // // output envelope
10 | // var env;
11 |
12 | // function setup() {
13 | // carrier = new p5sound.Oscillator();
14 |
15 | // carrierFreq = new p5sound.Signal(240);
16 | // carrier.freq(carrierFreq);
17 | // carrier.start();
18 |
19 | // env = new p5sound.Env(0.05, 1, 0.5, 0);
20 | // carrier.amp(env);
21 |
22 | // modulator = new p5sound.Oscillator();
23 | // modulator.disconnect();
24 | // modFreq = new p5sound.SignalMult(8);
25 | // modFreq.setInput(carrierFreq);
26 | // modulator.freq(modFreq);
27 | // modulator.start();
28 |
29 | // var m1 = new p5sound.SignalMult();
30 | // m1.setInput(modulator);
31 | // m1.setValue(100);
32 | // }
33 |
34 | // function draw() {
35 | // carrierFreq.fade(mouseX);
36 | // }
37 |
38 | // function mousePressed() {
39 | // env.play();
40 | // }
41 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/playbackRate/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * DEMO
3 | // * - change playback rate of a soundfile based on mouseX position
4 | // * - a negative playback rate will reverse the soundfile, but won't
5 | // * preserve current location of the playhead.
6 | // */
7 |
8 | // // ====================
9 |
10 | // var soundFile;
11 | // var p;
12 |
13 | // function preload() {
14 | // soundFormats('mp3', 'ogg');
15 | // soundFile = loadSound('../_files/Damscray_02');
16 | // }
17 |
18 | // function setup() {
19 | // soundFile.loop(0);
20 | // p = createP();
21 | // }
22 |
23 | // function draw() {
24 | // // map playback rate of a sound file to mouseX position
25 | // var newRate = map(mouseX, 0, 1200, -0.5, 1.5);
26 | // // newRate = constrain(newRate, 0.1, 1.5);
27 | // soundFile.rate(newRate);
28 | // p.html('Playback Rate: ' + newRate.toFixed(3));
29 | // }
30 |
31 | // function keyPressed() {
32 | // var key = keyCode;
33 | // // Spacebar: pause
34 | // if (key === 32) {
35 | // soundFile.pause();
36 | // }
37 | // }
38 |
--------------------------------------------------------------------------------
/.github/config.yml:
--------------------------------------------------------------------------------
1 | # Configuration for welcome - https://github.com/behaviorbot/welcome
2 |
3 | # Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
4 |
5 | # Comment to be posted to on first time issues
6 | newIssueWelcomeComment: >
7 | Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, please make sure to fill out the inputs in the issue forms. Thank you!
8 | # Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
9 |
10 | # Comment to be posted to on PRs from first time contributors in your repository
11 | newPRWelcomeComment: >
12 | 🎉 Thanks for opening this pull request! Please check out our [contributing guidelines](https://github.com/processing/p5sound.js/blob/main/CONTRIBUTING.md) if you haven't already. And be sure to add yourself to the [list of contributors on the readme page](https://github.com/processing/p5sound.js#contributors)!
13 |
14 | # Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
15 |
16 | # Comment to be posted to on pull requests merged by a first time user
17 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
6 | Resolves #[Add issue number here]
7 |
8 | Changes:
9 |
10 |
11 |
12 | Screenshots of the change:
13 |
14 |
15 | #### PR Checklist
16 |
19 |
20 | - [ ] `npm run lint` passes
21 | - [ ] [Inline documentation] is included / updated
22 | - [ ] [Unit tests] are included / updated
23 |
24 | [Inline documentation]: https://github.com/processing/p5.js/blob/main/contributor_docs/inline_documentation.md
25 | [Unit tests]: https://github.com/processing/p5.js/tree/main/contributor_docs#unit-tests
26 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/pan_soundfile/sketch.js:
--------------------------------------------------------------------------------
1 | // // ====================
2 | // // DEMO: play a sound at a random speed/pitch when the ball hits the edge.
3 | // // Pan the sound file left when ball hits left edge and vice versa.
4 | // // ====================
5 |
6 | // var ball;
7 | // var soundFile;
8 |
9 | // function preload() {
10 | // soundFormats('mp3', 'ogg');
11 | // soundFile = loadSound('../_files/drum');
12 | // }
13 |
14 | // function setup() {
15 | // createCanvas(400, 400);
16 |
17 | // soundFile.volume = 0.6;
18 |
19 | // // create the ball
20 | // ball = {
21 | // x: width / 2,
22 | // y: height / 2,
23 | // speed: 7
24 | // };
25 | // }
26 |
27 | // function draw() {
28 | // background(0);
29 |
30 | // ball.x += ball.speed;
31 |
32 | // // when the ball hits the wall...
33 | // if (ball.x > width || ball.x < 0) {
34 | // // map the ball's x location to a panning degree (float between -1.0 and 1.0)
35 | // var panning = map(ball.x, 0, width, -1, 1);
36 | // soundFile.pan(panning);
37 |
38 | // // set a random playback speed for the sound
39 | // var newSpeed = random(1);
40 | // ball.speed = -ball.speed;
41 | // soundFile.rate(newSpeed);
42 |
43 | // // play the sound
44 | // soundFile.play();
45 | // }
46 | // ellipse(ball.x, ball.y, 100, 100);
47 | // }
48 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/outOfPhase/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Tell two sine wave oscillators to start at the same time,
3 | // * 50% out of phase. Phase Cancellation results!
4 | // * Change the phase with the slider.
5 | // */
6 |
7 | // // create a variable for the sound file
8 | // var osc1, osc2, fft;
9 | // var phaseSlider;
10 |
11 | // function setup() {
12 | // createCanvas(800, 400);
13 | // noFill();
14 |
15 | // osc1 = new p5sound.SinOsc();
16 | // osc2 = new p5sound.SinOsc();
17 | // fft = new p5sound.FFT();
18 | // osc1.phase(0.5);
19 | // osc2.phase(0);
20 | // osc1.amp(1);
21 | // osc2.amp(1);
22 | // osc1.start();
23 | // osc2.start();
24 |
25 | // phaseSlider = createSlider(0, 100, 50);
26 | // }
27 |
28 | // function draw() {
29 | // background(30);
30 |
31 | // // analyze the waveform of all sound in the sketch
32 | // waveform = fft.waveform();
33 |
34 | // // draw the shape of the waveform
35 | // stroke(255);
36 | // strokeWeight(10);
37 | // beginShape();
38 | // for (var i = 0; i < waveform.length; i++) {
39 | // var x = map(i, 0, waveform.length, 0, width);
40 | // var y = map(waveform[i], -1, 1, -height / 2, height / 2);
41 | // vertex(x, y + height / 2);
42 | // }
43 | // endShape();
44 |
45 | // var osc1Phase = phaseSlider.value() / 100;
46 | // osc1.phase(osc1Phase);
47 | // }
48 |
--------------------------------------------------------------------------------
/test/reporter/simple.js:
--------------------------------------------------------------------------------
1 | module.exports = function(runner) {
2 | var failures = (runner.failures = []);
3 |
4 | var stats = (runner.stats = {
5 | suites: 0,
6 | tests: 0,
7 | passes: 0,
8 | pending: 0,
9 | failures: 0,
10 | duration: 0,
11 | start: 0,
12 | end: 0
13 | });
14 |
15 | runner.on('start', function() {
16 | console.log('-> start');
17 | stats.start = new Date().getTime();
18 | });
19 |
20 | runner.on('test', function(test) {
21 | stats.tests++;
22 | });
23 |
24 | runner.on('suite', function(suite) {
25 | stats.suites++;
26 | });
27 |
28 | runner.on('suite end', function(suite) {});
29 |
30 | runner.on('pending', function(test) {
31 | stats.pending++;
32 | console.log('? pending: %s', test.fullTitle());
33 | });
34 |
35 | runner.on('pass', function(test) {
36 | stats.passes++;
37 | console.log('-> pass: %s', test.fullTitle());
38 | });
39 |
40 | runner.on('fail', function(test, err) {
41 | stats.failures++;
42 | test.err = err;
43 | failures.push(test);
44 | console.log('!! fail: %s -- error: %s', test.fullTitle(), err.message);
45 | });
46 |
47 | runner.on('end', function() {
48 | stats.end = new Date().getTime();
49 | stats.duration = stats.end - stats.start;
50 | console.log('-> end: %d/%d', stats.passes, stats.passes + stats.failures);
51 | });
52 | };
53 |
--------------------------------------------------------------------------------
/notes.md:
--------------------------------------------------------------------------------
1 | # glossary
2 |
3 | p5.js-sound: original p5.sound library
4 | p5.sound.js: newer p5.sound library
5 |
6 | # 2023 November 06
7 |
8 | status: library builds, documentation builds with mistakes.
9 |
10 | Kenneth Lim has helped me out with how to build the documentation https://github.com/processing/p5.sound.js/issues/63
11 |
12 | over there, it was mentioned that there is a file on the original library at https://github.com/processing/p5.js-sound/blob/ae7a00a802da9346c6474f8fdaf8448a37a6ad58/fragments/before.frag which is the header that the reference of p5.sound.js needs to be able to build the documentation.
13 |
14 | i dived on the the p5.js-sound repo, and this fragment is being used by webpack to build, which i am not using right now to build p5.sound.js, and also on a 7k lines file at https://github.com/processing/p5.js-sound/blob/main/docs/reference/assets/js/reference.js, which is a copy-paste from several libraries, including:
15 |
16 | - https://github.com/jashkenas/underscore
17 | - https://github.com/jashkenas/backbone/
18 | - https://github.com/requirejs/text/
19 | - https://github.com/twitter/typeahead.js
20 |
21 | in particular, these versions:
22 |
23 | - https://github.com/jashkenas/underscore/blob/1.5.2/underscore.js
24 | - https://github.com/jashkenas/backbone/blob/1.1.0/backbone.js
25 | - https://github.com/requirejs/text/blob/2.0.10/text.js
26 | - https://github.com/twitter/typeahead.js/tree/v0.10.2
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.yml:
--------------------------------------------------------------------------------
1 | name: 🌱 New Feature Request
2 | description: This template is for requesting a new feature be added.
3 | labels: [Feature Request]
4 | body:
5 | - type: textarea
6 | attributes:
7 | label: Increasing Access
8 | description: How would this new feature help [increase access](https://github.com/processing/p5.js/blob/main/contributor_docs/access.md) to p5.js? (If you're not sure, you can type "Unsure" here and let others from the community offer their thoughts.)
9 | validations:
10 | required: true
11 | - type: checkboxes
12 | id: sub-area
13 | attributes:
14 | label: Most appropriate sub-area of p5.js?
15 | description: You may select more than one.
16 | options:
17 | - label: Accessibility
18 | - label: Color
19 | - label: Core/Environment/Rendering
20 | - label: Data
21 | - label: DOM
22 | - label: Events
23 | - label: Image
24 | - label: IO
25 | - label: Math
26 | - label: Typography
27 | - label: Utilities
28 | - label: WebGL
29 | - label: Build Process
30 | - label: Unit Testing
31 | - label: Internalization
32 | - label: Friendly Errors
33 | - label: Other (specify if possible)
34 | - type: textarea
35 | attributes:
36 | label: Feature request details
37 | validations:
38 | required: true
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/existing-feature-enhancement.yml:
--------------------------------------------------------------------------------
1 | name: 💡 Existing Feature Enhancement
2 | description: This template is for suggesting an improvement for an existing feature.
3 | labels: [Enhancement]
4 | body:
5 | - type: textarea
6 | attributes:
7 | label: Increasing Access
8 | description: How would this new feature help [increase access](https://github.com/processing/p5.js/blob/main/contributor_docs/access.md) to p5.js? (If you're not sure, you can type "Unsure" here and let others from the community offer their thoughts.)
9 | validations:
10 | required: true
11 | - type: checkboxes
12 | id: sub-area
13 | attributes:
14 | label: Most appropriate sub-area of p5.js?
15 | description: You may select more than one.
16 | options:
17 | - label: Accessibility
18 | - label: Color
19 | - label: Core/Environment/Rendering
20 | - label: Data
21 | - label: DOM
22 | - label: Events
23 | - label: Image
24 | - label: IO
25 | - label: Math
26 | - label: Typography
27 | - label: Utilities
28 | - label: WebGL
29 | - label: Build Process
30 | - label: Unit Testing
31 | - label: Internalization
32 | - label: Friendly Errors
33 | - label: Other (specify if possible)
34 | - type: textarea
35 | attributes:
36 | label: Feature enhancement details
37 | validations:
38 | required: true
39 |
--------------------------------------------------------------------------------
/src/audioWorklet/soundFileProcessor.js:
--------------------------------------------------------------------------------
1 | // import dependencies via preval.require so that they're available as values at compile time
2 | const processorNames = preval.require('./processorNames');
3 | const RingBuffer = preval.require('./ringBuffer').default;
4 | // const processorNames = require('./processorNames');
5 | // const RingBuffer = require('./ringBuffer').default;
6 |
7 | class SoundFileProcessor extends AudioWorkletProcessor {
8 | constructor(options) {
9 | super();
10 |
11 | const processorOptions = options.processorOptions || {};
12 | this.bufferSize = processorOptions.bufferSize || 256;
13 | this.inputRingBuffer = new RingBuffer(this.bufferSize, 1);
14 | this.inputRingBufferArraySequence = [new Float32Array(this.bufferSize)];
15 | }
16 |
17 | process(inputs) {
18 | const input = inputs[0];
19 | // we only care about the first input channel, because that contains the position data
20 | this.inputRingBuffer.push([input[0]]);
21 |
22 | if (this.inputRingBuffer.framesAvailable >= this.bufferSize) {
23 | this.inputRingBuffer.pull(this.inputRingBufferArraySequence);
24 | const inputChannel = this.inputRingBufferArraySequence[0];
25 | const position = inputChannel[inputChannel.length - 1] || 0;
26 |
27 | this.port.postMessage({ name: 'position', position: position });
28 | }
29 |
30 | return true;
31 | }
32 | }
33 |
34 | registerProcessor(processorNames.soundFileProcessor, SoundFileProcessor);
35 |
--------------------------------------------------------------------------------
/src/audioWorklet/index.js:
--------------------------------------------------------------------------------
1 | import p5sound from '../main.js';
2 |
3 | const moduleSources = [
4 | // require('raw-loader!./recorderProcessor').default,
5 | // require('raw-loader!./soundFileProcessor').default
6 | // require('raw-loader!./amplitudeProcessor').default
7 | require('./soundFileProcessor').default
8 | ];
9 |
10 | const ac = p5sound.audioContext;
11 |
12 | let initializedAudioWorklets = false;
13 |
14 | function loadAudioWorkletModules() {
15 | return Promise.all(
16 | moduleSources.map(function (moduleSrc) {
17 | const blob = new Blob([moduleSrc], { type: 'application/javascript' });
18 | const objectURL = URL.createObjectURL(blob);
19 | return (
20 | ac.audioWorklet
21 | .addModule(objectURL)
22 | // in "p5 instance mode," the module may already be registered
23 | .catch(() => Promise.resolve())
24 | );
25 | })
26 | );
27 | }
28 |
29 | p5.prototype.registerMethod('init', function () {
30 | if (initializedAudioWorklets) return;
31 | // ensure that a preload function exists so that p5 will wait for preloads to finish
32 | if (!this.preload && !window.preload) {
33 | this.preload = function () {};
34 | }
35 |
36 | // use p5's preload system to load necessary AudioWorklet modules before setup()
37 | this._incrementPreload();
38 | const onWorkletModulesLoad = function () {
39 | initializedAudioWorklets = true;
40 | this._decrementPreload();
41 | }.bind(this);
42 | loadAudioWorkletModules().then(onWorkletModulesLoad);
43 | });
44 |
--------------------------------------------------------------------------------
/src/errorHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | Helper function to generate an error
3 | with a custom stack trace that points to the sketch
4 | and removes other parts of the stack trace.
5 |
6 | @private
7 | @class customError
8 | @constructor
9 | @param {String} name custom error name
10 | @param {String} errorTrace custom error trace
11 | @param {String} failedPath path to the file that failed to load
12 | @property {String} name custom error name
13 | @property {String} message custom error message
14 | @property {String} stack trace the error back to a line in the user's sketch.
15 | Note: this edits out stack trace within p5.js and p5.sound.
16 | @property {String} originalStack unedited, original stack trace
17 | @property {String} failedPath path to the file that failed to load
18 | @return {Error} returns a custom Error object
19 | */
20 | let CustomError = function (name, errorTrace, failedPath) {
21 | let err = new Error();
22 | let tempStack, splitStack;
23 |
24 | err.name = name;
25 | err.originalStack = err.stack + errorTrace;
26 | tempStack = err.stack + errorTrace;
27 | err.failedPath = failedPath;
28 |
29 | // only print the part of the stack trace that refers to the user code:
30 | splitStack = tempStack.split('\n').filter(function (ln) {
31 | return !ln.match(/(p5.|native code|globalInit)/g);
32 | });
33 | err.stack = splitStack.join('\n');
34 |
35 | return err; // TODO: is this really a constructor?
36 | };
37 | export default CustomError;
38 |
--------------------------------------------------------------------------------
/test/test-minified.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Example Mocha Test
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/waveform/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * DEMO: Draw the waveform of a sound as it plays using p5.FFT.waveform()
3 | // */
4 |
5 | // var soundFile;
6 | // var fft;
7 | // var fftBands = 1024;
8 |
9 | // // Array of amplitude values (0-255) over time.
10 | // var waveform = [];
11 |
12 | // function preload() {
13 | // soundFormats('mp3', 'ogg');
14 | // soundFile = loadSound('../_files/beat');
15 | // }
16 |
17 | // function setup() {
18 | // createCanvas(fftBands, 256);
19 | // noFill();
20 |
21 | // soundFile.loop();
22 |
23 | // /**
24 | // * Create an FFT object.
25 | // * Accepts optional parameters for
26 | // * - Smoothing
27 | // * - Length of the FFT's analyze/waveform array. Must be a power of two between 16 and 1024 (default).
28 | // */
29 | // fft = new p5sound.FFT(0.99, fftBands);
30 |
31 | // p = createP('press any key to pause / play');
32 | // }
33 |
34 | // function draw() {
35 | // background(250);
36 |
37 | // /**
38 | // * Analyze the sound as a waveform (amplitude over time)
39 | // */
40 | // waveform = fft.waveform();
41 |
42 | // // Draw snapshot of the waveform
43 | // beginShape();
44 | // for (var i = 0; i < waveform.length; i++) {
45 | // stroke(5);
46 | // strokeWeight(5);
47 | // vertex(i * 2, map(waveform[i], -1, 1, height, 0));
48 | // }
49 | // endShape();
50 | // }
51 |
52 | // function keyPressed() {
53 | // if (soundFile.isPlaying()) {
54 | // soundFile.pause();
55 | // } else {
56 | // soundFile.play();
57 | // }
58 | // }
59 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "node": true,
4 | "browser": true,
5 | "amd": true,
6 | "es6": true
7 | },
8 | "globals": {
9 | "p5sound": true,
10 | "define": true,
11 | "Float32Array": true,
12 | "Uint8Array": true
13 | },
14 | "root": true,
15 | "extends": ["eslint:recommended"],
16 | "parserOptions": {
17 | "ecmaVersion": 2017,
18 | "sourceType": "module",
19 | "allowImportExportEverywhere": true
20 | },
21 | "rules": {
22 | "no-cond-assign": [2, "except-parens"],
23 | "eqeqeq": ["error", "smart"],
24 | "no-use-before-define": [
25 | 2,
26 | {
27 | "functions": false
28 | }
29 | ],
30 | "new-cap": 0,
31 | "no-caller": 2,
32 | "no-undef": 0,
33 | "no-unused-vars": ["error", { "args": "none" }],
34 | "no-empty": ["error", { "allowEmptyCatch": true }],
35 | "no-console": "off",
36 | "max-len": ["error", {
37 | "code": 80,
38 | "ignoreComments": true,
39 | "ignoreStrings": true,
40 | "ignoreTemplateLiterals": true,
41 | "ignoreRegExpLiterals": true
42 | }],
43 | "indent": ["error", 2, {
44 | "SwitchCase": 1
45 | }],
46 | "semi": ["error", "always"],
47 | "quotes": ["error", "single", {
48 | "avoidEscape": true
49 | }],
50 | "comma-dangle": ["error", "never"],
51 | "object-curly-spacing": ["error", "always"],
52 | "arrow-parens": ["error", "as-needed"],
53 | "linebreak-style": ["error", "unix"],
54 | "no-trailing-spaces": ["error"],
55 | "no-prototype-builtins": "off",
56 | "no-async-promise-executor": "off"
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/DelaySoundFile/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: p5sound.Delay w/ p5sound.SoundFile + p5sound.Amplitude
3 | // * Click the mouse to hear the p5sound.Delay process a sound file.
4 | // * MouseX controls the p5sound.Delay Filter Frequency.
5 | // * MouseY controls both the p5sound.Delay Time and Resonance.
6 | // */
7 |
8 | // var soundFile, analyzer, delay;
9 |
10 | // function preload() {
11 | // soundFormats('ogg', 'mp3');
12 | // soundFile = loadSound('../_files/beatbox.mp3');
13 | // }
14 |
15 | // function setup() {
16 | // createCanvas(710, 400);
17 |
18 | // soundFile.disconnect(); // so we'll only hear delay
19 |
20 | // delay = new p5sound.Delay();
21 | // delay.process(soundFile, 0.12, 0.7, 2300);
22 | // delay.setType('pingPong'); // a stereo effect
23 |
24 | // analyzer = new p5sound.Amplitude();
25 | // }
26 |
27 | // function draw() {
28 | // background(0);
29 |
30 | // // get volume reading from the p5sound.Amplitude analyzer
31 | // var level = analyzer.getLevel();
32 |
33 | // // use level to draw a green rectangle
34 | // var levelHeight = map(level, 0, 0.1, 0, height);
35 | // fill(100, 250, 100);
36 | // rect(0, height, width, -levelHeight);
37 |
38 | // var filterFreq = map(mouseX, 0, width, 60, 15000);
39 | // filterFreq = constrain(filterFreq, 60, 15000);
40 | // var filterRes = map(mouseY, 0, height, 3, 0.01);
41 | // filterRes = constrain(filterRes, 0.01, 3);
42 | // delay.filter(filterFreq, filterRes);
43 | // var delTime = map(mouseY, 0, width, 0.2, 0.01);
44 | // delTime = constrain(delTime, 0.01, 0.2);
45 | // delay.delayTime(delTime);
46 | // }
47 |
48 | // function mousePressed() {
49 | // soundFile.play();
50 | // }
51 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/recordLoops/sketch.js:
--------------------------------------------------------------------------------
1 | // // Example: Record a sound and then play it back.
2 | // // We need p5.AudioIn (mic / sound source), p5.SoundRecorder
3 | // // (records the sound), and a p5.SoundFile (play back).
4 |
5 | // var mic, recorder, myLoop;
6 |
7 | // var state = 0; // mousePress will increment from Record, to Stop, to Play
8 |
9 | // var kick;
10 |
11 | // function preload() {
12 | // // load the kick
13 | // kick = loadSound('../_files/beatbox.mp3');
14 | // }
15 |
16 | // function setup() {
17 | // createCanvas(400, 400);
18 | // background(200);
19 | // fill(0);
20 |
21 | // kick.loop();
22 |
23 | // // create an audio in
24 | // mic = new p5sound.AudioIn();
25 |
26 | // // users must manually enable their browser microphone for recording to work properly!
27 | // mic.start();
28 |
29 | // // create a sound recorder
30 | // recorder = new p5sound.SoundRecorder();
31 |
32 | // // connect the mic to the recorder
33 | // recorder.setInput(mic);
34 |
35 | // // create an empty sound file that we will use to playback the recording
36 | // soundFile = new p5sound.SoundFile();
37 | // }
38 |
39 | // function mousePressed() {
40 | // // use the '.enabled' boolean to make sure user enabled the mic (otherwise we'd record silence)
41 | // if (mic.enabled && !recorder.recording) {
42 | // // Tell recorder to record to a p5.SoundFile which we will use for playback
43 | // var fourBeats = kick.duration() * 4;
44 | // myLoop = new p5sound.SoundFile();
45 | // recorder.record(myLoop, fourBeats, playRecording);
46 | // background(255, 0, 0);
47 | // }
48 | // }
49 |
50 | // function playRecording() {
51 | // myLoop.loop();
52 | // background(0, 255, 0);
53 | // }
54 |
--------------------------------------------------------------------------------
/tasks/build/eslint-samples.js:
--------------------------------------------------------------------------------
1 | // // This file contains the "eslint-samples" task.
2 |
3 | // 'use strict';
4 | // import { magenta } from 'chalk';
5 |
6 | // module.exports = grunt => {
7 | // grunt.registerMultiTask(
8 | // 'eslint-samples',
9 | // 'Validate samples with ESLint',
10 | // async function() {
11 | // const done = this.async();
12 | // const opts = this.options({
13 | // outputFile: false,
14 | // quiet: false,
15 | // maxWarnings: -1,
16 | // envs: ['eslint-samples/p5sound'],
17 | // verbose: true,
18 | // debug: true
19 | // });
20 |
21 | // if (this.filesSrc.length === 0) {
22 | // grunt.log.writeln(magenta('Could not find any files to validate'));
23 | // return true;
24 | // }
25 |
26 | // // need to use require here because we want this to only
27 | // // get loaded after the data file has been created by a
28 | // // prior grunt task
29 | // const sampleLinter = require('../../utils/sample-linter.js');
30 | // const result = await sampleLinter.eslintFiles(opts, this.filesSrc);
31 | // const report = result.report;
32 | // const output = result.output;
33 |
34 | // if (opts.outputFile) {
35 | // grunt.file.write(opts.outputFile, output);
36 | // } else if (output) {
37 | // console.log(output);
38 | // }
39 |
40 | // const tooManyWarnings =
41 | // opts.maxWarnings >= 0 && report.warningCount > opts.maxWarnings;
42 |
43 | // if (report.errorCount === 0 && tooManyWarnings) {
44 | // grunt.warn(
45 | // `ESLint found too many warnings (maximum: ${opts.maxWarnings})`
46 | // );
47 | // }
48 |
49 | // done(report.errorCount === 0);
50 | // }
51 | // );
52 | // };
53 |
--------------------------------------------------------------------------------
/docs/documented-method.js:
--------------------------------------------------------------------------------
1 | // https://github.com/umdjs/umd/blob/main/templates/returnExports.js
2 | (function (root, factory) {
3 | if (typeof define === 'function' && define.amd) {
4 | define([], factory);
5 | } else if (typeof module === 'object' && module.exports) {
6 | module.exports = factory();
7 | } else {
8 | root.DocumentedMethod = factory();
9 | }
10 | }(this, function () {
11 | function extend(target, src) {
12 | Object.keys(src).forEach(function(prop) {
13 | target[prop] = src[prop];
14 | });
15 | return target;
16 | }
17 |
18 | function DocumentedMethod(classitem) {
19 | extend(this, classitem);
20 |
21 | if (this.overloads) {
22 | // Make each overload inherit properties from their parent
23 | // classitem.
24 | this.overloads = this.overloads.map(function(overload) {
25 | return extend(Object.create(this), overload);
26 | }, this);
27 |
28 | if (this.params) {
29 | throw new Error('params for overloaded methods should be undefined');
30 | }
31 |
32 | this.params = this._getMergedParams();
33 | }
34 | }
35 |
36 | DocumentedMethod.prototype = {
37 | // Merge parameters across all overloaded versions of this item.
38 | _getMergedParams: function() {
39 | const paramNames = {};
40 | const params = [];
41 |
42 | this.overloads.forEach(function(overload) {
43 | if (!overload.params) {
44 | return;
45 | }
46 | overload.params.forEach(function(param) {
47 | if (param.name in paramNames) {
48 | return;
49 | }
50 | paramNames[param.name] = param;
51 | params.push(param);
52 | });
53 | });
54 |
55 | return params;
56 | }
57 | };
58 |
59 | return DocumentedMethod;
60 | }));
61 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/record/sketch.js:
--------------------------------------------------------------------------------
1 | // // Example: Record a sound and then play it back.
2 | // // We need p5.AudioIn (mic / sound source), p5.SoundRecorder
3 | // // (records the sound), and a p5.SoundFile (play back).
4 |
5 | // var mic, recorder, soundFile;
6 |
7 | // var state = 0; // mousePress will increment from Record, to Stop, to Play
8 |
9 | // function setup() {
10 | // createCanvas(400, 400);
11 | // background(200);
12 | // fill(0);
13 | // text('Enable mic and click the mouse to begin recording', 20, 20);
14 |
15 | // // create an audio in
16 | // mic = new p5sound.AudioIn();
17 |
18 | // // users must manually enable their browser microphone for recording to work properly!
19 | // mic.start();
20 |
21 | // // create a sound recorder
22 | // recorder = new p5sound.SoundRecorder();
23 |
24 | // // connect the mic to the recorder
25 | // recorder.setInput(mic);
26 |
27 | // // create an empty sound file that we will use to playback the recording
28 | // soundFile = new p5sound.SoundFile();
29 | // }
30 |
31 | // function mousePressed() {
32 | // // use the '.enabled' boolean to make sure user enabled the mic (otherwise we'd record silence)
33 | // if (state === 0 && mic.enabled) {
34 | // // Tell recorder to record to a p5.SoundFile which we will use for playback
35 | // recorder.record(soundFile);
36 |
37 | // background(255, 0, 0);
38 | // text('Recording now! Click to stop.', 20, 20);
39 | // state++;
40 | // } else if (state === 1) {
41 | // recorder.stop(); // stop recorder, and send the result to soundFile
42 |
43 | // background(0, 255, 0);
44 | // text('Recording stopped. Click to play', 20, 20);
45 | // state++;
46 | // } else if (state === 2) {
47 | // soundFile.play(); // play the result!
48 | // }
49 | // }
50 |
--------------------------------------------------------------------------------
/src/audioContext.js:
--------------------------------------------------------------------------------
1 | // import Tone.js dependency
2 | import * as Tone from 'tone';
3 |
4 | // create a new AudioContext from Web Audio API
5 | const audioContext = new window.AudioContext();
6 |
7 | // set the context for Tone.js to be the same as p5.sound.js
8 | Tone.setContext(audioContext);
9 |
10 | /**
11 | *
Returns the Audio Context for this sketch. Useful for users
12 | * who would like to dig deeper into the Web Audio API
14 | * . and the reference for it at
16 | * MDN Web Docs
17 | *
18 | *
Browsers require users to start the audio context
19 | * with a user gesture, such as touchStarted in the example below.
20 | *
21 | * @for p5sound
22 | * @method getAudioContext
23 | * @return {Object} audioContext for this sketch
24 | * @example
25 | * function draw() {
26 | * background(255);
27 | * textAlign(CENTER);
28 | *
29 | * if (getAudioContext().state == 'running') {
30 | * text('audioContext is running', width/2, height/2);
31 | * } else if (getAudioContext().state == 'suspended') {
32 | * text('audio is suspended', width/2, height/2);
33 | * } else if (getAudioContext().state == 'closed') {
34 | * text('audioContext is closed', width/2, height/2);
35 | * }
36 | *
37 | * text('tap or mouse press to change behavior', width/2, height/2 + 20);
38 | *
39 | * function mousePressed() {
40 | * if (getAudioContext().state == 'suspended') {
41 | * getAudioContext().resume();
42 | * } else if (getAudioContext().state == 'running') {
43 | * getAudioContext().suspend();
44 | * }
45 | *
46 | */
47 | export function getAudioContext() {
48 | return audioContext;
49 | }
50 |
51 | export default audioContext;
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/waveform_with_playhead/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * DEMO
3 | // * - find the peaks in an audio file to draw the entire waveform with SoundFile.getPeaks();
4 | // * - draw cursor on a timeline with SoundFile.currentTime() and SoundFile.duration();
5 | // */
6 |
7 | // // ====================
8 |
9 | // var soundFile;
10 |
11 | // var p, peakCount;
12 |
13 | // function preload() {
14 | // soundFormats('ogg', 'mp3');
15 | // soundFile = loadSound('../_files/lucky_dragons');
16 | // }
17 |
18 | // function setup() {
19 | // createCanvas(800, 400);
20 | // soundFile.loop();
21 | // background(0);
22 | // p = createP('peaks to draw: ' + peakCount);
23 | // createP('Press any key to play/pause.');
24 | // }
25 |
26 | // function draw() {
27 | // background(255);
28 |
29 | // peakCount = map(this.mouseY, height, 0, 5, 2000);
30 | // if (peakCount < 8) {
31 | // peakCount = 8;
32 | // }
33 |
34 | // var waveform = soundFile.getPeaks(peakCount);
35 | // fill(0);
36 | // stroke(0);
37 | // strokeWeight(2);
38 | // beginShape();
39 | // for (var i = 0; i < waveform.length; i++) {
40 | // vertex(
41 | // map(i, 0, waveform.length, 0, width),
42 | // map(waveform[i], -1, 1, height, 0)
43 | // );
44 | // }
45 | // endShape();
46 |
47 | // // update display text:
48 | // p.html('MouseY = Visible Amplitude Peaks: ' + peakCount.toFixed(3));
49 |
50 | // drawCursor();
51 | // }
52 |
53 | // function drawCursor() {
54 | // noStroke();
55 | // fill(0, 255, 0);
56 | // rect(
57 | // map(soundFile.currentTime(), 0, soundFile.duration(), 0, width),
58 | // 0,
59 | // 5,
60 | // height
61 | // );
62 | // }
63 |
64 | // // Keyboard Controls
65 | // function keyTyped() {
66 | // if (soundFile.isPlaying()) {
67 | // soundFile.pause();
68 | // } else {
69 | // soundFile.play();
70 | // }
71 | // }
72 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/waveform_peaks_with_playhead/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * DEMO
3 | // * - find the peaks in an audio file to draw the entire waveform with SoundFile.getPeaks();
4 | // * - draw cursor on a timeline with SoundFile.currentTime() and SoundFile.duration();
5 | // */
6 |
7 | // // ====================
8 |
9 | // var soundFile;
10 |
11 | // var p, peakCount;
12 |
13 | // function preload() {
14 | // soundFormats('ogg', 'mp3');
15 | // soundFile = loadSound('../_files/lucky_dragons');
16 | // }
17 |
18 | // function setup() {
19 | // createCanvas(800, 400);
20 | // noFill();
21 |
22 | // soundFile.loop();
23 | // background(0);
24 | // p = createP('peaks to draw: ' + peakCount);
25 | // createP('Press any key to play/pause.');
26 | // }
27 |
28 | // function draw() {
29 | // background(255);
30 |
31 | // peakCount = map(this.mouseY, height, 0, 5, 2000);
32 | // if (peakCount < 8) {
33 | // peakCount = 8;
34 | // }
35 | // var waveform = soundFile.getPeaks(peakCount);
36 | // fill(0);
37 | // stroke(0);
38 | // strokeWeight(2);
39 | // beginShape();
40 | // for (var i = 0; i < waveform.length; i++) {
41 | // vertex(
42 | // map(i, 0, waveform.length, 0, width),
43 | // map(waveform[i], -1, 1, height, 0)
44 | // );
45 | // }
46 | // endShape();
47 |
48 | // // update display text:
49 | // p.html('MouseY = Visible Amplitude Peaks: ' + peakCount.toFixed(3));
50 |
51 | // drawCursor();
52 | // }
53 |
54 | // function drawCursor() {
55 | // noStroke();
56 | // fill(0, 255, 0);
57 | // rect(
58 | // map(soundFile.currentTime(), 0, soundFile.duration(), 0, width),
59 | // 0,
60 | // 5,
61 | // height
62 | // );
63 | // }
64 |
65 | // // Keyboard Controls
66 | // function keyTyped() {
67 | // if (soundFile.isPlaying()) {
68 | // soundFile.pause();
69 | // } else {
70 | // soundFile.play();
71 | // }
72 | // }
73 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/Reverb_convolve/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: Convolution Reverb
3 | // *
4 | // * The p5.Convolver can recreate the sound of actual spaces using convolution.
5 | // *
6 | // * Toggle between five different buffer sources
7 | // *
8 | // * Convolution samples Creative Commons BY recordinghopkins, via freesound.org
9 | // * https://www.freesound.org/people/recordinghopkins/
10 | // */
11 |
12 | // var sound, cVerb;
13 | // var currentIR = 0;
14 | // var p;
15 |
16 | // function preload() {
17 | // // we have included both MP3 and OGG versions of all the impulses/sounds
18 | // soundFormats('ogg', 'mp3');
19 |
20 | // // create a p5.Convolver
21 | // cVerb = createConvolver('../_files/bx-spring');
22 |
23 | // // add Impulse Responses to cVerb.impulses array, in addition to bx-spring
24 | // cVerb.addImpulse('../_files/small-plate');
25 | // cVerb.addImpulse('../_files/drum');
26 | // cVerb.addImpulse('../_files/concrete-tunnel');
27 |
28 | // // load a sound that will be processed by the p5.ConvultionReverb
29 | // sound = loadSound('../_files/Damscray_DancingTiger');
30 | // }
31 |
32 | // function setup() {
33 | // // disconnect from main output...
34 | // sound.disconnect();
35 | // // ... and process with cVerb so that we only hear the reverb
36 | // cVerb.process(sound);
37 |
38 | // createP('Click to play a sound and change the impulse');
39 | // p = createP('');
40 | // }
41 |
42 | // function mousePressed() {
43 | // // cycle through the array of cVerb.impulses
44 | // currentIR++;
45 | // if (currentIR >= cVerb.impulses.length) {
46 | // currentIR = 0;
47 | // }
48 | // cVerb.toggleImpulse(currentIR);
49 |
50 | // // play the sound through the impulse
51 | // sound.play();
52 |
53 | // // display the current Impulse Response name (the filepath)
54 | // p.html('Convolution Impulse Response: ' + cVerb.impulses[currentIR].name);
55 | // }
56 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/soundfile_playMode/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Toggle play mode between 'restart' and 'sustain'.
3 | // * Sustain is the default playmode for SoundFiles
4 | // * Music from Damscray, "Dancing Tiger", Creative Commons BY-NC-SA
5 | // */
6 |
7 | // var playMode = 'sustain';
8 | // var sample1, sample2, button;
9 |
10 | // function preload() {
11 | // sample1 = loadSound([
12 | // '../_files/Damscray_01.ogg',
13 | // '../_files/Damscray_01.mp3'
14 | // ]);
15 | // sample2 = loadSound([
16 | // '../_files/Damscray_02.ogg',
17 | // '../_files/Damscray_02.mp3'
18 | // ]);
19 | // }
20 |
21 | // function setup() {
22 | // createCanvas(0, 0);
23 |
24 | // createP(
25 | // 'Press "a" and "s" on your keyboard to play two different samples. Trigger lots of sounds at once! Change mode to hear the difference'
26 | // );
27 |
28 | // button = createButton('Current Play Mode: ');
29 | // button.mousePressed(togglePlayMode);
30 | // }
31 |
32 | // function draw() {
33 | // button.html('Current Play Mode: ' + playMode);
34 | // }
35 |
36 | // // alternate between 'sustain' and 'restart', and set playMode of both samples
37 | // function togglePlayMode() {
38 | // if (playMode === 'sustain') {
39 | // playMode = 'restart';
40 | // } else {
41 | // playMode = 'sustain';
42 | // }
43 | // sample1.playMode(playMode);
44 | // sample2.playMode(playMode);
45 | // }
46 |
47 | // function keyPressed(k) {
48 | // if (k.keyCode === 65) {
49 | // sample1.play(0, 1, 0.6);
50 |
51 | // // Get even more monophonic by only letting one sample play at a time
52 | // if (playMode === 'restart' && sample2.isPlaying()) {
53 | // sample2.stopAll();
54 | // }
55 | // }
56 | // if (k.keyCode === 83) {
57 | // if (playMode === 'restart' && sample1.isPlaying()) {
58 | // sample1.stopAll();
59 | // }
60 | // sample2.play(0, 1, 0.6);
61 | // }
62 | // }
63 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/envelopeOnOff/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: Create an Envelope (p5sound.Env) to control oscillator amplitude.
3 | // * Trigger the Attack portion of the envelope when the mouse is clicked.
4 | // * Trigger the Release when the mouse is released.
5 | // */
6 |
7 | // var triOsc;
8 | // var env;
9 | // var a;
10 |
11 | // // Times and levels for the ADSR envelope
12 | // var attackTime = 0.001;
13 | // var attackLevel = 0.9;
14 | // var decayTime = 0.25;
15 | // var decayLevel = 0.2;
16 | // var sustainTime = 0.1;
17 | // var sustainLevel = decayLevel;
18 | // var releaseTime = 0.8;
19 | // var duration = 1000;
20 | // // Set the note trigger
21 | // var trigger;
22 |
23 | // // An index to count up the notes
24 | // var note = 0;
25 |
26 | // function setup() {
27 | // createCanvas(600, 600);
28 | // background(255);
29 |
30 | // trigger = millis();
31 |
32 | // triOsc = new p5sound.TriOsc();
33 | // triOsc.freq(220);
34 | // triOsc.start();
35 | // env = new p5sound.Env(
36 | // attackTime,
37 | // attackLevel,
38 | // decayTime,
39 | // decayLevel,
40 | // sustainTime,
41 | // sustainLevel,
42 | // releaseTime
43 | // );
44 | // triOsc.amp(env);
45 | // fill(0);
46 | // createP('click mouse to triggerAttack, release mouse to triggerRelease');
47 |
48 | // a = new p5sound.Amplitude();
49 | // }
50 |
51 | // function draw() {
52 | // var size = 10;
53 | // background(255, 255, 255, 20);
54 | // ellipse(
55 | // map((trigger - millis()) % duration, 1000, 0, 0, width) % width,
56 | // map(a.getLevel(), 0, 0.5, height - size, 0),
57 | // size,
58 | // size
59 | // );
60 | // }
61 |
62 | // function mousePressed() {
63 | // // The envelope gets triggered with the oscillator as input and the times and levels we defined earlier
64 | // env.triggerAttack();
65 | // trigger = millis() + duration;
66 | // }
67 |
68 | // function mouseReleased() {
69 | // env.triggerRelease();
70 | // }
71 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/found-a-bug.yml:
--------------------------------------------------------------------------------
1 | name: 🐛 Found a Bug
2 | description: This template is for reporting bugs (broken or incorrect behaviour). If you have questions about your own code, please visit our forum discourse.processing.org instead.
3 | labels: [Bug]
4 | body:
5 | - type: checkboxes
6 | id: sub-area
7 | attributes:
8 | label: Most appropriate sub-area of p5.sound.js?
9 | description: You may select more than one.
10 | options:
11 | - label: Accessibility
12 | - label: Core/Environment/Rendering
13 | - label: Data
14 | - label: Events
15 | - label: IO
16 | - label: Math
17 | - label: Utilities
18 | - label: Build Process
19 | - label: Unit Testing
20 | - label: Internalization
21 | - label: Friendly Errors
22 | - label: Other (specify if possible)
23 | - type: input
24 | attributes:
25 | label: p5.sound.js version
26 | description: You can find this in the first line of the p5.sound.js file.
27 | validations:
28 | required: false
29 | - type: input
30 | attributes:
31 | label: Web browser and version
32 | description: In the address bar, on Chrome enter "chrome://version", on Firefox enter "about:support". On Safari, use "About Safari".
33 | validations:
34 | required: false
35 | - type: input
36 | attributes:
37 | label: Operating System
38 | description: "Ex: Windows/MacOSX/Linux/Android/iOS along with version"
39 | validations:
40 | required: false
41 | - type: textarea
42 | attributes:
43 | label: Steps to reproduce this
44 | description: Include a simple code snippet that demonstrates the problem, along with any console errors produced. If this isn't possible, then simply describe the issue as best you can!
45 | value: "### Steps:
46 |
47 | 1.
48 |
49 | 2.
50 |
51 | 3.
52 |
53 |
54 | ### Snippet:
55 |
56 |
57 | ```js
58 |
59 |
60 | // Paste your code here :)
61 |
62 |
63 | ```"
64 | validations:
65 | required: true
66 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/DelayNoiseEnvelope/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: p5sound.Delay w/ p5sound.Noise, p5sound.Env & p5sound.Amplitude
3 | // *
4 | // * Click the mouse to hear the p5sound.Delay process a Noise Envelope.
5 | // *
6 | // * MouseX controls the p5sound.Delay Filter Frequency.
7 | // * MouseY controls both the p5sound.Delay Time and Resonance.
8 | // */
9 |
10 | // var noise, env, analyzer, delay;
11 |
12 | // function setup() {
13 | // createCanvas(710, 400);
14 | // noise = new p5sound.Noise('white'); // other types include 'brown' and 'pink'
15 |
16 | // // Turn down because we'll control .amp with a p5sound.Env
17 | // noise.amp(0);
18 |
19 | // noise.start();
20 | // noise.disconnect(); // so we will only hear the p5sound.Delay effect
21 |
22 | // delay = new p5sound.Delay();
23 | // delay.process(noise, 0.12, 0.7, 2300); // tell delay to process noise
24 |
25 | // // the Env accepts time / value pairs to
26 | // // create a series of timed fades
27 | // env = new p5sound.Env(0.01, 1, 0.2, 0.1);
28 |
29 | // // p5sound.Amplitude will analyze all sound in the sketch
30 | // analyzer = new p5sound.Amplitude();
31 | // }
32 |
33 | // function draw() {
34 | // background(0);
35 |
36 | // // get volume reading from the p5sound.Amplitude analyzer
37 | // var level = analyzer.getLevel();
38 | // // then use level to draw a green rectangle
39 | // var levelHeight = map(level, 0, 0.4, 0, height);
40 | // fill(100, 250, 100);
41 | // rect(0, height, width, -levelHeight);
42 |
43 | // // map mouseX and mouseY to p5sound.Delay parameters
44 | // var filterFreq = map(mouseX, 0, width, 60, 15000);
45 | // filterFreq = constrain(filterFreq, 60, 15000);
46 | // var filterRes = map(mouseY, 0, height, 3, 0.01);
47 | // filterRes = constrain(filterRes, 0.01, 3);
48 | // delay.filter(filterFreq, filterRes);
49 | // var delTime = map(mouseY, 0, width, 0.2, 0.01);
50 | // delTime = constrain(delTime, 0.01, 0.2);
51 | // delay.delayTime(delTime);
52 | // }
53 |
54 | // function mousePressed() {
55 | // env.play(noise);
56 | // }
57 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/looper_simple/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Create a sequence using a Part.
3 | // * Add two Phrases to the part, and tell the part to loop.
4 | // *
5 | // * The callback includes parameters (the value at that position in the Phrase array)
6 | // * as well as time, which should be used to schedule playback with precision.
7 | // */
8 |
9 | // var osc, env; // used by playNote
10 | // var noise, noiseEnv; // used by playSnare
11 | // var part; // a part we will loop
12 | // var currentBassNote = 47;
13 |
14 | // function setup() {
15 | // // prepare the osc and env used by playNote()
16 | // env = new p5sound.Env(0.01, 0.8, 0.2, 0);
17 | // osc = new p5sound.TriOsc(); // connects to main output by default
18 | // osc.start(0);
19 | // osc.connect();
20 | // env.setInput(osc);
21 |
22 | // // prepare the noise and env used by playSnare()
23 | // noise = new p5sound.Noise();
24 | // // noise.amp(0.0);
25 | // noise.start();
26 | // noiseEnv = new p5sound.Env(0.01, 0.5, 0.1, 0);
27 | // noiseEnv.setInput(noise);
28 | // // create a part with 8 spaces, where each space represents 1/16th note (default)
29 | // part = new p5sound.Part(8, 1 / 16);
30 |
31 | // // add phrases, with a name, a callback, and
32 | // // an array of values that will be passed to the callback if > 0
33 | // part.addPhrase('snare', playSnare, [0, 0, 1, 0]);
34 | // part.addPhrase('bass', playBass, [47, 42, 45, 47, 45, 42, 40, 42]);
35 |
36 | // // // set tempo (Beats Per Minute) of the part and tell it to loop
37 | // part.setBPM(80);
38 | // part.loop();
39 | // }
40 |
41 | // function playBass(time, params) {
42 | // currentBassNote = params;
43 | // osc.freq(midiToFreq(params), 0, time);
44 | // env.play(osc, time);
45 | // }
46 |
47 | // function playSnare(time, params) {
48 | // noiseEnv.play(noise, time);
49 | // }
50 |
51 | // // draw a ball mapped to current note height
52 | // function draw() {
53 | // background(255);
54 | // fill(255, 0, 0);
55 | // var noteHeight = map(currentBassNote, 40, 50, height, 0);
56 | // ellipse(width / 2, noteHeight, 30, 30);
57 | // }
58 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/PulseFFT/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * PWM
3 | // */
4 | // var freqSlider, freqLabel, ampLabel, ampSlider, widthLabel, widthSlider, button;
5 |
6 | // var pulse;
7 | // var freq = 1; // current frequency (updated by slider)
8 | // var amp = 1.0;
9 | // var w = 0.25;
10 | // var fft;
11 |
12 | // var oscOn = false;
13 |
14 | // function setup() {
15 | // createCanvas(800, 400);
16 | // noFill();
17 |
18 | // widthLabel = createP('Width: ' + w);
19 | // widthSlider = createSlider(0.0, 100.0, w * 100);
20 |
21 | // button = createButton('start');
22 | // button.mousePressed(toggleOsc);
23 |
24 | // freqLabel = createP('Frequency: ');
25 | // freqSlider = createSlider(1, 700, freq);
26 |
27 | // ampLabel = createP('Amplitude: ' + amp);
28 | // ampSlider = createSlider(0.0, 100.0, amp * 100);
29 |
30 | // pulse = new p5sound.Pulse(freq);
31 | // pulse.amp(amp);
32 |
33 | // // create an fft to analyze the audio
34 | // fft = new p5sound.FFT();
35 |
36 | // // begin sound
37 | // toggleOsc();
38 | // }
39 |
40 | // function draw() {
41 | // background(30);
42 |
43 | // amp = ampSlider.value() / 100;
44 | // pulse.amp(amp);
45 | // ampLabel.html('Amplitude: ' + amp + '/ 1.0');
46 |
47 | // freq = freqSlider.value();
48 | // pulse.freq(freq);
49 | // freqLabel.html('Frequency: ' + freq + ' Hz');
50 |
51 | // w = widthSlider.value() / 100;
52 | // pulse.width(w);
53 | // widthLabel.html('Width: ' + w + '/ 1.0');
54 |
55 | // // process the waveform
56 | // waveform = fft.waveform();
57 |
58 | // // draw the shape of the waveform
59 | // stroke(255);
60 | // strokeWeight(10);
61 | // beginShape();
62 | // for (var i = 0; i < waveform.length; i++) {
63 | // var x = map(i, 0, waveform.length, 0, width);
64 | // var y = map(waveform[i], -1, 1, -height / 2, height / 2);
65 | // vertex(x, y + height / 2);
66 | // }
67 | // endShape();
68 | // }
69 |
70 | // function toggleOsc() {
71 | // if (oscOn) {
72 | // pulse.stop();
73 | // button.html('start');
74 | // } else {
75 | // pulse.start();
76 | // button.html('stop');
77 | // }
78 | // oscOn = !oscOn;
79 | // }
80 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/FFT_waveform_2/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * DEMO: Draw the waveform of a sound as it plays using p5sound.FFT.waveform()
3 | // */
4 |
5 | // var soundFile;
6 | // var fft;
7 | // var fftSize = 1024;
8 |
9 | // var xOffset = 0;
10 |
11 | // // Array of amplitude values (0-255) over time. Length will be 1/2 fftSize.
12 | // var waveform = [];
13 |
14 | // function preload() {
15 | // soundFormats('ogg', 'mp3');
16 | // soundFile = loadSound('../_files/lucky_dragons');
17 | // }
18 |
19 | // function setup() {
20 | // createCanvas(fftSize, 400);
21 | // fill(60, 60, 180);
22 | // background(0);
23 |
24 | // // a slower playback rate also lowers the pitch, and with lower frequencies the waveforms are longer
25 | // soundFile.rate(0.2);
26 |
27 | // // loop the sound file
28 | // soundFile.loop();
29 |
30 | // // Create an FFT object. Give it smoothing and fftSize
31 | // fft = new p5sound.FFT(0.99, fftSize);
32 | // createP('Press spacebar to pause');
33 | // }
34 |
35 | // function draw() {
36 | // background(30, 30, 30, frameCount % 40 + 4);
37 |
38 | // /**
39 | // * Analyze the sound as a waveform (amplitude over time)
40 | // */
41 | // if (frameCount % 2 === 0) {
42 | // waveform = fft.waveform();
43 | // }
44 | // // Draw two mirrored snapshots of the waveform
45 | // for (var i = 0; i < waveform.length; i++) {
46 | // noStroke();
47 | // fill(60, 60, 180, waveform[i] % 100);
48 | // ellipse(
49 | // (-(i * 2) % width) / 2 + width / 2 + 1,
50 | // height -
51 | // (map(Math.log(waveform[i]), 0, 10, 0, height) +
52 | // log(i / 2) * waveform[i]) /
53 | // 4,
54 | // waveform[i] / 100,
55 | // waveform[i] * 2
56 | // );
57 | // ellipse(
58 | // ((i * 2) % width) / 2 + width / 2,
59 | // height -
60 | // (map(Math.log(waveform[i]), 0, 10, 0, -height) +
61 | // log(i / 2) * waveform[i]) /
62 | // 4,
63 | // waveform[i] / 100,
64 | // waveform[i] * 2
65 | // );
66 | // }
67 |
68 | // xOffset++;
69 | // }
70 |
71 | // function keyPressed(e) {
72 | // console.log(e);
73 | // if (e.keyCode === 32) {
74 | // soundFile.pause();
75 | // }
76 | // }
77 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/Filter_BandPass/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: Apply a p5.BandPass filter to white noise.
3 | // * Visualize the sound with FFT.
4 | // * Map mouseX to the bandpass frequency
5 | // * and mouseY to resonance/width of the a BandPass filter
6 | // */
7 |
8 | // var description = 'loading';
9 | // var p;
10 | // var noise;
11 | // var fft;
12 | // var filter, filterFreq, filterWidth;
13 |
14 | // function setup() {
15 | // createCanvas(710, 256);
16 | // fill(255, 40, 255);
17 |
18 | // filter = new p5sound.BandPass();
19 |
20 | // noise = new p5sound.Noise();
21 |
22 | // noise.disconnect(); // Disconnect soundfile from main output...
23 | // filter.process(noise); // ...and connect to filter so we'll only hear BandPass.
24 | // noise.start();
25 |
26 | // fft = new p5sound.FFT();
27 |
28 | // // update description text
29 | // p = createP(description);
30 | // var p2 = createP(
31 | // 'Draw the array returned by FFT.analyze( ). This represents the frequency spectrum, from lowest to highest frequencies.'
32 | // );
33 | // }
34 |
35 | // function draw() {
36 | // background(30);
37 |
38 | // // Map mouseX to a bandpass freq from the FFT spectrum range: 10Hz - 22050Hz
39 | // filterFreq = map(mouseX, 0, width, 10, 22050);
40 | // // Map mouseY to resonance/width
41 | // filterWidth = map(mouseY, 0, height, 0, 90);
42 | // // set filter parameters
43 | // filter.set(filterFreq, filterWidth);
44 |
45 | // // Draw every value in the FFT spectrum analysis where
46 | // // x = lowest (10Hz) to highest (22050Hz) frequencies,
47 | // // h = energy / amplitude at that frequency
48 | // var spectrum = fft.analyze();
49 | // noStroke();
50 | // for (var i = 0; i < spectrum.length; i++) {
51 | // var x = map(i, 0, spectrum.length, 0, width);
52 | // var h = -height + map(spectrum[i], 0, 255, height, 0);
53 | // rect(x, height, width / spectrum.length, h);
54 | // }
55 |
56 | // updateDescription();
57 | // }
58 |
59 | // // display current Filter params
60 | // function updateDescription() {
61 | // description =
62 | // 'Playing! Press any key to pause. Filter Frequency = ' +
63 | // filterFreq +
64 | // ' Filter Width = ' +
65 | // filterWidth;
66 | // p.html(description);
67 | // }
68 |
--------------------------------------------------------------------------------
/test/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/Filter_LowPass/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: Apply a p5.LowPass filter to a p5.SoundFile.
3 | // * Visualize the sound with FFT.
4 | // * Map mouseX to the the filter's cutoff frequency
5 | // * and mouseY to resonance/width of the a BandPass filter
6 | // */
7 |
8 | // var soundFile;
9 | // var fft;
10 |
11 | // var description = 'loading';
12 | // var p;
13 |
14 | // var filter, filterFreq, filterRes;
15 |
16 | // function preload() {
17 | // soundFormats('mp3', 'ogg');
18 | // soundFile = loadSound('../_files/beat');
19 | // }
20 |
21 | // function setup() {
22 | // createCanvas(710, 256);
23 | // fill(255, 40, 255);
24 |
25 | // // loop the sound file
26 | // soundFile.loop();
27 |
28 | // filter = new p5sound.LowPass();
29 |
30 | // // Disconnect soundfile from main output.
31 | // // Then, connect it to the filter, so that we only hear the filtered sound
32 | // soundFile.disconnect();
33 | // soundFile.connect(filter);
34 |
35 | // fft = new p5sound.FFT();
36 |
37 | // // update description text
38 | // p = createP(description);
39 | // var p2 = createP(
40 | // 'Draw the array returned by FFT.analyze( ). This represents the frequency spectrum, from lowest to highest frequencies.'
41 | // );
42 | // }
43 |
44 | // function draw() {
45 | // background(30);
46 |
47 | // // Map mouseX to a the cutoff frequency for our lowpass filter
48 | // filterFreq = map(mouseX, 0, width, 10, 22050);
49 | // // Map mouseY to resonance/width
50 | // filterRes = map(mouseY, 0, height, 15, 5);
51 | // // set filter parameters
52 | // filter.set(filterFreq, filterRes);
53 |
54 | // // Draw every value in the FFT spectrum analysis where
55 | // // x = lowest (10Hz) to highest (22050Hz) frequencies,
56 | // // h = energy / amplitude at that frequency
57 | // var spectrum = fft.analyze();
58 | // noStroke();
59 | // for (var i = 0; i < spectrum.length; i++) {
60 | // var x = map(i, 0, spectrum.length, 0, width);
61 | // var h = -height + map(spectrum[i], 0, 255, height, 0);
62 | // rect(x, height, width / spectrum.length, h);
63 | // }
64 |
65 | // updateDescription();
66 | // }
67 |
68 | // // Change description text if the song is loading, playing or paused
69 | // function updateDescription() {
70 | // description =
71 | // 'Filter Frequency = ' + filterFreq + ' Filter Res = ' + filterRes;
72 | // p.html(description);
73 | // }
74 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/micLevel_on_off/sketch.js:
--------------------------------------------------------------------------------
1 | // var mic;
2 | // var amplitude, micLevel, mainLevel, levelLabel;
3 |
4 | // var soundToggle;
5 | // var soundOn = false;
6 | // var micOn = true;
7 | // var micToggle;
8 |
9 | // var h;
10 |
11 | // function setup() {
12 | // createCanvas(400, 400);
13 | // noStroke();
14 | // fill(255);
15 |
16 | // mic = new p5sound.AudioIn();
17 | // mic.start();
18 |
19 | // // create controls
20 | // levelLabel = createP('main Volume: ');
21 | // mainLevel = createSlider(0, 100, 50);
22 |
23 | // soundToggle = createButton('Sound ON');
24 | // soundToggle.mousePressed(toggleSound);
25 |
26 | // micToggle = createButton('Stop Mic');
27 | // micToggle.mousePressed(toggleMic);
28 |
29 | // h = createP('enable the mic...');
30 | // createP(
31 | // 'NOTE: Mic is disconnected from main output (speakers) by default. Turning sound on with mic.connect( ) may cause a feedback loop between the mic and speakers. Try headphones.'
32 | // );
33 | // }
34 |
35 | // function draw() {
36 | // background(0);
37 |
38 | // // get the volume level, accepts an optional smoothing value or defaults to 0.
39 | // micLevel = mic.getLevel();
40 |
41 | // text('input volume: ' + micLevel, 5, 10);
42 |
43 | // // if the mic picks up a level greater than zero, we can assume
44 | // // that the user has allowed their browser to access the microphone.
45 | // if (micLevel > 0) {
46 | // h.html('Make some noise!');
47 | // }
48 |
49 | // ellipse(width / 2, height / 2, 400 * micLevel + 10, 400 * micLevel + 10);
50 |
51 | // // set main output
52 | // levelLabel.html('main Volume: ' + mainLevel.value() / 100);
53 | // mainVolume(mainLevel.value() / 100);
54 | // }
55 |
56 | // // Toggle whether mic is connected to main output
57 | // function toggleSound() {
58 | // if (soundOn === false) {
59 | // mic.connect();
60 | // soundOn = true;
61 | // soundToggle.html('Sound OFF');
62 | // } else {
63 | // mic.disconnect();
64 | // soundOn = false;
65 | // soundToggle.html('Sound ON');
66 | // }
67 | // }
68 |
69 | // // Toggle whether the mic is on (getting input) or off
70 | // function toggleMic() {
71 | // if (micOn === true) {
72 | // mic.stop();
73 | // micOn = false;
74 | // micToggle.html('Start Mic');
75 | // } else {
76 | // mic.start();
77 | // micOn = true;
78 | // micToggle.html('Stop mic');
79 | // }
80 | // }
81 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/amplitude_analysis/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * DEMO: Use p5sound.Amplitude (volume) to change the size of an ellipse
3 | // */
4 |
5 | // var size;
6 |
7 | // var soundFile;
8 | // var amplitude;
9 |
10 | // // description text
11 | // var description;
12 | // var p1;
13 |
14 | // var smoothing = 0.01;
15 | // var smoothSlider, smoothLabel;
16 |
17 | // function preload() {
18 | // soundFile = loadSound(['../_files/beat.mp3', '../_files/beat.ogg']);
19 | // }
20 |
21 | // function setup() {
22 | // createCanvas(400, 400);
23 | // background(0);
24 | // noStroke();
25 | // fill(255);
26 |
27 | // soundFile.loop();
28 |
29 | // // create a new p5sound.Amplitude. Optionally, give it a 'smoothing' value betw 0.0 and .999
30 | // amplitude = new p5sound.Amplitude(smoothing);
31 |
32 | // // instruction text
33 | // description =
34 | // 'Spacebar: pause/unpause the loop. Press "N" to toggle Normalize';
35 | // p1 = createP(description);
36 |
37 | // smoothSlider = createSlider(0.0, 99.9, smoothing * 100);
38 | // smoothLabel = createP('Smoothing: ' + smoothing);
39 | // }
40 |
41 | // function draw() {
42 | // background(0);
43 |
44 | // // get volume from the amplitude process
45 | // var volume = amplitude.getLevel();
46 |
47 | // // print the volume to the canvas. It is a float between 0 and 1.0.
48 | // text('volume: ' + volume, 20, 20);
49 |
50 | // // Change size based on volume. First, map to useful values.
51 | // size = map(volume, 0, 1.0, 25, 400);
52 | // ellipse(width / 2, height / 2, size, size);
53 |
54 | // // instruction text
55 | // description =
56 | // 'Spacebar: pause/unpause the loop. Press "N" to toggle Normalize. Normalized is ' +
57 | // amplitude.normalize;
58 | // p1.html(description);
59 |
60 | // // change smoothing
61 | // smoothing = smoothSlider.value() / 100;
62 | // smoothLabel.html('Smoothing: ' + smoothing);
63 | // amplitude.smooth(smoothing);
64 | // }
65 |
66 | // // on key pressed...
67 | // function keyPressed(e) {
68 | // // spacebar pauses
69 | // if (e.keyCode === 32) {
70 | // if (soundFile.isPlaying()) {
71 | // soundFile.pause();
72 | // } else {
73 | // soundFile.play();
74 | // }
75 | // }
76 |
77 | // // 'n' keypress toggles normalize on/off
78 | // if (e.keyCode === 78) {
79 | // amplitude.toggleNormalize();
80 | // }
81 | // }
82 |
83 | // function mouseClicked() {
84 | // if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
85 | // if (getMasterVolume() === 0) {
86 | // setMasterVolume(0, 1);
87 | // } else {
88 | // setMasterVolume(0.1), 1;
89 | // }
90 | // }
91 | // }
92 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/autoCorrelation/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Auto Correlation multiples each sample in a buffer by all
3 | // * of the other samples. This emphasizes the fundamental
4 | // * frequency. Auto Correlation is useful for pitch detection,
5 | // * as well as for visualization
6 | // *
7 | // * This example is a Correlogram which is a plot
8 | // * of the autocorrelations.
9 | // *
10 | // * Example by Jason Sigal and Golan Levin.
11 | // */
12 |
13 | // var source, fft;
14 | // var bNormalize = true;
15 | // var centerClip = false;
16 |
17 | // function setup() {
18 | // createCanvas(windowWidth, windowHeight);
19 | // noFill();
20 |
21 | // source = new p5sound.AudioIn();
22 | // source.start();
23 |
24 | // fft = new p5sound.FFT();
25 | // fft.setInput(source);
26 | // }
27 |
28 | // function draw() {
29 | // background(200);
30 |
31 | // // array of values from -1 to 1
32 | // var timeDomain = fft.waveform(2048, 'float32');
33 | // var corrBuff = autoCorrelate(timeDomain);
34 |
35 | // beginShape();
36 | // for (var i = 0; i < corrBuff.length; i++) {
37 | // var w = map(i, 0, corrBuff.length, 0, width);
38 | // var h = map(corrBuff[i], -1, 1, height, 0);
39 | // curveVertex(w, h);
40 | // }
41 | // endShape();
42 | // }
43 |
44 | // function autoCorrelate(buffer) {
45 | // var newBuffer = [];
46 | // var nSamples = buffer.length;
47 |
48 | // var autocorrelation = [];
49 | // var index;
50 |
51 | // // center clip removes any samples under 0.1
52 | // if (centerClip) {
53 | // var cutoff = 0.1;
54 | // for (var i = 0; i < buffer.length; i++) {
55 | // var val = buffer[i];
56 | // buffer[i] = Math.abs(val) > cutoff ? val : 0;
57 | // }
58 | // }
59 |
60 | // for (var lag = 0; lag < nSamples; lag++) {
61 | // var sum = 0;
62 | // for (index = 0; index < nSamples; index++) {
63 | // var indexLagged = index + lag;
64 | // if (indexLagged < nSamples) {
65 | // var sound1 = buffer[index];
66 | // var sound2 = buffer[indexLagged];
67 | // var product = sound1 * sound2;
68 | // sum += product;
69 | // }
70 | // }
71 |
72 | // // average to a value between -1 and 1
73 | // newBuffer[lag] = sum / nSamples;
74 | // }
75 |
76 | // if (bNormalize) {
77 | // var biggestVal = 0;
78 | // for (index = 0; index < nSamples; index++) {
79 | // if (abs(newBuffer[index]) > biggestVal) {
80 | // biggestVal = abs(newBuffer[index]);
81 | // }
82 | // }
83 | // for (index = 0; index < nSamples; index++) {
84 | // newBuffer[index] /= biggestVal;
85 | // }
86 | // }
87 |
88 | // return newBuffer;
89 | // }
90 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/envelope/sketch.js:
--------------------------------------------------------------------------------
1 | // // Adapting Wilm Thoben's Envelope example from the Processing Handbook ex2
2 |
3 | // /*
4 | // This sketch shows how to use envelopes and oscillators. Envelopes are pre-defined amplitude
5 | // distribution over time. The sound library provides an ASR envelope which stands for attach,
6 | // sustain, release. The amplitude rises then sustains at the maximum level and decays slowly
7 | // depending on pre defined time segments.
8 |
9 | // .________
10 | // . ---
11 | // . ---
12 | // . ---
13 | // A S R
14 |
15 | // */
16 |
17 | // var triOsc;
18 | // var env;
19 | // var a;
20 |
21 | // // Times and levels for the ASR envelope
22 | // var attackTime = 0.01;
23 | // var attackLevel = 0.7;
24 | // var decayTime = 0.3;
25 | // var decayLevel = 0.2;
26 | // var sustainTime = 0.1;
27 | // var sustainLevel = decayLevel;
28 | // var releaseTime = 0.5;
29 |
30 | // var midiSequence = [60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72];
31 | // var duration = 1000;
32 | // // Set the note trigger
33 | // var trigger;
34 |
35 | // // An index to count up the notes
36 | // var note = 0;
37 |
38 | // function setup() {
39 | // createCanvas(600, 600);
40 | // background(255);
41 |
42 | // trigger = millis();
43 |
44 | // triOsc = new p5sound.TriOsc();
45 | // triOsc.amp(0);
46 | // triOsc.start();
47 |
48 | // env = new p5sound.Env(
49 | // attackTime,
50 | // attackLevel,
51 | // decayTime,
52 | // decayLevel,
53 | // sustainTime,
54 | // sustainLevel,
55 | // releaseTime
56 | // );
57 | // fill(0);
58 |
59 | // a = new p5sound.Amplitude();
60 | // }
61 |
62 | // function draw() {
63 | // var size = 10;
64 | // background(255, 255, 255, 20);
65 | // ellipse(
66 | // map((trigger - millis()) % duration, 1000, 0, 0, width),
67 | // map(a.getLevel(), 0, 0.5, height - size, 0),
68 | // size,
69 | // size
70 | // );
71 |
72 | // // If the determined trigger moment in time matches up with the computer clock and we if the
73 | // // sequence of notes hasn't been finished yet the next note gets played.
74 | // if (millis() > trigger) {
75 | // // midiToFreq transforms the MIDI value into a frequency in Hz which we use to control the triangle oscillator
76 | // triOsc.freq(midiToFreq(midiSequence[note]));
77 |
78 | // // The envelope gets triggered with the oscillator as input and the times and levels we defined earlier
79 | // env.play(triOsc);
80 |
81 | // // Create the new trigger according to predefined durations and speed it up by deviding by 1.5
82 | // trigger = millis() + duration;
83 |
84 | // // Advance by one note in the midiSequence;
85 | // note++;
86 |
87 | // // Loop the sequence, notice the jitter
88 | // if (note === 12) {
89 | // note = 0;
90 | // }
91 | // }
92 | // }
93 |
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | // core
2 | import './constants';
3 |
4 | import './shims';
5 |
6 | import { getAudioContext } from './audioContext';
7 | p5.prototype.getAudioContext = getAudioContext;
8 |
9 | import p5sound from './main';
10 |
11 | // helpers
12 | import {
13 | sampleRate,
14 | freqToMidi,
15 | midiToFreq,
16 | noteToFreq,
17 | soundFormats,
18 | disposeSound,
19 | _checkFileFormats,
20 | _mathChain,
21 | convertToWav,
22 | interleave,
23 | writeUTFBytes,
24 | safeBufferSize,
25 | saveSound
26 | } from './helpers';
27 |
28 | p5.prototype.sampleRate = sampleRate;
29 | p5.prototype.freqToMidi = freqToMidi;
30 | p5.prototype.midiToFreq = midiToFreq;
31 | p5.prototype.noteToFreq = noteToFreq;
32 | p5.prototype.soundFormats = soundFormats;
33 | p5.prototype.disposeSound = disposeSound;
34 | p5.prototype._checkFileFormats = _checkFileFormats;
35 | p5.prototype._mathChain = _mathChain;
36 | p5.prototype.convertToWav = convertToWav;
37 | p5.prototype.interleave = interleave;
38 | p5.prototype.writeUTFBytes = writeUTFBytes;
39 | p5.prototype.safeBufferSize = safeBufferSize;
40 | p5.prototype.saveSound = saveSound;
41 |
42 | p5.prototype.registerMethod('remove', p5.prototype.disposeSound);
43 |
44 | import './errorHandler';
45 |
46 | // TODO: fix, when audioWorklet is imported, p5sound is out of scope!
47 | // import './audioWorklet';
48 |
49 | // p5.prototype.registerMethod('init', p5sound.init);
50 |
51 | // import Amplitude from './Amplitude';
52 | // p5.prototype.Amplitude = Amplitude;
53 |
54 | // import AudioIn from './AudioIn';
55 | // p5.prototype.AudioIn = AudioIn;
56 |
57 | import AnalyzerFFT from './AnalyzerFFT';
58 | p5.prototype.AnalyzerFFT = AnalyzerFFT;
59 |
60 | import BiquadFilter from './BiquadFilter';
61 | p5.prototype.BiquadFilter = BiquadFilter;
62 | import { LowPass, HighPass, BandPass } from './BiquadFilter';
63 | p5.prototype.LowPass = LowPass;
64 | p5.prototype.HighPass = HighPass;
65 | p5.prototype.BandPass = BandPass;
66 |
67 | import Delay from './Delay';
68 | p5.prototype.Delay = Delay;
69 |
70 | import Effect from './Effect';
71 | p5.prototype.Effect = Effect;
72 |
73 | import Envelope from './Envelope';
74 | p5.prototype.Envelope = Envelope;
75 |
76 | import Gain from './Gain';
77 | p5.prototype.Gain = Gain;
78 |
79 | import Noise from './Noise';
80 | p5.prototype.Noise = Noise;
81 |
82 | import Oscillator from './Oscillator';
83 | p5.prototype.Oscillator = Oscillator;
84 | import { SinOsc, TriOsc, SawOsc, SqrOsc } from './Oscillator';
85 | p5.prototype.SinOsc = SinOsc;
86 | p5.prototype.TriOsc = TriOsc;
87 | p5.prototype.SawOsc = SawOsc;
88 | p5.prototype.SqrOsc = SqrOsc;
89 |
90 | import Panner from './Panner';
91 | p5.prototype.Panner = Panner;
92 |
93 | import SoundFile, { loadSound } from './SoundFile';
94 | p5.prototype.SoundFile = SoundFile;
95 | p5.prototype.loadSound = loadSound;
96 | // register preload handling of loadSound
97 | p5.prototype.registerPreloadMethod('loadSound', p5.prototype);
98 |
99 | module.exports = p5sound;
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/Reverb_convolve_FFT/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: Convolution Reverb w/ FFT
3 | // *
4 | // * The p5.Convolver can recreate the sound of actual spaces using convolution.
5 | // *
6 | // * Toggle between different impulses with the mouse. Press any key to hear the
7 | // * original impulse recording.
8 | // *
9 | // * Convolution samples Creative Commons BY recordinghopkins, via freesound.org
10 | // * https://www.freesound.org/people/recordinghopkins/
11 | // */
12 | // var sound, env, cVerb, fft;
13 | // var currentIR = 0;
14 | // var p;
15 | // var rawImpulse;
16 |
17 | // function preload() {
18 | // // we have included both MP3 and OGG versions of all the impulses/sounds
19 | // soundFormats('ogg', 'mp3');
20 |
21 | // // create a p5.Convolver
22 | // cVerb = createConvolver('../_files/bx-spring');
23 |
24 | // // add Impulse Responses to cVerb.impulses array, in addition to bx-spring
25 | // cVerb.addImpulse('../_files/small-plate');
26 | // cVerb.addImpulse('../_files/drum');
27 | // cVerb.addImpulse('../_files/beatbox');
28 | // cVerb.addImpulse('../_files/concrete-tunnel');
29 |
30 | // // load a sound that will be processed by the p5.ConvultionReverb
31 | // sound = loadSound('../_files/Damscray_DancingTiger');
32 | // }
33 |
34 | // function setup() {
35 | // createCanvas(710, 400);
36 | // rawImpulse = loadSound('../_files/' + cVerb.impulses[currentIR].name);
37 |
38 | // // disconnect from main output...
39 | // sound.disconnect();
40 | // // ... and process with cVerb
41 | // // so that we only hear the reverb
42 | // cVerb.process(sound);
43 |
44 | // createP('Click to play a sound and change the impulse');
45 | // createP('Press any key to play the impulse source as a SoundFile');
46 | // p = createP('');
47 |
48 | // fft = new p5sound.FFT();
49 | // }
50 |
51 | // function draw() {
52 | // background(30);
53 | // fill(0, 255, 40);
54 |
55 | // var spectrum = fft.analyze();
56 |
57 | // // Draw every value in the frequencySpectrum array as a rectangle
58 | // noStroke();
59 | // for (var i = 0; i < spectrum.length; i++) {
60 | // var x = map(i, 0, spectrum.length, 0, width);
61 | // var h = -height + map(spectrum[i], 0, 255, height, 0);
62 | // rect(x, height, width / spectrum.length, h);
63 | // }
64 | // }
65 |
66 | // function mousePressed() {
67 | // // cycle through the array of cVerb.impulses
68 | // currentIR++;
69 | // if (currentIR >= cVerb.impulses.length) {
70 | // currentIR = 0;
71 | // }
72 | // cVerb.toggleImpulse(currentIR);
73 |
74 | // // play the sound through the impulse
75 | // sound.play();
76 |
77 | // // display the current Impulse Response name (the filepath)
78 | // p.html('Convolution Impulse Response: ' + cVerb.impulses[currentIR].name);
79 |
80 | // rawImpulse.setPath('../_files/' + cVerb.impulses[currentIR].name);
81 | // }
82 |
83 | // function keyPressed() {
84 | // rawImpulse.play();
85 | // }
86 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/FFT_freqRange/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Display the average amount of energy (amplitude) across a range
3 | // * of frequencies using the p5sound.FFT class and its methods analyze()
4 | // * and getEnergy().
5 | // *
6 | // * This example divides the frequency spectrum into eight bands.
7 | // */
8 |
9 | // var soundFile;
10 | // var fft;
11 |
12 | // var description = 'loading';
13 | // var p;
14 |
15 | // function preload() {
16 | // soundFormats('mp3', 'ogg');
17 | // soundFile = loadSound('../_files/beat');
18 | // }
19 |
20 | // function setup() {
21 | // createCanvas(1024, 400);
22 | // fill(255, 40, 255);
23 | // noStroke();
24 | // textAlign(CENTER);
25 |
26 | // fft = new p5sound.FFT();
27 |
28 | // p = createP(description);
29 | // var p2 = createP(
30 | // 'Description: Using getEnergy(low, high) to measure amplitude within a range of frequencies.'
31 | // );
32 | // }
33 |
34 | // function draw() {
35 | // background(30, 20, 30);
36 | // updateDescription();
37 |
38 | // fft.analyze(); // analyze before calling fft.getEnergy()
39 |
40 | // // Generate 8 bars to represent 8 different frequency ranges
41 | // for (var i = 0; i < 8; i++) {
42 | // noStroke();
43 | // fill((i * 30) % 100 + 50, 195, (i * 25 + 50) % 255);
44 |
45 | // // Each bar has a unique frequency range
46 | // var centerFreq = pow(2, i) * 125 / 2;
47 | // var loFreq = pow(2, i - 1) * 125 / 2 + centerFreq / 4;
48 | // var hiFreq = centerFreq + centerFreq / 2;
49 |
50 | // // get the average value in a frequency range
51 | // var freqValue = fft.getEnergy(loFreq, hiFreq - 1);
52 |
53 | // // Rectangle height represents the average value of this frequency range
54 | // var h = -height + map(freqValue, 0, 255, height, 0);
55 | // rect((i + 1) * width / 8 - width / 8, height, width / 8, h);
56 |
57 | // fill(255);
58 | // text(
59 | // loFreq.toFixed(0) + ' Hz - ' + hiFreq.toFixed(0) + ' Hz',
60 | // (i + 1) * width / 8 - width / 8 / 2,
61 | // 30
62 | // );
63 | // }
64 | // }
65 |
66 | // function keyPressed() {
67 | // if (soundFile.isPlaying()) {
68 | // soundFile.pause();
69 | // } else {
70 | // soundFile.loop();
71 | // }
72 | // }
73 |
74 | // // Change description text if the song is loading, playing or paused
75 | // function updateDescription() {
76 | // if (!soundFile.isPlaying()) {
77 | // description = 'Paused...';
78 | // p.html(description);
79 | // } else if (soundFile.isPlaying()) {
80 | // description = 'Playing!';
81 | // p.html(description);
82 | // } else {
83 | // for (var i = 0; i < frameCount % 3; i++) {
84 | // // add periods to loading to create a fun loading bar effect
85 | // if (frameCount % 4 === 0) {
86 | // description += '.';
87 | // }
88 | // if (frameCount % 25 === 0) {
89 | // description = 'loading';
90 | // }
91 | // }
92 | // p.html(description);
93 | // }
94 | // }
95 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/oscillatorWaveform/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: change the frequency of an oscillator and visualize the waveform
3 | // */
4 |
5 | // var freqSlider, freqLabel, ampLabel, ampSlider, button;
6 |
7 | // var osc;
8 | // var freq = 220; // current frequency (updated by slider)
9 | // var amp = 0.5;
10 | // var fft;
11 |
12 | // var oscOn = false;
13 |
14 | // function setup() {
15 | // createCanvas(800, 400);
16 | // noFill();
17 |
18 | // freqLabel = createP('Frequency: ');
19 | // freqSlider = createSlider(1, 700, freq);
20 |
21 | // ampLabel = createP('Amplitude: ' + amp);
22 | // ampSlider = createSlider(0.0, 100.0, amp * 100);
23 |
24 | // button = createButton('start');
25 | // button.mousePressed(toggleOsc);
26 |
27 | // // Other types of oscillators include TriOsc, SawOsc, SqrOsc, and generic Oscillator.
28 | // osc = new p5sound.SinOsc(freq);
29 | // osc.amp(amp);
30 |
31 | // p = createP('Current Waveform: ' + osc.getType());
32 |
33 | // // these buttons will change the osc's waveform
34 | // sine = createButton('sine');
35 | // sine.mousePressed(setSine);
36 | // saw = createButton('sawtooth');
37 | // saw.mousePressed(setSawtooth);
38 | // tri = createButton('triangle');
39 | // tri.mousePressed(setTriangle);
40 | // sq = createButton('square');
41 | // sq.mousePressed(setSquare);
42 |
43 | // // create an fft to analyze the audio
44 | // fft = new p5sound.FFT();
45 | // }
46 |
47 | // function draw() {
48 | // background(30);
49 |
50 | // amp = ampSlider.value() / 100;
51 | // osc.amp(amp);
52 | // ampLabel.html('Amplitude: ' + amp + '/ 1.0');
53 |
54 | // freq = freqSlider.value();
55 | // osc.freq(freq);
56 | // freqLabel.html('Frequency: ' + freq + ' Hz');
57 |
58 | // p.html('Current Waveform: ' + osc.getType());
59 |
60 | // // analyze the waveform
61 | // waveform = fft.waveform();
62 |
63 | // // draw the shape of the waveform
64 | // stroke(255);
65 | // strokeWeight(10);
66 | // beginShape();
67 | // for (var i = 0; i < waveform.length; i++) {
68 | // var x = map(i, 0, waveform.length, 0, width);
69 | // var y = map(waveform[i], -1, 1, -height / 2, height / 2);
70 | // vertex(x, y + height / 2);
71 | // }
72 | // endShape();
73 | // }
74 |
75 | // // Turn the oscillator on / off
76 | // function toggleOsc() {
77 | // if (oscOn) {
78 | // osc.stop();
79 | // button.html('start');
80 | // } else {
81 | // osc.start();
82 | // button.html('stop');
83 | // }
84 | // oscOn = !oscOn;
85 | // }
86 |
87 | // // Methods to change the oscillator type.
88 | // // You can change the type by using osc.setType('sine').
89 | // function setSine() {
90 | // osc.setType('sine');
91 | // }
92 |
93 | // function setTriangle() {
94 | // osc.setType('triangle');
95 | // }
96 |
97 | // function setSawtooth() {
98 | // osc.setType('sawtooth');
99 | // }
100 |
101 | // function setSquare() {
102 | // osc.setType('square');
103 | // }
104 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/oscillatorMod_AM/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: Amplitude Modulation involves two oscillators, referred
3 | // * to as the carrier and the modulator, where the modulator controls
4 | // * the carrier's amplitude.
5 | // *
6 | // * The carrier is typically set at an audible frequency (i.e. 440 Hz)
7 | // * and connected to main output by default. The carrier.amp is
8 | // * set to zero because we will have the modulator control its amplitude.
9 | // *
10 | // * The modulator is typically set to a frequency that is lower than
11 | // * humans can hear (i.e. 1 Hz, or one cycle every second). The modulator
12 | // * is disconnected from main output. Instead, it is connected
13 | // * to the amplitude of the Carrier, like this: carrier.amp(modulator).
14 | // *
15 | // * MouseX controls the amplitude of the modulator from 0 to 1. When the
16 | // * modulator's amplitude is set to 0, the amplitude modulation has no effect.
17 | // *
18 | // * MouseY controls the frequency of the modulator from 0 to 20hz.
19 | // * Both impact our perception of the Carrier frequency. A subtle amount
20 | // * of Amplitude Modulation can simulate effects such as Tremolo.
21 | // * Ring Modulation is a type of Amplitude Modulation where the original
22 | // * carrier signal is not present.
23 | // */
24 |
25 | // var carrier; // this is the oscillator we will hear
26 | // var modulator; // this oscillator will modulate the amplitude of the carrier
27 | // var fft; // we'll visualize the waveform
28 |
29 | // function setup() {
30 | // createCanvas(800, 400);
31 | // background(30); // alpha
32 | // noFill();
33 |
34 | // carrier = new p5sound.Oscillator(); // connects to main output by default
35 | // carrier.start();
36 | // carrier.freq(340);
37 | // carrier.amp(0.2);
38 | // // carrier's amp is 0 by default, giving our modulator total control
39 |
40 | // modulator = new p5sound.Oscillator('triangle');
41 | // modulator.disconnect(); // disconnect the modulator from main output
42 | // modulator.start();
43 | // modulator.freq(5);
44 | // modulator.amp(1);
45 |
46 | // // Modulate the carrier's amplitude with the modulator
47 | // carrier.amp(modulator);
48 |
49 | // // create an fft to analyze the audio
50 | // fft = new p5sound.FFT();
51 | // }
52 |
53 | // function draw() {
54 | // background(30, 30, 30, 100); // alpha
55 |
56 | // // // map mouseY to moodulator freq between 0 and 20hz
57 | // var modFreq = map(mouseY, 0, height, 4, 0);
58 | // modulator.freq(modFreq);
59 |
60 | // var modAmp = map(mouseX, 0, width, 0, 0.5);
61 | // modulator.amp(modAmp, 0.01); // fade time of 0.1 for smooth fading
62 |
63 | // // analyze the waveform
64 | // waveform = fft.waveform();
65 |
66 | // // draw the shape of the waveform
67 | // stroke(240);
68 | // strokeWeight(4);
69 | // beginShape();
70 | // for (var i = 0; i < waveform.length; i++) {
71 | // var x = map(i, 0, waveform.length, 0, width);
72 | // var y = map(waveform[i], -1, 1, -height / 2, height / 2);
73 | // vertex(x, y + height / 2);
74 | // }
75 | // endShape();
76 | // }
77 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/oscillatorMod_FM/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Frequency Modulation involves two oscillators, referred
3 | // * to as the carrier and the modulator, where the modulator controls
4 | // * the carrier's frequency.
5 | // *
6 | // * The carrier oscillates at an audible frequency (i.e. 440 Hz)
7 | // * and connected to main output by default.
8 | // *
9 | // * The modulator is typically set to a frequency that is lower
10 | // * than humans can hear (i.e. 1 Hz, or one cycle every second).
11 | // * The modulator is disconnected from main output, and is connected
12 | // * to the frequency of the carrier, like this: carrier.freq(modulator).
13 | // *
14 | // * In this example...
15 | // * - MouseX controls the amplitude of the modulator from 0 to 1. When the
16 | // * modulator's amplitude is set to 0, the amplitude modulation has no effect.
17 | // *
18 | // * - MouseY controls the frequency of the modulator from 0 to 20hz.
19 | // * Both impact our perception of the Carrier frequency. A subtle amount
20 | // * of Amplitude Modulation can simulate effects such as Tremolo.
21 | // * Ring Modulation is a type of Amplitude Modulation where the original
22 | // * carrier signal is not present.
23 | // *
24 | // * - The modulator output, a signal between -1 and 1,
25 | // * is scaled to a range between 100 and 300 using .mult and .add
26 | // */
27 |
28 | // var carrier; // this is the oscillator we will hear
29 | // var modulator; // this oscillator will modulate the amplitude of the carrier
30 | // var fft; // we'll visualize the waveform
31 |
32 | // function setup() {
33 | // createCanvas(800, 400);
34 | // noFill();
35 |
36 | // carrier = new p5sound.Oscillator('sine');
37 | // carrier.amp(1); // set amplitude
38 | // carrier.freq(220); // set frequency
39 | // carrier.start(); // start oscillating
40 |
41 | // modulator = new p5sound.Oscillator('sawtooth');
42 | // modulator.disconnect();
43 | // modulator.amp(1); // will map to mouseX
44 | // modulator.freq(4); // will map to mouseY
45 | // modulator.start();
46 |
47 | // // multiply amplitude range by 200, then add 100
48 | // carrier.freq(modulator.mult(200).add(100));
49 |
50 | // // create an fft to analyze the audio
51 | // fft = new p5sound.FFT();
52 | // }
53 |
54 | // function draw() {
55 | // background(30);
56 |
57 | // // map mouseY to moodulator freq between 0 and 20hz
58 | // var modFreq = map(mouseY, 0, height, 20, 0);
59 | // modulator.freq(modFreq);
60 |
61 | // // change the original amplitude of the sawOsc, before it's scaled.
62 | // // negative amp reverses the waveform, and sounds percussive
63 | // var modAmp = map(mouseX, 0, width, -1, 1);
64 | // modulator.amp(modAmp);
65 |
66 | // // analyze the waveform
67 | // waveform = fft.waveform();
68 |
69 | // // draw the shape of the waveform
70 | // stroke(255);
71 | // strokeWeight(10);
72 | // beginShape();
73 | // for (var i = 0; i < waveform.length; i++) {
74 | // var x = map(i, 0, waveform.length, 0, width);
75 | // var y = map(waveform[i], -1, 1, -height / 2, height / 2);
76 | // vertex(x, y + height / 2);
77 | // }
78 | // endShape();
79 | // }
80 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/noiseMod_AM/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: Amplitude Modulation involves two oscillators, referred
3 | // * to as the carrier and the modulator, where the modulator controls
4 | // * the carrier's amplitude.
5 | // *
6 | // * The carrier is typically set at an audible frequency (i.e. 440 Hz)
7 | // * and connected to main output by default. The carrier.amp is
8 | // * set to zero because we will have the modulator control its amplitude.
9 | // *
10 | // * The modulator is typically set to a frequency that is lower than
11 | // * humans can hear (i.e. 1 Hz, or one cycle every second). The modulator
12 | // * is disconnected from main output. Instead, it is connected
13 | // * to the amplitude of the Carrier, like this: carrier.amp(modulator).
14 | // *
15 | // * MouseX controls the amplitude of the modulator from 0 to 1. When the
16 | // * modulator's amplitude is set to 0, the amplitude modulation has no effect.
17 | // *
18 | // * MouseY controls the frequency of the modulator from 0 to 20hz.
19 | // * Both impact our perception of the Carrier frequency. A subtle amount
20 | // * of Amplitude Modulation can simulate effects such as Tremolo.
21 | // * Ring Modulation is a type of Amplitude Modulation where the original
22 | // * carrier signal is not present.
23 | // */
24 |
25 | // var carrier; // this is the oscillator we will hear
26 | // var modulator; // this oscillator will modulate the amplitude of the carrier
27 | // var fft; // we'll visualize the waveform
28 |
29 | // function setup() {
30 | // createCanvas(800, 400);
31 | // background(30); // alpha
32 | // noFill();
33 |
34 | // carrier = new p5sound.Noise(); // connects to main output by default
35 | // // carrier.freq(340);
36 | // carrier.amp(0);
37 | // // carrier's amp is 0 by default, giving our modulator total control
38 |
39 | // carrier.start();
40 |
41 | // modulator = new p5sound.Oscillator('triangle');
42 | // modulator.disconnect(); // disconnect the modulator from main output
43 | // modulator.freq(5);
44 | // modulator.amp(0.5);
45 | // modulator.start();
46 |
47 | // // Modulate the carrier's amplitude with the modulator
48 | // // Optionally, we can scale the signal.
49 | // carrier.amp(modulator.scale(-1, 1, 1, -1));
50 | // // carrier.amp(modulator);
51 |
52 | // // create an fft to analyze the audio
53 | // fft = new p5sound.FFT();
54 | // }
55 |
56 | // function draw() {
57 | // background(30, 30, 30, 100); // alpha
58 |
59 | // // map mouseY to moodulator freq between 0 and 20hz
60 | // var modFreq = map(mouseY, 0, height, 4, 0);
61 | // modulator.freq(modFreq);
62 |
63 | // var modAmp = map(mouseX, 0, width, 0, 1);
64 | // modulator.amp(modAmp, 0.01); // fade time of 0.1 for smooth fading
65 |
66 | // // analyze the waveform
67 | // waveform = fft.waveform();
68 |
69 | // // draw the shape of the waveform
70 | // stroke(240);
71 | // strokeWeight(4);
72 | // beginShape();
73 | // for (var i = 0; i < waveform.length; i++) {
74 | // var x = map(i, 0, waveform.length, 0, width);
75 | // var y = map(waveform[i], -1, 1, -height / 2, height / 2);
76 | // vertex(x, y + height / 2);
77 | // }
78 | // endShape();
79 | // }
80 |
--------------------------------------------------------------------------------
/test/manual-test-examples/addons/p5.sound/soundfileMod_AM/sketch.js:
--------------------------------------------------------------------------------
1 | // /**
2 | // * Example: Amplitude Modulation involves two oscillators, referred
3 | // * to as the carrier and the modulator, where the modulator controls
4 | // * the carrier's amplitude.
5 | // *
6 | // * The carrier is typically set at an audible frequency (i.e. 440 Hz)
7 | // * and connected to main output by default. The carrier.amp is
8 | // * set to zero because we will have the modulator control its amplitude.
9 | // *
10 | // * The modulator is typically set to a frequency that is lower than
11 | // * humans can hear (i.e. 1 Hz, or one cycle every second). The modulator
12 | // * is disconnected from main output. Instead, it is connected
13 | // * to the amplitude of the Carrier, like this: carrier.amp(modulator).
14 | // *
15 | // * MouseX controls the amplitude of the modulator from 0 to 1. When the
16 | // * modulator's amplitude is set to 0, the amplitude modulation has no effect.
17 | // *
18 | // * MouseY controls the frequency of the modulator from 0 to 20hz.
19 | // * Both impact our perception of the Carrier frequency. A subtle amount
20 | // * of Amplitude Modulation can simulate effects such as Tremolo.
21 | // * Ring Modulation is a type of Amplitude Modulation where the original
22 | // * carrier signal is not present.
23 | // */
24 |
25 | // var carrier; // this is the oscillator we will hear
26 | // var modulator; // this oscillator will modulate the amplitude of the carrier
27 | // var fft; // we'll visualize the waveform
28 |
29 | // function preload() {
30 | // carrier = loadSound('../_files/Damscray_01.mp3'); // connects to main output by default
31 | // }
32 |
33 | // function setup() {
34 | // createCanvas(800, 400);
35 | // background(30); // alpha
36 | // noFill();
37 |
38 | // // carrier.freq(340);
39 | // carrier.amp(0);
40 | // // carrier's amp is 0 by default, giving our modulator total control
41 |
42 | // carrier.loop();
43 |
44 | // modulator = new p5sound.Oscillator('triangle');
45 | // modulator.disconnect(); // disconnect the modulator from main output
46 | // modulator.freq(5);
47 | // modulator.amp(1);
48 | // modulator.start();
49 |
50 | // // Modulate the carrier's amplitude with the modulator
51 | // // Optionally, we can scale the signal.
52 | // carrier.amp(modulator.scale(-1, 1, 1, -1));
53 |
54 | // // create an fft to analyze the audio
55 | // fft = new p5sound.FFT();
56 | // }
57 |
58 | // function draw() {
59 | // background(30, 30, 30, 100); // alpha
60 |
61 | // // map mouseY to moodulator freq between 0 and 20hz
62 | // var modFreq = map(mouseY, 0, height, 4, 0);
63 | // modulator.freq(modFreq);
64 |
65 | // var modAmp = map(mouseX, 0, width, 0, 1);
66 | // modulator.amp(modAmp, 0.01); // fade time of 0.1 for smooth fading
67 |
68 | // // analyze the waveform
69 | // waveform = fft.waveform();
70 |
71 | // // draw the shape of the waveform
72 | // stroke(240);
73 | // strokeWeight(4);
74 | // beginShape();
75 | // for (var i = 0; i < waveform.length; i++) {
76 | // var x = map(i, 0, waveform.length, 0, width);
77 | // var y = map(waveform[i], -1, 1, -height / 2, height / 2);
78 | // vertex(x, y + height / 2);
79 | // }
80 | // endShape();
81 | // }
82 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme/layouts/main.handlebars:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | p5.js | reference
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
p5.Envelope: An Envelope is a series
21 | * of fades over time. Often used to control an object's
22 | * output gain level as an "ADSR Envelope" (Attack, Decay,
23 | * Sustain, Release). Can also modulate other parameters.
24 | *
p5.Delay: A delay effect with
25 | * parameters for feedback, delayTime, and lowpass filter.
26 | *
p5.Filter: Filter the frequency range of a
27 | * sound.
28 | *
29 | *
p5.Reverb: Add reverb to a sound by specifying
30 | * duration and decay.