├── test ├── node │ ├── helpers.js │ └── test-docs-preprocessor.js ├── manual-test-examples │ ├── addons │ │ └── p5.sound │ │ │ ├── peakDetect │ │ │ ├── sketch.js │ │ │ └── index.html │ │ │ ├── _files │ │ │ ├── beat.mp3 │ │ │ ├── beat.ogg │ │ │ ├── drum.mp3 │ │ │ ├── drum.ogg │ │ │ ├── beatbox.mp3 │ │ │ ├── beatbox.ogg │ │ │ ├── doorbell.mp3 │ │ │ ├── doorbell.ogg │ │ │ ├── studio-b.mp3 │ │ │ ├── studio-b.ogg │ │ │ ├── bx-spring.mp3 │ │ │ ├── bx-spring.ogg │ │ │ ├── small-plate.mp3 │ │ │ ├── small-plate.ogg │ │ │ ├── concrete-tunnel.mp3 │ │ │ ├── concrete-tunnel.ogg │ │ │ ├── large-dark-plate.mp3 │ │ │ ├── large-dark-plate.ogg │ │ │ ├── Damscray_-_Dancing_Tiger_01.mp3 │ │ │ ├── Damscray_-_Dancing_Tiger_01.ogg │ │ │ ├── Damscray_-_Dancing_Tiger_02.mp3 │ │ │ ├── Damscray_-_Dancing_Tiger_02.ogg │ │ │ ├── lucky_dragons_-_power_melody.mp3 │ │ │ └── lucky_dragons_-_power_melody.ogg │ │ │ ├── micFFT │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── record │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── PulseFFT │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── micLevel │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── noiseMod_AM │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── outOfPhase │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── recordLoops │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── waveform │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── Filter_BandPass │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── Filter_LowPass │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── Reverb_basic │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── Reverb_convolve │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── looper_simple │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── micLevel_on_off │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── oscillatorMod_AM │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── oscillatorMod_FM │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── pan_soundfile │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── pause_soundfile │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── peakDetect_basic │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── play_soundfile │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── playbackRate │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── soundFormats │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── soundfileMod_AM │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── Reverb_convolve_FFT │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── envelope │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── loadSound_callback │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── loadSound_preload │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── oscillatorWaveform │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── oscillator_FMSynth │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── soundfile_playMode │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── DelaySoundFile │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── FFT_freqRange │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── FFT_waveform_2 │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── autoCorrelation │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── envelopeOnOff │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── oscillatorSecondsFromNow │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── waveform_with_playhead │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── DelayNoiseEnvelope │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── amplitude_analysis │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ ├── waveform_peaks_with_playhead │ │ │ ├── index.html │ │ │ └── sketch.js │ │ │ └── FFT_frequency_spectrum │ │ │ ├── index.html │ │ │ └── sketch.js │ ├── empty-example │ │ ├── sketch.js │ │ └── index.html │ ├── styles.css │ └── module.html ├── js │ ├── mocha_setup.js │ ├── chai_helpers.js │ └── p5_helpers.js ├── unit │ ├── assets │ │ ├── beat.mp3 │ │ └── cat.webm │ ├── sound │ │ └── oscillator.js │ ├── spec.js │ └── core │ │ └── version.js ├── reporter │ └── simple.js ├── test-minified.html └── test.html ├── fragments ├── after.frag └── before.frag ├── utils └── sample-linter.js ├── .github ├── FUNDING.yml ├── labeler.yml ├── workflows │ ├── ci-lint.yml │ └── ci-test.yml ├── config.yml ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE │ ├── feature-request.yml │ ├── existing-feature-enhancement.yml │ └── found-a-bug.yml ├── docs ├── yuidoc-p5-theme │ ├── assets │ │ ├── blobs.csv │ │ ├── mammals.csv │ │ ├── Bold.ttf │ │ ├── beat.mp3 │ │ ├── beat.ogg │ │ ├── drum.mp3 │ │ ├── drum.ogg │ │ ├── mask.png │ │ ├── Italic.ttf │ │ ├── bricks.jpg │ │ ├── mask2.png │ │ ├── small.mp4 │ │ ├── small.ogv │ │ ├── small.webm │ │ ├── Damscray.mp3 │ │ ├── Damscray.ogg │ │ ├── Regular.otf │ │ ├── beatbox.mp3 │ │ ├── beatbox.ogg │ │ ├── bx-spring.mp3 │ │ ├── bx-spring.ogg │ │ ├── doorbell.mp3 │ │ ├── doorbell.ogg │ │ ├── drawImage.png │ │ ├── favicon.ico │ │ ├── fingers.mov │ │ ├── gradient.png │ │ ├── laDefense.jpg │ │ ├── moonwalk.jpg │ │ ├── rockies.jpg │ │ ├── studio-b.mp3 │ │ ├── studio-b.ogg │ │ ├── Damscray_01.mp3 │ │ ├── Damscray_01.ogg │ │ ├── Damscray_02.mp3 │ │ ├── Damscray_02.ogg │ │ ├── inconsolata.otf │ │ ├── laDefense50.png │ │ ├── rockies128.jpg │ │ ├── small-plate.mp3 │ │ ├── small-plate.ogg │ │ ├── bricks_third.jpg │ │ ├── lucky_dragons.mp3 │ │ ├── lucky_dragons.ogg │ │ ├── test.txt │ │ ├── concrete-tunnel.mp3 │ │ ├── concrete-tunnel.ogg │ │ ├── large-dark-plate.mp3 │ │ ├── large-dark-plate.ogg │ │ ├── fonts │ │ │ ├── inconsolata.eot │ │ │ ├── inconsolata.otf │ │ │ ├── inconsolata.ttf │ │ │ └── inconsolata.woff │ │ ├── Damscray_DancingTiger.mp3 │ │ ├── transformation-matrix.png │ │ ├── shader.vert │ │ ├── transformation-matrix-4-4.png │ │ ├── Damscray_-_Dancing_Tiger_01.ogg │ │ ├── Damscray_-_Dancing_Tiger_02.mp3 │ │ ├── arnott-wallace-wink-loop-once.gif │ │ ├── nancy-liang-wind-loop-forever.gif │ │ ├── arnott-wallace-eye-loop-forever.gif │ │ ├── mammals.xml │ │ ├── octahedron.obj │ │ ├── shader.frag │ │ ├── shader-gradient.frag │ │ └── img │ │ │ └── p5js.svg │ ├── helpers │ │ └── helpers_prod.js │ └── layouts │ │ └── main.handlebars └── documented-method.js ├── src ├── audioWorklet │ ├── processorNames.js │ ├── .eslintrc │ ├── soundFileProcessor.js │ ├── index.js │ ├── recorderProcessor.js │ └── amplitudeProcessor.js ├── constants.js ├── errorHandler.js ├── audioContext.js └── app.js ├── .editorconfig ├── .gitignore ├── .vscode └── extensions.json ├── notes.md ├── .eslintrc.json ├── tasks ├── build │ ├── eslint-samples.js │ ├── browserify.js │ └── combineModules.js └── test │ └── mocha-chrome.js ├── package.json └── README.md /test/node/helpers.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /fragments/after.frag: -------------------------------------------------------------------------------- 1 | })); -------------------------------------------------------------------------------- /utils/sample-linter.js: -------------------------------------------------------------------------------- 1 | // placeholder file -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/peakDetect/sketch.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/js/mocha_setup.js: -------------------------------------------------------------------------------- 1 | mocha.setup('tdd'); 2 | mocha.reporter('html'); 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: processing 2 | custom: https://processingfoundation.org/ 3 | -------------------------------------------------------------------------------- /test/unit/assets/beat.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/unit/assets/beat.mp3 -------------------------------------------------------------------------------- /test/unit/assets/cat.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/unit/assets/cat.webm -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/blobs.csv: -------------------------------------------------------------------------------- 1 | ID,Name,Flavor,Shape,Color 2 | Blob1,Blobby,Sweet,Blob,Pink 3 | Blob2,Saddy,Savory,Blob,Blue -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/mammals.csv: -------------------------------------------------------------------------------- 1 | id,species,name 2 | 0,Capra hircus,Goat 3 | 1,Panthera pardus,Leopard 4 | 2,Equus zebra,Zebra -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Bold.ttf -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/beat.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/beat.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/beat.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/beat.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/drum.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/drum.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/drum.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/drum.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/mask.png -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Italic.ttf -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/bricks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/bricks.jpg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/mask2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/mask2.png -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/small.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/small.mp4 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/small.ogv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/small.ogv -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/small.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/small.webm -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Damscray.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Damscray.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Damscray.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Damscray.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Regular.otf -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/beatbox.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/beatbox.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/beatbox.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/beatbox.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/bx-spring.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/bx-spring.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/bx-spring.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/bx-spring.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/doorbell.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/doorbell.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/doorbell.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/doorbell.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/drawImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/drawImage.png -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/favicon.ico -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/fingers.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/fingers.mov -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/gradient.png -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/laDefense.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/laDefense.jpg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/moonwalk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/moonwalk.jpg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/rockies.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/rockies.jpg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/studio-b.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/studio-b.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/studio-b.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/studio-b.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Damscray_01.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Damscray_01.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Damscray_01.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Damscray_01.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Damscray_02.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Damscray_02.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Damscray_02.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Damscray_02.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/inconsolata.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/inconsolata.otf -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/laDefense50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/laDefense50.png -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/rockies128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/rockies128.jpg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/small-plate.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/small-plate.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/small-plate.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/small-plate.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/bricks_third.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/bricks_third.jpg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/lucky_dragons.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/lucky_dragons.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/lucky_dragons.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/lucky_dragons.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/test.txt: -------------------------------------------------------------------------------- 1 | I am a cat 2 | I like apples 3 | I have three feet 4 | I like my nose 5 | I smell like butter 6 | I talk like an orange -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/concrete-tunnel.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/concrete-tunnel.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/concrete-tunnel.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/concrete-tunnel.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/large-dark-plate.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/large-dark-plate.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/large-dark-plate.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/large-dark-plate.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/fonts/inconsolata.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/fonts/inconsolata.eot -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/fonts/inconsolata.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/fonts/inconsolata.otf -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/fonts/inconsolata.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/fonts/inconsolata.ttf -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/fonts/inconsolata.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/fonts/inconsolata.woff -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Damscray_DancingTiger.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Damscray_DancingTiger.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/transformation-matrix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/transformation-matrix.png -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/shader.vert: -------------------------------------------------------------------------------- 1 | precision highp float; varying vec2 vPos; 2 | attribute vec3 aPosition; 3 | void main() { vPos = (gl_Position = vec4(aPosition,1.0)).xy; } 4 | -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/transformation-matrix-4-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/transformation-matrix-4-4.png -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/beat.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/beat.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/beat.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/beat.ogg -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/drum.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/drum.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/drum.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/drum.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Damscray_-_Dancing_Tiger_01.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Damscray_-_Dancing_Tiger_01.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/Damscray_-_Dancing_Tiger_02.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/Damscray_-_Dancing_Tiger_02.mp3 -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/arnott-wallace-wink-loop-once.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/arnott-wallace-wink-loop-once.gif -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/nancy-liang-wind-loop-forever.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/nancy-liang-wind-loop-forever.gif -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/beatbox.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/beatbox.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/beatbox.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/beatbox.ogg -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/doorbell.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/doorbell.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/doorbell.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/doorbell.ogg -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/studio-b.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/studio-b.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/studio-b.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/studio-b.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/arnott-wallace-eye-loop-forever.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/docs/yuidoc-p5-theme/assets/arnott-wallace-eye-loop-forever.gif -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/bx-spring.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/bx-spring.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/bx-spring.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/bx-spring.ogg -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/small-plate.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/small-plate.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/small-plate.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/small-plate.ogg -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/concrete-tunnel.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/concrete-tunnel.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/concrete-tunnel.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/concrete-tunnel.ogg -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/large-dark-plate.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/large-dark-plate.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/large-dark-plate.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/large-dark-plate.ogg -------------------------------------------------------------------------------- /src/audioWorklet/processorNames.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // amplitudeProcessor: 'amplitude-processor' 3 | // recorderProcessor: 'recorder-processor', 4 | soundFileProcessor: 'sound-file-processor' 5 | }; 6 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/Damscray_-_Dancing_Tiger_01.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/Damscray_-_Dancing_Tiger_01.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/Damscray_-_Dancing_Tiger_01.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/Damscray_-_Dancing_Tiger_01.ogg -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/Damscray_-_Dancing_Tiger_02.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/Damscray_-_Dancing_Tiger_02.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/Damscray_-_Dancing_Tiger_02.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/Damscray_-_Dancing_Tiger_02.ogg -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/lucky_dragons_-_power_melody.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/lucky_dragons_-_power_melody.mp3 -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/_files/lucky_dragons_-_power_melody.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing/p5.sound.js-ARCHIVE/HEAD/test/manual-test-examples/addons/p5.sound/_files/lucky_dragons_-_power_melody.ogg -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/mammals.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Goat 4 | Leopard 5 | Zebra 6 | -------------------------------------------------------------------------------- /test/manual-test-examples/empty-example/sketch.js: -------------------------------------------------------------------------------- 1 | // function setup() { 2 | // // put setup code here 3 | // createCanvas(windowWidth, windowHeight); 4 | // } 5 | 6 | // function draw() { 7 | // // put drawing code here 8 | // background(0); 9 | // } 10 | -------------------------------------------------------------------------------- /src/audioWorklet/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | "currentFrame": true, 4 | "currentTime": true, 5 | "sampleRate": true, 6 | "preval": true 7 | }, 8 | "parserOptions": { 9 | "sourceType": "module" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @module Constants 3 | * @submodule Constants 4 | * @for p5sound 5 | */ 6 | 7 | /** 8 | * Version of this p5sound.js. 9 | * @property {String} VERSION 10 | * @final 11 | */ 12 | export const VERSION = 13 | 'VERSION_CONST_WILL_BE_REPLACED_BY_BROWSERIFY_BUILD_PROCESS'; 14 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/micFFT/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/record/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/PulseFFT/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/micLevel/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/noiseMod_AM/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/outOfPhase/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/peakDetect/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/recordLoops/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/waveform/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/Filter_BandPass/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/Filter_LowPass/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/Reverb_basic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/Reverb_convolve/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/looper_simple/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/micLevel_on_off/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/oscillatorMod_AM/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/oscillatorMod_FM/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/pan_soundfile/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/pause_soundfile/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/peakDetect_basic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/play_soundfile/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/playbackRate/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/soundFormats/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/soundfileMod_AM/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig: http://EditorConfig.org 2 | 3 | # Top-most EditorConfig file 4 | root = true 5 | 6 | # Rules for JavaScript files: 7 | 8 | [*.js] 9 | # 2 space indentation 10 | indent_style = space 11 | indent_size = 2 12 | # No trailing spaces 13 | trim_trailing_whitespace = true 14 | # Unix-style newlines 15 | end_of_line = lf 16 | # Newline ending every file 17 | insert_final_newline = true 18 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/Reverb_convolve_FFT/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/envelope/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/loadSound_callback/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/loadSound_preload/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/oscillatorWaveform/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/oscillator_FMSynth/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/soundfile_playMode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/octahedron.obj: -------------------------------------------------------------------------------- 1 | v 0.000000E+00 0.000000E+00 40.0000 2 | v 22.5000 22.5000 0.000000E+00 3 | v 22.5000 -22.5000 0.000000E+00 4 | v -22.5000 -22.5000 0.000000E+00 5 | v -22.5000 22.5000 0.000000E+00 6 | v 0.000000E+00 0.000000E+00 -40.0000 7 | 8 | f 1 2 3 9 | f 1 3 4 10 | f 1 4 5 11 | f 1 5 2 12 | f 6 5 4 13 | f 6 4 3 14 | f 6 3 2 15 | f 6 2 1 16 | f 6 1 5 17 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/DelaySoundFile/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/FFT_freqRange/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/FFT_waveform_2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/autoCorrelation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/envelopeOnOff/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/oscillatorSecondsFromNow/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/waveform_with_playhead/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/DelayNoiseEnvelope/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/amplitude_analysis/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/waveform_peaks_with_playhead/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/FFT_frequency_spectrum/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/unit/sound/oscillator.js: -------------------------------------------------------------------------------- 1 | const Oscillator = require('../../../src/Oscillator.js'); 2 | 3 | let assert = require('chai').assert; 4 | suite('Array', function () { 5 | suite('audio', function () { 6 | test('oscillator is an audioNode', function () { 7 | assert.typeOf(new Oscillator('sine', 400), 'function'); 8 | }); 9 | }); 10 | }); 11 | 12 | 13 | // test('should be a function', function () { 14 | // // assert.ok(myp5sound.abs); 15 | // assert.typeOf(100, 'number'); 16 | // }); -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/micLevel/sketch.js: -------------------------------------------------------------------------------- 1 | // /** 2 | // * Make some noise to float the ellipse 3 | // */ 4 | 5 | // function setup() { 6 | // createCanvas(400, 400); 7 | // mic = new p5sound.AudioIn(); 8 | // mic.start(); 9 | // } 10 | 11 | // function draw() { 12 | // background(0); 13 | 14 | // // getLevel takes an optional smoothing value, or defaults to 0.0 15 | // micLevel = mic.getLevel(); 16 | // ellipse(width / 2, height - micLevel * height, 100, 100); 17 | // } 18 | -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/shader.frag: -------------------------------------------------------------------------------- 1 | precision highp float; varying vec2 vPos; 2 | uniform vec2 p; 3 | uniform float r; 4 | const int I = 500; 5 | void main() { 6 | vec2 c = p + vPos * r, z = c; 7 | float n = 0.0; 8 | for (int i = I; i > 0; i --) { 9 | if(z.x*z.x+z.y*z.y > 4.0) { 10 | n = float(i)/float(I); 11 | break; 12 | } 13 | z = vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y) + c; 14 | } 15 | gl_FragColor = vec4(0.5-cos(n*17.0)/2.0,0.5-cos(n*13.0)/2.0,0.5-cos(n*23.0)/2.0,1.0); 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Apple 2 | *.DS_STORE 3 | 4 | 5 | .project 6 | 7 | # Node.js 8 | node_modules/* 9 | 10 | experiments/* 11 | lib/p5.sound* 12 | lib/modules 13 | docs/reference/* 14 | !*.gitkeep 15 | examples/3d/ 16 | .idea 17 | dist/ 18 | p5.sound.zip 19 | bower-repo/ 20 | p5-website/ 21 | 22 | # Visual Studio Code 23 | .vscode/settings.json 24 | .nyc_output/* 25 | coverage/ 26 | 27 | release/ 28 | parameterData.json 29 | yarn.lock 30 | 31 | # examples being tested use p5.js on the assets folder 32 | examples/assets/*.js -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | "Area:Accessibility": 2 | - '\[[xX]\]\s*Accessibility' 3 | "Area:Core": 4 | - '\[[xX]\]\s*Core' 5 | "Area:Data": 6 | - '\[[xX]\]\s*Data' 7 | "Area:Events": 8 | - '\[[xX]\]\s*Events' 9 | "Area:IO": 10 | - '\[[xX]\]\s*IO' 11 | "Area:Utilities": 12 | - '\[[xX]\]\s*Utilities' 13 | "Build Process": 14 | - '\[[xX]\]\s*Build Process' 15 | "Unit Testing": 16 | - '\[[xX]\]\s*Unit Testing' 17 | "Internalization": 18 | - '\[[xX]\]\s*Internalization' 19 | "Friendly Errors": 20 | - '\[[xX]\]\s*Friendly Errors' 21 | -------------------------------------------------------------------------------- /test/unit/spec.js: -------------------------------------------------------------------------------- 1 | let spec = { 2 | core: [ 3 | '2d_primitives', 4 | 'attributes', 5 | 'environment', 6 | 'error_helpers', 7 | 'main', 8 | 'preload', 9 | 'rendering', 10 | 'structure', 11 | 'version' 12 | ] 13 | }; 14 | Object.keys(spec).map(function(folder) { 15 | spec[folder].map(function(file) { 16 | let string = [ 17 | '' 22 | ]; 23 | document.write(string.join('')); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /test/manual-test-examples/styles.css: -------------------------------------------------------------------------------- 1 | html, body {margin:0; padding:0;} 2 | 3 | header { 4 | width: 100%; 5 | position: absolute; 6 | color: black; 7 | background-color: rgba(240, 240, 240, 0.75); 8 | font-family: Arial, Helvetica, sans-serif; 9 | font-size: 105%; 10 | } 11 | 12 | header p { 13 | width: 100%; 14 | text-align: center; 15 | } 16 | 17 | #gl-info { 18 | font-family: Arial, Helvetica, sans-serif; 19 | position: absolute; 20 | top:0; 21 | right: 0; 22 | background:rgba(255, 255, 255, 0.5); 23 | padding:5px; 24 | font-size: 10px; 25 | } 26 | -------------------------------------------------------------------------------- /.github/workflows/ci-lint.yml: -------------------------------------------------------------------------------- 1 | name: Linting Code 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - '*' 10 | 11 | jobs: 12 | lint: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v1 17 | - name: Use Node.js 18.x 18 | uses: actions/setup-node@v1 19 | with: 20 | node-version: 18.x 21 | - name: Get node modules 22 | run: npm ci 23 | env: 24 | CI: true 25 | - name: Lint source code 26 | run: npm run lint 27 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. 3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 4 | 5 | // List of extensions which should be recommended for users of this workspace. 6 | "recommendations": [ 7 | "eg2.vscode-npm-script", 8 | "yzhang.markdown-all-in-one", 9 | "dbaeumer.vscode-eslint" 10 | ], 11 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace. 12 | "unwantedRecommendations": [] 13 | } 14 | -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/helpers/helpers_prod.js: -------------------------------------------------------------------------------- 1 | var configHelpers = {}; 2 | 3 | // For production, the reference docs are put in the /reference/ folder 4 | // of the p5 website, so we'll define our paths with this assumption. 5 | // For more context, see https://github.com/processing/p5.js-website. 6 | var config = { 7 | p5SiteRoot: '..', 8 | p5Lib: '../js/p5.min.js', 9 | p5SoundLib: '../js/p5.sound.min.js' 10 | }; 11 | 12 | Object.keys(config).forEach(function(key) { 13 | configHelpers[key] = function() { 14 | return config[key]; 15 | }; 16 | }); 17 | 18 | module.exports = configHelpers; 19 | -------------------------------------------------------------------------------- /test/manual-test-examples/module.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.github/workflows/ci-test.yml: -------------------------------------------------------------------------------- 1 | name: Testing 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - '*' 10 | 11 | jobs: 12 | test: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v1 17 | - name: Use Node.js 18.x 18 | uses: actions/setup-node@v1 19 | with: 20 | node-version: 18.x 21 | - name: Get node modules 22 | run: npm ci 23 | env: 24 | CI: true 25 | - name: build and test 26 | run: npm test 27 | env: 28 | CI: true 29 | 30 | -------------------------------------------------------------------------------- /test/js/chai_helpers.js: -------------------------------------------------------------------------------- 1 | // Setup chai 2 | // let expect = chai.expect; 3 | let assert = chai.assert; 4 | 5 | assert.arrayApproximately = function(arr1, arr2, delta) { 6 | assert.equal(arr1.length, arr2.length); 7 | for(let i = 0; i < arr1.length; i++) { 8 | assert.approximately(arr1[i], arr2[i], delta); 9 | } 10 | }; 11 | 12 | // a custom assertion for validation errors that correctly handles 13 | // minified p5 libraries. 14 | assert.validationError = function(fn) { 15 | if (p5sound.ValidationError) { 16 | assert.throws(fn, p5sound.ValidationError); 17 | } else { 18 | assert.doesNotThrow(fn, Error, 'got unwanted exception'); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/shader-gradient.frag: -------------------------------------------------------------------------------- 1 | // Code adopted from "Creating a Gradient Color in Fragment Shader" 2 | // by Bahadır on stackoverflow.com 3 | // https://stackoverflow.com/questions/47376499/creating-a-gradient-color-in-fragment-shader 4 | 5 | 6 | precision highp float; varying vec2 vPos; 7 | uniform vec2 offset; 8 | uniform vec3 colorCenter; 9 | uniform vec3 colorBackground; 10 | 11 | void main() { 12 | 13 | vec2 st = vPos.xy + offset.xy; 14 | 15 | // color1 = vec3(1.0,0.55,0); 16 | // color2 = vec3(0.226,0.000,0.615); 17 | 18 | float mixValue = distance(st,vec2(0,1)); 19 | vec3 color = mix(colorCenter,colorBackground,mixValue); 20 | 21 | gl_FragColor = vec4(color,mixValue); 22 | } -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/micFFT/sketch.js: -------------------------------------------------------------------------------- 1 | // /** 2 | // * Visualize the frequency spectrum of live audio input 3 | // */ 4 | 5 | // var mic, fft; 6 | 7 | // function setup() { 8 | // createCanvas(512, 400); 9 | // noStroke(); 10 | // fill(0, 255, 255); 11 | 12 | // mic = new p5sound.AudioIn(); 13 | // mic.start(); 14 | // fft = new p5sound.FFT(); 15 | // fft.setInput(mic); 16 | // } 17 | 18 | // function draw() { 19 | // background(200); 20 | // var spectrum = fft.analyze(); 21 | 22 | // beginShape(); 23 | // vertex(0, height); 24 | // for (i = 0; i < spectrum.length; i++) { 25 | // vertex(i, map(spectrum[i], 0, 255, height, 0)); 26 | // } 27 | // endShape(); 28 | // } 29 | -------------------------------------------------------------------------------- /test/manual-test-examples/empty-example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |

Empty Example

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 |
26 | 27 | 28 |
29 | 30 | 31 | 32 | 33 |

Processing Intuition times JavaScript power

34 |
35 | 36 |
37 |
38 | 39 |

Reference

40 | 41 | 42 |
43 | 44 | 45 |
46 |
47 |
48 | 49 |
50 | 51 | 56 |
57 | 58 | 59 |

 

60 |
61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /test/manual-test-examples/addons/p5.sound/FFT_frequency_spectrum/sketch.js: -------------------------------------------------------------------------------- 1 | // /** 2 | // * This example draws the frequency spectrum of a sound by using 3 | // * the p5sound.FFT object's analyze() method. 4 | // * 5 | // * FFT is a Fast Fourier Transform function that calculates 6 | // * amplitude across the frequency spectrum. The analyze() method returns 7 | // * an array of values. These values represent how much volume exists in a 8 | // * sound at various frequencies (or pitches). The beginning of the 9 | // * array represents the lowest frequencies (bass), and the end of the 10 | // * array represents the highest frequencies (treble). 11 | // * 12 | // * By default, the array length is 1024. We can determine the size of the array by including 13 | // * an optional parameter, but the number must be a power of 2 between 14 | // * 16 and 1024. 15 | // */ 16 | 17 | // var soundFile; 18 | // var fft; 19 | // var fftBands = 512; 20 | 21 | // var description = 'loading'; 22 | // var p; 23 | 24 | // // This will be an array of amplitude values from lowest to highest frequencies 25 | // var frequencySpectrum = []; 26 | 27 | // function preload() { 28 | // soundFormats('mp3', 'ogg'); 29 | // soundFile = loadSound('../_files/lucky_dragons'); 30 | // } 31 | 32 | // function setup() { 33 | // createCanvas(fftBands, 256); 34 | // fill(255, 40, 255); 35 | 36 | // // loop the sound file 37 | // soundFile.loop(); 38 | 39 | // fft = new p5sound.FFT(); 40 | 41 | // // update description text 42 | // p = createP(description); 43 | // var p2 = createP( 44 | // 'Draw the array returned by FFT.analyze( ). This represents the frequency spectrum, from lowest to highest frequencies.' 45 | // ); 46 | 47 | // // set the master volume; 48 | // masterVolume(0.5); 49 | // } 50 | 51 | // function draw() { 52 | // background(30); 53 | 54 | // // update the description if the sound is playing 55 | // updateDescription(); 56 | 57 | // /** 58 | // * Analyze the sound. 59 | // * Return array of frequency volumes, from lowest to highest frequencies. 60 | // */ 61 | // frequencySpectrum = fft.analyze(); 62 | 63 | // // Draw every value in the frequencySpectrum array as a rectangle 64 | // noStroke(); 65 | // for (var i = 0; i < fftBands; i++) { 66 | // var x = map(i, 0, fftBands, 0, width); 67 | // var h = -height + map(frequencySpectrum[i], 0, 255, height, 0); 68 | // rect(x, height, width / fftBands, h); 69 | // } 70 | // } 71 | 72 | // // Change description text if the song is loading, playing or paused 73 | // function updateDescription() { 74 | // if (soundFile.isPaused()) { 75 | // description = 'Paused...'; 76 | // p.html(description); 77 | // } else if (soundFile.isPlaying()) { 78 | // description = 'Playing! Press any key to pause'; 79 | // p.html(description); 80 | // } else { 81 | // for (var i = 0; i < frameCount % 3; i++) { 82 | // // add periods to loading to create a fun loading bar effect 83 | // if (frameCount % 4 === 0) { 84 | // description += '.'; 85 | // } 86 | // if (frameCount % 25 === 0) { 87 | // description = 'loading'; 88 | // } 89 | // } 90 | // p.html(description); 91 | // } 92 | // } 93 | 94 | // // pause the song if a key is pressed 95 | // function keyPressed() { 96 | // if (soundFile.isPlaying()) { 97 | // soundFile.pause(); 98 | // } else { 99 | // soundFile.play(); 100 | // } 101 | // } 102 | -------------------------------------------------------------------------------- /src/audioWorklet/recorderProcessor.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 | 5 | class RecorderProcessor extends AudioWorkletProcessor { 6 | constructor(options) { 7 | super(); 8 | 9 | const processorOptions = options.processorOptions || {}; 10 | this.numOutputChannels = options.outputChannelCount || 2; 11 | this.numInputChannels = processorOptions.numInputChannels || 2; 12 | this.bufferSize = processorOptions.bufferSize || 1024; 13 | this.recording = false; 14 | 15 | this.clear(); 16 | 17 | this.port.onmessage = event => { 18 | const data = event.data; 19 | if (data.name === 'start') { 20 | this.record(data.duration); 21 | } else if (data.name === 'stop') { 22 | this.stop(); 23 | } 24 | }; 25 | } 26 | 27 | process(inputs) { 28 | if (!this.recording) { 29 | return true; 30 | } else if (this.sampleLimit && this.recordedSamples >= this.sampleLimit) { 31 | this.stop(); 32 | return true; 33 | } 34 | 35 | const input = inputs[0]; 36 | 37 | this.inputRingBuffer.push(input); 38 | 39 | if (this.inputRingBuffer.framesAvailable >= this.bufferSize) { 40 | this.inputRingBuffer.pull(this.inputRingBufferArraySequence); 41 | 42 | for (let channel = 0; channel < this.numOutputChannels; ++channel) { 43 | const inputChannelCopy = 44 | this.inputRingBufferArraySequence[channel].slice(); 45 | if (channel === 0) { 46 | this.leftBuffers.push(inputChannelCopy); 47 | if (this.numInputChannels === 1) { 48 | this.rightBuffers.push(inputChannelCopy); 49 | } 50 | } else if (channel === 1 && this.numInputChannels > 1) { 51 | this.rightBuffers.push(inputChannelCopy); 52 | } 53 | } 54 | 55 | this.recordedSamples += this.bufferSize; 56 | } 57 | return true; 58 | } 59 | 60 | record(duration) { 61 | if (duration) { 62 | this.sampleLimit = Math.round(duration * sampleRate); 63 | } 64 | this.recording = true; 65 | } 66 | 67 | stop() { 68 | this.recording = false; 69 | const buffers = this.getBuffers(); 70 | const leftBuffer = buffers[0].buffer; 71 | const rightBuffer = buffers[1].buffer; 72 | this.port.postMessage( 73 | { name: 'buffers', leftBuffer: leftBuffer, rightBuffer: rightBuffer }, 74 | [leftBuffer, rightBuffer] 75 | ); 76 | this.clear(); 77 | } 78 | 79 | getBuffers() { 80 | const buffers = []; 81 | buffers.push(this.mergeBuffers(this.leftBuffers)); 82 | buffers.push(this.mergeBuffers(this.rightBuffers)); 83 | return buffers; 84 | } 85 | 86 | mergeBuffers(channelBuffer) { 87 | let result = new Float32Array(this.recordedSamples); 88 | let offset = 0; 89 | let lng = channelBuffer.length; 90 | for (let i = 0; i < lng; i++) { 91 | let buffer = channelBuffer[i]; 92 | result.set(buffer, offset); 93 | offset += buffer.length; 94 | } 95 | return result; 96 | } 97 | 98 | clear() { 99 | this.leftBuffers = []; 100 | this.rightBuffers = []; 101 | this.inputRingBuffer = new RingBuffer( 102 | this.bufferSize, 103 | this.numInputChannels 104 | ); 105 | this.inputRingBufferArraySequence = new Array(this.numInputChannels) 106 | .fill(null) 107 | .map(() => new Float32Array(this.bufferSize)); 108 | this.recordedSamples = 0; 109 | this.sampleLimit = null; 110 | } 111 | } 112 | 113 | registerProcessor(processorNames.recorderProcessor, RecorderProcessor); 114 | -------------------------------------------------------------------------------- /docs/yuidoc-p5-theme/assets/img/p5js.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tasks/test/mocha-chrome.js: -------------------------------------------------------------------------------- 1 | /* Grunt Task to test mocha in a local Chrome instance */ 2 | 3 | const puppeteer = require('puppeteer'); 4 | const util = require('util'); 5 | const mapSeries = require('promise-map-series'); 6 | const fs = require('fs'); 7 | const EventEmitter = require('events'); 8 | 9 | const mkdir = util.promisify(fs.mkdir); 10 | const writeFile = util.promisify(fs.writeFile); 11 | 12 | module.exports = function(grunt) { 13 | grunt.registerMultiTask('mochaChrome', async function() { 14 | const done = this.async(); 15 | 16 | // Launch Chrome in headless mode 17 | const browser = await puppeteer.launch({ 18 | headless: true, 19 | args: ['--no-sandbox', '--disable-setuid-sandbox'] 20 | }); 21 | 22 | try { 23 | // options here come from `Gruntfile.js` > `mochaConfig.test` 24 | const options = this.data.options; 25 | 26 | for (const testURL of options.urls) { 27 | const event = new EventEmitter(); 28 | const page = await browser.newPage(); 29 | 30 | try { 31 | // Using eval to start the test in the browser 32 | // A 'mocha:end' event will be triggered with test runner end 33 | await page.evaluateOnNewDocument(` 34 | addEventListener('DOMContentLoaded', () => { 35 | if (typeof mocha !== 'undefined') { 36 | const _mochaRun = mocha.run.bind(mocha); 37 | mocha.reporter('spec'); 38 | mocha.color(true); 39 | mocha.run = function(fn) { 40 | debugger; 41 | var runner = _mochaRun(function(stats) { 42 | if (typeof fn === 'function') 43 | return fn(stats); 44 | }); 45 | 46 | runner.on('end', () => { 47 | const results = { stats: runner.stats, coverage: window.__coverage__ } 48 | fireMochaEvent('mocha:end', results); 49 | }); 50 | 51 | return runner; 52 | }; 53 | } 54 | }); 55 | `); 56 | 57 | // Pipe console messages from the browser to the terminal 58 | page.on('console', async msg => { 59 | const args = await mapSeries(msg.args(), v => v.jsonValue()); 60 | console.log(util.format.apply(util, args)); 61 | }); 62 | 63 | // Wait for test end function to be called and emit on the event 64 | await page.exposeFunction('fireMochaEvent', event.emit.bind(event)); 65 | 66 | await new Promise(async (resolve, reject) => { 67 | // When test end, check if there are any failures and record coverage 68 | event.on('mocha:end', async results => { 69 | const { stats, coverage } = results; 70 | if (stats.failures) { 71 | reject(stats); 72 | } 73 | await saveCoverage(coverage); 74 | resolve(stats); 75 | }); 76 | 77 | // Nagivate to URL and start test 78 | await page.goto(testURL); 79 | }); 80 | } finally { 81 | await page.close(); 82 | } 83 | } 84 | 85 | done(); 86 | } catch (e) { 87 | if (e instanceof Error) { 88 | done(e); 89 | } else { 90 | done(new Error(e)); 91 | } 92 | } finally { 93 | await browser.close(); 94 | } 95 | }); 96 | }; 97 | 98 | async function saveCoverage(cov) { 99 | if (cov) { 100 | try { 101 | await mkdir('./.nyc_output/', { recursive: true }); 102 | await writeFile('./.nyc_output/out.json', JSON.stringify(cov)); 103 | } catch (e) { 104 | console.error(e); 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /fragments/before.frag: -------------------------------------------------------------------------------- 1 | /** 2 | *

p5.sound extends p5 with Web Audio functionality including audio input, 4 | * playback, analysis and synthesis. 5 | *

6 | *