├── docs
├── img
│ ├── .gitignore
│ ├── sublime.png
│ ├── first_sketch.png
│ ├── test-image-0.jpg
│ ├── test-image-1.jpg
│ ├── thick-asterisk-alone.svg
│ ├── thick-asterisk-alone-stroke.svg
│ ├── thick-asterisk-alone.txt
│ └── thick-asterisk-alone-gray.svg
├── css
│ └── f
│ │ ├── inconsolata.eot
│ │ ├── inconsolata.otf
│ │ ├── inconsolata.ttf
│ │ ├── inconsolata.woff
│ │ ├── AvenirNextLTW01-Medium.eot
│ │ ├── AvenirNextLTW01-Medium.ttf
│ │ └── AvenirNextLTW01-Medium.woff
├── reference
│ ├── assets
│ │ ├── css
│ │ │ ├── logo.png
│ │ │ └── external-small.png
│ │ ├── favicon.png
│ │ ├── img
│ │ │ └── spinner.gif
│ │ ├── index.html
│ │ ├── js
│ │ │ ├── yui-prettify.js
│ │ │ └── api-filter.js
│ │ └── vendor
│ │ │ └── prettify
│ │ │ └── prettify-min.css
│ └── api.js
├── wiki-assets
│ ├── before-after.png
│ ├── browser-tests.png
│ ├── file-architecture.png
│ └── mocha-chrome-tests.png
├── yuidoc-p5-theme-src
│ └── scripts
│ │ ├── tpl
│ │ ├── search.html
│ │ ├── itemEnd.html
│ │ ├── menu.html
│ │ ├── search_suggestion.html
│ │ ├── library.html
│ │ ├── list.html
│ │ └── class.html
│ │ ├── .jshintrc
│ │ ├── config.js
│ │ ├── views
│ │ ├── menuView.js
│ │ └── pageView.js
│ │ ├── vendor
│ │ └── bootstrap
│ │ │ ├── transition.js
│ │ │ └── alert.js
│ │ └── main.js
├── yuidoc-p5-theme
│ └── package.json
├── js
│ └── main.js
└── progress.txt
├── fragments
└── after.frag
├── .prettierrc
├── .eslintignore
├── .prettierignore
├── .babelrc
├── .github
├── FUNDING.yml
└── workflows
│ ├── ci-test.yml
│ └── ci-lint.yml
├── examples
├── files
│ ├── beat.mp3
│ ├── beat.ogg
│ ├── drum.mp3
│ ├── drum.ogg
│ ├── Tripping.mp3
│ ├── Tripping.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_DancingTiger.mp3
│ ├── Damscray_DancingTiger.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
│ └── Soni_Ventorum_Wind_Quintet_-_08_-_Danzi_Wind_Quintet_Op_67_No_3_In_E-Flat_Major_4_Allegretto.mp3
├── bells_envelope_test
│ ├── assets
│ │ └── LadyChapelStAlbansCathedral.wav
│ └── index.html
├── Compressor
│ └── index.html
├── envExp
│ └── index.html
├── envelope
│ ├── index.html
│ └── sketch.js
├── grid_sequencer
│ └── index.html
├── micFFT
│ ├── index.html
│ └── sketch.js
├── outOfPhase
│ ├── index.html
│ └── sketch.js
├── record
│ ├── index.html
│ └── sketch.js
├── Reverb_basic
│ ├── index.html
│ └── sketch.js
├── Reverb_convolve
│ ├── index.html
│ └── sketch.js
├── _sound_loop
│ ├── index.html
│ └── sketch.js
├── array_of_notes
│ ├── index.html
│ └── sketch.js
├── envelopeOnOff
│ ├── index.html
│ └── sketch.js
├── fractal_music
│ └── index.html
├── graphical_eq
│ └── index.html
├── looper_simple
│ ├── index.html
│ └── sketch.js
├── micLevel
│ ├── index.html
│ └── sketch.js
├── noiseMod_AM
│ └── index.html
├── pan_soundfile
│ ├── index.html
│ └── sketch.js
├── pause_soundfile
│ ├── index.html
│ └── sketch.js
├── peakDetect
│ └── index.html
├── playbackRate
│ ├── index.html
│ └── sketch.js
├── recordLoops
│ ├── index.html
│ └── sketch.js
├── removeSketch
│ ├── index.html
│ └── sketch.js
├── soundfileMod_AM
│ └── index.html
├── spatial_panning
│ ├── index.html
│ └── sketch.js
├── virtual_piano
│ ├── index.html
│ └── sketch.js
├── waveform
│ ├── index.html
│ └── sketch.js
├── DelayNoiseEnvelope
│ ├── index.html
│ └── sketch.js
├── FFT_freqRange
│ ├── index.html
│ └── sketch.js
├── FFT_linAverages
│ └── index.html
├── FFT_logAverages
│ └── index.html
├── Reverb_convolve_FFT
│ └── index.html
├── _monosynth_basic
│ ├── index.html
│ └── sketch.js
├── audioIn_Multiple_Sources
│ └── index.html
├── autoCorrelation
│ ├── index.html
│ └── sketch.js
├── envelope_designer
│ └── index.html
├── granular_sampler
│ └── index.html
├── loadSound_callback
│ ├── index.html
│ └── sketch.js
├── loop_stepSequencer
│ ├── index.html
│ └── sketch.js
├── micLevel_on_off
│ ├── index.html
│ └── sketch.js
├── mixingSounds
│ ├── index.html
│ └── sketch.js
├── onended_callback
│ ├── index.html
│ └── sketch.js
├── oscillatorMod_AM
│ └── index.html
├── oscillatorMod_FM
│ └── index.html
├── oscillatorWaveform
│ └── index.html
├── oscillator_FMSynth
│ ├── index.html
│ └── sketch.js
├── playbackRatePart
│ ├── index.html
│ └── sketch.js
├── polyphonicSynth-Keyboard
│ └── index.html
├── pulseWaveform
│ ├── index.html
│ └── sketch.js
├── soundFormats
│ ├── index.html
│ └── sketch.js
├── soundfile_playMode
│ ├── index.html
│ └── sketch.js
├── soundfile_remove_cue
│ ├── index.html
│ └── sketch.js
├── visualize_pentatonic
│ └── index.html
├── FFT_scaleNeighbors
│ ├── index.html
│ └── sketch.js
├── amplitude_analysis
│ ├── index.html
│ └── sketch.js
├── array_of_notes_soundloop
│ └── index.html
├── envelopeMultipleSources
│ └── index.html
├── loadSound_preload
│ ├── index.html
│ └── sketch.js
├── oscillatorSecondsFromNow
│ ├── index.html
│ └── sketch.js
├── play_soundfile
│ ├── index.html
│ └── sketch.js
├── FFT_frequency_spectrum
│ └── index.html
├── FFT_scaleOneThirdOctave
│ └── index.html
├── Filter_BandPass
│ ├── index.html
│ └── sketch.js
├── Filter_LowPass
│ ├── index.html
│ └── sketch.js
├── granular_sampler_psynth
│ └── index.html
├── loadSound_404ErrorHandling
│ ├── index.html
│ └── sketch.js
├── waveform_peaks_with_playhead
│ ├── index.html
│ └── sketch.js
├── learningProcessingExamples
│ ├── 04_pan
│ │ ├── index.html
│ │ └── sketch.js
│ ├── 06_noise
│ │ ├── index.html
│ │ └── sketch.js
│ ├── 07_envelope
│ │ ├── index.html
│ │ └── sketch.js
│ ├── 09_live_input
│ │ ├── index.html
│ │ └── sketch.js
│ ├── 01c_soundFormats
│ │ ├── index.html
│ │ └── sketch.js
│ ├── 02_sound_effect
│ │ ├── index.html
│ │ └── sketch.js
│ ├── 10_mic_threshold
│ │ ├── index.html
│ │ └── sketch.js
│ ├── 01a_loadSound_playback
│ │ ├── index.html
│ │ └── sketch.js
│ ├── 03_manipulate_sound
│ │ ├── index.html
│ │ └── sketch.js
│ ├── 06_oscillator_frequency
│ │ ├── index.html
│ │ └── sketch.js
│ ├── 08_amplitude_analysis
│ │ ├── index.html
│ │ └── sketch.js
│ └── 01b_preloadSound_playback
│ │ ├── index.html
│ │ └── sketch.js
├── peakDetect_basic
│ ├── index.html
│ └── sketch.js
├── genetic_music
│ └── index.html
├── markov_music
│ └── index.html
├── envAmpFreq
│ ├── index.html
│ └── sketch.js
├── distortion
│ ├── index.html
│ └── sketch.js
├── envelopeRamp
│ ├── index.html
│ └── sketch.js
├── _polyphonic_synth
│ └── index.html
├── envelope_exponential_play
│ ├── index.html
│ └── sketch.js
├── envelope_exponential_trig_rel
│ ├── index.html
│ └── sketch.js
├── spatial_panning_listener
│ ├── flock.js
│ └── index.html
└── loadSound_with_Drag_and_Drop
│ ├── index.html
│ └── sketch.js
├── test
├── testAudio
│ ├── drum.mp3
│ ├── drum.ogg
│ ├── bx-spring.mp3
│ └── bx-spring.ogg
├── tests
│ ├── p5.OnsetDetect.js
│ ├── p5.AudioContext.js
│ ├── p5.PeakDetect.js
│ ├── p5.AudioVoice.js
│ ├── p5.Panner.js
│ ├── p5.Noise.js
│ ├── p5.Gain.js
│ ├── p5.Pulse.js
│ ├── main.js
│ └── p5.Metro.js
├── index.html
├── setup.js
└── tests.js
├── .gitignore
├── src
├── deprecations
│ └── Signal.js
├── audioWorklet
│ ├── processorNames.js
│ ├── .eslintrc
│ ├── index.js
│ └── soundFileProcessor.js
├── eqFilter.js
├── audioVoice.js
├── onsetDetect.js
└── errorHandler.js
├── .editorconfig
├── templates
└── pre-commit-hook.js
├── .eslintrc
├── LICENSE
├── package.json
├── webpack.config.js
└── gh-page
└── generator.js
/docs/img/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/fragments/after.frag:
--------------------------------------------------------------------------------
1 | }));
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true
3 | }
4 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | Gruntfile.js
2 | webpack.config.js
3 | lib/
4 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | Gruntfile.js
2 | webpack.config.js
3 | lib/
4 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "plugins": ["preval"]
4 | }
5 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: processing
2 | custom: https://processingfoundation.org/
3 |
--------------------------------------------------------------------------------
/docs/img/sublime.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/img/sublime.png
--------------------------------------------------------------------------------
/examples/files/beat.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/beat.mp3
--------------------------------------------------------------------------------
/examples/files/beat.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/beat.ogg
--------------------------------------------------------------------------------
/examples/files/drum.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/drum.mp3
--------------------------------------------------------------------------------
/examples/files/drum.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/drum.ogg
--------------------------------------------------------------------------------
/test/testAudio/drum.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/test/testAudio/drum.mp3
--------------------------------------------------------------------------------
/test/testAudio/drum.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/test/testAudio/drum.ogg
--------------------------------------------------------------------------------
/docs/css/f/inconsolata.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/css/f/inconsolata.eot
--------------------------------------------------------------------------------
/docs/css/f/inconsolata.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/css/f/inconsolata.otf
--------------------------------------------------------------------------------
/docs/css/f/inconsolata.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/css/f/inconsolata.ttf
--------------------------------------------------------------------------------
/docs/css/f/inconsolata.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/css/f/inconsolata.woff
--------------------------------------------------------------------------------
/docs/img/first_sketch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/img/first_sketch.png
--------------------------------------------------------------------------------
/docs/img/test-image-0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/img/test-image-0.jpg
--------------------------------------------------------------------------------
/docs/img/test-image-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/img/test-image-1.jpg
--------------------------------------------------------------------------------
/examples/files/Tripping.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/Tripping.mp3
--------------------------------------------------------------------------------
/examples/files/Tripping.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/Tripping.ogg
--------------------------------------------------------------------------------
/examples/files/beatbox.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/beatbox.mp3
--------------------------------------------------------------------------------
/examples/files/beatbox.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/beatbox.ogg
--------------------------------------------------------------------------------
/examples/files/doorbell.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/doorbell.mp3
--------------------------------------------------------------------------------
/examples/files/doorbell.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/doorbell.ogg
--------------------------------------------------------------------------------
/examples/files/studio-b.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/studio-b.mp3
--------------------------------------------------------------------------------
/examples/files/studio-b.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/studio-b.ogg
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | docs
2 | node_modules
3 | examples/__test
4 | p5soundnotes
5 | *.DS_Store
6 | .vscode
7 | lib/p5.*
8 |
--------------------------------------------------------------------------------
/examples/files/bx-spring.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/bx-spring.mp3
--------------------------------------------------------------------------------
/examples/files/bx-spring.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/bx-spring.ogg
--------------------------------------------------------------------------------
/test/testAudio/bx-spring.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/test/testAudio/bx-spring.mp3
--------------------------------------------------------------------------------
/test/testAudio/bx-spring.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/test/testAudio/bx-spring.ogg
--------------------------------------------------------------------------------
/examples/files/small-plate.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/small-plate.mp3
--------------------------------------------------------------------------------
/examples/files/small-plate.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/small-plate.ogg
--------------------------------------------------------------------------------
/docs/reference/assets/css/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/reference/assets/css/logo.png
--------------------------------------------------------------------------------
/docs/reference/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/reference/assets/favicon.png
--------------------------------------------------------------------------------
/docs/wiki-assets/before-after.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/wiki-assets/before-after.png
--------------------------------------------------------------------------------
/docs/wiki-assets/browser-tests.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/wiki-assets/browser-tests.png
--------------------------------------------------------------------------------
/examples/files/concrete-tunnel.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/concrete-tunnel.mp3
--------------------------------------------------------------------------------
/examples/files/concrete-tunnel.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/concrete-tunnel.ogg
--------------------------------------------------------------------------------
/docs/css/f/AvenirNextLTW01-Medium.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/css/f/AvenirNextLTW01-Medium.eot
--------------------------------------------------------------------------------
/docs/css/f/AvenirNextLTW01-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/css/f/AvenirNextLTW01-Medium.ttf
--------------------------------------------------------------------------------
/docs/reference/assets/img/spinner.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/reference/assets/img/spinner.gif
--------------------------------------------------------------------------------
/examples/files/large-dark-plate.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/large-dark-plate.mp3
--------------------------------------------------------------------------------
/examples/files/large-dark-plate.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/large-dark-plate.ogg
--------------------------------------------------------------------------------
/docs/css/f/AvenirNextLTW01-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/css/f/AvenirNextLTW01-Medium.woff
--------------------------------------------------------------------------------
/docs/wiki-assets/file-architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/wiki-assets/file-architecture.png
--------------------------------------------------------------------------------
/docs/wiki-assets/mocha-chrome-tests.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/wiki-assets/mocha-chrome-tests.png
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/tpl/search.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/files/Damscray_DancingTiger.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/Damscray_DancingTiger.mp3
--------------------------------------------------------------------------------
/examples/files/Damscray_DancingTiger.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/Damscray_DancingTiger.ogg
--------------------------------------------------------------------------------
/docs/reference/assets/css/external-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/docs/reference/assets/css/external-small.png
--------------------------------------------------------------------------------
/examples/files/Damscray_-_Dancing_Tiger_01.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/Damscray_-_Dancing_Tiger_01.mp3
--------------------------------------------------------------------------------
/examples/files/Damscray_-_Dancing_Tiger_01.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/Damscray_-_Dancing_Tiger_01.ogg
--------------------------------------------------------------------------------
/examples/files/Damscray_-_Dancing_Tiger_02.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/Damscray_-_Dancing_Tiger_02.mp3
--------------------------------------------------------------------------------
/examples/files/Damscray_-_Dancing_Tiger_02.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/Damscray_-_Dancing_Tiger_02.ogg
--------------------------------------------------------------------------------
/examples/files/lucky_dragons_-_power_melody.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/lucky_dragons_-_power_melody.mp3
--------------------------------------------------------------------------------
/examples/files/lucky_dragons_-_power_melody.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/lucky_dragons_-_power_melody.ogg
--------------------------------------------------------------------------------
/examples/bells_envelope_test/assets/LadyChapelStAlbansCathedral.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/bells_envelope_test/assets/LadyChapelStAlbansCathedral.wav
--------------------------------------------------------------------------------
/src/deprecations/Signal.js:
--------------------------------------------------------------------------------
1 | class Signal {
2 | constructor() {
3 | console.warn('p5.Signal is deprecated , Use Tone.js Signal instead ');
4 | }
5 | }
6 |
7 | export default Signal;
8 |
--------------------------------------------------------------------------------
/src/audioWorklet/processorNames.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | recorderProcessor: 'recorder-processor',
3 | soundFileProcessor: 'sound-file-processor',
4 | amplitudeProcessor: 'amplitude-processor',
5 | };
6 |
--------------------------------------------------------------------------------
/examples/files/Soni_Ventorum_Wind_Quintet_-_08_-_Danzi_Wind_Quintet_Op_67_No_3_In_E-Flat_Major_4_Allegretto.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wetdog/p5.js-sound/main/examples/files/Soni_Ventorum_Wind_Quintet_-_08_-_Danzi_Wind_Quintet_Op_67_No_3_In_E-Flat_Major_4_Allegretto.mp3
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/docs/reference/assets/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Redirector
5 |
6 |
7 |
8 | Click here to redirect
9 |
10 |
11 |
--------------------------------------------------------------------------------
/examples/Compressor/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/envExp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/envelope/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/grid_sequencer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/micFFT/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/outOfPhase/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/record/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/Reverb_basic/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/Reverb_convolve/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/_sound_loop/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/array_of_notes/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/envelopeOnOff/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/fractal_music/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/graphical_eq/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/looper_simple/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/micLevel/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/noiseMod_AM/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/pan_soundfile/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/pause_soundfile/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/peakDetect/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/playbackRate/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/recordLoops/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/removeSketch/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/soundfileMod_AM/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/spatial_panning/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/virtual_piano/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/waveform/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/DelayNoiseEnvelope/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/FFT_freqRange/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/FFT_linAverages/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/FFT_logAverages/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/Reverb_convolve_FFT/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/_monosynth_basic/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/audioIn_Multiple_Sources/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/autoCorrelation/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/envelope_designer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/granular_sampler/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/loadSound_callback/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/loop_stepSequencer/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/micLevel_on_off/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/mixingSounds/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/onended_callback/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/oscillatorMod_AM/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/oscillatorMod_FM/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/oscillatorWaveform/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/oscillator_FMSynth/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/playbackRatePart/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/polyphonicSynth-Keyboard/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/pulseWaveform/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/soundFormats/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/soundfile_playMode/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/soundfile_remove_cue/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/visualize_pentatonic/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/FFT_scaleNeighbors/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/amplitude_analysis/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/array_of_notes_soundloop/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/envelopeMultipleSources/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/loadSound_preload/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/oscillatorSecondsFromNow/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/play_soundfile/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/FFT_frequency_spectrum/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/FFT_scaleOneThirdOctave/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/Filter_BandPass/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/examples/Filter_LowPass/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/examples/granular_sampler_psynth/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/loadSound_404ErrorHandling/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/waveform_peaks_with_playhead/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/04_pan/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/06_noise/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/07_envelope/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/09_live_input/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/01c_soundFormats/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/02_sound_effect/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/10_mic_threshold/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/01a_loadSound_playback/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/03_manipulate_sound/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/06_oscillator_frequency/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/08_amplitude_analysis/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/01b_preloadSound_playback/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.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
--------------------------------------------------------------------------------
/examples/peakDetect_basic/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Click canvas to play the beat!
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/genetic_music/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/markov_music/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/micLevel/sketch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Make some noise to float the ellipse
3 | */
4 |
5 | function setup() {
6 | createCanvas(400,400);
7 | mic = new p5.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 | }
--------------------------------------------------------------------------------
/examples/envAmpFreq/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | click to trigger amplitude and frequency envelopes
13 |
14 |
--------------------------------------------------------------------------------
/examples/distortion/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | click to trigger saw oscillator through heavy distortion
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/tpl/itemEnd.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/tpl/menu.html:
--------------------------------------------------------------------------------
1 |
2 | <% var i=0; %>
3 | <% var max=Math.floor(groups.length/4); %>
4 | <% var rem=groups.length%max; %>
5 |
6 | <% _.each(groups, function(group){ %>
7 | <% var m = rem > 0 ? 1 : 0 %>
8 | <% if (i === 0) { %>
9 |
10 | <% } %>
11 | - <%=group%>
12 | <% if (i === (max+m-1)) { %>
13 |
14 | <% rem-- %>
15 | <% i=0 %>
16 | <% } else { %>
17 | <% i++ %>
18 | <% } %>
19 | <% }); %>
--------------------------------------------------------------------------------
/examples/onended_callback/sketch.js:
--------------------------------------------------------------------------------
1 | var soundFile;
2 |
3 | function preload() {
4 | soundFile = loadSound(['../files/beat.mp3', '../files/beat.ogg']);
5 | }
6 |
7 | function setup() {
8 | soundFile.onended(sayDone);
9 | soundFile.rate(3);
10 | soundFile.play();
11 | }
12 |
13 | function sayDone(sf) {
14 | console.log('Done playing: ');
15 | console.log(sf);
16 | console.log('Expect the argument to equal the soundfile that just ended playback: ')
17 | console.log(sf === this);
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Api Reference",
3 | "version": "0.0.1",
4 | "description": "An yuidoc theme with bootstrap 3 and backbone.js",
5 | "main": "index.html",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": ""
12 | },
13 | "keywords": [
14 | "yuidoc",
15 | "bootstrap"
16 | ],
17 | "author": "Esteban Almiron",
18 | "bugs": {
19 | "url": ""
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/examples/envelopeRamp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | envelope_ramp
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/tpl/search_suggestion.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%=name%>
4 |
5 |
6 | <% if (final) { %>
7 | constant
8 | <% } else if (itemtype) { %>
9 | <%=itemtype%>
10 | <% } %>
11 |
12 | <% if (className) { %>
13 | in <%=className%>
14 | <% } %>
15 |
16 | <% if (is_constructor) { %>
17 | constructor
18 | <% } %>
19 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/bells_envelope_test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | bells_envelope_test
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/test/tests/p5.OnsetDetect.js:
--------------------------------------------------------------------------------
1 | const expect = chai.expect;
2 |
3 | describe('p5.OnsetDetect', function () {
4 | it('can be initalized ', function () {
5 | const onsetDetect = new p5.OnsetDetect(40, 120, 0.8, () => {});
6 | expect(onsetDetect.freqLow).to.equal(40);
7 | expect(onsetDetect.freqHigh).to.equal(120);
8 | expect(onsetDetect.treshold).to.equal(0.8);
9 | expect(onsetDetect.energy).to.equal(0);
10 | });
11 |
12 | describe('methods', function () {
13 | //TODO : test update functions by mocking or using a FFT
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/examples/_polyphonic_synth/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/06_noise/sketch.js:
--------------------------------------------------------------------------------
1 | // Adapted from Learning Processing
2 | // Daniel Shiffman
3 | // http://www.learningprocessing.com
4 |
5 | // Example: Make Some Noise
6 |
7 | var noise;
8 |
9 | function setup() {
10 | createCanvas(780, 200);
11 | noise = new p5.Noise(); // other types include 'brown' and 'pink'
12 | noise.start();
13 | }
14 |
15 | function draw() {
16 | background(0);
17 |
18 | var vol = map(mouseX, 0, width, 0, 1);
19 | noise.amp(vol);
20 | vol = constrain(vol, 0, 1);
21 | ellipse(mouseX, 100, 32, 32);
22 | }
--------------------------------------------------------------------------------
/examples/envelope_exponential_play/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | envelope_exponential_play
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/examples/_monosynth_basic/sketch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Play a random note
3 | * every time you press a key
4 | */
5 |
6 | var monoSynth;
7 |
8 | function setup() {
9 | monoSynth = new p5.MonoSynth();
10 |
11 | createCanvas(400, 400);
12 | text('press to play a random note at a random velocity', 20, 20);
13 | }
14 |
15 | function mousePressed() {
16 | // pick a random midi note
17 | var midiVal = midiToFreq(round( random(50,72) ));
18 | monoSynth.triggerAttack(midiVal, random() );
19 | }
20 |
21 | function mouseReleased() {
22 | monoSynth.triggerRelease();
23 | }
24 |
--------------------------------------------------------------------------------
/examples/envelope_exponential_trig_rel/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | envelope_exponential_trig_rel
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/01a_loadSound_playback/sketch.js:
--------------------------------------------------------------------------------
1 | // Adapted from Learning Processing by Daniel Shiffman
2 | // http://www.learningprocessing.com
3 |
4 | var song;
5 |
6 | function setup() {
7 | song = loadSound('../../files/lucky_dragons_-_power_melody.mp3');
8 | createCanvas(640, 360);
9 | background(255,0,0);
10 | }
11 |
12 | function mousePressed() {
13 | if ( song.isPlaying() ) { // .isPlaying() returns a boolean
14 | song.stop();
15 | background(255,0,0);
16 | } else {
17 | song.play();
18 | background(0,255,0);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/docs/reference/assets/js/yui-prettify.js:
--------------------------------------------------------------------------------
1 | YUI().use('node', function(Y) {
2 | var code = Y.all('.prettyprint.linenums');
3 | if (code.size()) {
4 | code.each(function(c) {
5 | var lis = c.all('ol li'),
6 | l = 1;
7 | lis.each(function(n) {
8 | n.prepend('');
9 | l++;
10 | });
11 | });
12 | var h = location.hash;
13 | location.hash = '';
14 | h = h.replace('LINE_', 'LINENUM_');
15 | location.hash = h;
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "boss": true,
3 | "eqeqeq": true,
4 | "eqnull": true,
5 | "immed": true,
6 | "latedef": "nofunc",
7 | "newcap": false,
8 | "noarg": true,
9 | "quotmark": "single",
10 | "undef": true,
11 | "unused": "vars",
12 |
13 | "node": true,
14 |
15 | "trailing": true,
16 | "curly": true,
17 | "indent": 2,
18 |
19 | "globals": {
20 | "window": true,
21 | "$": true,
22 | "jQuery": true,
23 | "console": true,
24 | "module": true,
25 | "define": false,
26 | "require": false
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | TESTS
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/js/main.js:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Hastily written scroll to fixed position:
4 |
5 | TO DO:
6 |
7 | - needs to not fail on resize of resize after scrolling,
8 | - and needs to use animate() to add jquery easing
9 |
10 | */
11 |
12 | var elementPosition = $('#menu').offset();
13 |
14 | $(window).scroll(function(){
15 | if($(window).scrollTop() > elementPosition.top){
16 | $('#menu').css({'position':'fixed','top':'0', 'z-index': '9999'});
17 |
18 | } else {
19 | $('#menu').css({'position':'static'});
20 | }
21 | });
22 |
23 | window.onload = function() {
24 | //renderCode('demo');
25 | }
--------------------------------------------------------------------------------
/examples/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 p5.AudioIn();
13 | mic.start();
14 | fft = new p5.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
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/docs/reference/assets/vendor/prettify/prettify-min.css:
--------------------------------------------------------------------------------
1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/tpl/library.html:
--------------------------------------------------------------------------------
1 | <%= module.name %>
2 |
3 | <%= module.description %>
4 |
5 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/04_pan/sketch.js:
--------------------------------------------------------------------------------
1 | // Adapted from Learning Processing
2 | // Daniel Shiffman
3 | // http://www.learningprocessing.com
4 |
5 | var song;
6 |
7 | function preload() {
8 | song = loadSound('../../files/Damscray_DancingTiger.mp3');
9 | }
10 |
11 | function setup() {
12 | createCanvas(720, 200);
13 | song.loop();
14 | }
15 |
16 | function draw() {
17 | background(200);
18 | // Map mouseX to a panning value (between -1.0 and 1.0)
19 | var panning = map(mouseX, 0., width, -1.0, 1.0);
20 | panning = constrain(panning, -1.0, 1.0);
21 | song.pan(panning);
22 |
23 | // Draw a circle
24 | stroke(0);
25 | fill(51, 100);
26 | ellipse(mouseX, 100, 48, 48);
27 | }
--------------------------------------------------------------------------------
/.github/workflows/ci-test.yml:
--------------------------------------------------------------------------------
1 | name: Testing
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | pull_request:
7 | branches: [ main ]
8 |
9 | jobs:
10 | test:
11 | runs-on: ubuntu-latest
12 | strategy:
13 | matrix:
14 | node-version: [10.x, 12.x]
15 |
16 |
17 | steps:
18 | - uses: actions/checkout@v1
19 | - name: Use Node.js ${{ matrix.node-version }}
20 | uses: actions/setup-node@v1
21 | with:
22 | node-version: ${{ matrix.node-version }}
23 | - name: Get node modules
24 | run: npm ci
25 | env:
26 | CI: true
27 | - name: Build
28 | run: npm run build
29 | env:
30 | CI: true
31 |
--------------------------------------------------------------------------------
/examples/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 p5.TriOsc();
7 | osc.freq(260);
8 | createP('mousePressed: set amplitude to .7 over the course of .2 seconds');
9 | createP('mouseReleased: 1 second fade to 0. Start the fade 0.5 seconds from now');
10 | }
11 |
12 | function mousePressed () {
13 | osc.start();
14 | // fade amplitude to .7 over the course of .2 seconds
15 | osc.amp(0.7, 0.002);
16 | }
17 |
18 | function mouseReleased() {
19 | // fade amplitude to zero over the course of 1 second. Start the fade after .5 seconds.
20 | osc.amp(0, 0.2, 0.5);
21 | }
22 |
--------------------------------------------------------------------------------
/examples/loadSound_404ErrorHandling/sketch.js:
--------------------------------------------------------------------------------
1 | // error handler
2 |
3 | function setup() {
4 | createCanvas(800,200);
5 | loadSound('http://badURL.mp3', soundReady, soundError);
6 | loadSound('../badPath.mp3', soundReady, soundError);
7 |
8 | createConvolver('http://badURL.mp3', soundReady, soundError);
9 | createConvolver('../badPath.mp3', soundReady, soundError);
10 | }
11 |
12 | function soundReady(soundFile){
13 | soundFile.play();
14 | }
15 |
16 | // the error has the following properties:
17 | function soundError(e) {
18 | console.log('New error:');
19 | console.log('- name: ' + e.name);
20 | console.log('- message: ' + e.message);
21 | console.log('- stack: ' + e.stack);
22 | console.log('- failed path: ' + e.failedPath);
23 | }
--------------------------------------------------------------------------------
/examples/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_-_Dancing_Tiger_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 p5.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 | }
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/01b_preloadSound_playback/sketch.js:
--------------------------------------------------------------------------------
1 | // loadSound during preload()
2 | // This ensures it will be loaded and ready to play by setup()
3 |
4 | var song;
5 |
6 | function preload() {
7 | song = loadSound('../../files/lucky_dragons_-_power_melody.mp3');
8 | }
9 |
10 | function setup() {
11 | createCanvas(720, 200);
12 | song.loop(); // song is ready to play during setup() because it was loaded during preload
13 | background(0,255,0);
14 | }
15 |
16 | function mousePressed() {
17 | if ( song.isPlaying() ) { // .isPlaying() returns a boolean
18 | song.pause(); // .play() will resume from .pause() position
19 | background(255,0,0);
20 | } else {
21 | song.play();
22 | background(0,255,0);
23 | }
24 | }
--------------------------------------------------------------------------------
/docs/img/thick-asterisk-alone.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/docs/img/thick-asterisk-alone-stroke.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/docs/img/thick-asterisk-alone.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
--------------------------------------------------------------------------------
/test/tests/p5.AudioContext.js:
--------------------------------------------------------------------------------
1 | const expect = chai.expect;
2 |
3 | describe('p5.AudioContext', function () {
4 | describe('getAudioContext', function () {
5 | it('returns a audioContext', function () {
6 | let audioContext = p5.prototype.getAudioContext();
7 | expect(audioContext).to.have.property('baseLatency').to.be.an('number');
8 | expect(audioContext).to.have.property('destination');
9 | expect(audioContext).to.have.property('state').to.be.an('string');
10 | });
11 | });
12 |
13 | describe('userStartAudio', function () {
14 | it('can get initialized and returns a promise', function (done) {
15 | let startAudio = p5.prototype.userStartAudio();
16 | startAudio.then(() => {
17 | done();
18 | });
19 | });
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/examples/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 setup() {
9 | createCanvas(400, 400);
10 | background(0);
11 |
12 | // create a SoundFile
13 | soundFile = loadSound( ['../files/beatbox.ogg', '../files/beatbox.mp3'] );
14 |
15 | createP('Press any key to play the sound');
16 | }
17 |
18 | // when a key is pressed...
19 | function keyPressed() {
20 |
21 | // play the sound file
22 | soundFile.play();
23 |
24 | // also make the background yellow
25 | background(255, 255, 0);
26 | }
27 |
28 | function keyReleased() {
29 | // make the background black again when the key is released
30 | background(0);
31 | }
32 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/tpl/list.html:
--------------------------------------------------------------------------------
1 |
6 |
7 | <% _.each(groups, function(group){ %>
8 | <%=group.name%>
9 |
10 | <% _.each(group.subgroups, function(subgroup, ind) { %>
11 |
12 | <% if (subgroup.name !== '0') { %>
13 | - <%=subgroup.name%>
14 | <% } %>
15 | <% _.each(subgroup.items, function(item) { %>
16 | - <%=item.name%><% if (item.itemtype === 'method') { %>()<%}%>
17 | <% }); %>
18 |
19 | <% }); %>
20 |
21 | <% }); %>
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/.github/workflows/ci-lint.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: Linting
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 | jobs:
13 | lint:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | strategy:
18 | matrix:
19 | node-version: [10.x, 12.x]
20 |
21 | steps:
22 | - uses: actions/checkout@v2
23 | - name: Use Node.js ${{ matrix.node-version }}
24 | uses: actions/setup-node@v1
25 | with:
26 | node-version: ${{ matrix.node-version }}
27 | - run: npm ci
28 | - run: npm run lint
29 |
--------------------------------------------------------------------------------
/examples/peakDetect_basic/sketch.js:
--------------------------------------------------------------------------------
1 | var cnv, soundFile, fft, peakDetect;
2 | var ellipseWidth = 10;
3 |
4 | function setup() {
5 | cnv = createCanvas(100,100);
6 |
7 | soundFile = loadSound('../files/beat.mp3');
8 | fft = new p5.FFT();
9 | peakDetect = new p5.PeakDetect();
10 |
11 | setupSound();
12 | }
13 |
14 | function draw() {
15 | background(0);
16 |
17 | fft.analyze();
18 | peakDetect.update(fft);
19 |
20 | if ( peakDetect.isDetected ) {
21 | ellipseWidth = 50;
22 | } else {
23 | ellipseWidth *= 0.95;
24 | }
25 |
26 | ellipse(width/2, height/2, ellipseWidth, ellipseWidth);
27 | }
28 |
29 |
30 | function setupSound() {
31 | cnv.mouseClicked( function() {
32 | if (soundFile.isPlaying() ) {
33 | soundFile.stop();
34 | } else {
35 | soundFile.play();
36 | }
37 | });
38 | }
--------------------------------------------------------------------------------
/examples/loadSound_callback/sketch.js:
--------------------------------------------------------------------------------
1 | // Sound samples from Damscray - "Dancing Tiger",
2 | // Creative Commons BY-NC-SA
3 |
4 |
5 | function setup() {
6 | createCanvas(400,200);
7 | soundFormats('ogg', 'mp3');
8 | soundFile = loadSound('../files/Damscray_-_Dancing_Tiger_01', soundReady);
9 | }
10 |
11 | function soundReady(){
12 | soundFile.rate(1.75);
13 | soundFile.loop();
14 |
15 | text('File is ready! Click to pause / unpause', 50, 10);
16 |
17 | // draw the waveform
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 | }
--------------------------------------------------------------------------------
/examples/loadSound_preload/sketch.js:
--------------------------------------------------------------------------------
1 | // Sound samples from Damscray - "Dancing Tiger",
2 | // Creative Commons BY-NC-SA
3 |
4 |
5 | function preload(){
6 | soundFormats('ogg', 'mp3');
7 | soundFile = loadSound('../files/Damscray_-_Dancing_Tiger_01');
8 | }
9 |
10 | function setup() {
11 | createCanvas(400,200);
12 |
13 | text('File is ready! Click to pause / play.', 50, 10);
14 |
15 | soundFile.rate(.8);
16 | soundFile.reverseBuffer();
17 | soundFile.loop();
18 |
19 | peaks = soundFile.getPeaks();
20 | beginShape();
21 | for (i = 0; i< peaks.length; i++){
22 | vertex(map(i, 0, peaks.length, 0, width), map(peaks[i], -1, 1, height, 0) );
23 | }
24 | endShape();
25 |
26 | }
27 |
28 | function mousePressed(){
29 | if (soundFile.isPlaying()){
30 | soundFile.pause();
31 | } else {
32 | soundFile.play();
33 | }
34 | }
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/06_oscillator_frequency/sketch.js:
--------------------------------------------------------------------------------
1 | // Adapted from Learning Processing
2 | // Daniel Shiffman
3 | // http://www.learningprocessing.com
4 |
5 | // Example: Oscillator Frequency
6 |
7 | var osc;
8 |
9 | function setup() {
10 | createCanvas(720, 200);
11 |
12 | // Instantiate a Sine Wave Oscillator
13 | osc = new p5.SinOsc();
14 |
15 | // Tell the Oscillator to start oscillating.
16 | // We hear the frequency of these oscillators as a pitch.
17 | osc.start();
18 |
19 | // Oscillator has an output amplitude of 0.5 by default.
20 | // We can make it louder.
21 | osc.amp(1);
22 | }
23 |
24 | function draw() {
25 | background(200);
26 |
27 | // map the mouseX to set frequency of the between 40 and 880 Hz
28 | var freq = map(mouseX, 0, width, 40, 880);
29 | osc.freq(freq);
30 | ellipse(mouseX, 100, 32, 32);
31 | }
--------------------------------------------------------------------------------
/docs/img/thick-asterisk-alone-gray.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/examples/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 |
--------------------------------------------------------------------------------
/templates/pre-commit-hook.js:
--------------------------------------------------------------------------------
1 | // hooks/pre-commit.js
2 |
3 | const exec = require('child_process').exec;
4 | // Executes shell commands synchronously
5 | const sh = require('child_process').execSync;
6 |
7 | exec('git diff --cached --quiet', function (err, stdout, stderr) {
8 |
9 | // only run if there are staged changes
10 | // i.e. what you would be committing if you ran "git commit" without "-a" option.
11 | if (err) {
12 |
13 | // stash unstaged changes - only test what's being committed
14 | sh('git stash --keep-index --quiet');
15 |
16 | exec('grunt {{task}}', function (err, stdout, stderr) {
17 |
18 | console.log(stdout);
19 |
20 | // restore stashed changes
21 | sh('git stash pop --quiet');
22 |
23 | let exitCode = 0;
24 | if (err) {
25 | console.log(stderr);
26 | exitCode = -1;
27 | }
28 | process.exit(exitCode);
29 | });
30 | }
31 |
32 | });
--------------------------------------------------------------------------------
/test/tests/p5.PeakDetect.js:
--------------------------------------------------------------------------------
1 | const expect = chai.expect;
2 |
3 | describe('p5.PeakDetect', function () {
4 | it('can be initialized without any arguments', function () {
5 | const peakDetect = new p5.PeakDetect();
6 | expect(peakDetect.cutoff).to.equal(0);
7 | expect(peakDetect.framesSinceLastPeak).to.equal(0);
8 | expect(peakDetect.energy).to.equal(0);
9 | expect(peakDetect.isDetected).to.equal(false);
10 | });
11 | it('can be initialized with arguemts', function () {
12 | const peakDetect = new p5.PeakDetect(40, 120, 0.8, 20);
13 | expect(peakDetect.f1).to.equal(40);
14 | expect(peakDetect.f2).to.equal(120);
15 | expect(peakDetect.threshold).to.equal(0.8);
16 | expect(peakDetect.framesPerPeak).to.equal(20);
17 | });
18 | describe('methods', function () {
19 | //TODO : test update, onPeak functions by mocking or using a FFT
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/examples/envAmpFreq/sketch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Control the level of an envelope
3 | */
4 |
5 | var env; // this is the env
6 | var osc; // this oscillator will modulate the amplitude of the carrier
7 | var freqEnv; // env for frequency
8 |
9 | function setup() {
10 | env = new p5.Envelope();
11 | env.setADSR(0.01, 0.2, 0.2, 0.3);
12 | env.setRange(0, 1);
13 |
14 | freqEnv = new p5.Envelope();
15 | freqEnv.setADSR(0.01, 0.2, 0.2, 0.3);
16 | freqEnv.setRange(300, 5000);
17 |
18 |
19 | osc = new p5.Oscillator(); // connects to main output by default
20 | osc.start(0);
21 | osc.freq(220);
22 | // osc.freq(env.scale(0,1,800,300));
23 | osc.freq(freqEnv);
24 | osc.amp(env);
25 | }
26 |
27 | function mousePressed() {
28 | env.triggerAttack();
29 | freqEnv.triggerAttack();
30 | }
31 |
32 | function mouseReleased() {
33 | env.triggerRelease();
34 | freqEnv.triggerRelease();
35 | }
36 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/08_amplitude_analysis/sketch.js:
--------------------------------------------------------------------------------
1 | // Learning Processing
2 | // Daniel Shiffman
3 | // http://www.learningprocessing.com
4 |
5 | // Playback Amplitude Analysis
6 |
7 | var song;
8 |
9 | var analyzer;
10 |
11 | function preload() {
12 | song = loadSound('../../files/lucky_dragons_-_power_melody.mp3');
13 | }
14 |
15 | function setup() {
16 | createCanvas(720, 200);
17 | song.loop();
18 |
19 | // create a new Amplitude analyzer
20 | analyzer = new p5.Amplitude();
21 |
22 | // Patch the input to an volume analyzer
23 | analyzer.setInput(song);
24 | }
25 |
26 | function draw() {
27 | background(255);
28 |
29 | // Get the overall volume (between 0 and 1.0)
30 | var vol = analyzer.getLevel();
31 | fill(127);
32 | stroke(0);
33 |
34 | // Draw an ellipse with size based on volume
35 | ellipse(width/2, height/2, 10+vol*200, 10+vol*200);
36 | }
37 |
--------------------------------------------------------------------------------
/examples/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 |
10 | // output envelope
11 | var env;
12 |
13 | function setup() {
14 | carrier = new p5.Oscillator();
15 |
16 | carrierFreq = new p5.Signal(240);
17 | carrier.freq(carrierFreq);
18 | carrier.start();
19 |
20 | env = new p5.Envelope(0.05, 1, 0.5, 0);
21 | carrier.amp(env);
22 |
23 | modulator = new p5.Oscillator();
24 | modulator.disconnect();
25 | modFreq = new p5.SignalMult(8);
26 | modFreq.setInput(carrierFreq);
27 | modulator.freq(modFreq);
28 | modulator.start();
29 |
30 | var m1 = new p5.SignalMult();
31 | m1.setInput(modulator);
32 | m1.setValue(100);
33 | }
34 |
35 | function draw() {
36 | carrierFreq.fade(mouseX);
37 | }
38 |
39 | function mousePressed() {
40 | env.play();
41 | }
--------------------------------------------------------------------------------
/docs/reference/api.js:
--------------------------------------------------------------------------------
1 | YUI.add("yuidoc-meta", function(Y) {
2 | Y.YUIDoc = { meta: {
3 | "classes": [
4 | "Amplitude",
5 | "AudioIn",
6 | "Env",
7 | "FFT",
8 | "Noise",
9 | "Oscillator",
10 | "Pulse",
11 | "SoundFile",
12 | "p5.Element",
13 | "p5.MediaElement",
14 | "p5.dom",
15 | "p5.sound"
16 | ],
17 | "modules": [
18 | "p5.dom",
19 | "p5.sound"
20 | ],
21 | "allModules": [
22 | {
23 | "displayName": "p5.dom",
24 | "name": "p5.dom",
25 | "description": "This is the p5.dom library."
26 | },
27 | {
28 | "displayName": "p5.sound",
29 | "name": "p5.sound",
30 | "description": "p5.sound extends p5 with Web Audio functionality including audio input, playback, analysis and synthesis."
31 | }
32 | ]
33 | } };
34 | });
--------------------------------------------------------------------------------
/examples/playbackRatePart/sketch.js:
--------------------------------------------------------------------------------
1 | var mySound, myPhrase, myPart;
2 | var pattern = [1,0,0,2,0,2,0,0];
3 | var msg = 'click to play';
4 |
5 | function preload() {
6 | mySound = loadSound('../files/beatbox.mp3');
7 | }
8 |
9 | function setup() {
10 | noStroke();
11 | fill(255);
12 | textAlign(CENTER);
13 | outputVolume(0.1);
14 |
15 | myPhrase = new p5.Phrase('bbox', makeSound, pattern);
16 | myPart = new p5.Part();
17 | myPart.addPhrase(myPhrase);
18 | myPart.setBPM(60);
19 | }
20 |
21 | function draw() {
22 | background(0);
23 | text(msg, width/2, height/2);
24 | }
25 |
26 | function makeSound(time, playbackRate) {
27 | // mySound.rate(playbackRate);
28 | // mySound.play(time);
29 | mySound.play(time, playbackRate);
30 |
31 | }
32 |
33 | function mouseClicked() {
34 | if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
35 | myPart.start();
36 | msg = 'playing pattern';
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/09_live_input/sketch.js:
--------------------------------------------------------------------------------
1 | // make some noise to float the ellipse
2 | // p5.AudioIn contains its own p5.Amplitude object,
3 | // so you can call getLevel on p5.AudioIn without
4 | // creating a p5.Amplitude.
5 |
6 | var input;
7 | var analyzer;
8 |
9 | function setup() {
10 | createCanvas(200, 200);
11 |
12 | // Create an Audio input
13 | input = new p5.AudioIn();
14 |
15 | // start the Audio Input
16 | input.start();
17 |
18 | // create a new Amplitude analyzer
19 | analyzer = new p5.Amplitude();
20 |
21 | // Patch the input to an volume analyzer
22 | analyzer.setInput(input);
23 | }
24 |
25 | function draw() {
26 | background(200);
27 |
28 | // Get the overall volume (between 0 and 1.0)
29 | var vol = analyzer.getLevel();
30 | fill(127);
31 | stroke(0);
32 |
33 | // Draw an ellipse with height based on volume
34 | var h = map(vol, 0, 1, height, 0);
35 | ellipse(width/2, h - 25, 50, 50);
36 | }
--------------------------------------------------------------------------------
/examples/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_-_Dancing_Tiger_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 | }
--------------------------------------------------------------------------------
/examples/pause_soundfile/sketch.js:
--------------------------------------------------------------------------------
1 | // ====================
2 | // DEMO: pause sound when the user presses a key, resume on release
3 | // ====================
4 | 'use strict';
5 |
6 | var soundFile;
7 | var audioContextStarted = false;
8 |
9 | function preload() {
10 | // create a SoundFile
11 | soundFormats('ogg', 'mp3');
12 | soundFile = loadSound('../files/Damscray_-_Dancing_Tiger_02');
13 | }
14 |
15 | function setup() {
16 | createCanvas(400, 400);
17 | background(0, 255, 0);
18 |
19 | userStartAudio().then(function() {
20 | soundFile.loop();
21 | audioContextStarted = true;
22 | });
23 |
24 | createP('Press any key to pause. Resume when the key is released')
25 | }
26 |
27 | function keyTyped() {
28 | if (!audioContextStarted) {
29 | return;
30 | }
31 | soundFile.pause();
32 | background(255, 0, 0);
33 | }
34 |
35 | function keyReleased() {
36 | if (!audioContextStarted) {
37 | return;
38 | }
39 | soundFile.play();
40 | background(0, 255, 0);
41 | }
42 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "jasmine": true,
4 | "node": true,
5 | "mocha": true,
6 | "browser": true,
7 | "builtin": true,
8 | "es6": true
9 | },
10 | "globals": {
11 | "p5": true,
12 | "define": true,
13 | "Float32Array": true,
14 | "Uint8Array": true
15 | },
16 | "extends": ["eslint:recommended", "prettier"],
17 | "plugins": ["prettier"],
18 | "rules": {
19 | "prettier/prettier": ["error"],
20 | "no-cond-assign": [2, "except-parens"],
21 | "eqeqeq": ["error", "smart"],
22 | "no-use-before-define": [
23 | 2,
24 | {
25 | "functions": false
26 | }
27 | ],
28 | "new-cap": 0,
29 | "no-caller": 2,
30 | "no-undef": 0,
31 | "no-unused-vars": ["error", { "args": "none" }],
32 | "no-empty": ["error", { "allowEmptyCatch": true }],
33 | "no-console": "off"
34 |
35 | },
36 | "parserOptions": {
37 | "ecmaVersion": 8,
38 | "sourceType": "module",
39 | "allowImportExportEverywhere": true
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/test/tests/p5.AudioVoice.js:
--------------------------------------------------------------------------------
1 | const expect = chai.expect;
2 |
3 | describe('p5.AudioVoice', function () {
4 | it('can be created and disposed', function () {
5 | let av = new p5.AudioVoice();
6 | let audioContext = av.ac;
7 | expect(audioContext).to.have.property('baseLatency').to.be.an('number');
8 | expect(audioContext).to.have.property('destination');
9 | expect(audioContext).to.have.property('state').to.be.an('string');
10 | expect(av.output).to.have.property('gain');
11 | expect(av.output).to.have.property('context');
12 | av.dispose();
13 | expect(av).to.not.have.property('output');
14 | });
15 | it('can be connected and disconnected', function () {
16 | let av = new p5.AudioVoice();
17 | let filter = new p5.Filter();
18 |
19 | //if unit has input property
20 | av.connect(filter);
21 | av.disconnect();
22 |
23 | //if unit doesnot have an input property
24 | av = new p5.AudioVoice();
25 | av.connect(filter.input);
26 | av.disconnect();
27 | });
28 | });
29 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/tpl/class.html:
--------------------------------------------------------------------------------
1 |
2 | <% if (is_constructor) { %>
3 |
4 |
5 | <%=constructor%>
6 |
7 | <% } %>
8 |
9 | <% var fields = _.filter(things, function(item) { return item.itemtype === 'property' }); %>
10 | <% if (fields.length > 0) { %>
11 | Fields
12 |
13 | <% _.each(fields, function(item) { %>
14 | class="addon"<% } %> ><%=item.name%>: <%= item.description %>
15 |
16 | <% }); %>
17 |
18 | <% } %>
19 |
20 | <% var methods = _.filter(things, function(item) { return item.itemtype === 'method' }); %>
21 | <% if (methods.length > 0) { %>
22 | Methods
23 |
24 | <% _.each(methods, function(item) { %>
25 | class="addon"<% } %>><%=item.name%><% if (item.itemtype === 'method') { %>()<%}%>: <%= item.description %>
26 |
27 | <% }); %>
28 |
29 | <% } %>
--------------------------------------------------------------------------------
/test/setup.js:
--------------------------------------------------------------------------------
1 | const startTest = () => {
2 | //dynamic importing the modules , this ensures that tests must run after audioWorklet processors have been loaded properly
3 | import('./tests.js');
4 |
5 | let test_has_run = false;
6 |
7 | document.getElementById('mocha').innerHTML = 'click to begin tests';
8 |
9 | // chromes autoplay policy requires a user interaction
10 | // before the audiocontext can activate
11 | const mousePressed = () => {
12 | if (!test_has_run) {
13 | document.getElementById('mocha').innerHTML = '';
14 | p5.prototype.outputVolume(0);
15 | p5.prototype.userStartAudio();
16 | mocha.run();
17 | test_has_run = true;
18 | }
19 | };
20 | document.addEventListener('click', mousePressed, false);
21 | };
22 |
23 | //operating p5 in instance mode ( read more about it here - https://github.com/processing/p5.js/wiki/Global-and-instance-mode )
24 | const s = (sketch) => {
25 | sketch.setup = () => {
26 | mocha.setup('bdd');
27 | startTest();
28 | };
29 | };
30 |
31 | new p5(s);
32 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/config.js:
--------------------------------------------------------------------------------
1 | var require = {
2 | baseUrl: "assets/js",
3 | paths: {
4 | 'jquery': [
5 | '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min',
6 | 'vendor/jquery/jquery-1.11.0'
7 | ],
8 | 'underscore': 'vendor/underscore-amd/underscore',
9 | 'backbone': 'vendor/backbone-amd/backbone',
10 | // Require plugins
11 | 'text': 'vendor/require/text',
12 | 'domReady': 'vendor/require/domReady',
13 | // Twitter typeahead + bloodhound
14 | 'typeahead': 'vendor/typeahead-amd/typeahead.bundle',
15 | //'bloodhound': 'vendor/typeahead-amd/',
16 | 'prettify': 'vendor/prettify/prettify',
17 | // 'prism': 'vendor/prism/prism',
18 |
19 | // Collections
20 | 'itemsCollection': 'collections/itemsCollection',
21 | // Models
22 | 'itemModel': 'models/itemModel',
23 | // Views
24 | 'listView': 'views/listView',
25 | 'itemView': 'views/itemView',
26 | 'searchView': 'views/searchView',
27 | 'pageView': 'views/pageView',
28 | 'menuView': 'views/menuView',
29 | 'libraryView': 'views/libraryView'
30 | }
31 | };
--------------------------------------------------------------------------------
/examples/loadSound_with_Drag_and_Drop/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | Pick sounds from a menu here:
27 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/test/tests/p5.Panner.js:
--------------------------------------------------------------------------------
1 | // const expect = chai.expect;
2 |
3 | describe('p5.Panner', function () {
4 | let ac, output, input;
5 | beforeEach(function () {
6 | ac = p5.prototype.getAudioContext();
7 | output = ac.createGain();
8 | input = ac.createGain();
9 | });
10 | it('can be created', function () {
11 | new p5.Panner(input, output);
12 | });
13 | it('can be connected and disconnected', function () {
14 | let panner = new p5.Panner(input, output);
15 | panner.connect(input);
16 | panner.disconnect();
17 | });
18 | it('can be panned without a delay', function () {
19 | let panner = new p5.Panner(input, output);
20 | panner.pan(0.4);
21 | panner.pan(0.3, 0);
22 | //TODO: to check the value of left gain/ right gain (or) the stereoPanner.pan
23 | });
24 | it('can be panned with a delay', function () {
25 | let panner = new p5.Panner(input, output);
26 | panner.pan(0.4, 10);
27 | });
28 | it('can take inputChannels as 1 or 2', function () {
29 | let panner = new p5.Panner(input, output);
30 | panner.inputChannels(1);
31 | panner.inputChannels(2);
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/03_manipulate_sound/sketch.js:
--------------------------------------------------------------------------------
1 | // Adapted from Learning Processing
2 | // Daniel Shiffman
3 | // http://www.learningprocessing.com
4 |
5 | // A sound file object
6 | var song;
7 |
8 | function preload() {
9 | // Load a sound file
10 | song = loadSound('../../files/Damscray_DancingTiger.mp3');
11 | }
12 |
13 | function setup() {
14 | createCanvas(720, 720);
15 |
16 | // Loop the sound forever
17 | // (well, at least until stop() is called)
18 | song.loop();
19 | }
20 |
21 | function draw() {
22 | background(200);
23 |
24 | // Set the volume to a range between 0 and 1.0
25 | var volume = map(mouseX, 0, width, 0, 1);
26 | volume = constrain(volume, 0, 1);
27 | song.amp(volume);
28 |
29 | // Set the rate to a range between 0.1 and 4
30 | // Changing the rate alters the pitch
31 | var speed = map(mouseY, 0.1, height, 0, 2);
32 | speed = constrain(speed, 0.01, 4);
33 | song.rate(speed);
34 |
35 | // Draw some circles to show what is going on
36 | stroke(0);
37 | fill(51, 100);
38 | ellipse(mouseX, 100, 48, 48);
39 | stroke(0);
40 | fill(51, 100);
41 | ellipse(100, mouseY, 48, 48);
42 | }
--------------------------------------------------------------------------------
/test/tests.js:
--------------------------------------------------------------------------------
1 | import('./tests/main.js');
2 | import('./tests/p5.Helpers.js');
3 | import('./tests/p5.PeakDetect.js');
4 | import('./tests/p5.OnsetDetect.js');
5 | import('./tests/p5.Distortion.js');
6 | import('./tests/p5.AudioContext.js');
7 | import('./tests/p5.Looper.js');
8 | import('./tests/p5.Metro.js');
9 | import('./tests/p5.Effect.js');
10 | import('./tests/p5.Filter.js');
11 | import('./tests/p5.Gain.js');
12 | import('./tests/p5.FFT.js');
13 | import('./tests/p5.SoundLoop.js');
14 | import('./tests/p5.Compressor.js');
15 | import('./tests/p5.EQ.js');
16 | import('./tests/p5.AudioIn.js');
17 | import('./tests/p5.AudioVoice.js');
18 | import('./tests/p5.MonoSynth.js');
19 | import('./tests/p5.PolySynth.js');
20 | import('./tests/p5.SoundRecorder.js');
21 | import('./tests/p5.SoundFile.js');
22 | import('./tests/p5.Amplitude.js');
23 | import('./tests/p5.Oscillator.js');
24 | import('./tests/p5.Envelope.js');
25 | import('./tests/p5.Pulse.js');
26 | import('./tests/p5.Noise.js');
27 | import('./tests/p5.Panner.js');
28 | import('./tests/p5.Panner3d.js');
29 | import('./tests/p5.Delay.js');
30 | import('./tests/p5.Reverb.js');
31 | import('./tests/p5.Listener3d.js');
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2015 The Processing Foundation
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/examples/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 p5.SinOsc();
16 | osc2 = new p5.SinOsc();
17 | fft = new p5.FFT();
18 | osc1.phase(.5);
19 | osc2.phase(0);
20 | osc1.amp(1);
21 | osc2.amp(1);
22 | osc1.start(); osc2.start();
23 |
24 | phaseSlider = createSlider(0, 100, 50);
25 | }
26 |
27 | function draw() {
28 | background(30);
29 |
30 | // analyze the waveform of all sound in the sketch
31 | waveform = fft.waveform();
32 |
33 | // draw the shape of the waveform
34 | stroke(255);
35 | strokeWeight(10);
36 | beginShape();
37 | for (var i = 0; i width || ball.x < 0) {
37 |
38 | // map the ball's x location to a panning degree (float between -1.0 and 1.0)
39 | var panning = map(ball.x, 0, width, -1, 1);
40 | soundFile.pan(panning);
41 |
42 | // set a random playback speed for the sound
43 | var newSpeed = random(1);
44 | ball.speed = -ball.speed;
45 | soundFile.rate(newSpeed);
46 |
47 | // play the sound
48 | soundFile.play();
49 | }
50 | ellipse(ball.x, ball.y, 100, 100);
51 | }
--------------------------------------------------------------------------------
/examples/soundfile_remove_cue/sketch.js:
--------------------------------------------------------------------------------
1 | function setup() {
2 | background(0);
3 | noStroke();
4 | fill(255);
5 | textAlign(CENTER);
6 | text('click to play', width/2, height/2);
7 |
8 | mySound = loadSound('../files/beat.mp3');
9 |
10 | // schedule calls to changeText
11 | var firstCueId = mySound.addCue(0.50, changeText, "hello" );
12 | mySound.addCue(1.00, changeText, "p5" );
13 | var thirdCueId = mySound.addCue(1.50, changeText, "what" );
14 | mySound.addCue(2.00, changeText, "do" );
15 | mySound.addCue(2.50, changeText, "you" );
16 | mySound.addCue(3.00, changeText, "want" );
17 | mySound.addCue(4.00, changeText, "to" );
18 | mySound.addCue(5.00, changeText, "make" );
19 | mySound.addCue(6.00, changeText, "?" );
20 |
21 | //remove the first cue
22 | mySound.removeCue(firstCueId);
23 |
24 | //remove the third cue
25 | mySound.removeCue(thirdCueId);
26 | }
27 |
28 | function changeText(val) {
29 | background(0);
30 | text(val, width/2, height/2);
31 | }
32 |
33 | function mouseClicked() {
34 | if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
35 | if (mySound.isPlaying() ) {
36 | mySound.stop();
37 | } else {
38 | mySound.play();
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/examples/_sound_loop/sketch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Create a sequence using a Part with callbacks that play back soundfiles.
3 | * The callback includes parameters (the value at that position in the Phrase array)
4 | * as well as time, which should be used to schedule playback with precision.
5 | *
6 | */
7 |
8 | var click, beatbox ;
9 |
10 | var looper1, looper2;
11 |
12 |
13 | function preload() {
14 | soundFormats('mp3', 'ogg');
15 | click = loadSound('../files/drum');
16 | beatbox = loadSound('../files/beatbox');
17 |
18 | }
19 |
20 | function setup() {
21 |
22 | //Hemiola! 2 loops, playing sounds in a 4 over 3 pattern
23 | //gradually increase the tempo of both loops
24 | //
25 | //the looper's callback is passed the timeFromNow
26 | //this value should be used as a reference point from
27 | //which to schedule sounds
28 |
29 | looper1 = new p5.SoundLoop(function(timeFromNow){
30 | click.play(timeFromNow);
31 | looper1.bpm = looper1.bpm += 0.5;
32 | }, "8n");
33 |
34 | looper2 = new p5.SoundLoop(function(timeFromNow){
35 | beatbox.play(timeFromNow);
36 | looper2.bpm = looper1.bpm;
37 | }, "12n");
38 |
39 | //start the loops together
40 | looper1.syncedStart(looper2);
41 | }
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/src/audioWorklet/index.js:
--------------------------------------------------------------------------------
1 | import p5sound from '../main.js';
2 | const moduleSources = [
3 | require('raw-loader!./recorderProcessor').default,
4 | require('raw-loader!./soundFileProcessor').default,
5 | require('raw-loader!./amplitudeProcessor').default,
6 | ];
7 | const ac = p5sound.audiocontext;
8 | let initializedAudioWorklets = false;
9 |
10 | function loadAudioWorkletModules() {
11 | return Promise.all(
12 | moduleSources.map(function (moduleSrc) {
13 | const blob = new Blob([moduleSrc], { type: 'application/javascript' });
14 | const objectURL = URL.createObjectURL(blob);
15 | return ac.audioWorklet.addModule(objectURL);
16 | })
17 | );
18 | }
19 |
20 | p5.prototype.registerMethod('init', function () {
21 | if (initializedAudioWorklets) return;
22 | // ensure that a preload function exists so that p5 will wait for preloads to finish
23 | if (!this.preload && !window.preload) {
24 | this.preload = function () {};
25 | }
26 |
27 | // use p5's preload system to load necessary AudioWorklet modules before setup()
28 | this._incrementPreload();
29 | const onWorkletModulesLoad = function () {
30 | initializedAudioWorklets = true;
31 | this._decrementPreload();
32 | }.bind(this);
33 | loadAudioWorkletModules().then(onWorkletModulesLoad);
34 | });
35 |
--------------------------------------------------------------------------------
/src/eqFilter.js:
--------------------------------------------------------------------------------
1 | import Filter from './filter';
2 | import p5sound from './main';
3 |
4 | /**
5 | * EQFilter extends p5.Filter with constraints
6 | * necessary for the p5.EQ
7 | *
8 | * @private
9 | */
10 | class EQFilter extends Filter {
11 | constructor(freq, res) {
12 | super('peaking');
13 |
14 | this.disconnect();
15 | this.set(freq, res);
16 | this.biquad.gain.value = 0;
17 | delete this.input;
18 | delete this.output;
19 | delete this._drywet;
20 | delete this.wet;
21 | }
22 |
23 | amp() {
24 | console.warn('`amp()` is not available for p5.EQ bands. Use `.gain()`');
25 | }
26 |
27 | drywet() {
28 | console.warn('`drywet()` is not available for p5.EQ bands.');
29 | }
30 |
31 | connect(unit) {
32 | var u = unit || p5.soundOut.input;
33 | if (this.biquad) {
34 | this.biquad.connect(u.input ? u.input : u);
35 | } else {
36 | this.output.connect(u.input ? u.input : u);
37 | }
38 | }
39 | disconnect() {
40 | if (this.biquad) {
41 | this.biquad.disconnect();
42 | }
43 | }
44 |
45 | dispose() {
46 | // remove reference form soundArray
47 | const index = p5sound.soundArray.indexOf(this);
48 | p5sound.soundArray.splice(index, 1);
49 | this.disconnect();
50 | delete this.biquad;
51 | }
52 | }
53 |
54 | export default EQFilter;
55 |
--------------------------------------------------------------------------------
/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 |
5 | class SoundFileProcessor extends AudioWorkletProcessor {
6 | constructor(options) {
7 | super();
8 |
9 | const processorOptions = options.processorOptions || {};
10 | this.bufferSize = processorOptions.bufferSize || 256;
11 | this.inputRingBuffer = new RingBuffer(this.bufferSize, 1);
12 | this.inputRingBufferArraySequence = [new Float32Array(this.bufferSize)];
13 | }
14 |
15 | process(inputs) {
16 | const input = inputs[0];
17 | // we only care about the first input channel, because that contains the position data
18 | this.inputRingBuffer.push([input[0]]);
19 |
20 | if (this.inputRingBuffer.framesAvailable >= this.bufferSize) {
21 | this.inputRingBuffer.pull(this.inputRingBufferArraySequence);
22 | const inputChannel = this.inputRingBufferArraySequence[0];
23 | const position = inputChannel[inputChannel.length - 1] || 0;
24 |
25 | this.port.postMessage({ name: 'position', position: position });
26 | }
27 |
28 | return true;
29 | }
30 | }
31 |
32 | registerProcessor(processorNames.soundFileProcessor, SoundFileProcessor);
33 |
--------------------------------------------------------------------------------
/src/audioVoice.js:
--------------------------------------------------------------------------------
1 | import p5sound from './main';
2 |
3 | /**
4 | * Base class for monophonic synthesizers. Any extensions of this class
5 | * should follow the API and implement the methods below in order to
6 | * remain compatible with p5.PolySynth();
7 | *
8 | * @class p5.AudioVoice
9 | * @constructor
10 | */
11 | class AudioVoice {
12 | constructor() {
13 | this.ac = p5sound.audiocontext;
14 | this.output = this.ac.createGain();
15 | this.connect();
16 | p5sound.soundArray.push(this);
17 | }
18 | play(note, velocity, secondsFromNow, sustime) {}
19 |
20 | triggerAttack(note, velocity, secondsFromNow) {}
21 |
22 | triggerRelease(secondsFromNow) {}
23 |
24 | amp(vol, rampTime) {}
25 |
26 | /**
27 | * Connect to p5 objects or Web Audio Nodes
28 | * @method connect
29 | * @for p5.AudioVoice
30 | * @param {Object} unit
31 | */
32 | connect(unit) {
33 | var u = unit || p5sound.input;
34 | this.output.connect(u.input ? u.input : u);
35 | }
36 |
37 | /**
38 | * Disconnect from soundOut
39 | * @method disconnect
40 | * @for p5.AudioVoice
41 | */
42 | disconnect() {
43 | this.output.disconnect();
44 | }
45 |
46 | dispose() {
47 | if (this.output) {
48 | this.output.disconnect();
49 | delete this.output;
50 | }
51 | }
52 | }
53 |
54 | export default AudioVoice;
55 |
--------------------------------------------------------------------------------
/examples/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 p5.FFT(.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 |
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/07_envelope/sketch.js:
--------------------------------------------------------------------------------
1 | // Adapted from Learning Processing
2 | // Daniel Shiffman
3 | // http://www.learningprocessing.com
4 |
5 | // Example: Playing Notes With Envelope
6 |
7 | // An Envelope is a series of fades, defined
8 | // as time / value pairs. In this example, the envelope
9 | // will be used to "play" a note by controlling the output
10 | // amplitude of an oscillator.
11 | //
12 | // HOW THIS WORKS: The p5.Oscillator sends its output through
13 | // an internal Web Audio GainNode (p5.Oscillator.output).
14 | // By default, that node has a constant value of 0.5. It can
15 | // be reset with the osc.amp() method. Or, in this example, an
16 | // Envelope takes control of that node, turning the amplitude
17 | // up and down like a volume knob.
18 |
19 | var osc;
20 | var envelope;
21 |
22 | var scaleArray = [60, 62, 64, 65, 67, 69, 71, 72];
23 | var note = 0;
24 |
25 | function setup() {
26 | createCanvas(200, 200);
27 | osc = new p5.SinOsc();
28 |
29 | // Instantiate the envelope with time / value pairs
30 | envelope = new p5.Envelope(0.01, 0.5, 1, 0.5);
31 |
32 | osc.start();
33 | }
34 |
35 | function draw() {
36 | background(255);
37 |
38 | if (frameCount % 60 == 0) {
39 | var midiValue = scaleArray[note];
40 | var freqValue = midiToFreq(midiValue);
41 | osc.freq(freqValue);
42 |
43 | envelope.play(osc);
44 | note = (note + 1) % scaleArray.length;
45 | }
46 | }
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/10_mic_threshold/sketch.js:
--------------------------------------------------------------------------------
1 | // Adapted from Learning Processing
2 | // Daniel Shiffman
3 | // http://www.learningprocessing.com
4 |
5 | // in the previous example, we created an Amplitude object to getLevel().
6 | // AudioIn contains its own internal amplitude object, so we can actually
7 | // just call getLevel on the AudioIn itself.
8 |
9 | var input;
10 | var analyzer;
11 |
12 | function setup() {
13 | createCanvas(200, 200);
14 | background(255);
15 |
16 | // Create an Audio input
17 | input = new p5.AudioIn();
18 |
19 | input.start();
20 | }
21 |
22 | function draw() {
23 | // Get the overall volume (between 0 and 1.0)
24 | var volume = input.getLevel();
25 |
26 | // If the volume is greater than 0.1 a rectangle is drawn at a random location in the window.
27 | // The louder the volume, the larger the rectangle.
28 | var threshold = 0.1;
29 | if (volume > threshold) {
30 | stroke(0);
31 | fill(0, 100);
32 | rect(random(40, width), random(height), volume*50, volume*50);
33 | }
34 |
35 | // Graph the overall potential volume, with a line at the threshold
36 | var y = map(volume, 0, 1, height, 0);
37 | var ythreshold = map(threshold, 0, 1, height, 0);
38 |
39 | noStroke();
40 | fill(175);
41 | rect(0, 0, 20, height);
42 | // Then draw a rectangle on the graph, sized according to volume
43 | fill(0);
44 | rect(0, y, 20, y);
45 | stroke(0);
46 | line(0, ythreshold, 19, ythreshold);
47 | }
--------------------------------------------------------------------------------
/examples/removeSketch/sketch.js:
--------------------------------------------------------------------------------
1 | function init() {
2 | var s = function(c) {
3 |
4 | c.backgroundSound;
5 | c.sounds = {};
6 | c.soundFiles = [
7 | 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/51676/chords1.mp3',
8 | 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/51676/chords2.mp3',
9 | 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/51676/chords3.mp3',
10 | ];
11 | c.count = 0;
12 |
13 | c.preload = function() {
14 | c.backgroundSound = c.loadSound("https://s3-us-west-2.amazonaws.com/s.cdpn.io/51676/FM8_synth_chords.mp3");
15 |
16 | for (var i = 0; i < c.soundFiles.length; i++) {
17 | c.sounds[i] = c.loadSound(c.soundFiles[i]);
18 | }
19 | }
20 |
21 | c.setup = function() {
22 | c.cnv = c.createCanvas(c.windowWidth, c.windowHeight);
23 | c.text('click 5 times to remove the sketch', 20, 20);
24 | c.backgroundSound.amp(1);
25 | c.backgroundSound.loop(0, 1, 1, 0, (c.backgroundSound.duration() - 0.1));
26 | }
27 |
28 | c.draw = function() {
29 |
30 | }
31 |
32 | c.mousePressed = function() {
33 | if (c.count == 5) {
34 | c.remove();
35 | } else {
36 | c.sounds[c.count % 3].play();
37 | }
38 |
39 | c.count++;
40 | }
41 | };
42 |
43 | new p5(s);
44 | }
45 |
46 | init();
--------------------------------------------------------------------------------
/examples/loop_stepSequencer/sketch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Create a sequence using a Part with callbacks that play back soundfiles.
3 | * The callback includes parameters (the value at that position in the Phrase array)
4 | * as well as time, which should be used to schedule playback with precision.
5 | *
6 | */
7 |
8 | var click, beatbox;
9 | var clickPhrase = [1, 0, 0, 0];
10 | var bboxPhrase = [0, 0, 1, 0, 0, 0, 1, 1];
11 |
12 |
13 | var part; // a part we will loop
14 |
15 | function preload() {
16 | soundFormats('mp3', 'ogg');
17 | click = loadSound('../files/drum');
18 | beatbox = loadSound('../files/beatbox');
19 |
20 | }
21 |
22 | function setup() {
23 | // create a part with 8 spaces, where each space represents 1/16th note (default)
24 | part = new p5.Part(8, 1/16);
25 |
26 | // add phrases, with a name, a callback, and
27 | // an array of values that will be passed to the callback if > 0
28 | part.addPhrase('kick', playKick, clickPhrase);
29 | part.addPhrase('snare', playSnare, bboxPhrase);
30 |
31 | // set tempo (Beats Per Minute) of the part and tell it to loop
32 | part.setBPM(80);
33 | part.loop();
34 | }
35 |
36 | function playKick(time, params) {
37 | click.rate(params);
38 | click.play(time);
39 | }
40 |
41 | function playSnare(time, params) {
42 | beatbox.rate(params);
43 | beatbox.play(time);
44 | }
45 |
46 | // draw a ball mapped to current note height
47 | function draw() {
48 | background(255);
49 | fill(255, 0, 0);
50 | }
51 |
52 | // UI
53 | var hDiv = 2;
54 | var wDiv = 16;
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/01c_soundFormats/sketch.js:
--------------------------------------------------------------------------------
1 | // There is no single sound format that is supported
2 | // by all web browsers. For example, mp3 support is not native to
3 | // Firefox and Opera because the mp3 codec is patented.
4 | //
5 | // To ensure compatability, you can include the same sound file
6 | // in multiple formats, i.e. sound.mp3 and sound.ogg. Ogg is an
7 | // open source alternative to mp3. You can convert audio files
8 | // into web friendly formats for free online at http://media.io/
9 | //
10 | // The soundFormats() method tells loadSound which formats we have
11 | // included with our sketch. Then, loadSound will attempt to load
12 | // the first format that is supported by the client's web browser.
13 |
14 | var song;
15 |
16 | function preload() {
17 | // we have included both an .ogg file and an .mp3 file
18 | soundFormats('ogg', 'mp3');
19 |
20 | // if mp3 is not supported by this browser,
21 | // loadSound will load the ogg file we have included with our sketch
22 | song = loadSound('../../files/lucky_dragons_-_power_melody.mp3');
23 | }
24 |
25 | function setup() {
26 | createCanvas(720, 200);
27 |
28 | song.play(); // song loaded during preload(), ready to play in setup()
29 | background(0,255,0);
30 | }
31 |
32 | function mousePressed() {
33 | if ( song.isPlaying() ) { // .isPlaying() returns a boolean
34 | song.pause();
35 | background(255,0,0);
36 | } else {
37 | song.play(); // playback will resume from the pause position
38 | background(0,255,0);
39 | }
40 | }
--------------------------------------------------------------------------------
/docs/progress.txt:
--------------------------------------------------------------------------------
1 |
2 |
3 | //// Environment
4 | preload()
5 |
6 |
7 | //// DOM
8 |
9 |
10 | //// SHAPE
11 |
12 | createShape()
13 | loadShape()
14 | PShape
15 |
16 |
17 |
18 |
19 | curveTightness()
20 | curveVertex()
21 |
22 |
23 |
24 |
25 | // Loading & Displaying
26 | shape()
27 | shapeMode()
28 |
29 |
30 | //// INPUT
31 |
32 |
33 |
34 | // Files
35 | BufferedReader
36 | createInput()
37 | createReader()
38 | loadBytes()
39 |
40 | loadTable()
41 | open()
42 | parseXML()
43 | selectFolder()
44 | selectInput()
45 |
46 |
47 | //// OUTPUT
48 |
49 | // Image
50 | save()
51 | saveFrame()
52 |
53 | // Files
54 | beginRaw()
55 | beginRecord()
56 | createOutput()
57 | createWriter()
58 | endRaw()
59 | endRecord()
60 | PrintWriter
61 | saveBytes()
62 | saveJSONArray()
63 | saveJSONObject()
64 | saveStream()
65 | saveStrings()
66 | saveTable()
67 | saveXML()
68 | selectOutput()
69 |
70 |
71 |
72 | // Image
73 | // Loading & Displaying
74 |
75 | noTint()
76 | tint()
77 |
78 |
79 |
80 | // Rendering
81 |
82 | blendMode()
83 | createGraphics()
84 | PGraphics
85 |
86 |
87 |
88 | // Typography
89 |
90 |
91 | PFont
92 | // Loading & Displaying
93 | createFont()
94 | loadFont()
95 |
96 |
97 |
98 |
99 | // Metrics
100 | textAscent()
101 | textDescent()
102 |
103 |
104 |
105 |
106 |
107 | // Math
108 |
109 | // Random
110 | noise()
111 | noiseDetail()
112 | noiseSeed()
113 | random()
114 | randomGaussian()
115 | randomSeed()
116 |
--------------------------------------------------------------------------------
/src/onsetDetect.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Listen for onsets (a sharp increase in volume) within a given
3 | * frequency range.
4 | *
5 | * @class p5.OnsetDetect
6 | * @constructor
7 | * @param {Number} freqLow Low frequency
8 | * @param {Number} freqHigh High frequency
9 | * @param {Number} threshold Amplitude threshold between 0 (no energy) and 1 (maximum)
10 | * @param {Function} callback Function to call when an onset is detected
11 | */
12 | class OnsetDetect {
13 | constructor(freqLow, freqHigh, threshold, callback) {
14 | this.isDetected = false;
15 | this.freqLow = freqLow;
16 | this.freqHigh = freqHigh;
17 | this.treshold = threshold;
18 | this.energy = 0;
19 | this.penergy = 0;
20 |
21 | // speed of decay
22 | this.sensitivity = 500;
23 |
24 | this.callback = callback;
25 | }
26 |
27 | // callback here too?
28 | update(fftObject, callback) {
29 | this.energy = fftObject.getEnergy(this.freqLow, this.freqHigh) / 255;
30 |
31 | if (this.isDetected === false) {
32 | if (this.energy - this.penergy > this.treshold) {
33 | this.isDetected = true;
34 |
35 | if (this.callback) {
36 | this.callback(this.energy);
37 | } else if (callback) {
38 | callback(this.energy);
39 | }
40 |
41 | var self = this;
42 | setTimeout(function () {
43 | self.isDetected = false;
44 | }, this.sensitivity);
45 | }
46 | }
47 |
48 | this.penergy = this.energy;
49 | }
50 | }
51 |
52 | export default OnsetDetect;
53 |
--------------------------------------------------------------------------------
/examples/envelopeOnOff/sketch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Example: Create an Envelope (p5.Envelope) 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 osc;
8 | var env;
9 | var a;
10 |
11 | // Times and levels for the ADSR envelope
12 | var attackTime = 0.001;
13 | var attackLevel = 0.6;
14 | var decayTime = 0.1;
15 | var susPercent = 0.2;
16 | var releaseTime = 0.5;
17 | var releaseLevel = 0;
18 |
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 |
27 | function setup(){
28 | createCanvas(600, 300);
29 | background(20);
30 | fill(0,255,0);
31 |
32 | trigger = millis();
33 |
34 | osc = new p5.SinOsc();
35 | osc.freq(220);
36 | osc.start();
37 |
38 | env = new p5.Envelope();
39 | env.setADSR(attackTime, decayTime, susPercent, releaseTime);
40 | env.setRange(attackLevel, releaseLevel);
41 |
42 | osc.amp(env);
43 | createP('click mouse to triggerAttack, release mouse to triggerRelease');
44 |
45 | a = new p5.Amplitude();
46 | }
47 |
48 | function draw(){
49 | var size = 10;
50 | background(20, 20, 20, 70);
51 | ellipse( map ( (trigger - millis()) % duration, 1000, 0, 0, width) % width, map ( a.getLevel(), 0, .5, height-size, 0), size, size);
52 | }
53 |
54 | function mousePressed(){
55 | env.triggerAttack();
56 | trigger = millis() + duration;
57 | }
58 |
59 | function mouseReleased(){
60 | env.triggerRelease();
61 | }
--------------------------------------------------------------------------------
/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 | var CustomError = function (name, errorTrace, failedPath) {
21 | var err = new Error();
22 | var 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 |
--------------------------------------------------------------------------------
/examples/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 p5.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 p5.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 p5.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 |
43 | // Tell recorder to record to a p5.SoundFile which we will use for playback
44 | var fourBeats = (kick.duration() * 4);
45 | myLoop = new p5.SoundFile();
46 | recorder.record(myLoop, fourBeats, playRecording);
47 | background(255,0,0);
48 | }
49 | }
50 |
51 | function playRecording() {
52 | myLoop.loop();
53 | background(0,255,0);
54 | }
55 |
--------------------------------------------------------------------------------
/test/tests/p5.Noise.js:
--------------------------------------------------------------------------------
1 | const expect = chai.expect;
2 |
3 | describe('p5.Noise', function () {
4 | it('can be created and disposed', function () {
5 | let noise = new p5.Noise();
6 | expect(noise).to.not.have.property('f');
7 | expect(noise).to.not.have.property('oscillator');
8 | expect(noise).to.have.property('buffer');
9 | expect(noise.started).to.be.false;
10 | expect(noise.buffer.type).to.equal('white');
11 |
12 | noise.dispose();
13 | expect(noise.output).to.be.null;
14 | expect(noise.panner).to.be.null;
15 | expect(noise.buffer).to.be.null;
16 | expect(noise.noise).to.be.null;
17 | });
18 | describe('methods', function () {
19 | it('can get and set type', function (done) {
20 | let noise = new p5.Noise();
21 | noise.start();
22 | noise.setType('brown');
23 | expect(noise.getType()).to.equal('brown');
24 | noise.setType();
25 | expect(noise.getType()).to.equal('white');
26 | setTimeout(() => {
27 | expect(noise.started).to.be.true;
28 | done();
29 | }, 100);
30 | });
31 | it('can be started and stopped', function () {
32 | let noise = new p5.Noise();
33 | expect(noise).to.not.have.property('noise');
34 | noise.start();
35 | expect(noise).to.have.property('noise');
36 | expect(noise.noise).to.have.property('buffer');
37 | expect(noise.noise.loop).to.be.true;
38 | expect(noise.started).to.be.true;
39 | noise.stop();
40 | expect(noise.started).to.be.false;
41 | });
42 | //TODO: test noise buffer generator functions
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "p5.sound",
3 | "repository": {
4 | "type": "git",
5 | "url": "https://github.com/processing/p5.js-sound.git"
6 | },
7 | "version": "1.0.1",
8 | "license": "MIT",
9 | "devDependencies": {
10 | "@babel/core": "^7.4.5",
11 | "@babel/preset-env": "^7.4.5",
12 | "almond": "~0.2.7",
13 | "amdclean": "~2.0",
14 | "babel-loader": "^8.0.6",
15 | "babel-plugin-preval": "^3.0.1",
16 | "chai": "3.4.1",
17 | "eslint-config-prettier": "^6.11.0",
18 | "eslint-plugin-prettier": "^3.1.3",
19 | "grunt": "~1.5.3",
20 | "grunt-cli": "^1.4.3",
21 | "grunt-contrib-connect": "^1.0.2",
22 | "grunt-decomment": "^0.2.4",
23 | "grunt-eslint": "^20.0.0",
24 | "grunt-githooks": "^0.6.0",
25 | "grunt-mocha": "^1.0.4",
26 | "grunt-open": "^0.2.3",
27 | "grunt-webpack": "^3.1.3",
28 | "mocha": "10.1.0",
29 | "prettier": "2.0.5",
30 | "raw-loader": "^3.0.0",
31 | "tslint-config-prettier": "^1.18.0",
32 | "uglify-loader": "^3.0.0",
33 | "uglifyjs-webpack-plugin": "^2.1.3",
34 | "webpack": "^4.33.0",
35 | "webpack-auto-inject-version": "^1.2.2"
36 | },
37 | "dependencies": {
38 | "audioworklet-polyfill": "^1.1.2",
39 | "p5": "1.0.0",
40 | "sinon": "^9.0.3",
41 | "startaudiocontext": "^1.2.1",
42 | "tone": "0.10.0"
43 | },
44 | "scripts": {
45 | "build": "grunt",
46 | "test": "grunt run-tests",
47 | "lint": "grunt lint",
48 | "dev": "grunt dev",
49 | "postinstall": "cp ./node_modules/p5/lib/p5.js ./node_modules/p5/lib/p5.min.js ./lib && grunt githooks"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/examples/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_-_power_melody');
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 |
29 | function draw() {
30 | background(255);
31 |
32 | peakCount = map(this.mouseY, height, 0, 5, 2000);
33 | if (peakCount < 8) {
34 | peakCount = 8;
35 | }
36 | var waveform = soundFile.getPeaks(peakCount);
37 | fill(0);
38 | stroke(0);
39 | strokeWeight(2);
40 | beginShape();
41 | for (var i = 0; i< waveform.length; i++){
42 | vertex(map(i, 0, waveform.length, 0, width), map(waveform[i], -1, 1, height, 0));
43 | }
44 | endShape();
45 |
46 | // update display text:
47 | p.html('MouseY = Visible Amplitude Peaks: ' + peakCount.toFixed(3) );
48 |
49 | drawCursor();
50 | }
51 |
52 |
53 | function drawCursor() {
54 | noStroke();
55 | fill(0,255,0);
56 | rect(map(soundFile.currentTime(), 0, soundFile.duration(), 0, width), 0, 5, height);
57 | }
58 |
59 | // Keyboard Controls
60 | function keyTyped() {
61 | if (soundFile.isPlaying()) {
62 | soundFile.pause();
63 | } else {
64 | soundFile.play();
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/views/menuView.js:
--------------------------------------------------------------------------------
1 | define([
2 | 'underscore',
3 | 'backbone',
4 | 'App',
5 | 'text!tpl/menu.html'
6 | ], function(_, Backbone, App, menuTpl) {
7 |
8 | var menuView = Backbone.View.extend({
9 | el: '#collection-list-nav',
10 | /**
11 | * Init.
12 | * @returns {object} This view.
13 | */
14 | init: function() {
15 | this.menuTpl = _.template(menuTpl);
16 | return this;
17 | },
18 | /**
19 | * Render.
20 | * @returns {object} This view.
21 | */
22 | render: function() {
23 |
24 | var groups = [];
25 | _.each(App.modules, function (item, i) {
26 | if (!item.is_submodule) {
27 | if (!item.file || item.file.indexOf('addons') === -1) { //addons don't get displayed on main page
28 | groups.push(item.name);
29 | }
30 | }
31 | //}
32 | });
33 |
34 | // Sort groups by name A-Z
35 | groups.sort();
36 |
37 | var menuHtml = this.menuTpl({
38 | 'groups': groups
39 | });
40 |
41 | // Render the view
42 | this.$el.html(menuHtml);
43 | },
44 |
45 | hide: function() {
46 | this.$el.hide();
47 | },
48 |
49 | show: function() {
50 | this.$el.show();
51 | },
52 |
53 | /**
54 | * Update the menu.
55 | * @param {string} el The name of the current route.
56 | */
57 | update: function(menuItem) {
58 | //console.log(menuItem);
59 | // this.$menuItems.removeClass('active');
60 | // this.$menuItems.find('a[href=#'+menuItem+']').parent().addClass('active');
61 |
62 | }
63 | });
64 |
65 | return menuView;
66 |
67 | });
--------------------------------------------------------------------------------
/docs/reference/assets/js/api-filter.js:
--------------------------------------------------------------------------------
1 | YUI.add('api-filter', function (Y) {
2 |
3 | Y.APIFilter = Y.Base.create('apiFilter', Y.Base, [Y.AutoCompleteBase], {
4 | // -- Initializer ----------------------------------------------------------
5 | initializer: function () {
6 | this._bindUIACBase();
7 | this._syncUIACBase();
8 | },
9 | getDisplayName: function(name) {
10 |
11 | Y.each(Y.YUIDoc.meta.allModules, function(i) {
12 | if (i.name === name && i.displayName) {
13 | name = i.displayName;
14 | }
15 | });
16 |
17 | return name;
18 | }
19 |
20 | }, {
21 | // -- Attributes -----------------------------------------------------------
22 | ATTRS: {
23 | resultHighlighter: {
24 | value: 'phraseMatch'
25 | },
26 |
27 | // May be set to "classes" or "modules".
28 | queryType: {
29 | value: 'classes'
30 | },
31 |
32 | source: {
33 | valueFn: function() {
34 | var self = this;
35 | return function(q) {
36 | var data = Y.YUIDoc.meta[self.get('queryType')],
37 | out = [];
38 | Y.each(data, function(v) {
39 | if (v.toLowerCase().indexOf(q.toLowerCase()) > -1) {
40 | out.push(v);
41 | }
42 | });
43 | return out;
44 | };
45 | }
46 | }
47 | }
48 | });
49 |
50 | }, '3.4.0', {requires: [
51 | 'autocomplete-base', 'autocomplete-highlighters', 'autocomplete-sources'
52 | ]});
53 |
--------------------------------------------------------------------------------
/examples/mixingSounds/sketch.js:
--------------------------------------------------------------------------------
1 |
2 | // load two soundfile and crossfade beetween them
3 | var sound1,sound2;
4 | var gain1, gain2, gain3;
5 |
6 | function preload(){
7 | soundFormats('ogg', 'mp3');
8 | sound1 = loadSound('../files/Damscray_-_Dancing_Tiger_01');
9 | sound2 = loadSound('../files/beat.mp3');
10 | }
11 |
12 | function setup() {
13 | createCanvas(400,200);
14 |
15 | // create a 'mix bus' gain to which we will connect both soundfiles
16 | mixBus = new p5.Gain();
17 | mixBus.connect();
18 |
19 | // setup first sound for playing
20 | sound1.rate(1);
21 | sound1.loop();
22 | sound1.disconnect(); // diconnect from p5 output
23 |
24 | gain1 = new p5.Gain(); // setup a gain node
25 | gain1.setInput(sound1); // connect the first sound to its input
26 | gain1.connect(mixBus); // connect its output to the 'mix bus'
27 |
28 | sound2.rate(1);
29 | sound2.disconnect();
30 | sound2.loop();
31 |
32 | gain2 = new p5.Gain();
33 | gain2.setInput(sound2);
34 | gain2.connect(mixBus);
35 |
36 | }
37 |
38 |
39 | function draw(){
40 | background(180);
41 |
42 | // calculate the horizontal distance beetween the mouse and the right of the screen
43 | var d = dist(mouseX,0,width,0);
44 |
45 | // map the horizontal position of the mouse to values useable for volume control of sound1
46 | var vol1 = map(mouseX,0,width,0,1);
47 | var vol2 = 1-vol1; // when sound1 is loud, sound2 is quiet and vice versa
48 |
49 | gain1.amp(vol1,0.5,0);
50 | gain2.amp(vol2,0.5,0);
51 |
52 | // map the vertical position of the mouse to values useable for 'output volume control'
53 | var vol3 = map(mouseY,0,height,0,1);
54 | mixBus.amp(vol3,0.5,0);
55 | }
56 |
57 |
58 |
--------------------------------------------------------------------------------
/examples/spatial_panning/sketch.js:
--------------------------------------------------------------------------------
1 | // ====================
2 | // DEMO: P5.Panner3D: Moves sound in 3D space from max negative coordinates, to max positive
3 | // ====================
4 |
5 |
6 | var soundFile;
7 | var panner3d;
8 | var description, position;
9 |
10 | function preload() {
11 | soundFormats('mp3', 'ogg');
12 | soundFile = loadSound('../files/lucky_dragons_-_power_melody');
13 | }
14 |
15 | var i;
16 | var factorI;
17 | function setup() {
18 | createCanvas(500, 500, WEBGL);
19 |
20 |
21 | description = createDiv('Panner3D: The cone symbolizes the soundFile '+
22 | 'which is panning the soundin relation to the center of the '+
23 | 'canvas');
24 | p2 = createDiv(position);
25 |
26 | description.position(550,0).size(400,50);
27 | p2.position(550,50);
28 |
29 | panner1 = new p5.Panner3D();
30 |
31 |
32 | i = 0;
33 | factorI = 1;
34 | soundFile.disconnect();
35 | soundFile.loop();
36 | soundFile.connect(panner1);
37 | }
38 |
39 | function draw() {
40 | background(0);
41 |
42 | if (i > 500 || i < -500) {factorI = -1*factorI;}
43 |
44 | updateDescription();
45 |
46 | push();
47 | translate(i+=factorI*1,i + factorI*1,i + factorI*1);
48 | rotateX(frameCount* 0.01);
49 | rotateY(frameCount* 0.01);
50 | rotateZ(frameCount* 0.01);
51 | cone(100);
52 | pop();
53 |
54 | //pan the sound along with the cone
55 | panner1.set(i*10,i*10,i*10);
56 |
57 |
58 | }
59 |
60 | function updateDescription(){
61 | position = 'positionX: '+ panner1.positionX() +
62 | '
positionY: '+ panner1.positionY() +
63 | '
positionZ: '+ panner1.positionZ();
64 | p2.html(position);
65 | }
--------------------------------------------------------------------------------
/examples/learningProcessingExamples/02_sound_effect/sketch.js:
--------------------------------------------------------------------------------
1 | // Adapted from Learning Processing by Daniel Shiffman
2 | // http://www.learningprocessing.com
3 | // Doorbell sample by Corsica_S via freesound.org, Creative Commons BY 3.0
4 |
5 | // A sound file object
6 | var dingdong;
7 |
8 | // A doorbell object (that will trigger the sound)
9 | var doorbell;
10 |
11 | function setup() {
12 | createCanvas(200, 200);
13 |
14 | // Load the sound file.
15 | // We have included both an MP3 and an OGG version.
16 | soundFormats('mp3', 'ogg');
17 | dingdong = loadSound('../../files/doorbell.mp3');
18 |
19 | // Create a new doorbell
20 | doorbell = new Doorbell(width/2, height/2, 64);
21 | }
22 |
23 | function draw() {
24 | background(255);
25 | // Show the doorbell
26 | doorbell.display(mouseX, mouseY);
27 | }
28 |
29 | function mousePressed() {
30 | // If the user clicks on the doorbell, play the sound!
31 | if (doorbell.contains(mouseX, mouseY)) {
32 | dingdong.play();
33 | }
34 | }
35 |
36 | // A Class to describe a "doorbell" (really a button)
37 | var Doorbell = function(x_, y_, r_) {
38 | // Location and size
39 | var x = x_;
40 | var y = y_;
41 | var r = r_;
42 |
43 | // Is a point inside the doorbell? (used for mouse rollover, etc.)
44 | this.contains = function(mx, my) {
45 | if (dist(mx, my, x, y) < r) {
46 | return true;
47 | } else {
48 | return false;
49 | }
50 | };
51 |
52 | // Show the doorbell (hardcoded colors, could be improved)
53 | this.display = function(mx, my) {
54 | if (this.contains(mx, my)) {
55 | fill(100);
56 | } else {
57 | fill(175);
58 | }
59 | stroke(0);
60 | strokeWeight(4);
61 | ellipse(x, y, r, r);
62 | };
63 | };
--------------------------------------------------------------------------------
/test/tests/p5.Gain.js:
--------------------------------------------------------------------------------
1 | const expect = chai.expect;
2 | let gain;
3 |
4 | describe('p5.Gain', function () {
5 | beforeEach(function () {
6 | gain = new p5.Gain();
7 | });
8 |
9 | it('can be created', function () {
10 | expect(gain.input).to.have.property('gain');
11 | expect(gain.output).to.have.property('gain');
12 | let audioContext = gain.ac;
13 | expect(audioContext).to.have.property('baseLatency').to.be.an('number');
14 | expect(audioContext).to.have.property('destination');
15 | expect(audioContext).to.have.property('state').to.be.an('string');
16 | });
17 | it('can be created and disposed', function () {
18 | gain.dispose();
19 | expect(gain).to.not.have.property('input');
20 | expect(gain).to.not.have.property('output');
21 | });
22 |
23 | describe('methods', function () {
24 | describe('setInput', function () {
25 | it('can set Input', function () {
26 | let soundFile = p5.prototype.loadSound('./testAudio/drum.mp3');
27 | gain.setInput(soundFile);
28 | });
29 | });
30 | describe('connect, disconnect', function () {
31 | it('connects to p5.soundOut when no arguments are provided', function () {
32 | gain.connect();
33 | });
34 | it('can connect with or without input property', function () {
35 | let filter = new p5.Filter();
36 | gain.connect(filter);
37 | gain.connect(filter.input);
38 | });
39 | it('can disconnect', function () {
40 | let filter = new p5.Filter();
41 | gain.connect(filter);
42 | gain.disconnect();
43 | });
44 | });
45 | describe('amp', function () {
46 | it('can take only volume as input', function () {
47 | //TODO
48 | });
49 | });
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/examples/FFT_scaleNeighbors/sketch.js:
--------------------------------------------------------------------------------
1 | var source, fft;
2 |
3 | function setup() {
4 | createCanvas(windowWidth, windowHeight);
5 | noFill();
6 |
7 | source = new p5.AudioIn();
8 | source.start();
9 |
10 | fft = new p5.FFT(0.8, 1024);
11 | fft.setInput(source);
12 | }
13 |
14 | function draw() {
15 | background(220);
16 | var spectrum = fft.analyze();
17 | var newBuffer = [];
18 |
19 | if (source.freq) {
20 | source.freq(map(mouseX, 0, width, 100, 300));
21 | }
22 |
23 | var quarterSpectrum = spectrum.length/2;
24 |
25 | beginShape();
26 | for (var i = 0; i < quarterSpectrum; i++) {
27 | var point = smoothPoint(spectrum, i);
28 | newBuffer.push(point);
29 | var x = map(i, 0, quarterSpectrum, 0, width);
30 | var y = map(point, 0, 255, height, 0);
31 | curveVertex(x, y);
32 | }
33 | endShape();
34 | }
35 |
36 |
37 |
38 | // average each point with its neighbors
39 | function smoothPoint(spectrum, index) {
40 | var neighbors = 20;
41 |
42 | var val = 0;
43 |
44 | for (var i = index; i < (index+neighbors); i++) {
45 | val += spectrum[i];
46 | }
47 |
48 | // TO DO: scale value logarithmically
49 | // val *= logScale(index, spectrum.length);
50 |
51 | return val/neighbors;
52 | }
53 |
54 |
55 | /**
56 | * Given an index and the total number of entries, return the
57 | * log-scaled value.
58 | *
59 | * https://github.com/borismus/spectrograph/blob/master/g-spectrograph.js
60 | * MIT license
61 | */
62 | function logScale(index, total, opt_base) {
63 | var base = opt_base || 2;
64 | var logmax = logBase(total + 1, base);
65 | var exp = logmax * index / total;
66 | return Math.round(Math.pow(base, exp) - 1);
67 | }
68 |
69 | function logBase(val, base) {
70 | return Math.log(val) / Math.log(base);
71 | }
--------------------------------------------------------------------------------
/examples/distortion/sketch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Trigger an oscillator processed through distortion.
3 | */
4 |
5 | var env; // this is the env
6 | var osc; // this oscillator that will be effected by the distortion
7 | var distortion; // this is the waveshaper distortion effect
8 |
9 | var fft;
10 |
11 | function setup() {
12 | createCanvas(windowWidth, windowHeight);
13 | fft = new p5.FFT(0, 256);
14 |
15 |
16 | env = new p5.Envelope();
17 | env.setADSR(0.01, 0.2, 0.1, 0.3);
18 | env.setRange(1.0, 0.0);
19 |
20 | osc = new p5.SawOsc(); // connects to main output by default
21 | osc.start(0);
22 | osc.freq(220);
23 | osc.amp(env);
24 | osc.disconnect(); // Disconnect from output to process through distortion
25 |
26 | // Create a waveshaper distortion with 2x oversampling
27 | distortion = new p5.Distortion(1, '4x');
28 | osc.connect(distortion);
29 | }
30 |
31 | function draw() {
32 | var samples = fft.waveform();
33 | drawOscilloscope(samples);
34 | }
35 |
36 | function drawOscilloscope(samples) {
37 | var yTranslateScope = 50;
38 | var xTranslateScope = 50;
39 | var scopeWidth = width / 5;
40 | var scopeHeight = height / 4;
41 |
42 | fill(177, 177, 177);
43 | rect(xTranslateScope, yTranslateScope, scopeWidth, scopeHeight);
44 |
45 | stroke(0, 0, 0);
46 | strokeWeight(0.5);
47 |
48 | beginShape();
49 | for (var sampleIndex in samples) {
50 | var x = map(sampleIndex, 0, samples.length, 0, scopeWidth);
51 | var y = map(samples[sampleIndex], -1, 1, -scopeHeight / 2, scopeHeight / 2);
52 | vertex(x + xTranslateScope, y + scopeHeight/2 + yTranslateScope);
53 | }
54 | endShape();
55 | }
56 |
57 | function mousePressed() {
58 | env.triggerAttack();
59 | }
60 |
61 | function mouseReleased() {
62 | env.triggerRelease();
63 | }
64 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/vendor/bootstrap/transition.js:
--------------------------------------------------------------------------------
1 | /* ========================================================================
2 | * Bootstrap: transition.js v3.1.1
3 | * http://getbootstrap.com/javascript/#transitions
4 | * ========================================================================
5 | * Copyright 2011-2014 Twitter, Inc.
6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7 | * ======================================================================== */
8 |
9 |
10 | +function ($) {
11 | 'use strict';
12 |
13 | // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
14 | // ============================================================
15 |
16 | function transitionEnd() {
17 | var el = document.createElement('bootstrap')
18 |
19 | var transEndEventNames = {
20 | 'WebkitTransition' : 'webkitTransitionEnd',
21 | 'MozTransition' : 'transitionend',
22 | 'OTransition' : 'oTransitionEnd otransitionend',
23 | 'transition' : 'transitionend'
24 | }
25 |
26 | for (var name in transEndEventNames) {
27 | if (el.style[name] !== undefined) {
28 | return { end: transEndEventNames[name] }
29 | }
30 | }
31 |
32 | return false // explicit for ie8 ( ._.)
33 | }
34 |
35 | // http://blog.alexmaccaw.com/css-transitions
36 | $.fn.emulateTransitionEnd = function (duration) {
37 | var called = false, $el = this
38 | $(this).one($.support.transition.end, function () { called = true })
39 | var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
40 | setTimeout(callback, duration)
41 | return this
42 | }
43 |
44 | $(function () {
45 | $.support.transition = transitionEnd()
46 | })
47 |
48 | }(jQuery);
49 |
--------------------------------------------------------------------------------
/examples/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 |
44 | // cycle through the array of cVerb.impulses
45 | currentIR++;
46 | if (currentIR >= cVerb.impulses.length) {
47 | currentIR = 0;
48 | }
49 | cVerb.toggleImpulse(currentIR);
50 |
51 | // play the sound through the impulse
52 | sound.play();
53 |
54 | // display the current Impulse Response name (the filepath)
55 | p.html('Convolution Impulse Response: ' + cVerb.impulses[currentIR].name);
56 | }
57 |
--------------------------------------------------------------------------------
/examples/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 setup() {
11 | createCanvas(0,0);
12 | sample1 = loadSound( ['../files/Damscray_-_Dancing_Tiger_01.ogg', '../files/Damscray_-_Dancing_Tiger_01.mp3'] );
13 | sample2 = loadSound( ['../files/Damscray_-_Dancing_Tiger_02.ogg', '../files/Damscray_-_Dancing_Tiger_02.mp3'] );
14 |
15 | createP('Press "a" and "s" on your keyboard to play two different samples.
Trigger lots of sounds at once! Change mode to hear the difference');
16 |
17 | button = createButton('Current Play Mode: ');
18 | button.mousePressed(togglePlayMode);
19 | }
20 |
21 | function draw() {
22 | button.html('Current Play Mode: ' + playMode);
23 | }
24 |
25 | // alternate between 'sustain' and 'restart', and set playMode of both samples
26 | function togglePlayMode(){
27 | if (playMode == 'sustain'){
28 | playMode = 'restart';
29 | }
30 | else if (playMode == 'restart'){
31 | playMode = 'untilDone';
32 | }
33 | else {
34 | playMode = 'sustain';
35 | }
36 | sample1.playMode(playMode);
37 | sample2.playMode(playMode);
38 | }
39 |
40 | function keyPressed(k) {
41 | if (k.keyCode == 65) {
42 | sample1.play(0, 1, .6);
43 |
44 | // Get even more monophonic by only letting one sample play at a time
45 | if ( playMode =='restart' && sample2.isPlaying() ){
46 | sample2.stopAll();
47 | }
48 | }
49 | if (k.keyCode == 83) {
50 | if ( playMode =='restart' && sample1.isPlaying() ){
51 | sample1.stopAll();
52 | }
53 | sample2.play(0, 1, .6);
54 | }
55 | }
--------------------------------------------------------------------------------
/examples/loadSound_with_Drag_and_Drop/sketch.js:
--------------------------------------------------------------------------------
1 | var soundArray = [];
2 |
3 | var fileInput;
4 | var dndSelect;
5 | var container;
6 |
7 | function setup(){
8 | createCanvas(500,100);
9 |
10 | container = getElement('container');
11 |
12 | dndSelect = createDiv();
13 | dndSelect.addClass('dndSelect');
14 | dndSelect.html('Drag and Drop sounds here.');
15 |
16 | //Event listeners for the file selection elements
17 | dndSelect.drop(gotFile);
18 | dndSelect.dragOver(dndDragHandler);
19 | dndSelect.dragLeave(dndResetBackground);
20 |
21 | fileInput = createFileInput(gotFile);
22 | fileInput.parent(container);
23 |
24 | }
25 |
26 |
27 | function draw(){
28 | background(240);
29 |
30 | for(i =0; i 77*i && mouseX < (77*i)+75 && mouseY > 12.5 && mouseY < 87.5){
44 | if(soundArray[i].isLoaded()){
45 | if(soundArray[i].isPlaying()){
46 | soundArray[i].stop();
47 | }
48 | else{
49 | soundArray[i].play();
50 | }
51 | break;
52 | }
53 | }
54 | }
55 | }
56 |
57 |
58 | // callback from fileInput and drag and drop
59 | function gotFile(file){
60 | var newSF = loadSound(file);
61 | soundArray.push(newSF);
62 | dndResetBackground();
63 | }
64 |
65 | function dndDragHandler(evt){
66 | dndSelect.style('background-color', 'rgb(255,0,0)');
67 | evt.dataTransfer.dropEffect = 'copy';
68 | }
69 |
70 | function dndResetBackground() {
71 | dndSelect.style('background-color', 'rgb(230,230,230)');
72 | }
73 |
--------------------------------------------------------------------------------
/examples/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 | let mic, recorder, soundFile;
6 |
7 | let isRecordingStarted = false;
8 | let isResultPlayed = false;
9 |
10 | function setup() {
11 | createCanvas(400, 400);
12 | background(200);
13 | fill(0);
14 | text('Enable mic and click the mouse to begin recording', 20, 20);
15 |
16 | // create an audio in
17 | mic = new p5.AudioIn();
18 |
19 | // create a sound recorder
20 | recorder = new p5.SoundRecorder();
21 |
22 | // connect the mic to the recorder
23 | recorder.setInput(mic);
24 |
25 | // create an empty sound file that we will use to playback the recording
26 | soundFile = new p5.SoundFile();
27 | }
28 |
29 | function mousePressed() {
30 | userStartAudio();
31 | // use the '.enabled' boolean to make sure user enabled the mic (otherwise we'd record silence)
32 | if (!isRecordingStarted && !isResultPlayed) {
33 | // users must manually enable their browser microphone for recording to work properly!
34 | mic.start(function () {
35 | // Tell recorder to record to a p5.SoundFile which we will use for playback
36 | recorder.record(soundFile);
37 |
38 | background(255, 0, 0);
39 | text('Recording now! Click to stop.', 20, 20);
40 | isRecordingStarted = true;
41 | });
42 | } else if (isRecordingStarted && !isResultPlayed) {
43 | recorder.stop(); // stop recorder, and send the result to soundFile
44 | mic.dispose();
45 | background(0, 255, 0);
46 | text('Recording stopped. Click to play', 20, 20);
47 | isResultPlayed = true;
48 | } else if (isRecordingStarted && isResultPlayed) {
49 | soundFile.play(); // play the result!
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/examples/envelopeRamp/sketch.js:
--------------------------------------------------------------------------------
1 | var osc, envelope, fft;
2 | var myPhraseAttack, myPhraseRelease, myPart;
3 | var atPattern = [1, 0,0,0];
4 | var scaleArray = [60, 62, 64, 65, 67, 69, 71, 72];
5 | var note = 0;
6 | var startPoint = 0;
7 | var endPoint = 0;
8 | var numWaveforms = 50;
9 |
10 | function setup() {
11 | createCanvas(710, 200);
12 | osc = new p5.SinOsc();
13 | envelope = new p5.Envelope();
14 | envelope.setADSR(.005,0.02);
15 | osc.amp(0.);
16 | osc.start();
17 | myPhraseAttack = new p5.Phrase('testerAttack', makeSoundAttack, atPattern);
18 | myPart = new p5.Part();
19 | myPart.addPhrase(myPhraseAttack);
20 | myPart.setBPM(240);
21 | myPart.loop();
22 | myPart.start();
23 | fft = new p5.FFT();
24 | endPoint = width / numWaveforms;
25 | noFill();
26 | background(20);
27 | }
28 |
29 | function draw() {
30 |
31 |
32 | var waveform = fft.waveform(); // analyze the waveform
33 | beginShape();
34 | stroke(255, 255, 0);
35 | for (var i = 0; i < waveform.length; i++){
36 | var x = map(i, 0, waveform.length, startPoint, endPoint);
37 | var y = map(waveform[i], -1, 1, height, 0);
38 | vertex(x, y);
39 | }
40 | endShape();
41 | startPoint = endPoint + 1;
42 | endPoint += (width / numWaveforms);
43 | if (endPoint > width)
44 | {
45 | background(20);
46 | startPoint = 0;
47 | endPoint = (width / numWaveforms);
48 | }
49 | }
50 |
51 |
52 | function makeSoundAttack(time, playbackRate)
53 | {
54 | var midiValue = scaleArray[note];
55 | var freqValue = midiToFreq(midiValue);
56 | osc.freq(freqValue * 2, .001, time);
57 | envelope.ramp(osc, time, 1, 0);
58 | note = (note + 1) % scaleArray.length;
59 | setTimeout(redrawWaveform, time * 1000.0);
60 | }
61 |
62 |
63 | function redrawWaveform()
64 | {
65 | background(20);
66 | startPoint = 0;
67 | endPoint = (width / numWaveforms);
68 | }
69 |
--------------------------------------------------------------------------------
/examples/DelayNoiseEnvelope/sketch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Example: p5.Delay w/ p5.Noise, p5.Envelope & p5.Amplitude
3 | *
4 | * Click the mouse to hear the p5.Delay process a Noise Envelope.
5 | *
6 | * MouseX controls the p5.Delay Filter Frequency.
7 | * MouseY controls both the p5.Delay Time and Resonance.
8 | */
9 |
10 | var noise, env, analyzer, delay;
11 |
12 | function setup() {
13 | createCanvas(710, 400);
14 | noise = new p5.Noise('white'); // other types include 'brown' and 'pink'
15 |
16 | // Turn down because we'll control .amp with a p5.Envelope
17 | noise.amp(0);
18 |
19 | noise.start();
20 | noise.disconnect(); // so we will only hear the p5.Delay effect
21 |
22 | delay = new p5.Delay();
23 | delay.process(noise, .12, .7, 2300); // tell delay to process noise
24 |
25 | // the Envelope ADSR: attackTime, decayTime, sustainLevel, releaseTime
26 | env = new p5.Envelope();
27 | env.setADSR(0.01, 0.2, 0.2, 0.1)
28 | env.setRange(1, 0);
29 |
30 | // p5.Amplitude will analyze all sound in the sketch
31 | analyzer = new p5.Amplitude();
32 | }
33 |
34 | function draw() {
35 | background(0);
36 |
37 | // get volume reading from the p5.Amplitude analyzer
38 | var level = analyzer.getLevel();
39 | // then use level to draw a green rectangle
40 | var levelHeight = map(level, 0, .4, 0, height);
41 | fill(100,250,100);
42 | rect(0, height, width, - levelHeight);
43 |
44 | // map mouseX and mouseY to p5.Delay parameters
45 | var filterFreq = map(mouseX, 0, width, 60, 15000);
46 | filterFreq = constrain(filterFreq, 60, 15000);
47 | var filterRes = map(mouseY, 0, height, 3, 0.01);
48 | filterRes = constrain(filterRes, 0.01, 3);
49 | delay.filter(filterFreq, filterRes);
50 | var delTime = map(mouseY, 0, width, .2, .01);
51 | delTime = constrain(delTime, .01, .2);
52 | delay.delayTime(delTime);
53 | }
54 |
55 | function mousePressed() {
56 | env.play(noise, 0, 0.1, 0);
57 | }
--------------------------------------------------------------------------------
/examples/pulseWaveform/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 = .25;
10 | var fft;
11 |
12 |
13 | var oscOn = false;
14 |
15 | function setup() {
16 | createCanvas(800,400);
17 | noFill();
18 |
19 | widthLabel = createP('Width: ' + w);
20 | widthSlider = createSlider(0.0, 100.0, w*100);
21 |
22 | button = createButton('start');
23 | button.mousePressed(toggleOsc);
24 |
25 | freqLabel = createP('Frequency: ');
26 | freqSlider = createSlider(1, 700, freq);
27 |
28 | ampLabel = createP('Amplitude: ' + amp);
29 | ampSlider = createSlider(0.0, 100.0, amp*100);
30 |
31 |
32 | pulse = new p5.Pulse(freq);
33 | pulse.amp(amp);
34 |
35 | // create an fft to analyze the audio
36 | fft = new p5.FFT();
37 |
38 | // begin sound
39 | toggleOsc();
40 | }
41 |
42 | function draw() {
43 | background(30);
44 |
45 | amp = ampSlider.value()/100;
46 | pulse.amp(amp);
47 | ampLabel.html('Amplitude: ' + amp + '/ 1.0');
48 |
49 | freq = freqSlider.value();
50 | pulse.freq(freq);
51 | freqLabel.html('Frequency: ' + freq + ' Hz');
52 |
53 |
54 | w = widthSlider.value()/100;
55 | pulse.width(w);
56 | widthLabel.html('Width: ' + w + '/ 1.0');
57 |
58 | // process the waveform
59 | waveform = fft.waveform();
60 |
61 | // draw the shape of the waveform
62 | stroke(255);
63 | strokeWeight(10);
64 | beginShape();
65 | for (var i = 0; ifeedback loop between the mic and speakers. Try headphones.');
31 | }
32 |
33 | function draw() {
34 | background(0);
35 |
36 | // get the volume level, accepts an optional smoothing value or defaults to 0.
37 | micLevel = mic.getLevel();
38 |
39 | text('input volume: ' + micLevel, 5, 10);
40 |
41 | // if the mic picks up a level greater than zero, we can assume
42 | // that the user has allowed their browser to access the microphone.
43 | if (micLevel > 0) {
44 | h.html('Make some noise!');
45 | }
46 |
47 | ellipse(width/2,height/2, 400*micLevel + 10, 400*micLevel + 10);
48 |
49 | // set main output
50 | levelLabel.html('Output Volume: ' + outputLevel.value()/100);
51 | outputVolume(outputLevel.value()/100);
52 | }
53 |
54 |
55 | // Toggle whether mic is connected to main output
56 | function toggleSound() {
57 | if (soundOn == false) {
58 | mic.connect();
59 | soundOn = true;
60 | soundToggle.html('Sound OFF');
61 | } else {
62 | mic.disconnect();
63 | soundOn = false;
64 | soundToggle.html('Sound ON');
65 | }
66 | }
67 |
68 | // Toggle whether the mic is on (getting input) or off
69 | function toggleMic() {
70 | if (micOn == true) {
71 | mic.stop();
72 | micOn = false;
73 | micToggle.html('Start Mic');
74 | } else {
75 | mic.start();
76 | micOn = true;
77 | micToggle.html('Stop mic');
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/test/tests/p5.Pulse.js:
--------------------------------------------------------------------------------
1 | const expect = chai.expect;
2 |
3 | describe('p5.Pulse', function () {
4 | it('can be created without any arguments', function () {
5 | let pulse = new p5.Pulse();
6 | expect(pulse.w).to.be.zero;
7 | expect(pulse.oscillator.type).to.equal('sawtooth');
8 | expect(pulse.f).to.equal(440);
9 | expect(pulse.osc2).to.have.property('connection');
10 | expect(pulse.osc2).to.have.property('oscMods');
11 | expect(pulse.osc2).to.have.property('oscillator');
12 | expect(pulse.dcOffset).to.have.property('buffer');
13 | expect(pulse.dcOffset).to.have.property('channelCount');
14 | expect(pulse.dcGain).to.have.property('gain');
15 | expect(pulse.output.gain.value).to.equal(1);
16 | });
17 | it('can be with arguments', function () {
18 | let pulse = new p5.Pulse(220, 0.4);
19 | expect(pulse.w).to.equal(0.4);
20 | expect(pulse.f).to.equal(220);
21 | expect(pulse.dNode.delayTime.value).to.be.approximately(0.0009, 0.00001);
22 | expect(pulse.dcGain.gain.value).to.be.approximately(0.17, 0.001);
23 | });
24 | describe('methods', function () {
25 | it('can set width', function (done) {
26 | let pulse = new p5.Pulse();
27 | pulse.width(0.3);
28 | expect(pulse.dNode.delayTime.value).to.be.approximately(0.00068, 0.00001);
29 | expect(pulse.dcGain.gain.value).to.be.approximately(0.34, 0.001);
30 |
31 | //can take non-numerical value
32 | let osc = new p5.Oscillator();
33 | pulse.width(osc);
34 | done();
35 | });
36 | it('can be started and stopped', function (done) {
37 | let pulse = new p5.Pulse(444, 0.1);
38 | expect(pulse.started).to.be.false;
39 | pulse.start(221, 0.1);
40 | setTimeout(() => {
41 | expect(pulse.oscillator.frequency.value).to.equal(221);
42 | expect(pulse.oscillator.type).to.equal('sawtooth');
43 | expect(pulse.osc2.oscillator.type).to.equal('sawtooth');
44 | done();
45 | }, 500);
46 | expect(pulse.started).to.be.true;
47 | expect(pulse.osc2.started).to.be.true;
48 | pulse.stop();
49 | expect(pulse.started).to.be.false;
50 | expect(pulse.osc2.started).to.be.false;
51 | });
52 | it('can set frequency', function () {
53 | //TODO
54 | });
55 | });
56 | });
57 |
--------------------------------------------------------------------------------
/examples/envelope_exponential_trig_rel/sketch.js:
--------------------------------------------------------------------------------
1 | var osc, envelope, fft;
2 | var myPhraseAttack, myPhraseRelease, myPart;
3 | var atPattern = [1, 0,0,0];
4 | var relPattern = [0, 0,1,0];
5 | var scaleArray = [60, 62, 64, 65, 67, 69, 71, 72];
6 | var note = 0;
7 | var startPoint = 0;
8 | var endPoint = 0;
9 | var numWaveforms = 50;
10 |
11 | function setup() {
12 | createCanvas(710, 200);
13 | osc = new p5.SinOsc();
14 | envelope = new p5.Envelope();
15 | envelope.setExp(true);
16 | envelope.setADSR(0.1, 1.0, .1, 0.2, .01, 0.0); //AT, AL, DT, SL, RT, RL
17 | osc.amp(0.);
18 | osc.start();
19 | myPhraseAttack = new p5.Phrase('testerAttack', makeSoundAttack, atPattern);
20 | myPhraseRelease = new p5.Phrase('testerRelease', makeSoundRelease, relPattern);
21 | myPart = new p5.Part();
22 | myPart.addPhrase(myPhraseAttack);
23 | myPart.addPhrase(myPhraseRelease); // comment this back in to check release
24 | myPart.setBPM(100);
25 | myPart.loop();
26 | myPart.start();
27 | fft = new p5.FFT();
28 | endPoint = width / numWaveforms;
29 | noFill();
30 | background(20);
31 | }
32 |
33 | function draw() {
34 |
35 |
36 | var waveform = fft.waveform(); // analyze the waveform
37 | beginShape();
38 | stroke(255, 255, 0);
39 | for (var i = 0; i < waveform.length; i++){
40 | var x = map(i, 0, waveform.length, startPoint, endPoint);
41 | var y = map(waveform[i], -1, 1, height, 0);
42 | vertex(x, y);
43 | }
44 | endShape();
45 | startPoint = endPoint + 1;
46 | endPoint += (width / numWaveforms);
47 | if (endPoint > width)
48 | {
49 | background(20);
50 | startPoint = 0;
51 | endPoint = (width / numWaveforms);
52 | }
53 | }
54 |
55 |
56 | function makeSoundAttack(time, playbackRate)
57 | {
58 | var midiValue = scaleArray[note];
59 | var freqValue = midiToFreq(midiValue);
60 | osc.freq(freqValue * 2, .01, time); // comment this back in to check pitch changes
61 | envelope.triggerAttack(osc, time);
62 | note = (note + 1) % scaleArray.length;
63 | setTimeout(redrawWaveform, time * 1000.0);
64 |
65 | }
66 |
67 | function makeSoundRelease(time, playbackRate)
68 | {
69 | envelope.triggerRelease(osc, time); // comment this back in to check release
70 | }
71 |
72 | function redrawWaveform()
73 | {
74 | background(20);
75 | startPoint = 0;
76 | endPoint = (width / numWaveforms);
77 | }
78 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const path = require('path');
3 | const fs = require('fs');
4 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
5 | const WebpackAutoInject = require('webpack-auto-inject-version');
6 |
7 | const autoInjectVersionConfig = {
8 | SILENT: true,
9 | SHORT: 'p5.sound',
10 | components: {
11 | AutoIncreaseVersion: false,
12 | InjectAsComment: true,
13 | InjectByTag: false
14 | },
15 | componentsOptions: {
16 | InjectAsComment: {
17 | tag: 'Version: {version} - {date}',
18 | dateFormat: 'yyyy-mm-dd',
19 | multiLineCommentType: true,
20 | },
21 | }
22 | };
23 |
24 | module.exports = {
25 | context: __dirname + '/src',
26 | entry: {
27 | 'p5.sound': './app.js',
28 | 'p5.sound.min': './app.js'
29 | },
30 | output: {
31 | // where we want to output built files
32 | path: __dirname + "/lib"
33 | },
34 | mode: 'production',
35 | devtool: 'source-map',
36 | optimization: {
37 | runtimeChunk: true,
38 | },
39 | plugins: [
40 | new webpack.NormalModuleReplacementPlugin(/Tone(\.*)/, function(resource) {
41 | resource.request = path.join(__dirname, './node_modules/tone/', resource.request);
42 | }),
43 | new webpack.BannerPlugin({
44 | banner: fs.readFileSync('./fragments/before.frag').toString(),
45 | raw: true,
46 | }),
47 | new WebpackAutoInject(autoInjectVersionConfig)
48 | ],
49 | module: {
50 | rules: [
51 | {
52 | test: /node_modules(\.*)/,
53 | use: {
54 | loader: 'uglify-loader'
55 | }
56 | },
57 | {
58 | test: /\.js$/,
59 | exclude: /(node_modules)/,
60 | use: {
61 | loader: 'babel-loader'
62 | }
63 | },
64 | ]
65 | },
66 | optimization: {
67 | minimize: true,
68 | minimizer: [
69 | new UglifyJsPlugin({
70 | include: [/\.min\.js$/],
71 | cache: true,
72 | parallel: true,
73 | uglifyOptions: {
74 | compress: {
75 | drop_console: true
76 | },
77 | ecma: 6,
78 | mangle: true,
79 | output: {
80 | comments: false
81 | }
82 | },
83 | sourceMap: true,
84 | })
85 | ]
86 | },
87 | resolve: {
88 | modules: [path.resolve(__dirname, 'src'), 'node_modules']
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/examples/amplitude_analysis/sketch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * DEMO: Use p5.Amplitude (volume) to change the size of an ellipse
3 | */
4 |
5 | var soundFile;
6 | var amplitude;
7 |
8 | // description text
9 | var description;
10 | var p1;
11 |
12 | var smoothing = .01;
13 | var smoothSlider, smoothLabel;
14 |
15 | function preload() {
16 | soundFile = loadSound(['../files/beat.mp3', '../files/beat.ogg']);
17 | }
18 |
19 | function setup() {
20 | createCanvas(400, 400);
21 | background(0);
22 | noStroke();
23 | fill(255);
24 |
25 | soundFile.loop();
26 |
27 | // create a new p5.Amplitude. Optionally, give it a 'smoothing' value betw 0.0 and .999
28 | amplitude = new p5.Amplitude(smoothing);
29 |
30 | // instruction text
31 | description = 'Spacebar: pause/unpause the loop.
Press "N" to toggle Normalize';
32 | p1 = createP(description);
33 |
34 | smoothSlider = createSlider(0.0, 99.9, smoothing*100);
35 | smoothLabel = createP('Smoothing: ' + smoothing);
36 | }
37 |
38 | function draw() {
39 | background(0);
40 |
41 | // get volume from the amplitude process
42 | var volume = amplitude.getLevel();
43 |
44 | // print the volume to the canvas. It is a float between 0 and 1.0.
45 | text('volume: ' + volume, 20, 20);
46 |
47 | // Change size based on volume. First, map to useful values.
48 | var diameter = map(volume, 0, 1.0, 25, 400);
49 | ellipse(width/2, height/2, diameter, diameter);
50 |
51 | // instruction text
52 | description = 'Spacebar: pause/unpause the loop.
Press "N" to toggle Normalize. Normalized is '+amplitude.normalize;
53 | p1.html(description);
54 |
55 | // change smoothing
56 | smoothing = smoothSlider.value()/100;
57 | smoothLabel.html('Smoothing: ' + smoothing);
58 | amplitude.smooth(smoothing);
59 | }
60 |
61 | // on key pressed...
62 | function keyPressed(e) {
63 |
64 | // spacebar pauses
65 | if (e.keyCode == 32) {
66 | if (soundFile.isPlaying()) {
67 | soundFile.pause();
68 | } else {
69 | soundFile.play();
70 | }
71 | }
72 |
73 | // 'n' keypress toggles normalize on/off
74 | if (e.keyCode == 78) {
75 | amplitude.toggleNormalize();
76 | }
77 |
78 | }
79 |
80 | function mouseClicked() {
81 | if (mouseX > 0 && mouseX < width && mouseY > 0 && mouseY < height) {
82 | if ( getOutputVolume() == 0) {
83 | outputVolume(0, 1);
84 | } else {
85 | outputVolume(0.1),1;
86 | }
87 | }
88 | }
89 |
90 |
91 |
--------------------------------------------------------------------------------
/examples/envelope_exponential_play/sketch.js:
--------------------------------------------------------------------------------
1 | var osc, envelope, fft;
2 | var myPhraseAttack, myPhraseRelease, myPart;
3 | var atPattern = [1, 0,0,0];
4 | var relPattern = [0, 0,1,0];
5 | var scaleArray = [60, 62, 64, 65, 67, 69, 71, 72];
6 | var note = 0;
7 | var startPoint = 0;
8 | var endPoint = 0;
9 | var numWaveforms = 50;
10 |
11 | function setup() {
12 | createCanvas(710, 200);
13 | osc = new p5.SinOsc();
14 | envelope = new p5.Envelope(0.1, 1.0, 0.1, .5, .1, .5, .1, 0.0); //
15 | envelope.setExp(true);
16 | //envelope.setADSR(0.1, 1.0, 1.0, 0.2, 5.0, 0.0); //AT, AL, DT, SL, RT, RL
17 | osc.amp(0.);
18 | osc.start();
19 | myPhraseAttack = new p5.Phrase('testerAttack', makeSoundAttack, atPattern);
20 | myPhraseRelease = new p5.Phrase('testerRelease', makeSoundRelease, relPattern);
21 | myPart = new p5.Part();
22 | myPart.addPhrase(myPhraseAttack);
23 | myPart.addPhrase(myPhraseRelease); // comment this back in to check release
24 | myPart.setBPM(100);
25 | myPart.loop();
26 | myPart.start();
27 | fft = new p5.FFT();
28 | endPoint = width / numWaveforms;
29 | noFill();
30 | background(20);
31 | }
32 |
33 | function draw() {
34 |
35 |
36 | var waveform = fft.waveform(); // analyze the waveform
37 | beginShape();
38 | stroke(255, 255, 0);
39 | for (var i = 0; i < waveform.length; i++){
40 | var x = map(i, 0, waveform.length, startPoint, endPoint);
41 | var y = map(waveform[i], -1, 1, height, 0);
42 | vertex(x, y);
43 | }
44 | endShape();
45 | startPoint = endPoint + 1;
46 | endPoint += (width / numWaveforms);
47 | if (endPoint > width)
48 | {
49 | background(20);
50 | startPoint = 0;
51 | endPoint = (width / numWaveforms);
52 | }
53 | }
54 |
55 |
56 | function makeSoundAttack(time, playbackRate)
57 | {
58 | var midiValue = scaleArray[note];
59 | var freqValue = midiToFreq(midiValue);
60 | osc.freq(freqValue * 2, .01, time); // comment this back in to check pitch changes
61 | envelope.play(osc, time);
62 | //envelope.triggerAttack(osc, time);
63 | note = (note + 1) % scaleArray.length;
64 | setTimeout(redrawWaveform, time * 1000.0);
65 |
66 | }
67 |
68 | function makeSoundRelease(time, playbackRate)
69 | {
70 | //envelope.triggerRelease(osc, time); // comment this back in to check release
71 | }
72 |
73 | function redrawWaveform()
74 | {
75 | background(20);
76 | startPoint = 0;
77 | endPoint = (width / numWaveforms);
78 | }
79 |
--------------------------------------------------------------------------------
/examples/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 p5.AudioIn();
22 | source.start();
23 |
24 | fft = new p5.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 |
45 | function autoCorrelate(buffer) {
46 | var newBuffer = [];
47 | var nSamples = buffer.length;
48 |
49 | var autocorrelation = [];
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 (var 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 (var index = 0; index < nSamples; index++){
79 | if (abs(newBuffer[index]) > biggestVal){
80 | biggestVal = abs(newBuffer[index]);
81 | }
82 | }
83 | for (var index = 0; index < nSamples; index++){
84 | newBuffer[index] /= biggestVal;
85 | }
86 | }
87 |
88 | return newBuffer;
89 | }
--------------------------------------------------------------------------------
/examples/virtual_piano/sketch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Virtual Piano: Example for event-driven sound playback.
3 | *
4 | * This example uses the p5.PolySynth to produce instantaneously,
5 | * driven by user events.
6 | */
7 |
8 | var polySynth;
9 | var velocity = 0.7; // From 0-1
10 | var baseNote = 72;
11 | var keyOrder = "ASDFGHJKL";
12 | var keyStates = [0, 0, 0, 0, 0, 0, 0, 0, 0];
13 |
14 | function setup() {
15 | createCanvas(720, 400);
16 | textAlign(CENTER, CENTER);
17 | strokeWeight(3);
18 | // Create synth voice
19 | synth = new p5.PolySynth();
20 | }
21 |
22 | function draw() {
23 | var keyWidth = width / keyStates.length;
24 | // Draw keys
25 | for (var i = 0; i < keyStates.length; i++) {
26 | var keyColor;
27 | if (keyStates[i] === 1) {
28 | keyColor = color(255, 220, 120);
29 | } else {
30 | keyColor = color(150, 230, 245);
31 | }
32 | fill(keyColor);
33 | stroke(255);
34 | rect(i * keyWidth, 0, keyWidth, height);
35 | // Key label
36 | fill(40);
37 | noStroke();
38 | text(keyOrder[i], i * keyWidth + keyWidth / 2, height / 2);
39 | }
40 | }
41 |
42 | function keyPressed() {
43 | var keyIndex = keyOrder.indexOf(key);
44 | // Check if valid note key pressed
45 | if (keyIndex >= 0) {
46 | // Update key state
47 | keyStates[keyIndex] = 1;
48 | // Play synth
49 | var midiNoteNumber = baseNote + keyIndex; // 0-127; 60 is Middle C (C4)
50 | var freq = midiToFreq(midiNoteNumber);
51 | synth.noteAttack(freq, velocity, 0);
52 | }
53 | }
54 |
55 | function keyReleased() {
56 | var keyIndex = keyOrder.indexOf(key);
57 | // Check if valid note key pressed
58 | if (keyIndex >= 0) {
59 | // Update key state
60 | keyStates[keyIndex] = 0;
61 | // Stop synth
62 | var midiNoteNumber = baseNote + keyIndex; // 0-127; 60 is Middle C (C4)
63 | var freq = midiToFreq(midiNoteNumber);
64 | synth.noteRelease(freq, 0);
65 | }
66 | }
67 |
68 | function touchStarted() {
69 | var keyWidth = width / keyStates.length;
70 | var keyIndex = floor(mouseX / keyWidth);
71 | // Update key state
72 | keyStates[keyIndex] = 1;
73 | // Play synth
74 | var midiNoteNumber = baseNote + keyIndex; // 0-127; 60 is Middle C (C4)
75 | var freq = midiToFreq(midiNoteNumber);
76 | synth.noteAttack(freq, velocity, 0);
77 | }
78 |
79 | function touchEnded() {
80 | for (var i = 0; i < keyStates.length; i++) {
81 | keyStates[i] = 0;
82 | }
83 | synth.noteRelease();
84 | }
85 |
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/vendor/bootstrap/alert.js:
--------------------------------------------------------------------------------
1 | /* ========================================================================
2 | * Bootstrap: alert.js v3.1.1
3 | * http://getbootstrap.com/javascript/#alerts
4 | * ========================================================================
5 | * Copyright 2011-2014 Twitter, Inc.
6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7 | * ======================================================================== */
8 |
9 |
10 | +function ($) {
11 | 'use strict';
12 |
13 | // ALERT CLASS DEFINITION
14 | // ======================
15 |
16 | var dismiss = '[data-dismiss="alert"]'
17 | var Alert = function (el) {
18 | $(el).on('click', dismiss, this.close)
19 | }
20 |
21 | Alert.prototype.close = function (e) {
22 | var $this = $(this)
23 | var selector = $this.attr('data-target')
24 |
25 | if (!selector) {
26 | selector = $this.attr('href')
27 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
28 | }
29 |
30 | var $parent = $(selector)
31 |
32 | if (e) e.preventDefault()
33 |
34 | if (!$parent.length) {
35 | $parent = $this.hasClass('alert') ? $this : $this.parent()
36 | }
37 |
38 | $parent.trigger(e = $.Event('close.bs.alert'))
39 |
40 | if (e.isDefaultPrevented()) return
41 |
42 | $parent.removeClass('in')
43 |
44 | function removeElement() {
45 | $parent.trigger('closed.bs.alert').remove()
46 | }
47 |
48 | $.support.transition && $parent.hasClass('fade') ?
49 | $parent
50 | .one($.support.transition.end, removeElement)
51 | .emulateTransitionEnd(150) :
52 | removeElement()
53 | }
54 |
55 |
56 | // ALERT PLUGIN DEFINITION
57 | // =======================
58 |
59 | var old = $.fn.alert
60 |
61 | $.fn.alert = function (option) {
62 | return this.each(function () {
63 | var $this = $(this)
64 | var data = $this.data('bs.alert')
65 |
66 | if (!data) $this.data('bs.alert', (data = new Alert(this)))
67 | if (typeof option == 'string') data[option].call($this)
68 | })
69 | }
70 |
71 | $.fn.alert.Constructor = Alert
72 |
73 |
74 | // ALERT NO CONFLICT
75 | // =================
76 |
77 | $.fn.alert.noConflict = function () {
78 | $.fn.alert = old
79 | return this
80 | }
81 |
82 |
83 | // ALERT DATA-API
84 | // ==============
85 |
86 | $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
87 |
88 | }(jQuery);
89 |
--------------------------------------------------------------------------------
/test/tests/main.js:
--------------------------------------------------------------------------------
1 | const expect = chai.expect;
2 | describe('main output', function () {
3 | it('can initiate main class', function () {
4 | expect(p5.soundOut.input).to.have.property('gain');
5 | expect(p5.soundOut.input).to.have.property('context');
6 | expect(p5.soundOut.output).to.have.property('gain');
7 | expect(p5.soundOut.output).to.have.property('context');
8 | expect(p5.soundOut.limiter.threshold.value).to.equal(-3);
9 | expect(p5.soundOut.limiter.ratio.value).to.equal(20);
10 | expect(p5.soundOut.limiter.knee.value).to.equal(1);
11 | expect(p5.soundOut.audiocontext).to.have.property('audioWorklet');
12 | expect(p5.soundOut.audiocontext).to.have.property('baseLatency');
13 | expect(p5.soundOut.meter).to.have.property('gain');
14 | expect(p5.soundOut.meter).to.have.property('context');
15 | expect(p5.soundOut.fftMeter).to.have.property('gain');
16 | expect(p5.soundOut.fftMeter).to.have.property('context');
17 | expect(p5.soundOut.soundArray).to.be.an('array');
18 | expect(p5.soundOut.parts).to.be.an('array');
19 | expect(p5.soundOut.extensions).to.be.an('array');
20 |
21 | expect(p5.soundOut._silentNode).to.have.property('gain');
22 | expect(p5.soundOut._silentNode).to.have.property('context');
23 | expect(p5.soundOut._silentNode.gain.value).to.equal(0);
24 |
25 | console.log(p5.soundOut);
26 | });
27 |
28 | it('can set and return output volume', function (done) {
29 | p5.prototype.outputVolume(0.6);
30 |
31 | setTimeout(function () {
32 | expect(p5.prototype.getOutputVolume()).to.be.approximately(0.6, 0.05);
33 | expect(p5.prototype.outputVolume().value).to.be.approximately(0.6, 0.05);
34 | done();
35 | }, 100);
36 | });
37 | it('can set output volume after t seconds in future', function (done) {
38 | let t = 1;
39 | p5.prototype.outputVolume(0.9, 0, t);
40 |
41 | setTimeout(function () {
42 | expect(p5.prototype.getOutputVolume()).to.be.approximately(0.9, 0.05);
43 | done();
44 | }, 1100);
45 | });
46 |
47 | it('can create a linear fade effect in output volume ', function (done) {
48 | let t = 1;
49 | p5.prototype.outputVolume(1, t, 0);
50 |
51 | setTimeout(function () {
52 | expect(p5.prototype.getOutputVolume()).to.be.approximately(0.5, 0.5);
53 | done();
54 | }, 500);
55 | });
56 |
57 | it('can connect an audio node to p5sound output', function () {
58 | let noise = new p5.Noise();
59 | p5.prototype.outputVolume(noise);
60 | });
61 | });
62 |
--------------------------------------------------------------------------------
/examples/FFT_freqRange/sketch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Display the average amount of energy (amplitude) across a range
3 | * of frequencies using the p5.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 p5.FFT();
27 |
28 | p = createP(description);
29 | var p2 = createP('Description: Using getEnergy(low, high) to measure amplitude within a range of frequencies.');
30 | }
31 |
32 | function draw() {
33 | background(30,20,30);
34 | updateDescription();
35 |
36 | fft.analyze(); // analyze before calling fft.getEnergy()
37 |
38 | // Generate 8 bars to represent 8 different frequency ranges
39 | for (var i = 0; i < 8; i++){
40 | noStroke();
41 | fill((i*30) % 100 + 50, 195, (i*25 + 50) % 255 )
42 |
43 | // Each bar has a unique frequency range
44 | var centerFreq = (pow(2,i)*125)/2;
45 | var loFreq = (pow(2,i-1)*125)/2 + centerFreq/4;
46 | var hiFreq = (centerFreq + centerFreq/2);
47 |
48 | // get the average value in a frequency range
49 | var freqValue = fft.getEnergy(loFreq, hiFreq - 1);
50 |
51 | // Rectangle height represents the average value of this frequency range
52 | var h = -height + map(freqValue, 0, 255, height, 0);
53 | rect((i+1)*width/8 - width/8, height, width/8, h);
54 |
55 | fill(255);
56 | text( loFreq.toFixed(0) +' Hz - ' + hiFreq.toFixed(0)+' Hz', (i+1)*width/8 - width/8/2, 30);
57 | }
58 | }
59 |
60 | function keyPressed() {
61 | if (soundFile.isPlaying()){
62 | soundFile.pause();
63 | } else {
64 | soundFile.loop();
65 | }
66 | }
67 |
68 | // Change description text if the song is loading, playing or paused
69 | function updateDescription() {
70 | if (!soundFile.isPlaying()) {
71 | description = 'Paused...';
72 | p.html(description);
73 | }
74 | else if (soundFile.isPlaying()){
75 | description = 'Playing!';
76 | p.html(description);
77 | }
78 | else {
79 | for (var i = 0; i < frameCount%3; i++ ) {
80 |
81 | // add periods to loading to create a fun loading bar effect
82 | if (frameCount%4 == 0){
83 | description += '.';
84 | }
85 | if (frameCount%25 == 0) {
86 | description = 'loading';
87 |
88 | }
89 | }
90 | p.html(description);
91 | }
92 | }
--------------------------------------------------------------------------------
/examples/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 ADSR envelope which stands for attack,
6 | decay, sustain, release. The amplitude rises then decays to a sustain level, then decays slowly
7 | toward the release value.
8 |
9 | .
10 | . . _______
11 | . ---
12 | . ---
13 | A D 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.001;
23 | var attackLevel = 0.9;
24 | var decayTime = 0.3;
25 | var susPercent = 0.2;
26 | var sustainTime = 0.1;
27 | var releaseTime = 0.5;
28 | var releaseLevel = 0;
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, 400);
40 | fill(0, 255, 0);
41 |
42 | trigger = millis();
43 |
44 | triOsc = new p5.TriOsc();
45 | triOsc.amp(0);
46 | triOsc.start();
47 |
48 | env = new p5.Envelope();
49 | env.setADSR(attackTime, decayTime, susPercent, releaseTime);
50 | env.setRange(attackLevel, releaseLevel);
51 |
52 | a = new p5.Amplitude();
53 | }
54 |
55 | function draw(){
56 | var size = 10;
57 | background(20, 20, 20, 70);
58 | ellipse(map ( (trigger - millis()) % duration, 1000, 0, 0, width), map ( a.getLevel(), 0, .5, height-size, 0), size, size);
59 |
60 | // If the determined trigger moment in time matches up with the computer clock and we if the
61 | // sequence of notes hasn't been finished yet the next note gets played.
62 | if ((millis() > trigger)){
63 | // midiToFreq transforms the MIDI value into a frequency in Hz which we use to control the triangle oscillator
64 | triOsc.freq(midiToFreq(midiSequence[note]));
65 |
66 | // The envelope gets triggered with the oscillator as input and the times and levels we defined earlier
67 | // play accepts an object to play, time from now, and a sustain time—how long to hold before the release.
68 | env.play(triOsc, 0, sustainTime);
69 |
70 | // Create the new trigger according to predefined durations and speed it up by deviding by 1.5
71 | trigger = millis() + duration;
72 |
73 | // Advance by one note in the midiSequence;
74 | note++;
75 |
76 | // Loop the sequence, notice the jitter
77 | if(note == 12) {
78 | note = 0;
79 | }
80 | }
81 | }
--------------------------------------------------------------------------------
/docs/yuidoc-p5-theme-src/scripts/main.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Define global App.
3 | */
4 | var App = window.App || {};
5 | define('App', function() {
6 | return App;
7 | });
8 |
9 | /**
10 | * Load json API data and start the router.
11 | * @param {module} _
12 | * @param {module} Backbone
13 | * @param {module} App
14 | * @param {module} router
15 | */
16 | require([
17 | 'underscore',
18 | 'backbone',
19 | 'App'], function(_, Backbone, App) {
20 |
21 | // Set collections
22 | App.collections = ['allItems', 'classes', 'events', 'methods', 'properties', 'p5.sound', 'p5.dom'];
23 |
24 | // Get json API data
25 | $.getJSON("data.json", function(data) {
26 | App.data = data;
27 | App.classes = [];
28 | App.methods = [];
29 | App.properties = [];
30 | App.events = [];
31 | App.allItems = [];
32 | App.sound = { items: [] };
33 | App.dom = { items: [] };
34 | App.modules = [];
35 | App.project = data.project;
36 |
37 |
38 | var modules = data.modules;
39 |
40 | // Get class items (methods, properties, events)
41 | _.each(modules, function(m, idx, array) {
42 | App.modules.push(m);
43 | if (m.name == "p5.sound") {
44 | App.sound.module = m;
45 | }
46 | else if (m.name == "p5.dom") {
47 | App.dom.module = m;
48 | }
49 | });
50 |
51 |
52 | var items = data.classitems;
53 | var classes = data.classes;
54 |
55 | // Get classes
56 | _.each(classes, function(c, idx, array) {
57 | if (c.is_constructor) {
58 | App.classes.push(c);
59 | }
60 | });
61 |
62 | // Get class items (methods, properties, events)
63 | _.each(items, function(el, idx, array) {
64 |
65 | if (el.itemtype) {
66 | if (el.itemtype === "method") {
67 | App.methods.push(el);
68 | App.allItems.push(el);
69 | } else if (el.itemtype === "property") {
70 | App.properties.push(el);
71 | App.allItems.push(el);
72 | } else if (el.itemtype === "event") {
73 | App.events.push(el);
74 | App.allItems.push(el);
75 | }
76 |
77 | // libraries
78 | if (el.module === "p5.sound") {
79 | App.sound.items.push(el);
80 | }
81 | else if (el.module === "p5.dom" || el.module === 'DOM') {
82 | if (el.class === 'p5') {
83 | el.class = 'p5.dom';
84 | }
85 | App.dom.items.push(el);
86 | }
87 | }
88 | });
89 |
90 | _.each(App.classes, function(c, idx) {
91 | c.items = _.filter(App.allItems, function(it){ return it.class === c.name; });
92 | });
93 |
94 |
95 |
96 | require(['router']);
97 | });
98 | });
--------------------------------------------------------------------------------
/test/tests/p5.Metro.js:
--------------------------------------------------------------------------------
1 | const expect = chai.expect;
2 | let metro;
3 |
4 | describe('p5.Metro', function () {
5 | beforeEach(function () {
6 | metro = new p5.Metro();
7 | });
8 |
9 | it('can be created', function () {
10 | expect(metro).to.have.property('bpm').to.equal(120);
11 | expect(metro).to.have.property('clock');
12 | expect(metro).to.have.property('syncedParts').to.be.an('array');
13 | });
14 |
15 | it('can be initialised with a beatlength, bpm', function () {
16 | metro.beatLength(0.0625);
17 | metro.setBPM(60);
18 | expect(metro.tatums).to.equal(4);
19 | expect(metro.tatumTime).to.equal(0.25);
20 | expect(metro.getBPM()).to.equal(60);
21 | });
22 |
23 | it('can be started and stopped', function (done) {
24 | this.timeout = 2000;
25 | let ticks;
26 | metro.setBPM(600);
27 | metro.start();
28 | setTimeout(() => {
29 | ticks = metro.metroTicks;
30 | metro.stop();
31 | expect(ticks).to.not.equal(0);
32 | setTimeout(() => {
33 | expect(metro.metroTicks).to.equal(ticks);
34 | done();
35 | }, 100);
36 | }, 1000);
37 | });
38 |
39 | it('can be started and stopped with delay', function (done) {
40 | let ticks;
41 | metro.setBPM(600);
42 | metro.start(0.1);
43 | setTimeout(() => {
44 | ticks = metro.metroTicks;
45 | metro.stop(0.2);
46 | expect(ticks).to.not.equal(0);
47 | setTimeout(() => {
48 | expect(metro.metroTicks).to.be.above(ticks);
49 | }, 100);
50 | setTimeout(() => {
51 | ticks = metro.metroTicks;
52 | setTimeout(() => {
53 | expect(metro.metroTicks).to.equal(ticks);
54 | done();
55 | }, 100);
56 | }, 200);
57 | }, 1000);
58 | });
59 |
60 | it('can sync parts', function () {
61 | let part = new p5.Part();
62 | part.addPhrase('snare', () => {}, [0, 0, 1, 0]);
63 | part.setBPM(60);
64 | part.noLoop();
65 | part.start();
66 | expect(metro.syncedParts.length).to.equal(0);
67 | metro.resetSync(part);
68 | expect(metro.syncedParts.length).to.equal(1);
69 | });
70 |
71 | it('parts can be pushed into syncedParts', function () {
72 | let phraseAttack = new p5.Phrase('testerAttack', () => {}, [1, 0, 0, 0]);
73 | let part = new p5.Part();
74 | part.addPhrase(phraseAttack);
75 | part.setBPM(60);
76 | part.start();
77 | expect(metro.syncedParts.length).to.equal(0);
78 | metro.pushSync(part);
79 | expect(metro.syncedParts.length).to.equal(1);
80 | metro.pushSync(part);
81 | expect(metro.syncedParts.length).to.equal(2);
82 | metro.resetSync(part);
83 | expect(metro.syncedParts.length).to.equal(1);
84 | });
85 | });
86 |
--------------------------------------------------------------------------------
/gh-page/generator.js:
--------------------------------------------------------------------------------
1 | /**
2 | * generate an index.html file with links to all the examples in the examples folder.
3 | * To run, go to the main directory and run "node gh-page/generator.js"
4 | */
5 |
6 | var fs = require('fs');
7 | var path = require('path');
8 |
9 | // array of example names
10 | var exampleNames = getDirectories('./examples');
11 | var learningProcessingExamples = getDirectories('./examples/learningProcessingExamples');
12 |
13 | // output --> index.html
14 | var fileName = 'index.html';
15 |
16 | var stream = fs.createWriteStream(fileName);
17 |
18 | stream.once('open', function(fd) {
19 | var html = buildHtml(exampleNames, learningProcessingExamples);
20 |
21 | stream.end(html);
22 | });
23 |
24 | function buildHtml(exampleNames, learningProcessingExamples) {
25 | var header = '';
26 | var body = '\n'
27 | + '
\n'
31 | + '
\n'
32 | + '
'
35 | + '
Examples:
';
36 | // Sort examples case-insensitive
37 | exampleNames = exampleNames.sort(function (a, b) {
38 | return a.toLowerCase().localeCompare(b.toLowerCase());
39 | });
40 | exampleNames.forEach(function(example) {
41 | // include everything in example folder except for the files and _* folders:
42 | if (example != 'files' && example[0] != '_' && example.indexOf('learning') != 0) {
43 | body += '
\n'
44 | };
45 | });
46 |
47 | learningProcessingExamples.forEach(function(example) {
48 | body += '
\n'
49 | });
50 |
51 | body += '
\n';
52 |
53 | // concatenate header string
54 | // concatenate body string
55 |
56 | return '\n'
57 | + '\n'
58 | + '\n\n' + body + '\n';
59 | };
60 |
61 |
62 | /** helpers **/
63 |
64 | // ia http://stackoverflow.com/a/24594123/2994108
65 | function getDirectories(srcpath) {
66 | return fs.readdirSync(srcpath).filter(function(file) {
67 | return fs.statSync(path.join(srcpath, file)).isDirectory();
68 | });
69 | }
--------------------------------------------------------------------------------